Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 2 — Thiết lập môi trường và khung agent tối thiểu

Đã đọc 0/9 mục · còn khoảng 4 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Bài này bạn sẽ dựng một Documentation Agent "chạy được" ở mức tối thiểu: đọc một file code, gọi LLM, và trả về docstring. Từ khung này ta mở rộng dần ở các bài sau.

Kiến trúc thành phần

Một Documentation Agent gồm 4 khối:

  • Source Reader — đọc code (file, diff, hoặc AST).
  • LLM Client — gọi model để sinh/chỉnh docs.
  • Prompt Layer — chứa system prompt + template cho từng loại docs.
  • Writer — ghi kết quả ra file/PR/comment.
Source Reader --> Prompt Layer --> LLM Client --> Writer

Các bước thiết lập

  • Tạo virtualenv và cài thư viện:
python -m venv .venv
source .venv/bin/activate
pip install openai anthropic python-dotenv
  • Đặt API key vào .env (không commit file này):
OPENAI_API_KEY=sk-...
MODEL=gpt-4o-mini
  • Viết LLM Client mỏng — tách khỏi logic để dễ đổi provider:
import os
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()
client = OpenAI()

def ask_llm(system, user):
    resp = client.chat.completions.create(
        model=os.getenv("MODEL", "gpt-4o-mini"),
        temperature=0.2,          # docs can chinh xac, khong sang tao
        messages=[
            {"role": "system", "content": system},
            {"role": "user", "content": user},
        ],
    )
    return resp.choices[0].message.content
  • Tạo system prompt chuyên biệt cho tài liệu:
DOC_SYSTEM = (
    "Ban la ky su tai lieu. CHI mo ta nhung gi CO trong code. "
    "Neu khong chac, ghi 'khong ro tu code'. Khong bia tham so, "
    "khong bia gia tri tra ve. Giu dung ngon ngu goc cua project."
)
  • Ghép thành agent tối thiểu sinh docstring cho một file:
def gen_docstring(path):
    code = open(path).read()
    user = f"Sinh docstring kieu Google cho cac ham trong file:\n\n{code}"
    return ask_llm(DOC_SYSTEM, user)

if __name__ == "__main__":
    import sys
    print(gen_docstring(sys.argv[1]))
  • Chạy thử: python agent.py yourfile.py và đọc kết quả.

Vì sao temperature thấp

Tài liệu cần chính xác và ổn định, không cần sáng tạo. Đặt temperature=0.2 (hoặc thấp hơn) giúp giảm bịa đặt (hallucination) và làm output ổn định giữa các lần chạy — quan trọng khi bạn muốn diff kết quả.

Khung tư duy: chống hallucination ngay từ prompt

Rủi ro số một của doc agent là bịa tham số, kiểu trả về, hành vi không tồn tại. Ba lớp phòng thủ:

  • Prompt ràng buộc — yêu cầu "chỉ mô tả cái có trong code", cho phép nói "không rõ".
  • Ngữ cảnh đủ — đưa nguyên hàm + chữ ký + type hint, không đưa mẩu cụt.
  • Verify sau sinh — đối chiếu tham số trong docs với chữ ký thật (Bài 6).

Vì sao tách LLM Client thành một lớp mỏng

Đừng gọi API của provider rải rác trong toàn bộ mã. Hãy gói mọi lời gọi qua một hàm ask_llm() duy nhất. Lợi ích rất thực tế: khi bạn muốn đổi từ OpenAI sang Anthropic, sang một model chạy local (như qua Ollama) để tiết kiệm chi phí, hoặc thêm retry/logging/đếm token, bạn chỉ sửa một chỗ. Lớp mỏng này cũng là nơi lý tưởng để chèn cache (Bài 7): trước khi gọi model, kiểm tra xem nội dung hàm này đã sinh docs chưa, nếu chưa đổi thì trả về kết quả cũ, khỏi tốn tiền.

Cấu trúc thư mục gợi ý

Để agent dễ mở rộng qua các bài, tổ chức mã ngay từ đầu:

doc_agent/
  __init__.py
  llm.py        # ask_llm(), cau hinh provider
  prompts.py    # DOC_SYSTEM va cac template
  reader.py     # doc code (Bai 3)
  generator.py  # sinh docstring/README (Bai 4-5)
  verifier.py   # phat hien drift (Bai 6)
  cli.py        # entrypoint check|fix (Bai 7)

Mỗi khối một file, ghép qua CLI. Kiến trúc này giúp bạn thay từng phần (ví dụ đổi reader Python sang tree-sitter) mà không đụng phần còn lại.

Kiểm thử nhanh khung tối thiểu

  • Tạo một file sample.py với 2-3 hàm đơn giản, cố tình bỏ trống docstring.
  • Chạy python -m doc_agent.cli sample.py.
  • Đọc output: mọi tham số có được mô tả đúng không? Có tham số bịa không?
  • Thử hạ temperature xuống 0 và chạy lại 3 lần — output có ổn định (giống nhau) không?
  • Ghi lại thời gian và số token — đây là baseline chi phí bạn sẽ tối ưu ở Bài 7.

Sai lầm thường gặp

  • Hard-code provider vào khắp nơi. Khi cần đổi từ OpenAI sang model local, bạn phải sửa hàng chục chỗ. Luôn để một ask_llm() duy nhất.
  • Để temperature cao. Docs sẽ "bay", mỗi lần chạy một kiểu, khó review bằng diff.
  • Nhồi cả repo vào một prompt. Vượt context window, tốn tiền, và model lạc. Ở bài sau ta sẽ đọc theo diff/AST thay vì cả file.
  • Commit .env. Lộ API key. Luôn thêm .env vào .gitignore.
  • Không xử lý lỗi mạng/timeout. API sẽ có lúc lỗi; bọc ask_llm() bằng retry có backoff để agent không sập giữa chừng.
Kết bài: bạn đã có agent tối thiểu Reader→Prompt→LLM→Writer với cấu trúc dễ mở rộng. Bài 3 ta nâng chất lượng bằng cách phân tích cấu trúc code (AST) thay vì ném raw text.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi