第6课:多个AI一起干活 —— 子Agent架构
本课目标
一个 Claude 能搜索能写文件,已经很厉害了。但研究平台的精髓是多个 Claude 同时干活,各司其职。这节课讲怎么定义和调度子 Agent。
什么是子Agent?
回忆一下第1课的比方:
- 组长(Lead Agent) = 你的主 Claude,负责拆任务和调度
- 子Agent = 被组长派出去的"员工",每个有自己的角色和工具
子 Agent 不是另一种技术,它就是另一个 Claude 实例,只不过有不同的 prompt 和工具配置。
组长通过 Task 工具 来派活:
组长: "我要用 Task 工具,派一个 researcher 去搜索电池技术"
↓
系统自动创建一个新的 Claude 实例,加载 researcher 的 prompt 和工具
↓
researcher 开始干活(搜索、写笔记)
↓
干完了,结果返回给组长
定义子Agent
"""
06_subagents.py
定义和使用子 Agent
"""
import anyio
from claude_agent_sdk import (
ClaudeSDKClient, ClaudeAgentOptions, AgentDefinition,
AssistantMessage, TextBlock, ToolUseBlock
)
async def main():
# 定义子 Agent(就像写职位描述)
agents = {
# 研究员:负责搜索信息
"researcher": AgentDefinition(
description="搜索互联网收集资料的研究员",
prompt="""你是一个数据驱动的研究员。
收到研究任务后:
1. 用 WebSearch 搜索 3-5 次,重点找数字和数据
2. 把找到的信息整理成笔记
3. 用 Write 工具保存到 notes/ 目录下
注意:只搜索,不分析,不下结论。""",
tools=["WebSearch", "Write"],
model="haiku", # 用便宜的模型,省钱
),
# 总结员:负责汇总信息
"summarizer": AgentDefinition(
description="阅读资料并生成摘要的总结员",
prompt="""你是一个擅长总结的分析师。
收到任务后:
1. 用 Glob 找到 notes/ 目录下的所有文件
2. 用 Read 读取每个文件
3. 提炼关键信息,写一份 500 字以内的摘要
4. 用 Write 保存到 summary.md""",
tools=["Glob", "Read", "Write"],
model="haiku",
),
}
options = ClaudeAgentOptions(
system_prompt="""你是一个研究组长。
收到用户的研究请求后:
1. 把请求拆成 2-3 个子课题
2. 用 Task 工具派 researcher 去搜索每个子课题
3. 等所有 researcher 完成后,派 summarizer 做总结
4. 告诉用户结果已保存
你自己不搜索、不写文件,只负责调度。""",
allowed_tools=["Task"], # 组长只有"派活"这一个工具
agents=agents, # 注册子 Agent
permission_mode="bypassPermissions",
max_turns=10, # 需要足够多的轮次
)
async with ClaudeSDKClient(options=options) as client:
await client.query("帮我研究一下远程办公对企业的影响")
async for msg in client.receive_response():
if isinstance(msg, AssistantMessage):
for block in msg.content:
if isinstance(block, TextBlock):
print(block.text)
elif isinstance(block, ToolUseBlock):
if block.name == "Task":
agent_type = block.input.get("subagent_type", "未知")
desc = block.input.get("description", "")
print(f"\n🚀 派出 [{agent_type}]: {desc}")
anyio.run(main)
AgentDefinition 详解
AgentDefinition(
description="一句话描述这个Agent的作用", # 给组长看的,帮它决定啥时候派谁
prompt="详细的系统提示词...", # Agent 的"工作手册"
tools=["WebSearch", "Write"], # 能用哪些工具
model="haiku", # 用哪个模型
)
每个字段的作用:
| 字段 | 干嘛的 | 类比 |
|---|---|---|
| description | 告诉组长这个人能干啥 | 岗位简介 |
| prompt | 详细的工作要求和流程 | 员工手册 |
| tools | 能使用的工具列表 | 工作权限 |
| model | 用哪个 Claude 模型 | 能力等级 |
Prompt 的设计技巧
子 Agent 的 prompt 是整个系统的灵魂。写得好不好,直接决定输出质量。
研究员 prompt 的关键要素
研究平台的 researcher prompt 有 180 行,核心要求:
1. 强制搜索次数:MUST use WebSearch 5-10 times(不搜够不行)
2. 数据优先:找数字!市场规模、增长率、占比、排名
3. 不许偷懒:不能用自己的知识,必须搜出来的
4. 规定输出格式:markdown 笔记,带统计数据和来源
5. 指定保存位置:files/research_notes/ 目录
好 prompt 的共同特点
✅ 明确角色:"你是一个数据驱动的研究员"
✅ 明确流程:第1步、第2步、第3步
✅ 明确标准:至少搜索5次,至少10个数据点
✅ 明确禁止:不许用自己的知识,不许分析
✅ 明确输出:保存到哪,什么格式
❌ 模糊指令:"帮我搜索一些信息"
❌ 没有标准:"搜索相关内容"
❌ 没有流程:"做一个研究"
并行 vs 顺序
研究平台的关键设计:研究员并行,后续顺序。
graph LR
A["用户请求"] --> B["组长"]
B --> R1["researcher 1"]
B --> R2["researcher 2"]
B --> R3["researcher 3"]
B --> R4["researcher 4"]
R1 --> DA["数据分析师"]
R2 --> DA
R3 --> DA
R4 --> DA
DA --> RW["报告员"]
RW --> Done["完成"]
subgraph "并行阶段"
R1
R2
R3
R4
end
subgraph "顺序阶段"
DA
RW
end
为什么这样设计? - 研究员互不依赖,各搜各的,并行最快 - 分析师依赖研究员的笔记,必须等研究员都完成 - 报告员依赖分析师的图表,必须等分析师完成
组长的 prompt 里要写清楚这个顺序:
1. 同时派出多个 researcher(并行)
2. 等待所有 researcher 完成
3. 然后派出 data-analyst(依赖研究笔记)
4. 等待 data-analyst 完成
5. 最后派出 report-writer(依赖分析结果和图表)
子Agent之间怎么"沟通"?
子 Agent 之间不能直接对话!它们通过文件系统间接沟通:
researcher 1 ──写入──→ files/research_notes/topic1.md ──读取──→ data-analyst
researcher 2 ──写入──→ files/research_notes/topic2.md ──读取──→ data-analyst
data-analyst ──写入──→ files/charts/chart1.png ──读取──→ report-writer
data-analyst ──写入──→ files/data/data_summary.md ──读取──→ report-writer
就像流水线:前一个工位把半成品放到传送带上,后一个工位捡起来继续加工。
本课小结
- 子Agent = 有特定角色和工具的独立 Claude 实例
AgentDefinition定义角色描述、prompt、工具、模型- 组长通过 Task 工具派活,自己不干活
- 并行+顺序的混合调度:不互相依赖的任务并行,有依赖的顺序执行
- 子Agent通过文件沟通,不能直接对话
- Prompt 质量决定一切:要写明角色、流程、标准、输出格式
课后练习
- 在上面的示例基础上,加一个
fact-checker子 Agent,负责核实 summarizer 的内容 - 试试让组长同时派出 3 个 researcher 研究不同方向,观察是否真的并行执行
- 改一改 researcher 的 prompt,要求它必须用表格整理数据,观察输出变化