AIDive

Gói video

Vòng kiểm tra trong Claude Code: bảng bench, checklist Stop hook và nguồn

10 phút đọc

TL;DR

  • Khuyến nghị của chính Anthropic đúng về tinh thần: model có vòng phản hồi sẽ làm ra kết quả tốt hơn. Vấn đề là ai chạy vòng đó. Trong 116 lần chạy, /verify có sẵn trả về PASS 24 trên 24 lần, kể cả với một thay đổi làm hỏng một yêu cầu đã nêu rõ.
  • Model tự kiểm tra thay đổi của mình thì có chung điểm mù. Haiku 4.5 bỏ sót cùng một trường hợp unique-field ở 11 trên 11 lần chạy, trong mọi setup dùng cùng model, và /verify của chính nó còn đánh dấu tick bên cạnh trường hợp sai.
  • Trên Opus 5.5, /verify tốn gấp 2.5 lần ($0.96 so với $0.39) mà không đổi kết quả nào. Opus thường làm đúng 12 trên 12 và tự chạy test suite trong 11 lần.
  • Project skill là tùy chọn với model: nó chỉ kích hoạt ở 10 trên 24 lần chạy, 0 trên 6 với Haiku. Stop hook kích hoạt ở mọi lần chạy, với chi phí tăng khoảng 20% trên Opus.
  • Kiểm tra hiệu quả đến từ bên ngoài tác giả: cùng /verify đó chạy bằng Opus báo FAIL 3 trên 3 lần với thay đổi của Haiku và chỉ đúng bug. Gắn thành Stop hook, nó giúp Haiku sửa được bug 3 trên 3 lần, với $1.36 mỗi task so với $0.76 khi Opus tự viết task đó.
  • Nên áp dụng: một Stop hook cho phần deterministic, một verifier không phải tác giả cho phần cần phán đoán, và đừng dùng /verify trên Opus cho việc đã đặc tả rõ.

What the measurements say

Lời của Anthropic: "If Claude has that feedback loop, it will 2-3x the quality of the final result." s4 Blog biến nó thành quy trình áp dụng 5 bước: chọn thao tác kiểm tra thủ công lặp lại nhiều nhất, thử /verify có sẵn, viết quy trình bằng tiếng Anh thường thành một skill, làm cho nó deterministic, rồi chuyển sang CI. s1 Từ v2.1.215, "Claude no longer runs the /verify and /code-review skills on its own; invoke them with /verify or /code-review when you want them." s3

Các báo cáo thực tế đều nói về việc kiểm tra được tuyên bố nhưng không được chạy. Issue #96416 là một kết luận review với 19 mối lo, 5 được xác minh, vậy mà vẫn "accept as-is". s6 Issue #97039 là một tuyên bố "held up" sau khi chỉ kiểm tra một phần, dù checklist đã được nạp. s7 "build passes" và "production-ready" là hai mức khác nhau, và mỗi lần trượt tốn 2-3 vòng prompt lại. s8

Bench của chúng tôi chấm mọi lần "done" bằng các acceptance test ẩn mà agent không bao giờ thấy. 112 lần chạy task + 4 lần chạy /verify chéo model = 116 lần chạy, chi tiêu tương đương API là $66.29. "Done" sai: 12 trên 112, trong đó 11 là Haiku ở T6 trong mọi setup từ A đến E, 1 là Sonnet ở T6 với setup skill, khi các test mới của chính nó đang fail và skill không hề kích hoạt. s1

/verify có sẵn nói Verdict: PASS trong 24 trên 24 lần chạy ở cả ba model (23 parse được, 1 pass không có nhãn), kể cả T6 bị hỏng của Haiku. Trên Opus nó tốn $0.96 so với $0.39 khi chạy thường (gấp 2.5 lần) và 125 s so với 75 s; nó không đổi kết quả nào. s3

Project skill viết theo quy trình 5 bước được gọi ở 10 trên 24 lần chạy: Opus 8/12, Sonnet 2/6, Haiku 0/6. Stop hook kích hoạt ở mọi lần chạy, với $0.47 so với $0.39 trên Opus (+20 %). s19

Điểm mù là một yêu cầu, T6 req 4: một lệnh update duy nhất gán cùng một giá trị unique cho nhiều document khớp phải ném DuplicateKeyError. Haiku bỏ sót ở 11 trên 11 lần chạy, trong mọi setup (plain, /verify, skill, hook, tests first). /verify của chính Haiku kiểm tra "update one doc onto another's email" và không bao giờ thử một update tác động lên nhiều document. Quy tắc tests-first cũng không giúp được: vẫn 3/3 lần bỏ sót req 4, và một lần còn làm hỏng cả req 3. s1

