05 · Workflow patterns và multi-agent — khi nào tách, khi nào không

"Multi-agent" là từ khoá nghe rất hay trong phỏng vấn, và cũng là chỗ interviewer bắt lỗi nhiều nhất. Câu trả lời mức senior không phải "tôi đã dựng hệ 5 agent", mà là "tôi biết khi nào không nên, và khi nên thì trả giá bao nhiêu". Bài này đi từ các mẫu workflow đơn giản (code điều phối) tới multi-agent (model điều phối), với ba con số quyết định: lỗi cộng dồn, độ trễ đuôi khi fan-out, và rate limit.

Đã verify gì, chưa verify gì. Lab là mô phỏng Monte Carlo chạy thật (Python, numpy): xác suất lỗi cộng dồn, phân bố độ trễ khi chờ N worker, số request bị 429 dưới token bucket. Phân phối độ trễ là giả định minh hoạ (log-normal, p50 4 giây), không đo từ API. Hiệu quả thực của multi-agent (chất lượng, token) lấy từ bài viết công khai của Anthropic và Cognition, MAST (NeurIPS 2025) — chưa verify bằng hệ thống thật. Không có Context7; nguồn đã tra bằng web ngày 2026-09-30.

Câu trả lời 60 giây

"Tôi phân biệt theo câu hỏi: ai quyết định bước tiếp theo — code hay model? Code quyết định là workflow: prompt chaining, routing, parallelization, orchestrator-workers, evaluator-optimizer. Model quyết định là agent. Multi-agent là chia context cho nhiều agent — đổi chất lượng context của từng agent lấy chi phí điều phối. Anthropic báo multi-agent dùng khoảng 15 lần token so với chat và vượt single-agent 90% trên eval nghiên cứu — vì nghiên cứu song song hoá được. Nhưng với việc có phụ thuộc chặt như sửa code, các agent con ra quyết định mâu thuẫn vì không thấy quyết định của nhau. Trước khi tách, tôi tính ba thứ: 20 bước mỗi bước đúng 95% thì cả chuỗi chỉ đúng 36%; chờ 10 worker thì p50 tăng từ 4 lên 10 giây; và 20 worker bắn cùng lúc vào giới hạn 50 request/phút thì 43% request bị 429."

Thuật ngữ

Thuật ngữNghĩa ngắn
workflowLuồng mà code định sẵn thứ tự các lần gọi LLM.
orchestrator / workerMột LLM chia việc (orchestrator), nhiều LLM làm phần việc con (worker/subagent).
evaluator-optimizerMột LLM tạo, một LLM (hoặc code) chấm và phản hồi, lặp tới khi đạt.
fan-out / fan-inChia ra nhiều nhánh song song / gom kết quả về.
handoffAgent này chuyển hẳn hội thoại cho agent khác (vd bot bán hàng chuyển sang bot bảo hành).
tail latencyĐộ trễ ở phân vị cao (p95, p99) — thứ người dùng chậm nhất gặp.

1. Bài toán gốc và bối cảnh ra đời

Một agent đơn có ba giới hạn: context (việc đọc nhiều làm đầy cửa sổ, chất lượng giảm — bài 03), thời gian (các vòng chạy tuần tự), và chuyên môn hoá (một system prompt khó vừa giỏi phân loại, vừa giỏi viết, vừa giỏi kiểm). Các framework multi-agent (AutoGen 2023, CrewAI, LangGraph) phổ biến ý tưởng "đội agent" đóng vai. Hai bài viết cùng tháng 6/2025 tạo nên cuộc tranh luận mà interviewer hay nhắc:

Hai bài không mâu thuẫn: cả hai đồng ý rằng agent làm việc với context cục bộ sẽ ra quyết định xung đột; khác nhau ở loại nhiệm vụ. Trước đó, Anthropic "Building effective agents" (12/2024) đã hệ thống các mẫu workflow dùng ở mục 3 và khuyên: bắt đầu từ cái đơn giản nhất.

Multi-agent tối ưu cho: việc rộng, song song hoá được, đọc nhiều hơn viết, lượng thông tin vượt một context (nghiên cứu, rà soát nhiều tài liệu độc lập). Không tối ưu cho: việc phụ thuộc chặt, cần một mạch quyết định nhất quán (sửa code, thiết kế), ngân sách token thấp, cần độ trễ thấp.

2. Mô hình tư duy cốt lõi

