Thí nghiệm AI sinh test case gồm những gì

Spec thử nghiệm: một tính năng voucher có gài bẫy

Mình soạn một bản đặc tả tính năng quản lý mã giảm giá (voucher) trên Admin Portal, mã VCH-201, viết đúng kiểu spec ngoài đời: bảng phân quyền 3 role, bảng validation 10 field, sơ đồ vòng đời 5 trạng thái, luồng áp mã ở Checkout với thứ tự kiểm tra 6 bước, công thức tính tiền giảm, 5 acceptance criteria. Và một đoạn comment trao đổi của PO, Dev lead, QA ở cuối, y như một ticket Jira thật. Bạn có thể tham khảo specs này tại đây 

Điểm mấu chốt: spec cố tình được gài 12 cái bẫy, đúng những kiểu lỗi spec mà bạn gặp hằng ngày:

Loại bẫy Ví dụ trong spec VCH-201
Mâu thuẫn nội bộ Bảng ghi end_date tối đa 90 ngày, message lỗi chuẩn lại ghi "không quá 180 ngày"
Thông tin chỉ nằm trong comment PO comment: code không được bắt đầu bằng chữ số. Bảng validation không có dòng này
Sơ đồ thiếu nhánh Diagram không có mũi tên PAUSED → ACTIVE, nhưng comment PO nói "được, sẽ update sau"
Spec im lặng Voucher đang PAUSED mà quá end_date thì thành gì? Không ai nói
Diễn đạt nước đôi max_discount cột "Bắt buộc" ghi "Chỉ khi PERCENT", cột quy tắc lại ghi "bỏ trống = không giới hạn"
Hệ quả tính toán không ai nghĩ tới Đơn 15.000đ, giảm 5%, làm tròn xuống nghìn → giảm . Cho qua hay chặn?
Cửa sổ thời gian Job chuyển EXPIRED chạy 15 phút/lần → có 15 phút voucher đã hết hạn nhưng DB vẫn ghi ACTIVE

Một tester giỏi không chỉ viết test case cho những gì spec ghi. Họ phát hiện những gì spec quên ghi. 12 cái bẫy này là thước đo cho đúng năng lực đó. Danh sách bẫy được viết trước, cất riêng, và không agent nào được nhìn thấy.

Hai cách dùng AI được đem so

Mình dựng hai luồng AI sinh test case bằng Claude Code với subagent, cùng model, cùng spec, cùng format output. Khác biệt duy nhất nằm ở chỗ checklist nằm ở đâu.

  Cách 1: gộp chung (tự kiểm) Cách 2: tách kiểm độc lập
Ai viết test case 1 agent 1 agent
Agent viết có thấy checklist 12 tiêu chí? , nằm ngay trong context lúc viết Không, hoàn toàn mù checklist
Ai chấm Chính agent đó tự đọc lại và tự chấm Một agent verifier riêng, chỉ đọc, không được sửa
Vòng sửa Tự sửa trong cùng lượt, tối đa 2 vòng Verifier trả báo cáo FAIL kèm bằng chứng → agent viết sửa, tối đa 2 vòng revise
Số test case ra 98 119
Thời gian chạy ~13 phút ~37 phút

Bộ checklist 12 tiêu chí là loại nhị phân, PASS hoặc FAIL, mỗi FAIL phải kèm bằng chứng là ID test case cụ thể. Nó gồm những thứ rất quen với người viết test case chuẩn: ID duy nhất, truy vết được về requirement, có case negative, đủ giá trị biên, test data cụ thể, kết quả kỳ vọng quan sát được, mỗi step một hành động, dùng đúng thuật ngữ spec, khai báo assumption, không trùng lặp, có priority.

Môi trường thực hiện so sánh

Minh ghi rõ môi trường ở đây, và quan trọng hơn là ghi rõ những gì được giữ giống hệt nhau giữa hai setup, để khi kết quả lệch, ta biết chắc nó lệch vì đâu. Cấu trúc thư mục đã được để trong folder google drive trên đầu bài nha.

Nền tảng

