课程大纲 › 领域 1:Agent 架构与编排

1.3 配置子 Agent 的调用、上下文传递与生成

タスクステートメント1.3:サブエージェントの呼び出し、コンテキストの受け渡し、生成を設定する

官方大纲原文(日文):知识 4 条 · 技能 4 条

需要掌握的知识

  • サブエージェントを生成する仕組みとしてのTaskツール、およびコーディネーターがサブエージェントを呼び出すにはallowedToolsに"Task"を含める必要があるという要件
  • サブエージェントのコンテキストはプロンプトで明示的に提供する必要があること(サブエージェントは親のコンテキストを自動的に継承せず、呼び出し間でメモリを共有しない)
  • 各サブエージェントタイプの説明、システムプロンプト、ツール制限を含むAgentDefinitionの設定
  • 共通の分析ベースラインから異なるアプローチを探るための、フォークベースのセッション管理

需要能做到的事

  • 先行するエージェントの調査結果全体をサブエージェントのプロンプトに直接含める(例:ウェブ検索結果とドキュメント分析の出力を統合サブエージェントに渡す)
  • エージェント間でコンテキストを渡す際に、情報源の帰属を保持するため、構造化データ形式を使用してコンテンツとメタデータ(ソースURL、ドキュメント名、ページ番号)を分離する
  • 別々のターンに分けるのではなく、コーディネーターの単一の応答で複数のTaskツール呼び出しを出力することで、サブエージェントを並列に生成する
  • サブエージェントが適応できるように、段階的な手順の指示ではなく、リサーチの目標と品質基準を指定するコーディネータープロンプトを設計する

课程讲解 · AI 草稿,未经人工审核 以官方文档为准

这一条考什么

考你在 Claude Agent SDK 中具体如何"生成"子 Agent 并把上下文交给它:协调者必须被允许调用 Task 工具(新版 SDK 中更名为 Agent 工具);子 Agent 由 AgentDefinition 描述;上下文只能通过委派提示显式传递;多个独立子 Agent 要在同一条响应里并行发出;委派提示应写目标与质量标准而非逐步流程。还会涉及用 fork 会话从共同的分析基线出发探索不同方案。

核心概念

Task 工具与 allowedTools

在 Agent SDK 里,子 Agent 不是"自动出现"的,而是协调者通过调用一个专门的工具来生成:考试大纲称之为 Task 工具,当前 SDK 文档称之为 Agent 工具(Task 是旧名)。要点:

  • 你在 agents 里定义了子 Agent,只是让协调者"知道"它们存在(描述会出现在工具说明中)。
  • 协调者真正能委派的前提是 allowedTools 中包含 "Task"(或新版的 "Agent")。
  • 常见故障现象:协调者在文本里说"我会请搜索 Agent 去查……",但实际上从未生成子 Agent——根因就是 allowedTools 漏了这个工具,而不是系统提示没列出子 Agent 名单。

AgentDefinition 的配置

每种子 Agent 用一个 AgentDefinition 描述,核心字段:

  • description:一句话说明它做什么、什么时候该用。协调者靠它来选择子 Agent,写得含糊会导致误派。
  • prompt:子 Agent 自己的系统提示,定义角色、输出格式、质量要求。
  • tools:该子 Agent 可用工具的白名单,用来限制职责范围(例如综合 Agent 不给 WebSearch)。省略时通常继承全部可用工具,所以专职 Agent 最好显式限定。
  • model:可选,为该子 Agent 指定模型档位。
from claude_agent_sdk import AgentDefinition

synthesizer = AgentDefinition(
    description="把多份研究结果整合成带引用的结论。不做新的检索。",
    prompt="你是综合分析员。只依据提供的材料下结论,每个论断标注来源 id。",
    tools=["Read"],
)

上下文必须显式传递

子 Agent 拥有全新的上下文窗口:不继承父 Agent 的对话历史,不共享之前工具调用的结果,两次调用之间也没有共享记忆。子 Agent 能看到的只有:它的系统提示、它的工具,以及协调者在 Task 调用里写的那段任务提示。

所以当综合子 Agent 需要基于网页搜索结果与文档分析结果写结论时,正确做法是把两份完整的发现直接写进它的任务提示。"只传一句任务描述,指望自动继承上下文"不成立;"只传一个引用 id,让它自己去别的 Agent 那里取"增加了失败点;"给它工具回调其他子 Agent"破坏了中心辐射结构。

用结构化格式保留出处

在 Agent 之间传递内容时,应把内容与元数据分开存放,避免多次转述后丢失引用:

{
  "findings": [
    {
      "id": "F1",
      "claim": "2024 年全球固态电池中试线产能同比增长约 3 倍",
      "source": {"url": "https://example.com/report", "title": "行业年度报告", "page": 12},
      "retrieved_by": "web-search"
    },
    {
      "id": "F2",
      "claim": "硫化物电解质界面稳定性仍是主要瓶颈",
      "source": {"doc_name": "review_2025.pdf", "page": 7},
      "retrieved_by": "doc-analysis"
    }
  ]
}

综合 Agent 在结论中引用 F1、F2,报告 Agent 再把 id 映射回 URL、文档名、页码,出处就能完整保留到最终报告。

并行生成子 Agent