Mọi kiến trúc LLM là một đồ thị luồng điều khiển mà mỗi node là một lần gọi model. Câu hỏi thiết kế duy nhất: cạnh tiếp theo do code chọn (workflow) hay do model chọn (agent)? Multi-agent = phân mảnh context: mỗi agent thấy một phần — được context sạch, mất ngữ cảnh chung.
flowchart TB
  subgraph W["Workflow: code chọn cạnh"]
    C1["Chaining: A -> kiểm -> B"]
    C2["Routing: phân loại -> nhánh chuyên biệt"]
    C3["Parallel: chia phần / bỏ phiếu"]
    C4["Orchestrator-workers: LLM chia việc động"]
    C5["Evaluator-optimizer: tạo -> chấm -> sửa"]
  end
  subgraph A["Agent: model chọn cạnh"]
    A1["Single agent + tools"]
    A2["Multi-agent: lead + subagent (context riêng)"]
  end
  W -->|"khi không biết trước đường đi"| A

Hệ quả: mỗi lần tách thêm một agent/một bước là thêm một điểm có thể sai, một lần chờ, một bản sao context phải trả tiền, và một ranh giới thông tin. Đó là "thuế điều phối" — chỉ đáng khi phần lợi (song song, context sạch, chuyên môn hoá) lớn hơn.

3. Internals và quyết định thiết kế

3.1 Năm mẫu workflow

MẫuCách chạyVí dụ trong shopĐượcMất
Prompt chainingChuỗi bước cố định; giữa các bước có "cổng" kiểm bằng codeTrích xuất thông tin khiếu nại → kiểm schema → soạn trả lờiMỗi bước dễ, dễ debugLatency cộng dồn; lỗi bước trước lan sang
RoutingPhân loại đầu vào → nhánh/prompt/model phù hợpCâu hỏi đơn giản → Haiku; khiếu nại → Opus + toolTối ưu chi phí; prompt chuyên biệtPhân loại sai → nhánh sai
ParallelizationSectioning: chia phần độc lập; Voting: chạy N lần, lấy đa sốKiểm duyệt review: 3 bộ lọc song song (spam, độc hại, PII)Nhanh; bỏ phiếu tăng độ tin cậyChi phí × N; chờ nhánh chậm nhất
Orchestrator-workersLLM chia nhiệm vụ con động, worker làm, orchestrator tổng hợp"So sánh chính sách đổi trả của 8 nhà cung cấp"Linh hoạt với việc không biết trước số phầnChia sai → làm trùng/thiếu; token tăng mạnh
Evaluator-optimizerTạo → chấm theo tiêu chí → phản hồi → sửa, lặpViết mô tả sản phẩm đạt checklist SEO + đúng thông sốChất lượng tăng khi tiêu chí rõCó thể lặp mãi; evaluator cùng model dễ "tự khen"

3.2 Kiến trúc multi-agent

Kiến trúcCách thông tin điRủi ro chính
Lead + subagent (hub-and-spoke)Lead giao nhiệm vụ; subagent chạy context riêng; trả về tóm tắt 1–2k tokenMô tả nhiệm vụ mơ hồ → làm trùng/lạc đề; tóm tắt mất chi tiết
Handoff (chuyển giao)Agent chuyển toàn bộ hội thoại cho agent khácMất ngữ cảnh khi chuyển; vòng chuyển qua lại
Bảng chung (blackboard)Các agent đọc/ghi một kho chungGhi đè, race condition — bài toán concurrency kinh điển

Anthropic nêu mỗi subagent cần: mục tiêu, định dạng output, hướng dẫn dùng tool/nguồn nào, và ranh giới nhiệm vụ rõ ràng. Thiếu ranh giới, ba subagent cùng tìm một nguồn. Theo "Effective context engineering", subagent có thể dùng hàng chục nghìn token nhưng chỉ trả về bản tóm tắt 1 000–2 000 token.

3.3 Hiện thực trong Laravel

Workflow map thẳng vào công cụ có sẵn: chaining = Bus::chain; parallelization/orchestrator-workers = Bus::batch (có allowFailures(), callback then/catch/finally); state và kết quả trung gian lưu DB; giới hạn song song bằng số worker của queue riêng hoặc Redis::funnel.

// Phác thảo — chưa chạy trong lab
$plan = $orchestrator->plan($question);                  // 1 lần gọi LLM: trả JSON danh sách nhiệm vụ con (structured outputs)
Bus::batch(collect($plan->tasks)->map(fn ($t) => new RunSubagent($runId, $t)))
    ->allowFailures()                                      // 1 worker hỏng không huỷ cả batch
    ->onQueue('llm-workers')                               // queue riêng, số worker = giới hạn song song
    ->then(fn (Batch $b) => SynthesizeAnswer::dispatch($runId))
    ->dispatch();

Chọn model theo vai: orchestrator dùng model mạnh (lập kế hoạch sai thì mọi thứ sai theo), worker đọc nhiều dùng model rẻ hơn (Sonnet, Haiku). Tài liệu Anthropic lưu ý: trước khi xây tầng model rẻ/đắt, thử model mạnh ở effort thấp — thường ngang chi phí mà chỉ một namespace cache.