Thành phần Cấu hình
Công cụ điều phối Claude Code, mỗi agent là một subagent định nghĩa bằng file markdown trong thư mục .claude/agents/
Model của agent sinh và agent verifier Claude Fable 5.1, khai báo model: inherit nên cả hai cách kế thừa đúng một model từ phiên làm việc
Model của judge (bên chấm cuối) Claude Opus, cấu hình riêng, khác model sinh, để bên chấm không "cùng gu" với bên viết
Cách kích hoạt Mỗi cách là một slash command: một lệnh cho cách 1, một lệnh cho cách 2, một lệnh chấm judge. Người điều phối chỉ gõ lệnh, không tự viết hay tự chấm test case
Spec Một file markdown duy nhất, cả hai cách đọc cùng file, cùng phiên bản
Answer key (12 bẫy + 31 yêu cầu gốc) Viết xong trước khi chạy, để ngoài context của mọi agent sinh và verifier, chỉ judge được đọc

Chọn Fable 5.1 cho cả hai bên là có chủ ý. Nếu để cách 2 chạy model mạnh hơn, mọi khoảng cách đo được đều có thể đổ cho model, và thí nghiệm mất ý nghĩa. Còn judge chạy trên một model khác là để tránh một dạng thiên vị tinh vi: model thường "thích" văn phong của chính nó, và nếu judge cùng model với bên sinh, nó có thể chấm nhẹ tay hơn cho những đoạn nghe quen tai.

Những gì giống nhau giữa hai setup

Đây là danh sách tôi kiểm lại từng dòng trước khi chạy. Bất kỳ dòng nào khác nhau đều là một biến số lẫn vào kết quả.

Yếu tố Cách 1 Cách 2 Giống?
Model sinh test case Fable 5.1 Fable 5.1
Spec đầu vào VCH-201-voucher.md VCH-201-voucher.md
Vai được gán trong system prompt "Senior QA engineer sinh test case từ spec" "Senior QA engineer sinh test case từ spec"
Skill định dạng output tc-format: cùng header, cùng mục Assumptions, cùng bảng Requirement index, cùng khối test case (ID, Requirement, Type, Priority, Preconditions, Test data, Steps, Expected result) Cùng skill tc-format
Quy tắc trích yêu cầu "Đọc hết spec, trích mọi requirement vào Requirement index, gồm validation, message, chuyển trạng thái, phân quyền" Cùng câu chữ
Xử lý chỗ spec mơ hồ "Không hỏi lại, ghi mọi điểm mơ hồ thành assumption" Cùng câu chữ
Bộ công cụ agent được dùng Read, Write, Glob, Grep Read, Write, Glob, Grep
Nội dung checklist 12 tiêu chí Cùng file tc-checklist, cùng câu chữ từng mục Cùng file, verifier dùng
Giới hạn số vòng sửa Tối đa 2 vòng tự sửa Tối đa 2 vòng revise sau verifier
Nơi ghi output docs/refinements/VCH-201/test-cases-A.md docs/refinements/VCH-201/test-cases-B.md Có (chỉ khác hậu tố)
Ngôn ngữ output Theo ngôn ngữ spec (tiếng Việt, thuật ngữ giữ tiếng Anh) Cùng quy tắc
Ai được nhìn answer key Chặn với AI agent Chặn với AI agent

Điểm biệt

Yếu tố Cách 1 Cách 2
Skill nạp vào agent sinh tc-format + tc-checklist Chỉ tc-format
Chỉ dẫn lúc viết "Dùng 12 tiêu chí làm kim chỉ nam khi viết" "Phủ positive, negative, boundary cho từng requirement bằng phán đoán nghề nghiệp của bạn"
Ai chấm Cùng agent, cùng context, ngay sau khi viết xong Agent verifier riêng, context mới hoàn toàn, nạp tc-checklist
Verifier có được sửa file không (không có verifier) Không. Chỉ đọc, chỉ ghi báo cáo, chỉ mô tả cần sửa gì ở đâu, không được viết lại test case
Verifier đọc gì trước (không có) Đọc spec trước, tự lập danh sách requirement riêng, rồi mới mở file test case để đối chiếu
Thứ báo cáo tự chấm nằm ở đâu Nối vào cuối chính file test case, mục ## Self-check File báo cáo riêng, mỗi vòng một file

