Có dữ liệu AST rồi, giờ ta sinh docstring đúng, đầy đủ và nhất quán style trên cả codebase. Chất lượng docstring quyết định uy tín của agent: sai một lần là người ta ngừng tin.
Chọn một style và ép nó
Đừng để mỗi hàm một kiểu. Chọn một chuẩn: Google style, NumPy style, hoặc reST/Sphinx. Ví dụ Google style:
def fetch_user(user_id, retries=3, timeout=30):
"""Lay thong tin user tu dich vu backend.
Args:
user_id (int): ID duy nhat cua user.
retries (int): So lan thu lai khi that bai. Mac dinh 3.
timeout (int): Thoi gian cho toi da (giay). Mac dinh 30.
Returns:
dict: Ban ghi user, gom cac khoa 'id', 'name', 'email'.
Raises:
TimeoutError: Khi vuot qua timeout.
"""
Đưa một ví dụ mẫu (few-shot) như trên vào prompt để model bắt chước cấu trúc chính xác.
Các bước sinh docstring hàng loạt
- Lấy danh sách hàm cần docs từ Source Reader (Bài 3).
- Với mỗi hàm, build prompt gồm: contract tham số + ví dụ few-shot style + mã nguồn.
- Gọi LLM ở
temperaturethấp. - Chèn docstring vào đúng vị trí (ngay sau dòng
def) — dùng lineno/AST, không dùng thay-chuỗi thô. - Chạy formatter (
black,ruff) để chuẩn hóa. - Lưu dưới dạng diff/PR nháp, không ghi đè trực tiếp lên nhánh chính.
Chèn docstring an toàn
Dùng thư viện như libcst (giữ nguyên format, comment) thay vì nối chuỗi:
import libcst as cst
# libcst cho phep sua cay cu phap va giu nguyen dinh dang goc,
# an toan hon nhieu so voi noi chuoi hay regex.
Nối chuỗi/regex rất dễ làm hỏng thụt lề hoặc chèn nhầm chỗ.
Khung chất lượng: 5 tiêu chí một docstring tốt
- Chính xác — mọi tham số/return khớp chữ ký thật.
- Đầy đủ — không thiếu tham số, có mô tả Raises nếu hàm ném lỗi.
- Ngắn gọn — một câu tóm tắt ở dòng đầu.
- Giải thích "tại sao" khi hành vi không hiển nhiên (agent nên đánh dấu TODO cho người bổ sung ý đồ).
- Nhất quán style trên toàn repo.
Checklist review trước khi merge
- [ ] Số tham số trong docstring = số tham số chữ ký.
- [ ] Không có tham số "lạ" bị bịa.
- [ ] Kiểu trả về khớp thực tế code.
- [ ] Style đồng nhất với phần còn lại của repo.
- [ ] Formatter chạy sạch, không lỗi lint.
Xử lý theo lô (batch) để tiết kiệm chi phí
Trên repo có hàng trăm hàm cần docs, gọi LLM tuần tự vừa chậm vừa dễ chạm rate limit. Vài kỹ thuật thực chiến:
- Nhóm hàm nhỏ liên quan vào một lời gọi (ví dụ các hàm trong cùng một class), yêu cầu model trả về JSON gồm docstring cho từng hàm — giảm số round-trip.
- Gọi song song với giới hạn đồng thời (semaphore) để tránh vượt quota.
- Cache theo hash nội dung hàm: nếu hàm không đổi so với lần chạy trước, dùng lại docstring cũ.
- Sắp ưu tiên: sinh docs cho public API trước, private/nội bộ sau.
Đánh dấu chỗ cần con người bổ sung
Model mô tả tốt phần cơ học (tham số, return), nhưng phần "tại sao" — lý do chọn thuật toán, cảnh báo về hiệu năng, ràng buộc nghiệp vụ — thường nằm ngoài code. Thay vì để model bịa, hãy cho nó chèn một dấu nhắc để người bổ sung:
def rebalance(portfolio, strategy="equal"):
"""Can bang lai danh muc theo chien luoc cho truoc.
Args:
portfolio (dict): Danh muc hien tai.
strategy (str): Ten chien luoc. Mac dinh 'equal'.
Returns:
dict: Danh muc sau can bang.
Note:
TODO(doc): Giai thich VI SAO chon nguong 5%% o day.
"""
Dấu TODO(doc) biến những khoảng trống tri thức thành việc cụ thể, có thể grep và giao cho người phù hợp — thay vì để docstring nghe trơn tru nhưng thiếu chiều sâu.
Sai lầm thường gặp
- Để model "tán" dài dòng. Docstring 15 dòng cho hàm 3 dòng làm nhiễu. Ràng buộc độ dài trong prompt.
- Bịa mô tả
Returnskhi hàm không return gì. Contract hóa cả return type từ AST/type hint. - Ghi đè docstring người viết tay chứa ý đồ quý giá. Với hàm đã có docstring "tốt", hãy bổ sung phần thiếu thay vì thay mới hoàn toàn.
- Chèn bằng regex. Hỏng thụt lề Python. Dùng libcst/AST.
- Không chạy formatter/lint. Docs đúng nội dung nhưng bẩn format vẫn bị reviewer bực.
- Sinh hàng loạt rồi commit thẳng lên nhánh chính. Luôn xuất thành PR nháp để người review — agent tạo bản nháp, không phải quyết định cuối.