4. Đảm bảo và giới hạn — ba con số (lab)

4.1 Lỗi cộng dồn

1) Lỗi cộng dồn: xác suất cả chuỗi n bước đều đúng nếu mỗi bước đúng p
  p/bước       1       5      10      20      50
    0.99   0.990   0.951   0.904   0.818   0.605
    0.95   0.950   0.774   0.599   0.358   0.077
     0.9   0.900   0.590   0.349   0.122   0.005

   Có bước kiểm tra (verifier bắt được 80% lỗi, cho làm lại 1 lần):
   p=0.95: mỗi bước hiệu dụng 0.988 -> 20 bước 0.785 (không verifier: 0.358)
   p=0.9: mỗi bước hiệu dụng 0.972 -> 20 bước 0.567 (không verifier: 0.122)

Chuỗi 20 bước mà mỗi bước "khá tốt" (95%) chỉ hoàn thành đúng 36% số lần. Một bước kiểm (code hoặc LLM) bắt được 80% lỗi nâng lên 79%. Đây là lý do mẫu chaining có "cổng" và mẫu evaluator-optimizer tồn tại; và là lý do giảm số bước thường hiệu quả hơn làm từng bước tốt hơn chút ít. (Giả định các bước độc lập — thực tế lỗi có tương quan.)

4.2 Fan-out: chờ worker chậm nhất

2) Fan-out: orchestrator chờ worker CHẬM NHẤT. Latency mỗi worker ~ lognormal(p50 4s)
 N worker  p50 (s)  p95 (s)  p99 (s)
        1      4.0     10.7     16.0
        3      6.5     14.3     20.3
        5      7.9     16.0     22.7
       10      9.8     18.6     25.3
       20     12.0     21.5     28.8

Song song không có nghĩa là "nhanh bằng một worker": fan-in chờ nhánh chậm nhất, nên p50 của cả nhóm 10 worker (9,8 s) còn cao hơn p90 của một worker (≈ 8,6 s theo phân phối giả định). Cách giảm: timeout mỗi worker + chấp nhận kết quả thiếu, hoặc gửi thừa (hedging) cho nhánh quan trọng.

4.3 Rate limit khi fan-out

3) Rate limit: N worker cùng bắn vào giới hạn 50 request/phút (token bucket, bắt đầu đầy)
    2 worker x 6 call:  12 request,   0 bị 429 (0%)
    5 worker x 6 call:  30 request,   0 bị 429 (0%)
   10 worker x 6 call:  60 request,   0 bị 429 (0%)
   20 worker x 6 call: 120 request,  52 bị 429 (43%)

Dưới ngưỡng, không có gì xảy ra; vượt ngưỡng là sập theo kiểu vách đá — 43% request bị từ chối, và nếu mỗi worker tự retry thì bão retry làm tình hình tệ hơn. Rate limit của nhà cung cấp tính theo request/phút và token input/output/phút theo tổ chức — mọi tính năng AI của công ty chia chung một hạn mức. Giới hạn song song phải đặt ở một chỗ tập trung (semaphore/queue), không để từng agent tự quyết.

4.4 Chi phí và cache

N worker đọc cùng một tài liệu lớn, gửi song song, là N lần ghi cache và không lần đọc nào (cache chỉ đọc được sau khi request đầu bắt đầu stream — bài 03). Nhân với ~15 lần token của multi-agent, bài toán kinh tế chỉ đóng lại khi giá trị nhiệm vụ cao.

5. Failure modes

MAST (Cemri et al., "Why Do Multi-Agent LLM Systems Fail?", NeurIPS 2025 Datasets & Benchmarks) phân tích 1 642 trace của các framework multi-agent, rút ra 14 kiểu hỏng trong ba nhóm: đặc tả (41,8% — không theo yêu cầu, lặp bước đã làm, không nhận ra việc đã xong), lệch giữa các agent (36,9% — bỏ qua input của agent khác, không hỏi lại khi mơ hồ, lý luận và hành động không khớp), kiểm tra (21,3% — kết thúc sớm, không kiểm, kiểm nông). Kết luận của nhóm tác giả: phần lớn lỗi do thiết kế hệ thống, không do model.

