Cho agent thảo luận để ra kết quả, đừng cho chúng nói chuyện tự do
Nhiều người thích "cho mấy con agent nói chuyện với nhau". Nghe cũng hợp lý: một agent làm được việc, thì vài con ngồi trao đổi chắc sẽ làm tốt hơn. Nhưng nói chuyện tự do thường ra kết quả ba phải và thành một cái chợ.
Nói chuyện tự do ra kết quả ba phải. Thảo luận có luật thì mới ra thứ mình xài được.
Nhiều người thích “cho mấy con agent nói chuyện với nhau”. Nghe cũng hợp lý: một agent (tác nhân AI có thể nhận nhiệm vụ và trả kết quả) làm được việc, thì vài con ngồi trao đổi chắc sẽ làm tốt hơn. Nhưng nói chuyện tự do thường ra kết quả ba phải và thành một cái chợ. Cái chúng ta cần là kết quả. Cùng xem một số cách cho chúng không “nói chuyện” mà “thực sự thảo luận” để ra kết quả mình có thể xài.
Mình không bàn trên không. Lấy một bài toán cụ thể.
Bài toán: import CSV bị timeout
App có endpoint POST /imports. User gửi file CSV, app chuẩn hóa, ghi Postgres, gọi CRM bên ngoài. File lớn thì request chậm, đôi khi đụng timeout 30 giây. Team hai người. Chưa có hàng đợi. Chưa chắc mỗi ngày có hơn 20 lần import.
Câu hỏi cần trả lời: chỗ xử lý nặng nên nằm đâu?
Có ít nhất ba hướng đều nghe được.
Làm sau. Request chỉ nhận file, trả một mã import, rồi một worker làm phần nặng lúc khác. User không bị treo. Đổi lại, team phải nuôi thêm một hệ thống chạy nền.
Làm luôn. Parse xong trong đúng request đang mở, trả kết quả ngay, nhưng giới hạn kích thước file và số dòng để kịp trước 30 giây. Đơn giản. File lớn hoặc CRM chậm thì chết.
Dùng sẵn. Request ghi một dòng “đang chờ” vào database. Process đang có trong app thỉnh thoảng lấy ra làm. Tách được khỏi HTTP mà không cài thêm hàng đợi mới.
Ba hướng này không có đứa nào ngu. Đó là lý do bài toán này đáng để thảo luận. Nếu chỉ có một đáp án đúng, một session là đủ.
Có hai việc hay bị nhầm thành một. Việc một: chưa có đáp án, cần nhiều hướng độc lập. Việc hai: một agent đã thiết kế xong, mình muốn xin ý kiến về đúng bản đó. Cả hai đều hỏng nếu mình copy chat hỏi “bạn thấy sao?”. Cách đúng thì khác nhau.
Nếu cho chúng nói chuyện tự do
Cách dễ gặp: hỏi agent A. A chọn “làm sau” vì timeout 30 giây nghe như án tử cho request. Mình paste đáp án sang agent B: “Bạn thấy sao?”
Ngay lúc đó, “làm sau” không còn là một phương án. Nó đã thành khung của cuộc nói chuyện. B sửa vài chi tiết, thêm vài lưu ý, kết luận hàng đợi hợp lý. Agent C dung hòa: hàng đợi nhưng đơn giản một chút, “cân nhắc trade-off”.
Ba vòng nói. Một giả định. Thứ mình cầm trên tay không phải ba hướng. Là một hướng được viết lại ba lần, cộng một câu không ai chịu trách nhiệm.
Kết quả ba phải trông rất giống trí tuệ tập thể. Team hai người vẫn không biết thứ hai làm được vào tuần này. Đó là cái chợ.
Nhiều chat mà không có luật thì chỉ là nhiều cửa sổ. Lợi ích thật nằm ở một file chúng cùng đọc: cách “nói”, cách soi, cách cãi, bám mục tiêu nào, và output phải ra hình gì. Không có file đó, ba chat vẫn nói chuyện tự do — chỉ là ở ba tab.
File luật: bỏ vào folder, mỗi chat đọc
Mình để discussion.md cạnh spec.md. Mỗi chat mới chỉ được đọc hai file này (cộng đúng file việc của nó). Đó là cách chúng thảo luận. Chúng không DM nhau.
# discussion.md
Bạn không nói chuyện với agent khác.
Bạn đọc file, ghi file, dừng.
File này + `spec.md` là mục tiêu chung. Không đoán host đang thích gì.
## Hai việc. Đọc đúng việc được giao.
**Việc 1 — mở hướng** (chưa có đáp án)
Đề xuất đúng một hướng. Không đọc `candidate-*.md` khác. Không xếp hạng. Không dung hòa.
**Việc 2 — xin ý kiến** (đã có một bản thiết kế)
Soi đúng bản được đưa. Một góc. Không viết lại kiến trúc. Không chọn winner.
Nếu prompt không nói rõ việc nào: hỏi host một câu, rồi dừng. Đừng tự đoán.
## Bám mục tiêu thế nào
Chỉ được dùng:
- `spec.md` (vấn đề, ràng buộc, thế nào là xong)
- file được liệt kê trong prompt
- checklist của đúng góc (nếu là việc 2 hoặc bước soi)
Không được dùng:
- transcript / chat cũ
- "một agent khác đã đề xuất…"
- sở thích của host, trừ khi đã viết trong spec
- kiến thức chung kiểu "thường thì nên dùng hàng đợi"
Nếu spec thiếu dữ kiện: ghi "thiếu gì", đừng bịa. Bịa là lệch mục tiêu.
## Cách "nói" — thật ra là cách ghi
Cấm:
- khen cho có ("hướng này hợp lý")
- dung hòa ("kết hợp A và B")
- tự chấm đề xuất của mình
- tranh luận với agent khác trong chat
Được:
- chỉ vào một dòng spec hoặc checklist
- nói hướng vỡ ở đâu, bằng chứng nào
- nói hướng hết phù hợp khi tín hiệu nào xuất hiện
- đề xuất sửa nhỏ nhất, không đề xuất làm lại từ đầu
Cãi thì cãi vào ràng buộc. Không cãi vào gu.
## Output — việc 1, đề xuất
Ghi `candidate-N.md`:
# Hướng
(một câu)
# Cách chạy
# Đang giả định
# Hỏng khi
# Hết phù hợp khi
(tín hiệu đo được)
# Không làm
Đúng một hướng. Không liệt kê ba hướng rồi bảo host chọn.
## Output — việc 2, soi / cãi
Ghi `audit-GÓC.md`. Mỗi hướng một khối:
# Góc: bảo mật | chi phí | vận hành
# Bản đang soi: candidate-1.md
## Điểm: 0-10
(5 = dùng được nhưng đắt/khó chịu, không phải án tử)
## Chặn cứng: có | không
chỉ "có" khi phá một dòng "không được phép"
## Lý do
tối đa 3 câu, mỗi câu chỉ vào một dòng spec/checklist
## Sửa nhỏ nhất
tối đa 3 mục, không viết lại kiến trúc
## Thiếu dữ kiện
Cấm: "nhìn chung ổn", mọi bản đều 8/9.
## Output — gom nghĩa
Chỉ gom những bản nói cùng một cơ chế. Không chọn winner. Không thêm hướng mới.
## Người chốt là mình
Agent không ghi `decision.md` trừ khi mình ra lệnh rõ.
Cấm mở thêm một chat hỏi "vậy chọn cái nào?".
## Dừng
- Việc 1: đủ 3 hướng thì dừng mở thêm. Cả 3 trùng hết thì sửa spec.
- Việc 2: tối đa 3 vòng soi → sửa. Vòng 3 còn chặn thì mình đọc, đừng cãi tiếp.
- Agent sửa file ngoài phạm vi → dừng.
## Prompt tối thiểu
Việc 1:
Đọc discussion.md và spec.md. Việc 1. Ghi candidate-N.md. Không đọc candidate khác.
Việc 2:
Đọc discussion.md, spec.md, FILE_THIET_KE, checklist GÓC. Việc 2. Ghi audit-GÓC.md.
Bỏ file này vào folder quyết định. Chat 1, 2, 3 cùng đọc nó, không đọc nhau. Lúc đó nhiều chat mới ra ba hướng so sánh được, không phải ba bài văn.
Bốn bước trên đúng bài toán đó
Mỗi bước chỉ chạy đúng một việc trong file luật.
1. Mở hướng. Ba chat mới, cùng discussion.md + spec.md, không nhìn nhau. Một đứa được phép chọn “làm sau”, một đứa “làm luôn”, một đứa “dùng sẵn”. Không được đọc candidate của đứa kia. Chỉ cần nhắc “hàng đợi” trong prompt của chat 2 là chat 2 bắt đầu phản biện hàng đợi thay vì tự nghĩ.
2. Gom trùng. Session thứ tư không chọn bên thắng. Nó chỉ nói hai đề xuất có đang nói cùng một cơ chế không. “Làm sau bằng hàng đợi” và “dùng sẵn, process lấy việc từ database” đều tách khỏi HTTP. Câu chữ khác, xương giống. Gom lại. “Làm luôn trong request” là họ khác.
3. Soi từng góc. Một chat chỉ hỏi bảo mật. Một chat chỉ hỏi chi phí cho team hai người. Chat bảo mật không được bàn chuyện nuôi hàng đợi. Chat chi phí không được lấy “rẻ” để bỏ qua việc ghi secret ra log.
4. Mình chốt. Không hỏi thêm một LLM “vậy chọn cái nào?”. Đọc các file, loại cái bị chặn cứng, chọn trong phần còn lại, ghi ra decision.md. Tối đa ba vòng rồi dừng.
Ba ô bên trái không phải tên bước. Đó là ba câu trả lời cho đúng câu “chỗ xử lý nặng nằm đâu?”.
Làm trên Claude Code
Bỏ discussion.md rồi viết spec.md
Hai file, cùng folder, ví dụ decision/upload-processing/. discussion.md là luật nói chuyện. spec.md là đề bài lần này. Chat không được đọc cái này mà bỏ cái kia.
Spec không cần giống tài liệu công ty. Chỉ cần đủ để ba chat mới hiểu cùng một việc. Timeout 30 giây, team hai người, chưa có hàng đợi, traffic chưa rõ — những dòng đó đổi lựa chọn, nên phải có mặt.
# Problem
Endpoint POST /imports nhận CSV, parse, ghi Postgres, gọi CRM.
File lớn thì request chậm hoặc timeout.
Câu hỏi: chỗ xử lý nặng nên nằm đâu?
# Constraints
- Request timeout sau 30 giây.
- Team 2 người.
- Chưa có hàng đợi hay worker riêng.
- Chưa biết traffic có vượt 20 import/ngày không.
- Retry không được tạo bản ghi trùng.
- Không giữ HTTP connection quá 30 giây.
# Definition of done
- Đề xuất một hướng cụ thể.
- Nêu assumption đang dựa vào.
- Nêu failure mode chính.
- Nêu tín hiệu khiến hướng này hết phù hợp.
- Không viết code.
Mình chưa xin code vì code làm một phương án đắt hơn về tâm lý. Khi đã có patch vài trăm dòng, cả người lẫn agent đều chuyển sang sửa patch thay vì hỏi hướng đó có đúng không.
Ba chat mới, cùng spec
Mỗi chat một prompt, chỉ đổi số N. Không dán candidate-1.md vào chat 2. Không nói “một agent khác đề xuất hàng đợi”.
Đọc discussion.md và spec.md. Việc 1.
Ghi candidate-N.md. Không đọc candidate khác. Không viết code.
Ba file có thể ra đúng ba hướng ở trên. Mình không cần chúng dài. Chỉ cần mỗi file nói rõ nó đang giả định gì, nó hỏng thế nào, và dấu hiệu nào khiến hướng đó hết phù hợp.
Ba session cùng model vẫn có thể nghĩ gần giống nhau. Mục tiêu không phải tạo ba bộ não khác hẳn. Mục tiêu là đáp án đầu không thành tiền đề bắt buộc của đáp án sau.
Gom nghĩa, không chọn winner
Session 4 đọc ba candidate. Nếu “hàng đợi” và “process lấy job từ database” cùng là “tách khỏi request”, gom thành một option, giữ lại chỗ khác nhau. Nếu session này viết “nên làm hàng đợi”, xóa dòng đó hoặc chạy lại. Đứa gom nghĩa không được lén chốt.
Soi bảo mật riêng, soi chi phí riêng
Session bảo mật chỉ nhận các option đã gom và một checklist ngắn: giới hạn file, retry có nhân bản ghi không, job có chứa secret không, tenant này có đọc được import của tenant kia không, failure có đổ payload ra log không.
Session chi phí chỉ hỏi: team hai người có gánh thêm một hệ thống chạy nền không, với khoảng 20 import/ngày.
Đọc discussion.md, spec.md, clustered-options, checklist.
Việc 2. Góc {{bảo mật|chi phí}}. Ghi audit-GÓC.md.
Điểm 5 về chi phí không phải án tử. Nó là nhãn giá: hướng này mua độ bền bằng một hệ thống team chưa có người nuôi. chặn cứng thì khác. Option ghi access token vào bảng job rồi dump payload ra log thì bị chặn, dù chi phí có 8/10. Mình không lấy điểm đẹp ở một góc để bù lỗ ở góc khác.
Đó là chỗ luật giúp, rất cụ thể. Nói chuyện tự do sẽ cho ra câu “đắt một chút nhưng bảo mật chấp nhận được”. Câu đó nghe chín chắn. Nó xóa ranh giới. Checklist thì không cho xóa.
Chốt thứ đi làm được tuần này
Với 20 import/ngày, team hai người, chưa có hàng đợi: mình chọn làm luôn, giới hạn file và số dòng, có khóa chống nhân bản, đo thời gian thật. decision.md ghi luôn ngưỡng bỏ hướng này — ví dụ P95 chạm 25 giây, hoặc file thực tế vượt giới hạn.
# Decision
Chọn làm luôn trong request ở phiên bản đầu.
Giới hạn file và số dòng.
# Why
Traffic thấp, chưa đủ dữ liệu để nuôi thêm hàng đợi.
Làm được Definition of done nếu xử lý nằm dưới ngưỡng an toàn.
# Không được phá
- Khóa chống nhân bản mỗi lần import.
- Không ghi CSV hay secret vào log.
- Dừng trước timeout, trả lỗi có thể thử lại.
# Làm lại khi
- P95 vượt 25 giây.
- Traffic hoặc kích thước file tăng đáng kể.
- Cần retry nền.
Không có luật, cuộc nói chuyện hay kết thúc ở “làm sau, vì timeout”. Có luật, mình cầm một quyết định đi làm được, kèm điều kiện hủy. Vài tháng sau không cần nhớ đã cãi gì. Chỉ cần hỏi: dữ kiện thật đã vượt ngưỡng chưa.
Nếu mọi option đều bị chặn, sửa spec rồi chạy lại. Đừng hỏi LLM “vậy chọn cái nào?”. Không còn lựa chọn hợp lệ thì ép nó chọn chỉ cho ra một câu tự tin trên đầu bài lỗi.
Khi một agent đã có thiết kế, xin ý kiến thế nào
Đôi khi mình không cần ba hướng. Agent A đã viết xong một thiết kế: làm sau, có worker, có bảng job. Mình muốn một đứa khác nhìn giúp. Việc này hợp lệ. Cách hay làm thì hỏng.
Cách hỏng: copy cả đoạn A vừa thuyết phục mình, mở chat B, hỏi “bạn thấy thiết kế này thế nào?”. B đọc được A đã dẫn mình đi tới đâu. Nó góp ý quanh khung A đã dựng. Mình tưởng đang xin second opinion. Mình đang để A tự khen, qua miệng B.
Cách đúng: chat mới. Đưa tờ đề bài, file thiết kế (candidate-1.md hoặc bản vẽ), và một checklist đúng một góc — bảo mật, chi phí, hoặc “team hai người nuôi nổi không”. Không đưa đoạn “mình thích hướng này vì”. B không được viết lại kiến trúc. B không được chọn winner. B trả về: chỗ vỡ, chỗ chưa chắc, có phải chặn cứng không. Mình đọc, rồi bảo A sửa đúng chỗ đó, hoặc mình chấp nhận rủi ro và ghi ra.
Trên bài CSV: A đã chọn làm sau. Mình muốn hỏi bảo mật. Chat mới, dán spec + candidate-1.md + checklist secret / tenant / log. Không dán transcript A. B có thể chặn vì job chứa access token. Đó là ý kiến. Câu “hàng đợi hợp lý, chỉ cần cẩn thận secret” là khen. Khen không giúp mình quyết.
Viết code cũng cùng việc này. Writer đọc spec, tạo patch. Chat mới nhận patch và checklist, chỉ tìm lỗi. Không viết lại kiến trúc, không biến review thành patch thứ hai. Tối đa ba vòng. Lỗi cứ đổi hình thì dừng, xem lại spec.
Ví dụ: writer thêm giới hạn kích thước CSV và khóa chống nhân bản. Agent soi hỏi giới hạn được áp trước hay sau khi đọc hết file, khóa có bị dùng chung giữa hai khách không, làm lại lần nữa có tạo bản ghi trùng không. Phát hiện gắn file và dòng. Writer sửa đúng chỗ đó.
Khi nào không đáng
Một bug nhỏ, một file, test rõ: một session đủ. Dựng bốn bước cho việc đổi tên biến chỉ thêm thời gian đọc.
Đáng tiền khi nhiều hướng đều nghe được, hỏng thì đau, hoặc đáp án đầu đang đóng khung cả câu chuyện. Import CSV ở trên đủ cả ba. Đổi schema thanh toán, phân quyền, chỗ chạy job nền cũng vậy.
Chi phí không chỉ là token. Mình phải đọc output và chịu trách nhiệm chốt. Không có người đứng sau decision.md thì thêm agent chỉ thêm giấy.
Claude Code làm orchestrator giữ toàn cảnh. cmux để nhìn các session. Luật này là tầng để chúng không biến bài toán timeout 30 giây thành một cuộc họp.
Bài toán import của bạn, chỗ nào đang để agent nói chuyện, và chỗ nào cần chúng thảo luận?