Product Management
Đăng nhập
ESC

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

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

Bài 3 — Cung cấp context: agent cần biết gì để sinh test đúng

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

Cung cấp context: agent cần biết gì để sinh test đúng

Chất lượng test agent sinh ra tỷ lệ thuận với chất lượng context bạn đưa vào. Đưa mỗi hàm trần trụi, agent sẽ đoán mò kiểu dữ liệu và bịa assertion. Bài này dạy cách gom đúng và đủ context — không thừa (tốn token, nhiễu) không thiếu (agent đoán bừa).

Context tối thiểu cho một đơn vị test

Để sinh test cho một hàm, agent cần:

  • Mã nguồn hàm cần test.
  • Chữ ký + type hints / docstring để biết input/output kỳ vọng.
  • Các dependency được gọi (hàm/class con) để biết cần mock gì.
  • Ví dụ cách hàm được gọi trong codebase (call sites) để hiểu ngữ cảnh dùng thật.
  • Convention test của dự án: framework, cách đặt tên, fixture chung.

Ví dụ: context nghèo vs context giàu

Context nghèo:

def process(order):
    return service.charge(order.total)

Agent không biết order là gì, service.charge trả về gì. Nó sẽ bịa. Context giàu bổ sung:

# Type: Order(total: Decimal, id: str)
# service.charge(amount) -> ChargeResult(success: bool, tx_id: str)
# raises PaymentError khi số dư không đủ
# Call site: process(cart.to_order())  # total luôn > 0

Giờ agent biết cần mock service.charge, test cả case success=True/False và case PaymentError.

Kỹ thuật gom context tự động

  • Parse AST để trích chữ ký hàm, các import, và tên các hàm được gọi bên trong.
  • Truy vết dependency 1 cấp: lấy định nghĩa của hàm/class được gọi trực tiếp (không lấy cả cây, tránh phình context).
  • Grep call sites: tìm nơi hàm được gọi để đưa ví dụ dùng thật.
  • Đọc file test mẫu đã có trong dự án để agent bắt chước convention.
  • Nén thông minh: với dependency dài, chỉ đưa chữ ký + docstring thay vì toàn bộ thân hàm.
# pseudocode gom context
def build_context(func):
    ctx = read_source(func)
    ctx += extract_signature_and_docstring(func)
    for dep in first_level_deps(func):        # chỉ 1 cấp
        ctx += signature_only(dep)             # nén
    ctx += grep_call_sites(func, limit=3)
    ctx += pick_sample_test_file()             # học convention
    return ctx

Khung tư duy: "Đủ để một junior viết được test"

Hãy tự hỏi: nếu đưa đúng context này cho một lập trình viên junior chưa biết codebase, họ có viết được test đúng không? Nếu họ vẫn phải hỏi "hàm này trả về gì?" thì context còn thiếu. Nếu bạn đưa cả module 2000 dòng thì context thừa — junior cũng lạc.

Cân bằng token

  • Với hàm thuần (pure function): context nhỏ, chỉ cần source + type.
  • Với hàm có side effect (DB, network, file): phải kèm signature của dependency để agent biết mock gì.
  • Với integration test: cần thêm sơ đồ luồng và fixture khởi tạo trạng thái.

Chống "context rot": chất lượng quan trọng hơn số lượng

Một hiểu lầm phổ biến là "càng nhiều context càng tốt". Thực tế ngược lại: khi prompt phình lên, tín hiệu quan trọng bị chôn giữa hàng nghìn dòng không liên quan, và mô hình dễ lạc — hiện tượng gọi là context rot. Với một hàm 20 dòng, đừng đưa cả module 2000 dòng; hãy đưa đúng 20 dòng đó cộng vài chục dòng dependency đã nén. Kết quả là test chính xác hơn, chi phí thấp hơn, và agent ít bịa test cho những hàm không hề được yêu cầu. Nguyên tắc vàng: mỗi dòng context bạn thêm vào phải trả lời được câu hỏi "dòng này giúp viết test đúng hơn ở điểm nào?". Nếu không trả lời được, hãy bỏ nó ra.

Ví dụ nén dependency đúng cách

Giả sử hàm cần test gọi tới một class PaymentGateway dài 300 dòng. Đừng dán cả 300 dòng. Thay vào đó, chỉ đưa chữ ký các phương thức được gọi và docstring của chúng: charge(amount: Decimal) -> ChargeResult; raises PaymentError. Agent chỉ cần biết giao diện của dependency để mock đúng, không cần biết cài đặt bên trong. Việc nén này vừa giữ context gọn vừa buộc agent mock thay vì gọi thật.

Sai lầm thường gặp

  • Nhồi cả file/cả repo vào prompt: token đắt, agent nhiễu, dễ bịa test cho hàm không liên quan.
  • Quên đưa type/docstring: agent đoán sai kiểu, assertion sai, test pass giả hoặc fail giả.
  • Không đưa dependency signature: agent không biết mock gì, viết test gọi thật vào DB/API.
  • Bỏ qua convention dự án: test sinh ra dùng unittest trong khi dự án dùng pytest, không khớp fixture chung.
  • Đưa call site sai: lấy nhầm ví dụ ở test cũ đã lỗi thời, agent học theo cái sai.
Có context tốt rồi, bài 4 ta bắt tay dựng vòng lặp agent sinh test hoàn chỉnh đầu tiên.

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