LỗiBiểu hiệnPhát hiệnXử lý
Quyết định mâu thuẫnWorker A viết mô tả theo giọng trang trọng, B theo giọng teen; hai subagent sửa cùng file khác hướngEvaluator kiểm tính nhất quánKhông song song hoá việc phụ thuộc; truyền quyết định chung (style guide, schema) cho mọi worker
Làm trùng / bỏ sót3 subagent cùng tìm một nguồnTrace: đếm tool call trùngMô tả nhiệm vụ có ranh giới rõ
Tóm tắt bịaSubagent báo "đã xác minh" khi chưaYêu cầu trả về nguồn/trích dẫnLead kiểm ngẫu nhiên nguồn
Giao việc vô hạnAgent tạo agent tạo agentĐộ sâu cây traceGiới hạn độ sâu và tổng số agent
Bão 429 (lab 4.3)Tỉ lệ lỗi nhảy vọt khi N tăngMetric 429 theo tính năngSemaphore tập trung, backoff có jitter, hàng đợi
Một worker treoCả batch chờThời gian batchTimeout từng worker, allowFailures, tổng hợp với kết quả thiếu
Evaluator dễ dãiVòng lặp tạo-chấm dừng sớm với output kémSo điểm evaluator với người chấmTiêu chí kiểm được bằng code khi có thể; evaluator khác prompt/model

6. Vận hành trong production

7. So sánh và ma trận quyết định

TrụcMột lần gọiChaining / routingParallel / votingOrchestrator-workersSingle agentMulti-agent tự chủ
Chi phí1×vài ×N×N× + điều phối~4× chat~15× chat
LatencyThấpCộng dồnMax nhánhMax nhánh + lập kế hoạchNhiều vòngCao, khó đoán
Dễ debugRất dễDễDễTrung bìnhTrung bìnhKhó
Chất lượng việc rộng, song songThấpThấpTrung bìnhCaoTrung bình (giới hạn context)Cao
Chất lượng việc phụ thuộc chặt—Tốt nếu biết trước bướcKémKémTốtKém (mâu thuẫn)

Quy tắc chọn: bắt đầu từ một lần gọi; thêm bước khi eval chỉ ra cần; chỉ dùng multi-agent khi nhiệm vụ song song hoá được, thông tin vượt một context, giá trị nhiệm vụ trả nổi ~15× token, và đã có eval chứng minh vượt single-agent. Tránh multi-agent cho CSKH thông thường, sửa code trong một repo, hay bất cứ luồng nào biết trước các bước.

8. Góc nhìn tech lead: tác động tổ chức

9. Anti-patterns và bài học thực tế

Điều người làm lâu đều biết: đa số hệ "multi-agent" thành công trong production thực chất là workflow có vài bước LLM, được gọi là agent cho hay. Và đa số lần cải thiện đến từ gộp bước, không phải tách thêm.

10. Câu hỏi phụ interviewer hay hỏi tiếp

Khi nào dùng multi-agent?
Khi việc song song hoá được, lượng thông tin vượt một context, giá trị đủ trả ~15× token, và eval chứng minh hơn single-agent. Nghiên cứu/rà soát rộng là ví dụ tốt; sửa code và CSKH thường không.
Làm sao cho các agent không mâu thuẫn?
Tránh song song hoá việc phụ thuộc; truyền quyết định chung (schema, style, ràng buộc) cho mọi agent; chia sẻ trace thay vì tóm tắt khi cần nhất quán; bước tổng hợp có kiểm tra nhất quán.
Orchestrator-workers khác parallelization chỗ nào?
Parallelization: code chia phần cố định. Orchestrator-workers: LLM quyết định chia bao nhiêu phần, phần nào — linh hoạt hơn, rủi ro chia sai.
Tại sao 20 bước 95% lại tệ vậy?
Xác suất đúng cả chuỗi là 0,95^20 ≈ 0,36 nếu độc lập. Giảm số bước, thêm cổng kiểm, và cho phép sửa lỗi cục bộ.
Rate limit ảnh hưởng thiết kế thế nào?
Hạn mức chia chung cả tổ chức; fan-out phải đi qua giới hạn song song tập trung; retry có backoff + jitter và một tầng duy nhất; ưu tiên tính năng quan trọng.

Phụ lục: lab đã chạy

Môi trường: Python 3.11.15, numpy 2.4.6. Output gốc: labs/ai/out/05-multiagent.txt.

python3 labs/ai/py/multiagent_sim.py

Chưa verify: hiệu quả/chi phí thật của multi-agent (cần API key và nhiệm vụ thật); phân phối latency thật của API. Nguồn: Anthropic Engineering, "How we built our multi-agent research system" (6/2025); Cognition, "Don't Build Multi-Agents" (6/2025); Anthropic, "Building effective agents" (12/2024); Cemri et al., "Why Do Multi-Agent LLM Systems Fail?" (arXiv 2503.13657, NeurIPS 2025).

Bài trước: 04 · RAG với pgvector · Bài tiếp: 06 · MCP chuyên sâu.