Nghĩa là toàn bộ chênh lệch đo được phía sau chỉ có thể đến từ hai chỗ: checklist có nằm trong context lúc viết hay không, và người chấm có phải là người viết hay không. Hai biến này đi cùng nhau trong thí nghiệm hiện tạ. Đây cũng là mục tiêu chính của thí nghiệm lần này,

Với các thứ 2, mình cũng sẽ có 1 orchestrator nhỏ để đảm bảo được điều phối giữa 2 agent (generator và verifier) . Orchestrator sẽ  chuyển báo cáo từ verifier sang agent Generator và đếm số lượt phản hồi. Tuyệt đối không cho phép đưa thêm thông tin vào cho bất kỳ agent nào.

Cách thực hiện đánh giá

Mình dùng 3 phương án để đảm bảo tính độc lập trong quá trình đánh giá. Việc đánh giá cũng được sử dụng AI với model khác để đảm bảo tính độc lập:

  1. Answer key viết trước, chỉ cung cấp cho agent đánh giá. 12 bẫy và 31 yêu cầu gốc được soạn xong trước khi chạy bất kỳ agent nào, và không đưa vào context của agent nào cả. Điểm cuối cùng không lấy từ bản tự chấm của cách 1, cũng không lấy từ báo cáo verifier của cách 2, mà từ một agent chấm (judge) thứ ba.
  2. Chấm mù. Judge chỉ nhận hai file tên "X" và "Y", không biết đâu là cách 1, đâu là cách 2. Nó được dặn không để độ dài file hay độ "bóng bẩy" ảnh hưởng điểm, và mọi điểm PASS đều phải có bằng chứng.
  3. Chạy 2 lần, đảo vị trí. Vòng 1: X là cách 1, Y là cách 2. Vòng 2: đổi ngược lại. Nếu judge có thói quen thiên vị file đứng trước (position bias), đảo vị trí sẽ lộ ra ngay. Kết luận chỉ có hiệu lực khi cả hai vòng cùng chọn một bên.

Bạn để ý nhé: đây chính là tính độc lập ở tầng chấm điểm. Mình không tin cả bản tự chấm lẫn bản verifier, nên mới cần một judge không dính dáng gì đến quá trình sinh.

Kết quả

Bảng tổng kết

Tiêu chí đo Cách 1: gộp chung Cách 2: tách kiểm độc lập Bên hơn
Phủ 31 yêu cầu gốc 31/31 31/31 Hòa
Có case negative cho 20 yêu cầu nhận input 20/20 20/20 Hòa
Phủ giá trị biên cho 13 ràng buộc 12/13 13/13 Cách 2
Precision (không có test case thừa) 1.00 1.00 Hòa
Phát hiện bẫy gài trong spec 6/12 10/12 Cách 2
Đạt checklist chất lượng 8–9/12 11/12 Cách 2
Tổng số test case 98 119 (không tính điểm)

Cả hai vòng chấm đều chọn cách 2. Không có tiêu chí nào hai vòng mâu thuẫn nhau.

Bốn cái bẫy chỉ cấu trúc agent độ lập phát hiện được

Cả hai cách đều bắt được 6 bẫy "dễ thấy" như nhau: mâu thuẫn 90/180 ngày, quy tắc code trong comment, nhánh PAUSED → ACTIVE thiếu trong diagram, hai chỗ nước đôi của max_discount, và chuyện phân biệt hoa/thường khi gọi API. Cách 2 bắt thêm 4 điểm sau:

Bẫy Vấn đề spec không nói Cách 2 xử lý thế nào
Voucher PAUSED quá end_date Diagram chỉ có ACTIVE → EXPIRED. Voucher đang tạm dừng mà hết hạn thì job có đụng không? Khai báo assumption "job chỉ tác động voucher ACTIVE" + test case kiểm tra voucher DRAFT/PAUSED quá hạn vẫn giữ nguyên trạng thái, ghi rõ cần PO xác nhận
Cửa sổ 15 phút của job end_date là 23:59, khách áp mã lúc 00:05 hôm sau, job chưa chạy nên DB vẫn ACTIVE. Checkout từ chối hay cho qua? Test case riêng cho đúng khe 00:05 đó, kỳ vọng "Mã không còn hiệu lực" vì Checkout kiểm tra khoảng ngày theo thời gian thực, không phụ thuộc job
PERCENT làm tròn về 0 Đơn 15.000đ, giảm 5% = 750đ, làm tròn xuống 1.000 → 0đ Test case biên với đơn 15.000đ + assumption "mã vẫn được áp dụng, giảm 0đ"
Xóa voucher ngoài DRAFT Bảng phân quyền chỉ nói Admin xóa "chỉ khi Draft", không nói xóa trạng thái khác thì lỗi gì Test case gọi thẳng API xóa voucher ACTIVE, kỳ vọng HTTP 409, ghi rõ 409 là assumption cần dev xác nhận

