Một trong những quyết định kiến trúc quan trọng nhất khi xây dựng AI agent phức tạp là: task này nên để agent chính (main context) tự làm, hay nên giao (delegate) cho một sub-agent — một AI agent con được sinh ra để xử lý một phần việc cụ thể rồi trả kết quả về? Quyết định này ảnh hưởng trực tiếp đến số lượng token tiêu tốn, tốc độ phản hồi, và cả chất lượng kết quả cuối cùng. Chọn sai — delegate quá nhiều hoặc quá ít — có thể khiến chi phí vận hành agent tăng gấp nhiều lần mà không mang lại giá trị tương xứng.
Bài này đi sâu vào bài toán ra quyết định delegation, phân tích kinh tế học token của việc giao việc, bốn pattern (mẫu hình) delegation phổ biến nhất trong thực tế, và cách thiết kế một orchestrator (bộ điều phối) tối ưu — minh họa bằng CrewAI, một framework orchestration phổ biến hỗ trợ hierarchical process (quy trình phân cấp).
The Delegation Decision Problem (Bài Toán Ra Quyết Định Delegation)
Hãy tưởng tượng một agent chính đang xử lý yêu cầu: "Review toàn bộ pull request này, kiểm tra lỗi bảo mật, viết unit test còn thiếu, và cập nhật changelog." Đây là bốn công việc con (sub-task) có bản chất rất khác nhau: đọc hiểu code, phân tích bảo mật, sinh code test, và viết văn bản. Agent chính có ba lựa chọn cho mỗi sub-task:
- Tự xử lý trong main context — main context tự đọc code, tự phân tích, tự viết test, tự cập nhật changelog trong cùng một vòng lặp (agentic loop), cùng một context window.
- Delegate cho sub-agent — sinh ra một agent con, cấp cho nó một context riêng biệt (isolated context), giao nhiệm vụ, nhận kết quả tóm tắt (summary) trả về.
- Delegate một phần — chia nhỏ, một phần tự làm, một phần giao cho sub-agent.
Vấn đề là: không có công thức toán học chính xác cho quyết định này. Nó phụ thuộc vào nhiều biến số cùng lúc — kích thước dữ liệu cần xử lý, độ chuyên biệt của công việc, mức độ cần cách ly context, và cả overhead (chi phí phụ trội) của việc khởi tạo một agent mới.
Nhiều team mắc phải hai sai lầm đối lập:
- Over-delegation (giao việc quá đà): mọi tác vụ nhỏ, dù chỉ mất vài chục token để xử lý trực tiếp, đều được đóng gói thành một sub-agent riêng. Kết quả: overhead khởi tạo (system prompt, tool definitions, context nạp lại) vượt xa giá trị công việc thực tế mang lại.
- Under-delegation (không chịu giao việc): agent chính ôm hết mọi thứ vào một context window duy nhất, khiến context bị "phình" (context bloat) bởi dữ liệu trung gian không cần thiết cho luồng chính — ví dụ toàn bộ log lỗi thô của 500 file khi chỉ cần một dòng tóm tắt.
Câu hỏi cốt lõi cần đặt ra trước mỗi sub-task là: "Kết quả trung gian (intermediate result) của công việc này có cần tồn tại trong main context để agent chính tiếp tục suy luận, hay chỉ cần bản tóm tắt cuối cùng?" Nếu câu trả lời là "chỉ cần bản tóm tắt", đó là dấu hiệu mạnh cho việc delegate.
Mẹo: Trước khi quyết định delegate, hãy tự hỏi "sub-task này có sinh ra bao nhiêu token dữ liệu trung gian mà main context không cần nhìn thấy?". Nếu con số này lớn (ví dụ đọc một file log 50.000 token để tìm 3 lỗi), delegate gần như luôn là lựa chọn đúng, vì nó giữ context window của agent chính sạch và tập trung.
The Token Economics of Delegation (Kinh Tế Học Token Của Việc Delegation)
Để ra quyết định delegation đúng đắn, cần định lượng được chi phí và lợi ích bằng số token cụ thể, không chỉ dựa vào cảm tính.
Chi phí của việc tự xử lý (inline handling)
Khi agent chính tự xử lý một sub-task ngay trong context hiện tại, mọi input, output, và bước suy luận trung gian đều được ghi vào lịch sử hội thoại (conversation history) và tồn tại ở đó cho đến hết session — vì kiến trúc agentic loop thường gửi lại toàn bộ lịch sử ở mỗi lượt gọi LLM. Đây gọi là chi phí lũy kế (cumulative cost): một khối 8.000 token được thêm vào ở turn thứ 5 sẽ bị tính phí lại ở turn 6, 7, 8... cho đến khi kết thúc.
Ví dụ cụ thể: agent chính cần review 5 file code, mỗi file khoảng 2.000 token, để tìm lỗi bảo mật. Nếu xử lý inline:
- Nạp 5 file: 5 × 2.000 = 10.000 token vào context.
- Agent suy luận, viết ra phân tích chi tiết cho từng file: giả sử 1.500 token/file × 5 = 7.500 token.
- Tổng token thêm vào context: 17.500 token.
- Nếu agentic loop còn 10 turn nữa sau đó, và mỗi turn phải gửi lại toàn bộ history, thì 17.500 token này bị tính phí lại 10 lần → 175.000 token bị tính phí gián tiếp chỉ vì giữ chi tiết phân tích trong context.
Chi phí của việc delegate
Khi delegate cho sub-agent, chi phí gồm hai phần:
- Overhead khởi tạo: system prompt của sub-agent (thường 200-800 token), định nghĩa tool nó được dùng (100-500 token), và task description agent chính gửi xuống (100-300 token). Tổng overhead: khoảng 500-1.500 token cho mỗi lần spawn sub-agent.
- Chi phí xử lý bên trong sub-agent: sub-agent nạp 5 file (10.000 token) + suy luận chi tiết (7.500 token) = 17.500 token — nhưng chi phí này chỉ tồn tại trong context riêng của sub-agent, không lặp lại ở các turn tiếp theo của main context.
- Chi phí trả kết quả về: sub-agent trả về bản tóm tắt, ví dụ 300 token ("Tìm thấy 2 lỗi SQL injection ở file A dòng 45, 1 lỗi XSS ở file C dòng 12. Chi tiết: ..."). Con số này được thêm vào main context và sẽ bị tính phí lại ở các turn sau — nhưng chỉ 300 token, không phải 17.500 token.
So sánh trực tiếp với ví dụ 10 turn còn lại ở trên:
| Phương án | Token thêm vào main context | Token bị tính lại qua 10 turn |
|---|---|---|
| Xử lý inline | 17.500 | 175.000 |
| Delegate cho sub-agent | ~1.800 (overhead) + 300 (tóm tắt) = 2.100 | 21.000 |
Chênh lệch gần 8 lần. Đây chính là lý do delegation trở thành kỹ thuật tối ưu token quan trọng bậc nhất trong thiết kế agentic loop dài hơi (long-running agentic loop).
Tuy nhiên, kinh tế học này đảo ngược khi:
- Sub-task rất nhỏ (dưới 500 token xử lý), khiến overhead spawn (500-1.500 token) chiếm phần lớn tổng chi phí — delegate lúc này đắt hơn xử lý inline.
- Main context thực sự cần dữ liệu chi tiết cho các bước suy luận tiếp theo (không thể tóm tắt mà không mất thông tin quan trọng) — delegate buộc phải trả về bản tóm tắt dài, làm giảm lợi ích cách ly.
- Không còn turn nào phía sau để "tính lại" (đây là turn cuối cùng) — chi phí lũy kế bằng 0, nên xử lý inline không có nhược điểm về mặt token.
Mẹo: Dùng công thức nhanh để ước lượng: Lợi ích delegate ≈ (token trung gian tiết kiệm được) × (số turn còn lại) − overhead spawn sub-agent. Nếu số turn còn lại nhỏ (gần cuối agentic loop) hoặc sub-task quá nhỏ, công thức này cho kết quả âm — đừng delegate.
The Four Delegation Patterns (Bốn Pattern Delegation)
Qua thực tế triển khai nhiều hệ thống multi-agent, có bốn pattern delegation lặp lại thường xuyên nhất. Hiểu rõ bốn pattern này giúp lựa chọn đúng cấu trúc cho từng loại bài toán.
Pattern 1: Isolated Analysis (Delegate and Summarize)
Đây là pattern phổ biến nhất: giao cho sub-agent một khối dữ liệu lớn cần phân tích sâu, và chỉ nhận về bản tóm tắt. Sub-agent "hy sinh" context của nó để đọc, phân tích, và chưng cất (distill) thông tin thành dạng cô đọng.
Ví dụ ứng dụng: phân tích một codebase lớn để tìm tất cả nơi sử dụng một API đã deprecated (không còn được hỗ trợ), hoặc đọc một tài liệu PDF 40 trang để trích xuất các điều khoản hợp đồng quan trọng.
result = spawn_sub_agent(
task="Scan the entire /src directory for usages of the deprecated "
"`legacy_auth()` function. For each usage, report file path, "
"line number, and one-sentence context of how it's used. "
"Return ONLY a structured list — do not include full file contents.",
context_budget=50_000, # sub-agent may consume up to this many tokens internally
)
main_context.add(result.summary)
Đặc điểm nhận diện: input lớn, output nhỏ, và main context không cần dữ liệu thô ở bất kỳ bước nào sau đó.
Pattern 2: Specialized Execution (Delegate and Forget)
Ở pattern này, sub-agent được giao một nhiệm vụ có tính chuyên biệt cao — cần một system prompt, tool set, hoặc "vai" (persona) riêng biệt — và kết quả trả về không cần nuôi tiếp cho các bước suy luận sau. Main context "quên" luôn chi tiết, chỉ ghi nhận trạng thái hoàn thành.
Ví dụ: một sub-agent chuyên viết unit test theo convention riêng của team, nhận diện input là một function, trả về một file test hoàn chỉnh. Main context không cần biết sub-agent đã "vật lộn" qua bao nhiêu vòng thử-sửa để ra được file test đó.
test_agent_result = spawn_sub_agent(
role="Senior QA Engineer specialized in pytest",
task=f"Write comprehensive unit tests for this function:\n{function_code}\n"
f"Follow the project's existing test conventions in tests/conftest.py.",
tools=["read_file", "write_file", "run_tests"],
)
main_context.add(f"Test written: {test_agent_result.file_path}, "
f"{test_agent_result.test_count} tests, all passing.")
Pattern 3: Parallel Specialization (Fan-Out / Fan-In)
Khi có nhiều sub-task độc lập với nhau (không phụ thuộc kết quả của nhau), có thể fan-out (phân rẽ) — spawn nhiều sub-agent chạy song song, mỗi agent xử lý một phần — rồi fan-in (hợp nhất) kết quả về main context để tổng hợp.
Ví dụ: review một pull request thay đổi 4 module độc lập (frontend, backend API, database migration, CI config). Bốn sub-agent chuyên biệt có thể chạy đồng thời:
import asyncio
async def review_pr_parallel(pr_diff_by_module):
tasks = [
spawn_sub_agent_async(
role=f"{module} reviewer",
task=f"Review this diff for {module} for correctness and style:\n{diff}",
)
for module, diff in pr_diff_by_module.items()
]
results = await asyncio.gather(*tasks)
return results # fan-in: collect all summaries at once
reviews = asyncio.run(review_pr_parallel(pr_diff_by_module))
final_comment = compile_review(reviews)
Lợi ích không chỉ về token (mỗi sub-agent có context riêng, không context nào bị "vấy" thông tin của module khác) mà còn về wall-clock time (thời gian thực) — 4 sub-agent chạy song song nhanh hơn nhiều so với xử lý tuần tự.
Lưu ý quan trọng: fan-out chỉ hiệu quả khi các sub-task thực sự độc lập. Nếu module B cần biết kết quả review của module A (ví dụ một interface thay đổi ảnh hưởng cả hai), fan-out sẽ tạo ra các review mâu thuẫn nhau, và main context phải tốn thêm token để hòa giải (reconcile) mâu thuẫn đó.
Pattern 4: Iterative Delegation (Recursive Decomposition)
Pattern phức tạp nhất: một sub-agent, trong quá trình xử lý nhiệm vụ của nó, phát hiện ra nhiệm vụ cần được chia nhỏ tiếp — và tự spawn ra các sub-agent con của nó (recursive decomposition — phân rã đệ quy). Đây thường gặp trong các bài toán có độ sâu không biết trước, ví dụ: "phân tích toàn bộ dependency tree (cây phụ thuộc) của một package và tìm mọi lỗ hổng bảo mật đã biết."
def analyze_dependency(package_name, depth=0, max_depth=3):
if depth > max_depth:
return {"package": package_name, "note": "max depth reached, skipped"}
direct_deps = get_direct_dependencies(package_name)
vuln_report = spawn_sub_agent(
task=f"Check known CVEs for {package_name} version {get_version(package_name)}"
)
# If this package itself has many sub-dependencies worth deeper inspection,
# recursively delegate further — each recursive call gets its own isolated context
child_reports = []
if len(direct_deps) > 0 and vuln_report.risk_level != "low":
child_reports = [
analyze_dependency(dep, depth=depth + 1, max_depth=max_depth)
for dep in direct_deps
]
return {
"package": package_name,
"vulnerabilities": vuln_report.summary,
"children": child_reports,
}
Rủi ro lớn nhất của pattern này là explosion không kiểm soát (bùng nổ số lượng sub-agent) — nếu không có điều kiện dừng rõ ràng (như max_depth ở ví dụ trên), một cây phụ thuộc lớn có thể sinh ra hàng trăm sub-agent, mỗi sub-agent tốn overhead riêng, khiến tổng chi phí vượt xa lợi ích.
Mẹo: Với cả bốn pattern, luôn đặt một giới hạn cứng (hard limit) cho số lượng sub-agent tối đa được spawn trong một lần chạy — kể cả khi logic nghiệp vụ "có vẻ" cần nhiều hơn. Một giới hạn hợp lý (ví dụ 10-20 sub-agent mỗi orchestration run) buộc bạn phải thiết kế lại bài toán theo hướng gộp nhóm (batching) hiệu quả hơn, thay vì để chi phí tăng tuyến tính không kiểm soát.
Signals That Delegation Is the Right Choice (Dấu Hiệu Cho Thấy Nên Delegation)
Không cần phải tính toán chi tiết mỗi lần — sau một thời gian làm việc với agentic system, có thể nhận diện delegation qua các dấu hiệu (signal) sau:
- Khối lượng dữ liệu đầu vào lớn hơn nhiều so với kết quả cần giữ lại. Ví dụ: đọc 20.000 token log để tìm nguyên nhân một lỗi, nhưng kết quả cuối chỉ là một câu kết luận.
- Công việc cần một "vai" hoặc system prompt hoàn toàn khác với vai của agent chính — ví dụ agent chính đóng vai "product manager điều phối", nhưng sub-task cần vai "security auditor" với checklist chuyên biệt. Trộn hai vai trong cùng context dễ gây nhiễu (context confusion — tình trạng model lẫn lộn vai trò/mục tiêu).
- Công việc có thể chạy độc lập, song song với công việc khác — dấu hiệu rõ ràng cho Pattern 3 (Fan-Out/Fan-In).
- Công việc có khả năng cần nhiều vòng thử-sai (trial and error) mà quá trình thử-sai đó không có giá trị tham khảo cho các bước tiếp theo của main context. Ví dụ: debug một đoạn code bằng cách thử nhiều cách sửa khác nhau — main context chỉ cần biết cách sửa nào cuối cùng hoạt động, không cần biết 5 lần thử thất bại trước đó.
- Rủi ro "ô nhiễm context" (context contamination) — nếu để dữ liệu thô của sub-task nằm trong main context, nó có thể khiến model bị phân tâm hoặc suy luận sai ở các bước sau (ví dụ model "nhớ nhầm" một đoạn code lỗi tạm thời trong lúc debug là code chính thức).
Ngược lại, các dấu hiệu cho thấy không nên delegate:
- Sub-task nhỏ, dưới vài trăm token cả input và output.
- Main context cần theo dõi sát tiến trình suy luận (ví dụ cần "nhìn thấy" từng bước để người dùng giám sát/can thiệp).
- Chỉ còn 1-2 turn nữa là kết thúc agentic loop — không có "turn tương lai" để hưởng lợi từ việc giảm token lũy kế.
- Task cần truy cập trạng thái chia sẻ (shared state) phức tạp mà việc đồng bộ giữa main context và sub-agent context tốn nhiều token hơn là lợi ích cách ly mang lại.
Mẹo: Ghi lại (log) mỗi lần delegate: token overhead, token tóm tắt trả về, và số turn còn lại tại thời điểm delegate. Sau vài chục lần chạy, review log này để tìm ra pattern sub-task nào của riêng hệ thống bạn thường "delegate không đáng" — đây là dữ liệu thực tế tốt hơn nhiều so với quy tắc chung.
Orchestrator Design: The Thin Orchestrator Principle (Nguyên Tắc Thin Orchestrator)
Khi một hệ thống có nhiều sub-agent, vai trò của agent chính chuyển từ "người thực thi" (executor) sang "người điều phối" (orchestrator). Nguyên tắc quan trọng nhất ở đây là Thin Orchestrator (orchestrator mỏng/gọn): agent điều phối chỉ nên chứa logic định tuyến (routing) và tổng hợp (compiling) — tuyệt đối không tự ôm việc chuyên môn nặng vào context của chính nó.
Một orchestrator "dày" (thick orchestrator) — anti-pattern (mẫu hình nên tránh) — thường mắc lỗi: đọc toàn bộ dữ liệu chi tiết trước khi delegate, rồi sau đó vẫn delegate, khiến dữ liệu bị nạp hai lần; hoặc yêu cầu sub-agent trả về dữ liệu đầy đủ (full) thay vì bản tóm tắt, khiến orchestrator context phình to dù đã có sub-agent.
def thick_orchestrator(codebase_path, pr_diff):
# Anti-pattern #1: orchestrator reads everything itself BEFORE delegating,
# duplicating the token cost that the sub-agent will also incur.
all_files_content = read_all_files(codebase_path) # 40,000 tokens loaded here
main_context.add(all_files_content)
security_agent = spawn_sub_agent(
role="Security Reviewer",
task=f"Review this PR diff for security issues:\n{pr_diff}\n"
f"Here is the full codebase for reference:\n{all_files_content}",
# Anti-pattern #2: passing the already-loaded 40,000 tokens again
# into the sub-agent's context — paid for twice.
)
# Anti-pattern #3: asking the sub-agent to return everything,
# not a distilled summary, defeating the purpose of isolation.
full_report = security_agent.get_full_reasoning_trace()
main_context.add(full_report) # another ~15,000 tokens added to main context
style_agent = spawn_sub_agent(role="Style Reviewer", task=f"Review style:\n{pr_diff}")
main_context.add(style_agent.get_full_reasoning_trace())
# Orchestrator itself tries to re-derive the final verdict from raw traces,
# instead of letting sub-agents pre-digest it.
return summarize_everything_manually(main_context)
def thin_orchestrator(codebase_path, pr_diff):
# The orchestrator does NOT load the codebase itself.
# It only routes the task, letting each specialist load what it needs
# inside its own isolated context.
security_result = spawn_sub_agent(
role="Security Reviewer",
task=f"Review this PR diff for security issues. Load only the files "
f"referenced in the diff, not the whole codebase.\n{pr_diff}",
instructions="Return a structured summary: severity, file, line, one-line fix.",
)
style_result = spawn_sub_agent(
role="Style Reviewer",
task=f"Review this PR diff for style/convention issues:\n{pr_diff}",
instructions="Return a structured summary: max 5 bullet points.",
)
# Orchestrator context only ever holds the two small summaries —
# never the raw codebase, never the full reasoning trace.
main_context.add(security_result.summary) # ~400 tokens
main_context.add(style_result.summary) # ~200 tokens
# Routing + compiling is the ONLY job of the orchestrator.
return compile_final_review(security_result.summary, style_result.summary)
Sự khác biệt về token trong ví dụ trên là rất lớn: thick orchestrator giữ khoảng 55.000+ token trong main context (codebase đầy đủ + hai reasoning trace đầy đủ), trong khi thin orchestrator chỉ giữ khoảng 600 token (hai bản tóm tắt). Nếu agentic loop còn nhiều turn phía sau, chênh lệch này nhân lên gấp nhiều lần.
Ba quy tắc thiết kế Thin Orchestrator:
- Không đọc dữ liệu chi tiết thay cho sub-agent — chỉ đọc đủ để biết cần route (định tuyến) đi đâu.
- Luôn yêu cầu sub-agent trả về summary có cấu trúc (structured summary), không phải toàn bộ reasoning trace.
- Orchestrator chỉ giữ trạng thái điều phối (task nào đã giao, kết quả nào đã nhận, task nào còn treo) — không giữ nội dung nghiệp vụ chi tiết.
Mẹo: Khi review code của một orchestrator, hãy kiểm tra tỷ lệ token: nếu context của agent chính chứa nhiều dữ liệu "thô" hơn dữ liệu "đã điều phối/tóm tắt", đó là dấu hiệu orchestrator đang bị "dày hóa" và cần refactor lại theo hướng thin.
CrewAI: Hierarchical Process for Delegation Control (Hierarchical Process Trong CrewAI)
CrewAI là một trong những framework phổ biến để xây dựng hệ thống multi-agent, hỗ trợ sẵn khái niệm hierarchical process (quy trình phân cấp) — một manager agent (agent quản lý) đóng vai trò orchestrator, còn các specialist agent (agent chuyên gia) thực hiện công việc chuyên môn trong context riêng biệt của chúng. Đây là cách hiện thực hóa Thin Orchestrator Principle bằng một framework có sẵn cơ chế quản lý delegation.
from crewai import Agent, Task, Crew, Process
manager = Agent(
role="Engineering Delivery Manager",
goal="Coordinate specialists to produce a release-ready review summary "
"without performing the detailed analysis itself",
backstory="An experienced tech lead who delegates deep work and "
"focuses on synthesis and decision-making.",
allow_delegation=True,
verbose=True,
)
security_specialist = Agent(
role="Security Reviewer",
goal="Find and report security vulnerabilities in the given diff",
backstory="A senior application security engineer with deep knowledge "
"of OWASP Top 10 and secure coding practices.",
tools=[read_file_tool, grep_tool],
verbose=True,
)
performance_specialist = Agent(
role="Performance Reviewer",
goal="Identify performance regressions and inefficient patterns",
backstory="A backend performance engineer specialized in query "
"optimization and algorithmic complexity analysis.",
tools=[read_file_tool, profiler_tool],
verbose=True,
)
manager_task = Task(
description=(
"Given the pull request diff at {pr_diff}, delegate the security "
"analysis to the Security Reviewer and the performance analysis to "
"the Performance Reviewer. Instruct both to return a maximum "
"5-bullet-point summary each. Compile their summaries into a single "
"release-readiness verdict: APPROVE, APPROVE_WITH_COMMENTS, or BLOCK."
),
expected_output="A verdict (APPROVE / APPROVE_WITH_COMMENTS / BLOCK) "
"with a combined bullet list of key findings.",
agent=manager,
)
crew = Crew(
agents=[manager, security_specialist, performance_specialist],
tasks=[manager_task],
process=Process.hierarchical, # manager decides delegation at runtime
manager_llm="gpt-4o-mini", # manager itself can run on a cheaper model
verbose=True,
)
result = crew.kickoff(inputs={"pr_diff": pr_diff_text})
print(result)
Vài điểm cần chú ý khi dùng Process.hierarchical trong CrewAI:
allow_delegation=Truetrên manager agent là điều kiện bắt buộc để nó có quyền tự quyết định giao việc cho specialist agent nào, dựa trênrole/goal/backstorycủa từng specialist — CrewAI tự sinh cơ chế routing dựa trên các mô tả này.manager_llmthường có thể dùng một model rẻ hơn (ví dụ GPT-4o-mini hoặc Claude Haiku) so với model của specialist, vì công việc của manager chỉ là điều phối và tổng hợp — không đòi hỏi khả năng suy luận sâu như specialist đang phân tích chi tiết bảo mật hay performance. Đây là một dạng tối ưu chi phí kép: vừa giảm token nhờ context nhỏ, vừa giảm chi phí per-token nhờ model rẻ hơn.expected_outputtrên task nên được viết rõ ràng để ép cả specialist và manager trả về kết quả cô đọng — nếu để mặc định, agent có xu hướng trả về câu trả lời dài dòng, làm phình context của crew.- Tools chỉ nên gán cho specialist, không gán cho manager — đúng theo nguyên tắc Thin Orchestrator: manager không cần (và không nên) tự đọc file hay chạy công cụ phân tích.
So với Process.sequential (quy trình tuần tự) — nơi các agent chạy lần lượt theo một danh sách task cố định — Process.hierarchical linh hoạt hơn vì manager có thể quyết định runtime nên giao task nào cho agent nào, kể cả việc giao lại (re-delegate) nếu kết quả ban đầu chưa đạt. Tuy nhiên, sự linh hoạt này đi kèm với chi phí: manager cần một vài lượt suy luận (reasoning) để ra quyết định delegate, nên Process.hierarchical thường tốn nhiều token điều phối hơn Process.sequential một chút — đánh đổi hợp lý khi bài toán thực sự cần định tuyến động.
Mẹo: Khi mới migrate một pipeline agent đơn sang CrewAI hierarchical, hãy bắt đầu với 2-3 specialist agent có role/goal được viết cực kỳ rõ ràng và không chồng lấn nhau. Manager agent định tuyến dựa trên mô tả này — nếu hai specialist có goal mơ hồ hoặc trùng lặp, manager sẽ tốn thêm token "phân vân" hoặc giao nhầm việc.
Monitoring Orchestration Efficiency (Giám Sát Hiệu Quả Orchestration)
Thiết kế đúng pattern chỉ là bước đầu — để biết orchestration có thực sự tối ưu token trong vận hành thực tế, cần đo lường liên tục. Các chỉ số (metric) quan trọng cần theo dõi:
- Delegation ratio (tỷ lệ giao việc): số sub-agent được spawn trên tổng số sub-task cần xử lý. Tỷ lệ quá cao (gần 100%) có thể là dấu hiệu over-delegation với các task quá nhỏ; tỷ lệ quá thấp có thể là dấu hiệu context main đang bị phình vì xử lý inline quá nhiều.
- Overhead-to-value ratio (tỷ lệ overhead trên giá trị): tổng token overhead của việc spawn sub-agent (system prompt, tool definition) chia cho tổng token tiết kiệm được nhờ cách ly context. Nếu tỷ lệ này gần 1 (overhead gần bằng lợi ích), delegation đó không còn đáng giá.
- Summary compression ratio (tỷ lệ nén tóm tắt): token xử lý bên trong sub-agent chia cho token của bản tóm tắt trả về main context. Tỷ lệ nén cao (ví dụ 50:1 — xử lý 50.000 token, trả về 1.000 token) là dấu hiệu tốt của Pattern 1 (Isolated Analysis) đang hoạt động hiệu quả. Tỷ lệ nén thấp (2:1 hoặc 3:1) gợi ý cần siết lại instruction cho sub-agent để buộc nó tóm tắt gọn hơn.
- Orchestrator context growth rate (tốc độ tăng context của orchestrator): theo dõi qua mỗi turn, main context của orchestrator tăng bao nhiêu token. Với thin orchestrator vận hành đúng, tốc độ tăng này phải rất chậm và tuyến tính (chỉ tăng theo số bản tóm tắt nhận về), không tăng vọt (spike) đột ngột — spike thường là dấu hiệu một sub-agent nào đó trả về dữ liệu thô thay vì tóm tắt.
- Wasted sub-agent spawns (spawn lãng phí): số sub-agent được spawn nhưng kết quả trả về không được orchestrator sử dụng ở bước tổng hợp cuối — dấu hiệu của over-delegation hoặc logic routing sai.
Về công cụ, hầu hết framework orchestration (bao gồm CrewAI qua verbose=True và các callback/hook, hoặc tự log thủ công quanh hàm spawn_sub_agent) đều có thể xuất ra token count theo từng agent, từng task. Nên tổng hợp các số liệu này vào một dashboard hoặc log tổng hợp theo mỗi lần chạy orchestration, để so sánh xu hướng qua thời gian — đặc biệt quan trọng khi hệ thống agent được mở rộng thêm nhiều specialist mới, vì mỗi specialist mới đều có khả năng làm thay đổi delegation ratio tổng thể.
Mẹo: Đặt một ngưỡng cảnh báo (alert threshold) cho "wasted sub-agent spawns" và "overhead-to-value ratio" ngay trong pipeline CI/CD hoặc trong logging production. Khi các chỉ số này vượt ngưỡng liên tục qua nhiều lần chạy, đó là tín hiệu sớm để review lại thiết kế pattern delegation trước khi chi phí vận hành âm thầm leo thang.
Summary (Tổng Kết)
Delegation là một công cụ tối ưu token mạnh, nhưng không phải "cây đũa thần" áp dụng cho mọi trường hợp. Quyết định delegate hay tự xử lý cần dựa trên phân tích kinh tế học token cụ thể: overhead khởi tạo sub-agent so với token lũy kế tiết kiệm được qua các turn còn lại của agentic loop.
Bốn pattern delegation — Isolated Analysis, Specialized Execution, Parallel Specialization, và Iterative Delegation — đại diện cho các tình huống sử dụng khác nhau, từ phân tích dữ liệu lớn cần tóm tắt, đến công việc chuyên biệt cần "vai" riêng, đến các task độc lập chạy song song, đến bài toán cần phân rã đệ quy có kiểm soát.
Thiết kế orchestrator theo nguyên tắc Thin Orchestrator — chỉ định tuyến và tổng hợp, không tự ôm việc chuyên môn — là yếu tố quyết định giúp lợi ích của delegation thực sự phát huy, thay vì bị triệt tiêu bởi một orchestrator "dày" nạp dữ liệu trùng lặp. CrewAI với Process.hierarchical là một ví dụ cụ thể hiện thực hóa nguyên tắc này bằng framework, cho phép manager agent định tuyến động tới các specialist agent chạy trong context cách ly.
Cuối cùng, thiết kế đúng chỉ là điểm khởi đầu — giám sát liên tục các chỉ số như delegation ratio, overhead-to-value ratio, và summary compression ratio giúp phát hiện sớm khi hệ thống trượt khỏi trạng thái tối ưu, đặc biệt khi hệ thống agent được mở rộng và số lượng specialist tăng theo thời gian.