Cùng thay đổi đó của Haiku, /verify chạy bằng model khác: Sonnet nói PASS (1/1), Opus nói FAIL 3/3, mỗi lần đều chỉ ra cùng một trường hợp, một update ghi cùng một giá trị vào nhiều document, với $0.39 đến $0.47 mỗi lần kiểm tra. Khi làm Stop hook trên Haiku (setup F), verifier Opus giúp bug được sửa ở 3 trên 3 lần chạy; cả ba đều chạm giới hạn 60 turn khi sửa, với trung bình $1.36 mỗi lần chạy T6 đã gồm verifier, so với $0.76 khi Opus tự viết T6 với 0 "done" sai. s19

Measurements

Harness: Claude Code 2.1.283 headless (claude -p), config dir tách biệt, cùng prompt cho mỗi task, giới hạn 60 turn. Repo: msiemens/tinydb @ 18d73a1 (Python, 226 test). Sáu yêu cầu tính năng T1 đến T6, mỗi cái có 5 yêu cầu đã nêu (T5: 6). Các acceptance test ẩn, mỗi yêu cầu một test và không bao giờ cho agent xem, chấm mọi lần chạy; test suite của repo cũng được chạy. "Done" sai là một lần chạy kết thúc bằng tuyên bố hoàn thành trong khi một hidden test hoặc suite của repo vẫn fail.

Các setup: A plain (chỉ có yêu cầu); B /verify (A, rồi /verify có sẵn ở turn thứ hai); C verify skill (một project skill model có thể tự gọi, viết theo quy trình 5 bước); D Stop hook (prove-it.py: chặn dừng khi suite còn đỏ, và chặn lần dừng đầu để đòi một dòng bằng chứng cho mỗi yêu cầu); E tests first (một quy tắc CLAUDE.md: một test fail cho mỗi yêu cầu trước khi viết code); F Opus verifier hook (claude -p /verify --model opus trên thay đổi, chặn khi verdict không phải PASS, tối đa 2 vòng).

model setup runs false done avg cost avg turns avg wall
Opus 5.5 A plain 12 0 $0.39 16.6 75 s
Opus 5.5 B /verify 12 0 $0.96 22.3 125 s
Opus 5.5 C skill 12 0 $0.43 19.5 80 s
Opus 5.5 D hook 12 0 $0.47 19.8 94 s
Opus 5.5 E tests first 2 (T6) 0 $0.64 18.5 129 s
Sonnet 5 A 7 0 $0.44 24.0 112 s
Sonnet 5 B 6 0 $1.18 36.3 210 s
Sonnet 5 C 7 1 $0.48 25.7 136 s
Sonnet 5 D 6 0 $0.53 27.0 157 s
Haiku 4.5 A 8 3 $0.34 35.4 172 s
Haiku 4.5 B 6 1 $0.68 43.3 217 s
Haiku 4.5 C 6 1 $0.26 28.2 124 s
Haiku 4.5 D 8 3 $0.37 38.9 179 s
Haiku 4.5 E 3 (T6) 3 $0.41 38.3 186 s
Haiku 4.5 F Opus verifier 3 (T6) 0 $1.36 gồm verifier 61 (cap) 457 s
Sonnet 5 F 1 (T6) 0 $2.30 gồm verifier 50 512 s

Giới hạn: một repo (thư viện Python nhỏ, test tốt), sáu yêu cầu đã đặc tả rõ, 1 đến 3 lần lặp mỗi ô, chạy headless. Các hidden test chỉ kiểm tra những gì yêu cầu nêu ra.

Do this Monday

  • Tự viết một acceptance test cho mỗi yêu cầu đã nêu, trước khi bạn đọc "done" của model. Các hidden test của bench đã bắt được thứ mà mọi lần kiểm tra cùng model đều bỏ sót.
  • Thêm một Stop hook chạy test suite của bạn và trả về block decision khi suite còn đỏ. Nó kích hoạt ở mọi lần chạy; skill thì không.
  • Bắt lần dừng đầu tiên của task phải kèm một dòng bằng chứng cho mỗi yêu cầu (mẫu prove-it.py): một lệnh và output của nó, không phải một câu nói.
  • Chuyển phần kiểm tra cần phán đoán sang một model không viết thay đổi đó: claude -p /verify --model opus trên diff, chặn khi verdict không phải PASS, tối đa 2 vòng.
  • Trên Opus 5.5 với yêu cầu đã đặc tả rõ, đừng gõ /verify theo thói quen nữa. Nó tốn gấp 2.5 lần và không đổi gì trong 12 lần chạy; chỉ dành cho vùng code không có test hoặc khi săn một bug có từ trước.
  • Nếu bạn giao việc cho Haiku 4.5 để tiết kiệm, hãy tính ngân sách cho verifier: $1.36 mỗi task với Opus hook so với $0.76 khi Opus tự viết.
  • Ghi mọi lần retry của một bản sửa thất bại vào một ledger và dừng vòng lặp sau một lần lặp lại, để blocking hook không đốt token vào cùng một patch sai.
  • Đọc lại yêu cầu của bạn cho trường hợp nhiều dòng: "one update that matches several documents" chính là dạng trường hợp mà 11 trên 11 lần chạy Haiku không bao giờ thử.