Điểm chung của cả bốn điểm này là gì: tất cả đều không nằm cụ thể trong specs. Chúng chỉ hiện ra khi đối chiếu chéo bảng với sơ đồ, sơ đồ với comment, công thức với dữ liệu thực tế. Đây chính là phần "nghề" của tester, thứ mà các kỹ thuật thiết kế test như phân tích giá trị biên hay bảng chuyển trạng thái được sinh ra để hệ thống hóa.

Cả hai cách đều bỏ lỡ 2 bẫy giống nhau: đơn đã PAID rồi hoàn tiền thì có trả lại lượt dùng không, và admin sửa end_date khi voucher đang ACTIVE có được rút về quá khứ không. Không cấu hình nào đạt 12/12.

Điểm nổi bật: Agent có checklist lại trượt đúng mục checklist

Dưới đây là các điểm mà cấu hình 1 (Agent có checklist trước khi tạo test case) đã để lọt

Mục Nội dung tiêu chí Cách 1 tự chấm Judge chấm mù
C04 Đủ giá trị biên cho mọi ràng buộc PASS FAIL (thiếu biên "tổng đơn bằng đúng discount_value")
C06 Kết quả kỳ vọng phải quan sát được, không cần diễn giải PASS FAIL
C10 Hành vi ngoài spec phải khai báo ở mục Assumptions PASS FAIL (5 hành vi dùng ngầm)
C12 Priority gán nhất quán, P1 dành cho luồng lõi PASS FAIL ở 1/2 vòng

Cách 1 kết thúc với bản tự chấm ghi PASS 12/12.

Cụ thể nó để lọt gì:

  • 7 test case kết thúc bằng "hiện viền đỏ kèm message lỗi" mà không ghi message là gì. Tester chạy test không biết lấy chuỗi nào để đối chiếu. Trong khi spec có sẵn 5 message chuẩn.
  • 2 test case ghi kỳ vọng "HTTP 400 hoặc 409". Đây bản chất là 2 giả định cần phải đưa vào danh sách giả định để đảm bảo được làm rõ với các bên liên quan.
  • 1 test case ghi field "bị ẩn hoặc disable". Lỗi nước đôi, dẫn tới test case không chính xác, cần đưa vào danh sách giả định.
  • 5 hành vi không có trong spec bị dùng ngầm: hộp thoại xác nhận xóa, màn hình audit log, trường "số lượt đã dùng", mã lỗi API khi kích hoạt voucher hết hạn, nhãn nút ở Checkout. Test case được tạo có các yêu tố này mặc dù nó không được thể hiện rõ ràng trong specs.

Cách 2 không hề nhìn thấy checklist lúc viết. Bản nháp đầu tiên của nó tệ hơn hẳn: verifier đánh FAIL 5/12, với 25 test case dùng placeholder kiểu "các field bắt buộc hợp lệ" và hàng loạt kỳ vọng nước đôi. Nhưng sau hai vòng bị một agent khác soi từng ID, nó đạt 11/12 theo judge.

Có một chi tiết nhỏ mà mình thấy nói lên tất cả. Ở vòng sửa thứ hai, agent viết của cách 2 ghi vào revision log rằng đã tách các step gộp ở 10 test case. Verifier đọc lại file và ghi thẳng: "Revision log khẳng định đã tách; thực tế chưa." Agent generator tiếp tục nói dối và chỉ bị phát hiện nếu xử dụng agent khác để kiểm chứng lại !!!

Công bằng: cách 1 thắng ở đâu