当两个子任务相互独立(例如网页搜索与内部文档分析),协调者应在同一条助手响应中发出多个 Task 工具调用。运行时会并发执行它们,并把结果一起返回。若协调者在一轮里调用一个、等结果、下一轮再调用另一个,就是串行,延迟叠加。仅在提示里写"请并行执行"并不能保证并行,关键在于是否在单个响应中输出多个工具调用;换更小的模型只是降低单个耗时,不能解决串行问题。

委派提示:目标与标准,而非步骤

给研究型子 Agent 的提示应说明:

  • 研究目标(要回答的问题、范围边界)。
  • 质量标准(覆盖广度、来源多样性、时效性、需要的证据类型)。
  • 输出格式(如上面的结构化 findings)。

而不是"先搜 A,再搜 B,再打开前三个结果"。写死步骤会让子 Agent 在第一个搜索无果时无所适从;另一方面,"彻底研究一下 X"这种只有目标没有标准的提示又过于空泛。

基于 fork 的会话管理

当你已经完成一份代码库或资料的共同分析,想比较两种后续方案时,可以从该会话 fork 出两个分支:每个分支都继承这份分析基线,但之后的探索互不影响(会话管理的细节见 1.7)。这比让一个会话轮流尝试两种方案更干净,也比各自从零开始节省重新分析的成本。

正确做法与反模式

  • 正确:协调者的 allowedTools 包含 "Task"/"Agent"。反模式:只定义 agents,却奇怪协调者为何只"说"不"做"。
  • 正确:把前序 Agent 的完整发现写进综合子 Agent 的任务提示。反模式:依赖"自动继承上下文"或只传引用 id。
  • 正确:用结构化格式把 claim 与 URL、文档名、页码分开传递。反模式:把所有内容揉成一段散文,出处在转述中丢失。
  • 正确:独立子任务在同一条响应中发出多个 Task 调用。反模式:分多轮逐个调用,或靠提示语"请同时执行"。
  • 正确:委派提示描述目标与质量标准。反模式:写死逐步搜索流程,或只写一句"彻底研究"。

常见陷阱

  • "协调者的系统提示没有列出子 Agent 类型,所以它不知道可以调用"——AgentDefinition 已让其可见,真正缺的是 allowedTools 里的 Task/Agent。
  • "需要在 ClaudeAgentOptions 中配置显式的上下文转发"——不存在这种自动转发机制,上下文靠任务提示传递。
  • "给子 Agent 一个回调工具去向其他子 Agent 请求输出"——违背中心辐射,增加耦合。
  • "换成 Haiku 档模型以缩短耗时"——掩盖了串行调用这一真正原因。
  • "在详细步骤指令中再追加备用步骤"——仍然是流程式提示,正确方向是改为目标与质量标准。

实操练习

目标:验证"漏掉 Task 工具"与"并行委派"两种行为。

  1. 安装 claude-agent-sdk,准备下面的 spawn_lab.py。
  2. 先把 allowed_tools 中的 "Task" 删掉运行一次,观察协调者是否只是用文字描述委派。
  3. 加回 "Task"(若你的 SDK 版本使用新名称则为 "Agent")再运行,观察是否在同一条消息中出现两个子 Agent 调用。
import asyncio
from claude_agent_sdk import (
    query, ClaudeAgentOptions, AgentDefinition, AssistantMessage, ToolUseBlock,
)

agents = {
    "web-search": AgentDefinition(
        description="检索公开网页资料。",
        prompt="返回 JSON:findings 数组,每项含 claim 与 source.url。",
        tools=["WebSearch", "WebFetch"],
    ),
    "doc-analysis": AgentDefinition(
        description="分析当前目录下的 docs/ 文档。",
        prompt="返回 JSON:findings 数组,每项含 claim、source.doc_name、source.page。",
        tools=["Read", "Glob", "Grep"],
    ),
}

async def main():
    opts = ClaudeAgentOptions(
        agents=agents,
        allowed_tools=["Task", "Read", "Glob", "Grep", "WebSearch", "WebFetch"],
        system_prompt="两个子任务相互独立时,必须在同一条响应中同时委派。",
    )
    async for msg in query(prompt="调研 Rust 异步运行时的选型,网页与 docs/ 都要查。", options=opts):
        if isinstance(msg, AssistantMessage):
            calls = [b for b in msg.content if isinstance(b, ToolUseBlock)]
            if calls:
                print("本条消息中的工具调用:", [c.name for c in calls])

asyncio.run(main())

检查结果:步骤 2 中应看不到子 Agent 调用;步骤 3 中应出现一条消息内含两个子 Agent 调用,并且两个子 Agent 的返回都带有可追溯的来源字段。

自测清单

  • 为什么在 agents 中定义了子 Agent 后,协调者仍可能无法委派?
  • AgentDefinition 的 description、prompt、tools 各自影响什么?
  • 综合子 Agent 需要前序结果时,应如何把它们交给它?为什么不能依赖继承?
  • 如何组织跨 Agent 传递的数据,才能把 URL、文档名、页码保留到最终报告?
  • 怎样才能真正让两个子 Agent 并行运行?
  • 委派提示中"目标与质量标准"和"逐步流程"各有什么优缺点?

对应题目(6)

题目归类由 AI 判断,仅供参考。

练习这 6 道题