Loading...
    • 开发者指南
    • API 参考
    • MCP
    • 资源
    • 更新日志
    Search...
    ⌘K
    入门
    Claude 简介快速开始
    模型与定价
    模型概览选择模型Claude 4.6 新特性迁移指南模型弃用定价
    使用 Claude 构建
    功能概览使用 Messages API处理停止原因提示词最佳实践
    上下文管理
    上下文窗口压缩上下文编辑
    能力
    提示缓存扩展思考自适应思考推理力度流式消息批量处理引用多语言支持Token 计数嵌入视觉PDF 支持Files API搜索结果结构化输出
    工具
    概览如何实现工具使用细粒度工具流式传输Bash 工具代码执行工具程序化工具调用计算机使用工具文本编辑器工具网页抓取工具网页搜索工具记忆工具工具搜索工具
    Agent Skills
    概览快速开始最佳实践企业级 Skills通过 API 使用 Skills
    Agent SDK
    概览快速开始TypeScript SDKTypeScript V2(预览版)Python SDK迁移指南
    流式输入实时流式响应处理停止原因处理权限用户审批与输入使用钩子控制执行会话管理文件检查点SDK 中的结构化输出托管 Agent SDK安全部署 AI 智能体修改系统提示词SDK 中的 MCP自定义工具SDK 中的子智能体SDK 中的斜杠命令SDK 中的 Agent Skills跟踪成本与用量待办事项列表SDK 中的插件
    API 中的 MCP
    MCP 连接器远程 MCP 服务器
    第三方平台上的 Claude
    Amazon BedrockMicrosoft FoundryVertex AI
    提示工程
    概览提示词生成器使用提示词模板提示词优化器清晰直接使用示例(多样本提示)让 Claude 思考(思维链)使用 XML 标签赋予 Claude 角色(系统提示词)链式复杂提示长上下文技巧扩展思考技巧
    测试与评估
    定义成功标准开发测试用例使用评估工具降低延迟
    加强安全护栏
    减少幻觉提高输出一致性防范越狱攻击流式拒绝减少提示词泄露保持 Claude 角色设定
    管理与监控
    Admin API 概览数据驻留工作空间用量与成本 APIClaude Code Analytics API零数据留存
    Console
    Log in
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...

    Solutions

    • AI agents
    • Code modernization
    • Coding
    • Customer support
    • Education
    • Financial services
    • Government
    • Life sciences

    Partners

    • Amazon Bedrock
    • Google Cloud's Vertex AI

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Company

    • Anthropic
    • Careers
    • Economic Futures
    • Research
    • News
    • Responsible Scaling Policy
    • Security and compliance
    • Transparency

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Help and security

    • Availability
    • Status
    • Support
    • Discord

    Terms and policies

    • Privacy policy
    • Responsible disclosure policy
    • Terms of service: Commercial
    • Terms of service: Consumer
    • Usage policy
    指南

    SDK 中的子代理

    在 Claude Agent SDK 应用程序中定义和调用子代理,以隔离上下文、并行运行任务并应用专门的指令。

    子代理是主代理可以生成的独立代理实例,用于处理专注的子任务。 使用子代理可以为专注的子任务隔离上下文、并行运行多个分析,以及应用专门的指令而不会使主代理的提示词膨胀。

    本指南介绍如何使用 agents 参数在 SDK 中定义和使用子代理。

    概述

    您可以通过三种方式创建子代理:

    • 编程方式:在 query() 选项中使用 agents 参数(TypeScript、Python)
    • 基于文件系统:在 .claude/agents/ 目录中将代理定义为 markdown 文件(参见将子代理定义为文件)
    • 内置通用型:Claude 可以随时通过 Task 工具调用内置的 general-purpose 子代理,无需您进行任何定义

    本指南重点介绍编程方式,这是 SDK 应用程序的推荐方法。

    当您定义子代理时,Claude 会根据每个子代理的 description 字段决定是否调用它们。编写清晰的描述来说明何时应该使用该子代理,Claude 将自动委派适当的任务。您也可以在提示词中按名称显式请求子代理(例如,"使用 code-reviewer 代理来...")。

    使用子代理的好处

    上下文管理

    子代理与主代理保持独立的上下文,防止信息过载并保持交互的专注性。这种隔离确保专门的任务不会用无关的细节污染主对话上下文。

    示例:research-assistant 子代理可以探索数十个文件和文档页面,而不会用所有中间搜索结果来干扰主对话,只返回相关的发现。

    并行化

    多个子代理可以并发运行,显著加速复杂的工作流程。

    示例:在代码审查期间,您可以同时运行 style-checker、security-scanner 和 test-coverage 子代理,将审查时间从几分钟缩短到几秒钟。

    专门的指令和知识

    每个子代理都可以拥有定制的系统提示词,包含特定的专业知识、最佳实践和约束条件。

    示例:database-migration 子代理可以拥有关于 SQL 最佳实践、回滚策略和数据完整性检查的详细知识,这些在主代理的指令中会是不必要的噪音。

    工具限制

    子代理可以被限制使用特定的工具,降低意外操作的风险。

    示例:doc-reviewer 子代理可能只能访问 Read 和 Grep 工具,确保它可以分析但永远不会意外修改您的文档文件。

    创建子代理

    编程定义(推荐)

    直接在代码中使用 agents 参数定义子代理。此示例创建了两个子代理:一个具有只读访问权限的代码审查器和一个可以执行命令的测试运行器。Task 工具必须包含在 allowedTools 中,因为 Claude 通过 Task 工具调用子代理。

    import asyncio
    from 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(
                # Task tool is required for subagent invocation
                allowed_tools=["Read", "Grep", "Glob", "Task"],
                agents={
                    "code-reviewer": AgentDefinition(
                        # description tells Claude when to use this subagent
                        description="Expert code review specialist. Use for quality, security, and maintainability reviews.",
                        # prompt defines the subagent's behavior and expertise
                        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 restricts what the subagent can do (read-only here)
                        tools=["Read", "Grep", "Glob"],
                        # model overrides the default model for this subagent
                        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""",
                        # Bash access lets this subagent run test commands
                        tools=["Bash", "Read", "Grep"]
                    )
                }
            )
        ):
            if hasattr(message, "result"):
                print(message.result)
    
    asyncio.run(main())

    AgentDefinition 配置

    字段类型必需描述
    descriptionstring是描述何时使用此代理的自然语言描述
    promptstring是代理的系统提示词,定义其角色和行为
    toolsstring[]否允许的工具名称数组。如果省略,则继承所有工具
    model'sonnet' | 'opus' | 'haiku' | 'inherit'否此代理的模型覆盖。如果省略,默认使用主模型

    子代理不能生成自己的子代理。不要在子代理的 tools 数组中包含 Task。

    基于文件系统的定义(替代方案)

    您也可以在 .claude/agents/ 目录中将子代理定义为 markdown 文件。有关此方法的详细信息,请参阅 Claude Code 子代理文档。以编程方式定义的代理优先于同名的基于文件系统的代理。

    即使不定义自定义子代理,当 Task 在您的 allowedTools 中时,Claude 也可以生成内置的 general-purpose 子代理。这对于在不创建专门代理的情况下委派研究或探索任务非常有用。

    调用子代理

    自动调用

    Claude 会根据任务和每个子代理的 description 自动决定何时调用子代理。例如,如果您定义了一个 performance-optimizer 子代理,其描述为"用于查询调优的性能优化专家",当您的提示词提到优化查询时,Claude 将调用它。

    编写清晰、具体的描述,以便 Claude 能够将任务匹配到正确的子代理。

    显式调用

    要确保 Claude 使用特定的子代理,请在提示词中按名称提及它:

    "Use the code-reviewer agent to check the authentication module"

    这将绕过自动匹配并直接调用指定的子代理。

    动态代理配置

    您可以根据运行时条件动态创建代理定义。此示例创建了一个具有不同严格级别的安全审查器,对严格审查使用更强大的模型。

    import asyncio
    from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition
    
    # Factory function that returns an AgentDefinition
    # This pattern lets you customize agents based on runtime conditions
    def create_security_agent(security_level: str) -> AgentDefinition:
        is_strict = security_level == "strict"
        return AgentDefinition(
            description="Security code reviewer",
            # Customize the prompt based on strictness level
            prompt=f"You are a {'strict' if is_strict else 'balanced'} security reviewer...",
            tools=["Read", "Grep", "Glob"],
            # Key insight: use a more capable model for high-stakes reviews
            model="opus" if is_strict else "sonnet"
        )
    
    async def main():
        # The agent is created at query time, so each request can use different settings
        async for message in query(
            prompt="Review this PR for security issues",
            options=ClaudeAgentOptions(
                allowed_tools=["Read", "Grep", "Glob", "Task"],
                agents={
                    # Call the factory with your desired configuration
                    "security-reviewer": create_security_agent("strict")
                }
            )
        ):
            if hasattr(message, "result"):
                print(message.result)
    
    asyncio.run(main())

    检测子代理调用

    子代理通过 Task 工具调用。要检测子代理何时被调用,请检查 name: "Task" 的 tool_use 块。来自子代理上下文内的消息包含 parent_tool_use_id 字段。

    此示例遍历流式消息,记录子代理何时被调用以及后续消息何时来自该子代理的执行上下文。

    SDK 之间的消息结构有所不同。在 Python 中,内容块通过 message.content 直接访问。在 TypeScript 中,SDKAssistantMessage 包装了 Claude API 消息,因此内容通过 message.message.content 访问。

    import asyncio
    from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition
    
    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", "Task"],
                agents={
                    "code-reviewer": AgentDefinition(
                        description="Expert code reviewer.",
                        prompt="Analyze code quality and suggest improvements.",
                        tools=["Read", "Glob", "Grep"]
                    )
                }
            )
        ):
            # Check for subagent invocation in message content
            if hasattr(message, 'content') and message.content:
                for block in message.content:
                    if getattr(block, 'type', None) == 'tool_use' and block.name == 'Task':
                        print(f"Subagent invoked: {block.input.get('subagent_type')}")
    
            # Check if this message is from within a subagent's context
            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())

    恢复子代理

    子代理可以被恢复以从中断处继续。恢复的子代理保留其完整的对话历史,包括所有先前的工具调用、结果和推理。子代理会从停止的地方精确恢复,而不是重新开始。

    当子代理完成时,Claude 会在 Task 工具结果中接收其代理 ID。要以编程方式恢复子代理:

    1. 捕获会话 ID:在第一次查询期间从消息中提取 session_id
    2. 提取代理 ID:从消息内容中解析 agentId
    3. 恢复会话:在第二次查询的选项中传递 resume: sessionId,并在提示词中包含代理 ID

    您必须恢复同一会话才能访问子代理的记录。每次 query() 调用默认启动一个新会话,因此传递 resume: sessionId 以在同一会话中继续。

    如果您使用的是自定义代理(而非内置代理),您还需要在两次查询的 agents 参数中传递相同的代理定义。

    下面的示例演示了此流程:第一次查询运行子代理并捕获会话 ID 和代理 ID,然后第二次查询恢复会话以提出需要第一次分析上下文的后续问题。

    import { query, type SDKMessage } from '@anthropic-ai/claude-agent-sdk';
    
    // Helper to extract agentId from message content
    // Stringify to avoid traversing different block types (TextBlock, ToolResultBlock, etc.)
    function extractAgentId(message: SDKMessage): string | undefined {
      if (!('message' in message)) return undefined;
      // Stringify the content so we can search it without traversing nested blocks
      const content = JSON.stringify(message.message.content);
      const match = content.match(/agentId:\s*([a-f0-9-]+)/);
      return match?.[1];
    }
    
    let agentId: string | undefined;
    let sessionId: string | undefined;
    
    // First invocation - use the Explore agent to find API endpoints
    for await (const message of query({
      prompt: "Use the Explore agent to find all API endpoints in this codebase",
      options: { allowedTools: ['Read', 'Grep', 'Glob', 'Task'] }
    })) {
      // Capture session_id from ResultMessage (needed to resume this session)
      if ('session_id' in message) sessionId = message.session_id;
      // Search message content for the agentId (appears in Task tool results)
      const extractedId = extractAgentId(message);
      if (extractedId) agentId = extractedId;
      // Print the final result
      if ('result' in message) console.log(message.result);
    }
    
    // Second invocation - resume and ask follow-up
    if (agentId && sessionId) {
      for await (const message of query({
        prompt: `Resume agent ${agentId} and list the top 3 most complex endpoints`,
        options: { allowedTools: ['Read', 'Grep', 'Glob', 'Task'], resume: sessionId }
      })) {
        if ('result' in message) console.log(message.result);
      }
    }

    子代理记录独立于主对话持久存在:

    • 主对话压缩:当主对话压缩时,子代理记录不受影响。它们存储在单独的文件中。
    • 会话持久性:子代理记录在其会话内持久存在。您可以通过恢复同一会话在重启 Claude Code 后恢复子代理。
    • 自动清理:记录根据 cleanupPeriodDays 设置进行清理(默认:30 天)。

    工具限制

    子代理可以通过 tools 字段限制工具访问:

    • 省略该字段:代理继承所有可用工具(默认)
    • 指定工具:代理只能使用列出的工具

    此示例创建了一个只读分析代理,可以检查代码但不能修改文件或运行命令。

    import asyncio
    from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition
    
    async def main():
        async for message in query(
            prompt="Analyze the architecture of this codebase",
            options=ClaudeAgentOptions(
                allowed_tools=["Read", "Grep", "Glob", "Task"],
                agents={
                    "code-analyzer": AgentDefinition(
                        description="Static code analysis and architecture review",
                        prompt="""You are a code architecture analyst. Analyze code structure,
    identify patterns, and suggest improvements without making changes.""",
                        # Read-only tools: no Edit, Write, or Bash access
                        tools=["Read", "Grep", "Glob"]
                    )
                }
            )
        ):
            if hasattr(message, "result"):
                print(message.result)
    
    asyncio.run(main())

    常见工具组合

    用例工具描述
    只读分析Read、Grep、Glob可以检查代码但不能修改或执行
    测试执行Bash、Read、Grep可以运行命令和分析输出
    代码修改Read、Edit、Write、Grep、Glob完全读写访问,无命令执行
    完全访问所有工具从父代理继承所有工具(省略 tools 字段)

    故障排除

    Claude 未委派给子代理

    如果 Claude 直接完成任务而不是委派给您的子代理:

    1. 包含 Task 工具:子代理通过 Task 工具调用,因此它必须在 allowedTools 中
    2. 使用显式提示:在提示词中按名称提及子代理(例如,"使用 code-reviewer 代理来...")
    3. 编写清晰的描述:准确说明何时应该使用该子代理,以便 Claude 能够适当地匹配任务

    基于文件系统的代理未加载

    在 .claude/agents/ 中定义的代理仅在启动时加载。如果您在 Claude Code 运行时创建了新的代理文件,请重启会话以加载它。

    Windows:长提示词失败

    在 Windows 上,具有非常长提示词的子代理可能由于命令行长度限制(8191 个字符)而失败。保持提示词简洁或对复杂指令使用基于文件系统的代理。

    相关文档

    • Claude Code 子代理:全面的子代理文档,包括基于文件系统的定义
    • SDK 概述:Claude Agent SDK 入门

    Was this page helpful?

    • AgentDefinition 配置
    • Claude 未委派给子代理
    • Windows:长提示词失败