Cách 1 thắng đúng một tiêu chí: tính đơn nhất của step (C08). Nó tách mỗi thao tác thành một step riêng; test case đầu tiên có 11 step nhập 11 field rồi mới submit. Cách 2 đến vòng cuối vẫn còn gộp "vào Checkout và nhập mã" hay "mở chi tiết và quan sát" ở một số test case, sai chuẩn viết test case.

Nhưng cả hai vòng judge đều xếp đây là lỗi trình bày, sửa cơ học được. Tách step không đòi hỏi hiểu thêm gì về nghiệp vụ. Còn khoảng cách 4 bẫy của cách 1 là thiếu hiểu biết về spec, điểm này sẽ khó phát hiện hơn và đòi hỏi mức độ hiểu specs sâu hơn mới thấy được lỗi.

Nguyên nhân giả định

Mình trình bày đây là giả thuyết, không phải kết luận đã chứng minh.

  1. Thiên kiến tác giả. Khi cùng một context vừa viết vừa chấm, AI đang chấm bản nháp nó vừa tạo ra. Nó đã "tin" là mình hiểu đúng spec, nên đọc lại chỉ thấy cái mình định viết, không thấy cái mình bỏ sót. Đúng hệt con người: dev tự test code của mình thường test cái mình đã nghĩ tới.
  2. Checklist thành cái trần, không phải cái sàn. Khi 12 tiêu chí nằm sẵn trước mắt lúc viết, AI có xu hướng viết vừa đủ để tick hết ô rồi dừng. Agent không thấy checklist thì không có mốc nào để dừng, nên đào sâu spec hơn. Đây có thể là lý do nó bắt được 4 bẫy kia. Giả thuyết này ngược với trực giác của hầu hết chúng ta, và là cái tôi muốn thử tiếp nhất.
  3. Vòng phản hồi thật. Cách 2 có tối đa 2 lần verifier trả lỗi về, mỗi lần kèm ID test case và trích dẫn cụ thể. Mỗi vòng là một lần bị buộc nhìn lại bằng con mắt khác. Cách 1 tự trả lỗi cho chính mình, và ở vòng 1 nó chỉ tìm thấy đúng một lỗi.

Liên hệ nguyên tắc ISTQB: tính độc lập trong kiểm thử

ISTQB CTFL v4.0 dành hẳn một mục cho independence of testing. Ý chính: người kiểm thử càng độc lập với người tạo ra sản phẩm thì càng dễ phát hiện lỗi, vì không mang theo thiên kiến và giả định của chính tác giả. Syllabus phân thành các mức, và tôi thấy chúng ánh xạ rất khớp sang thế giới AI agent:

Mức độc lập theo ISTQB Với con người Với AI agent
Không độc lập Dev tự test code của mình Một agent vừa sinh vừa tự chấm trong cùng context (cách 1)
Độc lập một phần Đồng nghiệp cùng team test chéo Agent chấm riêng nhưng dùng chung context hoặc chung lịch sử chat
Độc lập cao Team test riêng trong công ty Agent verifier riêng, context sạch, chỉ được đọc, không được sửa (cách 2)
Độc lập rất cao Bên thứ ba bên ngoài Judge chấm mù, đảo vị trí, có answer key viết trước

ISTQB cũng nói thẳng mặt trái của độc lập: người kiểm thử tách biệt có thể thiếu ngữ cảnh, và giao tiếp giữa hai bên tốn kém hơn. Thí nghiệm này cho thấy đúng như vậy: cách 2 tốn gần gấp ba thời gian (và hiển nhiên là cũng tốn token hơn), và verifier ở vòng 3 vẫn còn than về vài step gộp mà judge cuối cùng coi là chuyện nhỏ.

Nguyên tắc không đổi khi thay người bằng AI. Một agent tự kiểm sản phẩm của mình dính đúng cái bẫy mà một dev tự test code của mình gặp phải. Chỉ khác là AI làm việc đó trong 13 phút thay vì 2 ngày, nên lỗi tự xác nhận cũng đến nhanh hơn và trông tự tin hơn: một bản báo cáo PASS 12/12 sạch sẽ, có bảng, có bằng chứng.

Sáu việc bạn làm được ngay

