Subagent là các phiên bản agent riêng biệt mà agent chính của bạn có thể sinh ra để xử lý các tác vụ con tập trung. Dùng chúng để tách biệt context, chạy nhiều phân tích song song, và áp dụng chỉ dẫn chuyên biệt mà không làm phình to prompt của agent chính.
Trang này giải thích cách định nghĩa và dùng subagent trong SDK thông qua tham số agents.
Tổng quan
Phần tiêu đề “Tổng quan”Bạn có thể tạo subagent bằng ba cách:
- Lập trình (programmatic): dùng tham số
agentstrong tùy chọnquery(). - Dựa trên filesystem: định nghĩa agent dưới dạng file markdown trong thư mục
.claude/agents/. Xem định nghĩa subagent dưới dạng file. - Built-in general-purpose: Claude có thể gọi subagent built-in
general-purposebất cứ lúc nào qua Agent tool mà không cần bạn định nghĩa gì.
Trang này tập trung vào cách lập trình, được khuyến nghị cho ứng dụng SDK.
Khi bạn định nghĩa subagent, Claude quyết định có nên gọi chúng hay không dựa trên trường description của mỗi subagent. Hãy viết mô tả rõ ràng giải thích khi nào nên dùng subagent, và Claude sẽ tự động giao việc phù hợp. Bạn cũng có thể yêu cầu tường minh một subagent theo tên trong prompt, ví dụ “Use the code-reviewer agent to…”.
Lợi ích khi dùng subagent
Phần tiêu đề “Lợi ích khi dùng subagent”Tách biệt context
Phần tiêu đề “Tách biệt context”Mỗi subagent chạy trong hội thoại riêng, hoàn toàn mới. Các tool call trung gian và kết quả nằm bên trong subagent; chỉ message cuối cùng của nó trả về cho agent cha.
Ví dụ: một subagent research-assistant có thể khám phá hàng chục file mà không có nội dung nào trong số đó tích lũy vào hội thoại chính. Agent cha nhận một bản tóm tắt gọn gàng, không phải mọi file mà subagent đã đọc.
Song song hóa
Phần tiêu đề “Song song hóa”Nhiều subagent có thể chạy đồng thời, nên các tác vụ con độc lập hoàn thành trong thời gian của tác vụ chậm nhất thay vì tổng thời gian của tất cả.
Ví dụ: trong một buổi review code, bạn có thể chạy đồng thời các subagent style-checker, security-scanner, và test-coverage thay vì chạy tuần tự.
Chỉ dẫn và kiến thức chuyên biệt
Phần tiêu đề “Chỉ dẫn và kiến thức chuyên biệt”Mỗi subagent có thể có system prompt riêng với chuyên môn, best practice, và ràng buộc cụ thể.
Ví dụ: một subagent database-migration có thể có kiến thức chi tiết về best practice SQL, chiến lược rollback, và kiểm tra tính toàn vẹn dữ liệu - những thứ sẽ là nhiễu không cần thiết trong chỉ dẫn của agent chính.
Giới hạn tool
Phần tiêu đề “Giới hạn tool”Subagent có thể bị giới hạn chỉ dùng một số tool nhất định, giảm rủi ro hành động ngoài ý muốn.
Ví dụ: một subagent doc-reviewer chỉ có quyền dùng Read và Grep, đảm bảo nó có thể phân tích nhưng không bao giờ vô tình sửa file tài liệu của bạn.
Tạo subagent
Phần tiêu đề “Tạo subagent”Định nghĩa lập trình (khuyến nghị)
Phần tiêu đề “Định nghĩa lập trình (khuyến nghị)”Định nghĩa subagent trực tiếp trong code bằng tham số agents. Claude gọi subagent qua tool Agent, nên hãy đưa Agent vào allowedTools để tự động duyệt lệnh gọi subagent mà không cần prompt xin quyền.
Ví dụ này tạo hai subagent: một code reviewer chỉ đọc và một test runner có thể thực thi lệnh.
import asynciofrom claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition
async def main(): async for message in query( prompt="Review the authentication module for security issues", options=ClaudeAgentOptions( # Tự động duyệt các tool này, bao gồm Agent để gọi subagent allowed_tools=["Read", "Grep", "Glob", "Agent"], agents={ "code-reviewer": AgentDefinition( # description cho Claude biết khi nào dùng subagent này description="Expert code review specialist. Use for quality, security, and maintainability reviews.", # prompt định nghĩa hành vi và chuyên môn của subagent prompt="""You are a code review specialist with expertise in security, performance, and best practices.
When reviewing code:- Identify security vulnerabilities- Check for performance issues- Verify adherence to coding standards- Suggest specific improvements
Be thorough but concise in your feedback.""", # tools giới hạn những gì subagent có thể làm (chỉ đọc ở đây) tools=["Read", "Grep", "Glob"], # model ghi đè model mặc định cho subagent này model="sonnet", ), "test-runner": AgentDefinition( description="Runs and analyzes test suites. Use for test execution and coverage analysis.", prompt="""You are a test execution specialist. Run tests and provide clear analysis of results.
Focus on:- Running test commands- Analyzing test output- Identifying failing tests- Suggesting fixes for failures""", # Quyền Bash cho phép subagent này chạy lệnh test tools=["Bash", "Read", "Grep"], ), }, ), ): if hasattr(message, "result"): print(message.result)
asyncio.run(main())import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({ prompt: "Review the authentication module for security issues", options: { // Tự động duyệt các tool này, bao gồm Agent để gọi subagent allowedTools: ["Read", "Grep", "Glob", "Agent"], agents: { "code-reviewer": { // description cho Claude biết khi nào dùng subagent này description: "Expert code review specialist. Use for quality, security, and maintainability reviews.", // prompt định nghĩa hành vi và chuyên môn của subagent prompt: `You are a code review specialist with expertise in security, performance, and best practices.
When reviewing code:- Identify security vulnerabilities- Check for performance issues- Verify adherence to coding standards- Suggest specific improvements
Be thorough but concise in your feedback.`, // tools giới hạn những gì subagent có thể làm (chỉ đọc ở đây) tools: ["Read", "Grep", "Glob"], // model ghi đè model mặc định cho subagent này model: "sonnet" }, "test-runner": { description: "Runs and analyzes test suites. Use for test execution and coverage analysis.", prompt: `You are a test execution specialist. Run tests and provide clear analysis of results.
Focus on:- Running test commands- Analyzing test output- Identifying failing tests- Suggesting fixes for failures`, // Quyền Bash cho phép subagent này chạy lệnh test tools: ["Bash", "Read", "Grep"] } } }})) { if ("result" in message) console.log(message.result);}Cấu hình AgentDefinition
Phần tiêu đề “Cấu hình AgentDefinition”| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
description | string | Có | Mô tả bằng ngôn ngữ tự nhiên về khi nào nên dùng agent này |
prompt | string | Có | System prompt định nghĩa vai trò và hành vi của agent |
tools | string[] | Không | Mảng tên tool được phép. Nếu bỏ trống, kế thừa mọi tool khả dụng cho subagent |
disallowedTools | string[] | Không | Mảng tên tool loại khỏi bộ tool của agent. Cũng chấp nhận mẫu ở cấp MCP server: mcp__server hoặc mcp__server__* loại mọi tool từ server đó, và mcp__* loại mọi MCP tool từ mọi server |
model | string | Không | Ghi đè model cho agent này. Chấp nhận alias như 'fable', 'opus', 'sonnet', 'haiku', 'inherit', hoặc một model ID đầy đủ. Mặc định dùng model chính nếu bỏ trống |
skills | string[] | Không | Danh sách tên skill được nạp trước vào context của agent khi khởi động. Skill không được liệt kê vẫn có thể gọi qua Skill tool |
memory | 'user' | 'project' | 'local' | Không | Nguồn bộ nhớ cho agent này |
mcpServers | (string | object)[] | Không | MCP server khả dụng cho agent này, theo tên hoặc cấu hình inline |
initialPrompt | string | Không | Tự động gửi làm lượt user đầu tiên khi agent này chạy ở vai trò agent chính. Bị bỏ qua khi agent được gọi làm subagent |
maxTurns | number | Không | Số lượt agentic tối đa trước khi agent dừng |
background | boolean | Không | Chạy agent này như một tác vụ nền không chặn khi được gọi |
effort | 'low' | 'medium' | 'high' | 'xhigh' | 'max' | number | Không | Mức độ nỗ lực suy luận cho agent này |
permissionMode | PermissionMode | Không | Permission mode cho việc thực thi tool trong agent này |
Trong Python SDK, các tên trường nhiều từ như disallowedTools và mcpServers giữ nguyên chính tả camelCase để khớp với định dạng wire, thay vì theo quy ước snake_case của Python.
Định nghĩa dựa trên filesystem (thay thế)
Phần tiêu đề “Định nghĩa dựa trên filesystem (thay thế)”Bạn cũng có thể định nghĩa subagent dưới dạng file markdown trong thư mục .claude/agents/. Xem tài liệu subagent Claude Code để biết chi tiết cách này. Agent định nghĩa theo cách lập trình được ưu tiên hơn agent dựa trên filesystem có cùng tên.
Subagent kế thừa những gì
Phần tiêu đề “Subagent kế thừa những gì”Context window của một subagent bắt đầu hoàn toàn mới, không có hội thoại cha, nhưng không hề trống rỗng. Nội dung duy nhất bạn truyền từ agent cha sang subagent là chuỗi prompt của Agent tool, nên hãy đưa mọi đường dẫn file, thông báo lỗi, hoặc quyết định mà subagent cần trực tiếp vào prompt đó.
| Subagent nhận được | Subagent không nhận được |
|---|---|
System prompt riêng (AgentDefinition.prompt) và prompt của Agent tool | Lịch sử hội thoại hoặc kết quả tool của agent cha |
CLAUDE.md của dự án (nạp qua settingSources) | Nội dung skill đã nạp trước, trừ khi được liệt kê trong AgentDefinition.skills |
Định nghĩa tool (kế thừa từ cha hoặc tập con trong tools, có lọc riêng cho lượt chạy nền) | System prompt của agent cha |
Một lỗi API khiến subagent kết thúc sớm, ví dụ rate limit, không bao giờ được gửi lại như kết quả của nó. Nếu rate limit, quá tải, hoặc lỗi server làm gián đoạn một subagent chạy foreground đã tạo ra output văn bản, Agent tool trả về output từng phần đó kèm ghi chú rằng subagent chưa hoàn thành.
Gọi subagent
Phần tiêu đề “Gọi subagent”Gọi tự động
Phần tiêu đề “Gọi tự động”Claude tự động quyết định khi nào gọi subagent dựa trên tác vụ và trường description của mỗi subagent. Ví dụ, nếu bạn định nghĩa subagent performance-optimizer với mô tả “Performance optimization specialist for query tuning”, Claude sẽ gọi nó khi prompt của bạn đề cập đến việc tối ưu truy vấn.
Hãy viết mô tả rõ ràng, cụ thể để Claude có thể khớp tác vụ với đúng subagent.
Gọi tường minh
Phần tiêu đề “Gọi tường minh”Để đảm bảo Claude dùng một subagent cụ thể, nhắc tên nó trong prompt:
"Use the code-reviewer agent to check the authentication module"Cách này bỏ qua việc khớp tự động và gọi trực tiếp subagent được nêu tên.
Cấu hình agent động
Phần tiêu đề “Cấu hình agent động”Bạn có thể tạo định nghĩa agent động dựa trên điều kiện thời gian chạy. Ví dụ này tạo một security reviewer với các mức độ nghiêm ngặt khác nhau, dùng model mạnh hơn cho các review nghiêm ngặt.
import asynciofrom claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition
# Hàm factory trả về một AgentDefinition# Mẫu này cho phép bạn tùy chỉnh agent dựa trên điều kiện thời gian chạydef create_security_agent(security_level: str) -> AgentDefinition: is_strict = security_level == "strict" return AgentDefinition( description="Security code reviewer", # Tùy chỉnh prompt dựa trên mức độ nghiêm ngặt prompt=f"You are a {'strict' if is_strict else 'balanced'} security reviewer...", tools=["Read", "Grep", "Glob"], # Điểm mấu chốt: dùng model mạnh hơn cho review có mức độ quan trọng cao model="opus" if is_strict else "sonnet", )
async def main(): # Agent được tạo tại thời điểm query, nên mỗi request có thể dùng cấu hình khác nhau async for message in query( prompt="Review this PR for security issues", options=ClaudeAgentOptions( allowed_tools=["Read", "Grep", "Glob", "Agent"], agents={ # Gọi factory với cấu hình mong muốn "security-reviewer": create_security_agent("strict") }, ), ): if hasattr(message, "result"): print(message.result)
asyncio.run(main())import { query, type AgentDefinition } from "@anthropic-ai/claude-agent-sdk";
// Hàm factory trả về một AgentDefinition// Mẫu này cho phép bạn tùy chỉnh agent dựa trên điều kiện thời gian chạyfunction createSecurityAgent(securityLevel: "basic" | "strict"): AgentDefinition { const isStrict = securityLevel === "strict"; return { description: "Security code reviewer", // Tùy chỉnh prompt dựa trên mức độ nghiêm ngặt prompt: `You are a ${isStrict ? "strict" : "balanced"} security reviewer...`, tools: ["Read", "Grep", "Glob"], // Điểm mấu chốt: dùng model mạnh hơn cho review có mức độ quan trọng cao model: isStrict ? "opus" : "sonnet" };}
// Agent được tạo tại thời điểm query, nên mỗi request có thể dùng cấu hình khác nhaufor await (const message of query({ prompt: "Review this PR for security issues", options: { allowedTools: ["Read", "Grep", "Glob", "Agent"], agents: { // Gọi factory với cấu hình mong muốn "security-reviewer": createSecurityAgent("strict") } }})) { if ("result" in message) console.log(message.result);}Phát hiện lệnh gọi subagent
Phần tiêu đề “Phát hiện lệnh gọi subagent”Claude gọi subagent qua Agent tool. Để phát hiện khi một subagent được gọi, kiểm tra block tool_use có name là "Agent". Message bên trong context của một subagent có trường parent_tool_use_id.
Cấu trúc message khác nhau giữa hai SDK. Trong Python, bạn truy cập block nội dung trực tiếp qua message.content. Trong TypeScript, SDKAssistantMessage bọc message API của Claude, nên bạn truy cập nội dung qua message.message.content.
import asynciofrom claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition, ToolUseBlock
async def main(): async for message in query( prompt="Use the code-reviewer agent to review this codebase", options=ClaudeAgentOptions( allowed_tools=["Read", "Glob", "Grep", "Agent"], agents={ "code-reviewer": AgentDefinition( description="Expert code reviewer.", prompt="Analyze code quality and suggest improvements.", tools=["Read", "Glob", "Grep"], ) }, ), ): # Kiểm tra lệnh gọi subagent. Khớp cả hai tên: phiên bản SDK cũ # phát ra "Task", phiên bản hiện tại phát ra "Agent". if hasattr(message, "content") and message.content: for block in message.content: if isinstance(block, ToolUseBlock) and block.name in ( "Task", "Agent", ): print(f"Subagent invoked: {block.input.get('subagent_type')}")
# Kiểm tra xem message này có đến từ context của subagent không if hasattr(message, "parent_tool_use_id") and message.parent_tool_use_id: print(" (running inside subagent)")
if hasattr(message, "result"): print(message.result)
asyncio.run(main())import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({ prompt: "Use the code-reviewer agent to review this codebase", options: { allowedTools: ["Read", "Glob", "Grep", "Agent"], agents: { "code-reviewer": { description: "Expert code reviewer.", prompt: "Analyze code quality and suggest improvements.", tools: ["Read", "Glob", "Grep"] } } }})) { const msg = message as any;
// Kiểm tra lệnh gọi subagent. Khớp cả hai tên: phiên bản SDK cũ // phát ra "Task", phiên bản hiện tại phát ra "Agent". for (const block of msg.message?.content ?? []) { if (block.type === "tool_use" && (block.name === "Task" || block.name === "Agent")) { console.log(`Subagent invoked: ${block.input.subagent_type}`); } }
// Kiểm tra xem message này có đến từ context của subagent không if (msg.parent_tool_use_id) { console.log(" (running inside subagent)"); }
if ("result" in message) { console.log(message.result); }}Tiếp tục (resume) subagent
Phần tiêu đề “Tiếp tục (resume) subagent”Bạn có thể tiếp tục một subagent để chạy tiếp từ chỗ dừng lại thay vì bắt đầu lại từ đầu. Một subagent được resume giữ nguyên toàn bộ lịch sử hội thoại, bao gồm mọi tool call, kết quả, và lý luận trước đó.
Khi một subagent hoàn tất, kết quả Agent tool bao gồm một block văn bản chứa agentId: <id>. Các agent built-in Explore và Plan chỉ chạy một lần và không trả về agentId, nên hãy dùng một agent tùy chỉnh hoặc general-purpose khi bạn cần resume. Để resume một subagent theo cách lập trình:
- Ghi lại session ID: trích xuất
session_idtừ message trong lần query đầu tiên - Trích xuất agent ID: phân tích
agentIdtừ văn bản kết quả Agent tool - Resume phiên: truyền
resume: sessionIdvào tùy chọn của query thứ hai, và bao gồm agent ID trong prompt của bạn
Transcript của subagent tồn tại độc lập với hội thoại chính:
- Nén hội thoại chính: khi hội thoại chính bị nén, transcript của subagent không bị ảnh hưởng. Chúng được lưu trong các file riêng.
- Lưu trữ phiên: transcript của subagent tồn tại trong phạm vi phiên của nó. Bạn có thể resume một subagent sau khi khởi động lại Claude Code bằng cách resume cùng phiên.
- Dọn dẹp tự động: Claude Code xóa transcript subagent sau thời gian lưu giữ
cleanupPeriodDays, mặc định 30 ngày.
Giới hạn tool
Phần tiêu đề “Giới hạn tool”Dùng trường tools để giới hạn những gì một subagent có thể làm:
- Bỏ trống
tools: subagent được cấp mọi tool khả dụng cho subagent - Liệt kê tool: subagent chỉ nhận những tool đó. Ví dụ, một code reviewer không bao giờ nên sửa file sẽ nhận
["Read", "Grep", "Glob"]
Một tool bạn bỏ ra ngoài sẽ không có trong phiên của subagent chút nào: Claude làm việc mà không có nó, không có prompt xin quyền hay lỗi.
Kết hợp tool phổ biến
Phần tiêu đề “Kết hợp tool phổ biến”| Trường hợp dùng | Tool | Mô tả |
|---|---|---|
| Phân tích chỉ đọc | Read, Grep, Glob | Có thể xem code nhưng không sửa hay thực thi |
| Chạy test | Bash, Read, Grep | Có thể chạy lệnh và phân tích output |
| Sửa code | Read, Edit, Write, Grep, Glob | Toàn quyền đọc/ghi mà không thực thi lệnh |
| Toàn quyền | Mọi tool | Kế thừa mọi tool khả dụng cho subagent (bỏ trống trường tools) |
Mở rộng với workflow động
Phần tiêu đề “Mở rộng với workflow động”Subagent phù hợp với vài tác vụ giao việc mỗi lượt. Với các lần chạy điều phối hàng chục đến hàng trăm agent, hãy dùng Workflow tool, chuyển việc điều phối vào một script được runtime thực thi bên ngoài context hội thoại. Xem workflow động để biết workflow khác gì với giao việc subagent theo từng lượt.
Xử lý sự cố
Phần tiêu đề “Xử lý sự cố”Claude không giao việc cho subagent
Phần tiêu đề “Claude không giao việc cho subagent”Nếu Claude tự hoàn thành tác vụ thay vì giao cho subagent của bạn:
- Kiểm tra lệnh gọi Agent đã được duyệt chưa: đưa
AgentvàoallowedToolsđể tự động duyệt lệnh gọi subagent. Nếu không, lệnh gọi Agent sẽ rơi vào callbackcanUseToolcủa bạn hoặc, trong chế độdontAsk, bị từ chối - Dùng prompt tường minh: nhắc tên subagent trong prompt, ví dụ “Use the code-reviewer agent to…”
- Viết mô tả rõ ràng: giải thích chính xác khi nào nên dùng subagent để Claude khớp tác vụ phù hợp
Agent dựa trên filesystem không được nạp
Phần tiêu đề “Agent dựa trên filesystem không được nạp”Claude Code theo dõi ~/.claude/agents/ và .claude/agents/ và nhận diện file agent mới hoặc đã sửa trong vài giây, không cần khởi động lại. Nếu một định nghĩa không bao giờ xuất hiện, hãy kiểm tra các nguyên nhân sau:
- Thư mục
agentsmới: bộ theo dõi chỉ bao phủ các thư mục đã tồn tại khi phiên bắt đầu, nên file đầu tiên trong một thư mục mới cần khởi động lại phiên. Đây là nguyên nhân phổ biến nhất. - Frontmatter không hợp lệ hoặc
nametrùng lặp: kiểm tra YAML của file, và xem đã có agent nào dùngnameđó chưa. --disable-slash-commands: các phiên khởi động với cờ này không theo dõi các thư mục này và luôn cần khởi động lại để nạp file mới.- Một agent lập trình có cùng tên:
agentstruyền vàoquery()sẽ ghi đè agent filesystem có cùng tên.
Lỗi prompt quá dài trên Windows
Phần tiêu đề “Lỗi prompt quá dài trên Windows”Trên Windows, subagent với prompt rất dài có thể thất bại do giới hạn độ dài dòng lệnh 8191 ký tự. Hãy giữ prompt ngắn gọn hoặc dùng agent dựa trên filesystem cho chỉ dẫn phức tạp.
Tài liệu liên quan
Phần tiêu đề “Tài liệu liên quan”- Subagent Claude Code: tài liệu subagent đầy đủ bao gồm định nghĩa dựa trên filesystem
- Workflow động: điều phối nhiều subagent từ một script cho các công việc quá lớn cho một hội thoại
- Tổng quan SDK: bắt đầu với Claude Agent SDK
lượt xem