Product Management
Đăng nhập
ESC

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

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

Bài 4 — Sinh docstring chất lượng cao và nhất quán phong cách

Đã đọ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.

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 ở temperature thấ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ả Returns khi 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.
Kết bài: agent sinh được docstring chuẩn, an toàn, nhất quán. Bài 5 ta lên tầng cao hơn — sinh và cập nhật README từ codebase.

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