Kể cả khi bạn chỉ dùng ChatGPT hay Claude một mình để AI sinh test case, không dựng multi-agent:

  1. Tách đôi hội thoại. Sinh test case ở một chat. Mở chat mới hoàn toàn, dán test case và spec vào, kèm checklist, yêu cầu chấm PASS/FAIL từng tiêu chí với bằng chứng là ID test case. Chat mới không có ký ức "mình vừa viết ra nó". Đó là tính độc lập, bản đơn giản nhất.
  2. Đừng đưa checklist vào lúc sinh. Để AI viết tự do theo spec, rồi mới lấy checklist ra soi. Nếu bạn đã có bộ prompt mẫu sinh test case, thử bỏ phần "tự kiểm tra" ra khỏi prompt đó và chuyển nó sang bước hai.
  3. Bắt khai báo assumption. Yêu cầu output có mục Assumptions liệt kê mọi chỗ spec không nói rõ, và mỗi test case dựa vào assumption nào phải ghi "(xem A-số)". Đây là nơi lộ ra AI có thật sự đọc kỹ spec hay chỉ chép lại. File của cách 2 kết thúc với 29 assumption; file của cách 1 có 14.
  4. Cấm kết quả kỳ vọng nước đôi. Quy tắc cứng: không có chữ "hoặc", không có "hiện message lỗi" chung chung. Phải ghi nguyên văn message hoặc mã HTTP cụ thể. Nếu spec chưa chốt, chọn một giá trị, ghi vào assumption, và đánh dấu cần PO xác nhận.
  5. Chấm bằng bẫy, đừng chấm bằng cảm giác. Muốn biết prompt hay quy trình nào tốt hơn: lấy một spec thật, tự gài vài mâu thuẫn bạn đã biết, rồi đếm xem AI bắt được mấy cái. Đừng đếm số test case. Trong thí nghiệm này bên nhiều test case hơn cũng là bên tốt hơn, nhưng đó là hệ quả của việc đọc kỹ, không phải nguyên nhân.
  6. Con người vẫn chốt cuối. Cấu hình tốt nhất vẫn bỏ lỡ 2/12 bẫy, và cả hai bên đều không nghĩ tới chuyện hoàn tiền. Câu hỏi AI có thay thế tester không có thêm một bằng chứng nữa: chưa, ít nhất là chưa ở bước đọc spec.

Ba hướng xử lý và ưu nhược của từng hướng

Từ kết quả trên, có ba cách bố trí quy trình AI sinh test case mà tôi cân nhắc. Hai cách đầu chính là hai biến thể vừa đo. Cách thứ ba là hướng tôi đề xuất, chưa đo, và tôi sẽ nói rõ vì sao mình tin nó đáng thử.

Hướng 1: gộp chung, agent tự kiểm

   
Ưu Rẻ nhất: một lượt chạy, ~13 phút, ít token nhất. Dễ dựng: một prompt, không cần điều phối. Mỗi step một hành động rất chuẩn vì checklist nhắc ngay lúc viết. Đủ dùng cho spec đơn giản, ít mâu thuẫn
Nhược Báo cáo tự chấm không tin được: tự tuyên PASS 12/12 nhưng chấm mù ra 8 đến 9. Bỏ lỡ nửa số bẫy spec. Lỗi lọt là lỗi đắt: thiếu hiểu biết về nghiệp vụ, không sửa cơ học được. Không có ai để "cãi" lại, nên sai từ đầu là sai đến cuối
Dùng khi Spec ngắn, sạch, đã được PO chốt kỹ; cần nháp nhanh để thảo luận; hoặc ngân sách token thật sự eo hẹp và sẽ có người review tay ngay sau đó

Hướng 2: tách hẳn, agent viết mù checklist, verifier độc lập

   
Ưu Bắt bẫy spec tốt nhất trong thí nghiệm (10/12). Khai báo assumption đầy đủ nhất (29 mục), tức là lộ ra đúng chỗ cần hỏi PO. Báo cáo verifier có bằng chứng theo ID nên người review tay đọc rất nhanh. Bắt được cả chuyện agent viết báo cáo sai "đã sửa"
Nhược Đắt gấp gần ba về thời gian, ba lượt verifier cộng hai lượt sửa. Bản nháp đầu tệ (FAIL 5/12) nên vòng 1 gần như luôn phải sửa, tức là lãng phí một vòng cho những lỗi hình thức mà chỉ cần nhắc trước là tránh được. Đến vòng cuối vẫn còn lỗi trình bày (step gộp). Cần dựng điều phối, nhiều file, khó hơn cho người mới
Dùng khi Spec có nhiều bảng, sơ đồ, comment chồng lên nhau; tính năng có tiền hoặc phân quyền; chi phí phát hiện muộn cao hơn nhiều so với vài chục phút máy chạy