Go further

  • Quy trình 5 bước và thang trưởng thành, từ kiểm tra thủ công đến CI gate: các bậc trên cùng (CI và PR gate) là nơi phần deterministic nên nằm khi hook của bạn đã chạy ổn ở local. s1
  • Ngữ nghĩa của Stop hook: một block decision kèm reason sẽ đưa turn quay lại model; hãy đọc exit code và JSON contract trước khi tự viết gate. s19
  • Groundtruth, một Stop hook từ chối kết thúc turn cho đến khi các check pass: phiên bản deterministic của ý tưởng này, đọc được như một implementation tham chiếu. s5
  • regressionledger, mặt chi phí: một hook ngăn vòng lặp retry cùng một bản sửa thất bại, phần mà Stop hook của chúng tôi còn thiếu khi các lần chạy chạm giới hạn 60 turn. s10

Sources

  • Building verification loops in Claude Code with skills, Anthropic blog. Vì sao nên đọc: quy trình 5 bước và cái thang mà setup skill của bench được xây dựa trên.
  • Building verification loops in Claude Code, official Claude channel. Vì sao nên đọc: ba phút về việc /verify làm gì ở lần chạy đầu, trước khi bạn quyết định có giữ nó hay không.
  • Claude Code CHANGELOG, GitHub. Vì sao nên đọc: v2.1.215 là nơi /verify chuyển sang chỉ do người dùng gọi, điều này thay đổi tần suất nó chạy với bạn.
  • Boris Cherny: give Claude a way to verify its work, X. Vì sao nên đọc: câu "2-3x the quality" nguyên văn.
  • Groundtruth, GitHub. Vì sao nên đọc: một Stop hook gate chạy được để copy thay vì viết từ đầu.
  • Issue #96416, GitHub. Vì sao nên đọc: bản transcript có ngày tháng của một review verdict chỉ xác minh 5 trên 19 mối lo rồi vẫn chấp nhận.
  • Issue #97039, GitHub. Vì sao nên đọc: cùng kiểu lỗi hai ngày sau, dù đã nạp checklist, nên checklist không phải cách chữa.
  • AI coding agents can verify some of their work now, dev.to. Vì sao nên đọc: cách nói rõ nhất về khoảng cách giữa "build passes" và "production-ready".
  • Saguaro, GitHub. Vì sao nên đọc: cuộc tranh luận review trong vòng lặp so với review ở cấp PR, kèm phản biện trong phần bình luận.
  • regressionledger, GitHub. Vì sao nên đọc: bài toán chi phí retry mà một blocking hook tạo ra, và một cách để giới hạn nó.
  • SPICE simulation to oscilloscope to verification with Claude Code, personal blog. Vì sao nên đọc: một vòng verification mà oracle là một thiết bị đo vật lý.
  • Hooks reference, code.claude.com. Vì sao nên đọc: block decision contract mà Stop hook của bạn phải tuân theo.

FAQ

/verify có sẵn có bắt được bug không?

Không, trong bench này. Nó trả về PASS ở 24 trên 24 lần chạy với Opus 5.5, Sonnet 5 và Haiku 4.5, kể cả một thay đổi của Haiku làm hỏng một yêu cầu đã nêu. Phát hiện hữu ích duy nhất của nó là một bug upstream có từ trước, không liên quan đến thay đổi.

Vì sao verifier mạnh hơn lại giúp được model viết yếu hơn?

Phép kiểm tra của chính Haiku chỉ thử trường hợp nó đã nghĩ tới. Opus, với cùng thay đổi và cùng /verify, đã thử một update tác động lên nhiều document và nói FAIL 3 trên 3 lần. Sonnet nói PASS. Verifier phải thấy một trường hợp mà tác giả không thấy.

Dùng Opus để verify Haiku hay dùng Opus để viết thì rẻ hơn?

Hãy viết bằng Opus. Opus verifier hook trên Haiku trung bình $1.36 mỗi lần chạy T6 và chạm giới hạn 60 turn mọi lần; Opus tự viết T6 trung bình $0.76 với 0 "done" sai.