Hướng 3: lai, checklist rút gọn lúc viết, verifier độc lập giữ checklist đầy đủ

   
Ưu (kỳ vọng) Giữ được phần độc lập tạo ra khoảng cách 4 bẫy, đồng thời bớt được vòng sửa đầu tiên vì bản nháp đã đúng hình thức. Chi phí nằm giữa hai hướng trên
Nhược Chưa đo. Có rủi ro chính là giả thuyết "checklist thành cái trần": đưa 5 mục vào lúc viết có thể đủ để agent lại viết vừa đủ tick ô rồi dừng. Phải chạy lại với cùng spec và cùng cách chấm mới biết
Dùng khi Muốn đưa vào quy trình thật sau khi đã có hai baseline trên để so

Bảng gọn để bạn chọn nhanh:

Tiêu chí Hướng 1 Hướng 2 Hướng 3
Thời gian, token Thấp Cao (~3×) Trung bình (dự kiến)
Phát hiện bẫy spec 6/12 10/12 Chưa đo, kỳ vọng gần hướng 2
Chất lượng hình thức bản nháp đầu Tốt Kém Tốt (dự kiến)
Độ tin của báo cáo chấm Thấp Cao Cao
Độ phức tạp dựng 1 prompt 3 agent + điều phối 3 agent + điều phối
Loại lỗi còn lọt Lỗi hiểu spec (đắt) Lỗi trình bày (rẻ) Chưa biết

Cách tôi lập luận khi chọn hướng lai để áp dụng

Tôi không chọn hướng 3 vì nó "ở giữa nên chắc an toàn". Tôi đi từng bước như sau, và ghi ra để bạn phản biện.

Bước 1: tách hai biến số đang đi chung. Trong thí nghiệm, cách 2 khác cách 1 ở hai chỗ cùng lúc: agent viết không thấy checklist, và người chấm là người khác. Kết quả cho thấy cặp này thắng, nhưng chưa nói được cái nào đóng góp bao nhiêu. Hướng 3 chính là cách tách: giữ nguyên "người chấm là người khác", chỉ thay đổi "agent viết thấy bao nhiêu checklist". Nếu hướng 3 vẫn bắt được 9 đến 10 bẫy thì độc lập là yếu tố chính. Nếu tụt về 6 đến 7 thì giả thuyết "checklist thành cái trần" là thật, và ta phải giữ agent viết mù hoàn toàn.

Bước 2: phân loại 12 tiêu chí theo thời điểm nó có ích. Tôi đọc lại từng mục và hỏi: mục này giúp agent viết tốt hơn ngay từ đầu, hay chỉ giúp phát hiện lỗi sau khi đã viết?

Nhóm Tiêu chí Vì sao xếp vào nhóm này
Định hướng lúc viết Truy vết về requirement, có negative, đủ biên, test data cụ thể, kỳ vọng quan sát được Đây là kỹ thuật thiết kế test. Biết trước thì viết đúng luôn, không biết thì phải sửa hàng chục test case ở vòng sau. Bản nháp đầu của cách 2 trượt đúng những mục này với 25 test case dùng placeholder
Chỉ có ích khi soi lại Khai báo assumption, dùng đúng thuật ngữ spec, không trùng lặp, priority nhất quán, ID duy nhất, có precondition, mỗi step một hành động Đây là kỷ luật rà soát. Đưa vào lúc viết thì agent tick ô cho có, như cách 1 đã tự cho PASS ở mục assumption dù dùng ngầm 5 hành vi ngoài spec. Chúng cần một con mắt khác

Năm mục nhóm đầu là checklist rút gọn cho agent viết. Bảy mục còn lại chỉ verifier thấy.

Bước 3: ưu tiên loại lỗi rẻ hơn. Nếu buộc phải chọn, tôi thà nhận lỗi trình bày còn hơn lỗi hiểu spec. Lỗi trình bày sửa bằng một vòng revise cơ học, thậm chí bằng script. Lỗi hiểu spec phải có người đọc lại từ đầu. Hướng 3 đẩy lỗi về phía rẻ: hình thức được lo từ lúc viết, hiểu spec được verifier độc lập soi.

Bước 4: giữ những rào chắn đã chứng minh có tác dụng. Ba thứ tôi không đổi khi chuyển sang hướng 3: verifier chỉ đọc không sửa, verifier tự lập danh sách requirement trước khi mở file test case, và điểm cuối cùng lấy từ judge chấm mù chứ không lấy từ báo cáo verifier. Chính rào chắn thứ hai đã bắt được vụ agent viết báo cáo "đã tách step" trong khi chưa tách.

Bước 5: định trước ngưỡng thất bại. Tôi viết sẵn điều kiện để bỏ hướng 3 trước khi chạy, để không tự thuyết phục mình sau khi thấy số: nếu hướng 3 bắt bẫy ít hơn hướng 2 từ 2 bẫy trở lên trên cùng spec, hoặc nếu số vòng verifier không giảm, thì hướng 3 không đáng và quay về hướng 2.

Khi áp dụng vào quy trình thật

Nếu bạn muốn đưa hướng này vào team, đây là thứ tự tôi khuyên, mỗi bước có một sản phẩm kiểm được:

  1. Chốt checklist trước. Mỗi mục phải PASS hoặc FAIL, FAIL phải kèm ID. Mục nào bạn thấy mình hay đánh "tạm được" thì viết lại cho đến khi không còn "tạm được". Checklist mơ hồ sẽ làm verifier báo sai, và lúc đó lỗi nằm ở checklist chứ không nằm ở kiến trúc.
  2. Chạy hướng 1 và hướng 2 trên 3 đến 5 spec thật của chính team, có gài bẫy bạn đã biết. Đây là baseline. Không có baseline thì mọi tranh luận sau này đều là cảm giác.
  3. Đo độ tin của verifier bằng chấm tay ít nhất 3 spec: đếm số finding verifier nêu ra mà bạn đồng ý trên tổng số finding. Dưới 80% thì quay lại bước 1.
  4. Chạy hướng 3 với checklist rút gọn 5 mục cho agent viết, so với baseline bằng cùng judge, cùng đảo vị trí.
  5. Giới hạn vòng sửa ở 2 và chấp nhận trạng thái "FAIL còn lỗi hình thức" đưa cho người review, thay vì chạy thêm vòng. Vòng thứ ba trong thí nghiệm chỉ sửa được 2 mục nhỏ mà tốn thêm mười mấy phút.
  6. Người review tay đọc mục Assumptions trước, rồi mới đọc test case. Đó là nơi tập trung mọi câu cần hỏi PO, và là phần AI không thể tự chốt.

Nếu bạn muốn học cách dựng những quy trình như thế này một cách bài bản, từ viết prompt sinh test case, dựng agent kiểm độc lập, đến thiết kế phép đo bằng bẫy, đó chính là nội dung khóa học AI cho tester của IT LEARN. Còn nếu chỉ muốn thử ngay tối nay: mở hai cửa sổ chat, và đừng để cửa sổ thứ hai biết cửa sổ thứ nhất đã viết gì.

Kết luận trong một câu

Cho AI tự chấm test case của chính nó bằng checklist chất lượng lại kém hơn việc để AI viết "mù checklist" rồi giao một AI khác kiểm độc lập. Trong thí nghiệm của tôi, cách tự kiểm bỏ lỡ 6/12 mâu thuẫn được gài sẵn trong spec và trượt đúng những mục checklist mà nó được giao để tự bắt. Cách kiểm độc lập bắt được 10/12 bẫy và đạt 11/12 mục checklist.

Nói cách khác: nguyên tắc tính độc lập trong kiểm thử mà ISTQB dạy từ chương đầu tiên vẫn đúng nguyên khi "tác giả" là một AI agent. Đổi con người thành AI, nguyên tắc kiểm thử không đổi. Chỉ có tốc độ mắc lỗi là nhanh hơn.