← 返回教程库

裸 SDK 手搓编排:用子代理拆活、并行、隔离上下文

最后更新 2026-06-22
你将学到
  • 想清楚什么时候该派子代理——上下文隔离、并行、专门指令、工具限制四个用武之地
  • 看懂子代理「独立会话、只回结论」这条铁律为什么省上下文
  • 照着一段完整的代码骨架,把主 Agent 派两个子 Agent 并行干活再汇总搭出来
  • 拿到一张「子代理委派失败」的排查清单,知道不触发/委派失败八成栽在哪

很多人一听「多 Agent 编排」,第一反应是去搜该上哪个框架——LangGraph、CrewAI、AutoGen,挑花了眼。但真相是:Claude Agent SDK 本身就带子代理原语,编排不一定要套框架。 你只要会建一个协调者 Agent、给它配一份「手下能派谁」的角色清单,剩下的拆活、并行、汇总,SDK 自己就管了。这一节我们不绕框架,直接用裸 SDK 把一个「主 Agent 派两个子 Agent 并行干活再汇总」的骨架搭出来,让你看清子代理到底省在哪、怎么写。

这篇适合谁:已经算清了编排成本、决定走「子代理委派」这条最省的路,现在要落到代码上的人。读完你会有一段能照着改的骨架,和一份委派不生效时的排查清单。


先想清楚:子代理的四个用武之地

别一上来就拆。拆之前先问自己——这活到底是不是子代理该干的?子代理真正的价值就四条,对上一条再派:

  1. 上下文隔离:某块任务会产生一大堆中间料(网页原文、长文档、检索结果),但下游只需要它的结论。让子代理在自己的会话里烧这些料,干完只回一段结论——中间料从不进主 Agent 的上下文。这是子代理最核心、最省钱的用法。
  2. 并行:几块任务互不依赖(查竞品 A、查竞品 B、查竞品 C),就同时派出去一起跑,而不是排队一个一个来。墙上时间直接除以并发数。
  3. 专门指令:每个子代理有自己的系统提示词。「研究员」只管调研、「审稿人」只管挑刺,各自的人设和规矩互不干扰,比把所有职责塞进一个超长系统提示词清爽得多。
  4. 工具限制:每个子代理只给它该用的工具。研究员只给联网搜索,写手一个工具都不给——既是安全边界,也减少模型"乱按按钮"的概率。

记住这条铁律,下面所有设计都从它来:每个子代理跑在自己独立的会话里,只把最终结果回给主 Agent,中间过程不占主 Agent 的上下文。


最小可用:主 Agent 派两个子 Agent 并行干活

任务定死:同时调研两个竞品,各自出一段结论,主 Agent 汇总成一句话对比。 这是「上下文隔离 + 并行」最典型的场景。

在 Claude Agent SDK 的托管 Agent 里,多 Agent 是这么搭的:先把每个子代理当成独立的 Agent 建出来,再建一个协调者(coordinator) Agent,在它的 multiagent 配置里列出「我手下能派谁」的角色清单。协调者跑起来后,会自己决定派谁、并行还是串行,每个子代理在自己的 thread(独立事件流、独立上下文) 里干活。

下面是一段结构完整、思路可跑的骨架。具体的类名、方法名、字段名以官方文档为准——不同 SDK 版本写法有差异,这里给的是「该有哪几步、每步在干嘛」,不是逐字复制就能跑的真实签名。

import anthropic

client = anthropic.Anthropic()  # 读环境变量里的 ANTHROPIC_API_KEY

# ── 第 1 步:建一个「研究员」子代理 ────────────────────────────
# 关键点全在这:专门指令(只调研) + 工具限制(只给联网) + 只回结论
researcher = client.beta.agents.create(
    name="研究员",
    model="claude-opus-4-8",
    system=(
        "你只做一件事:调研。联网搜资料、读、提炼,"
        "最后只回 300 字以内的结论要点,绝不贴原文、不解释过程。"
    ),
    tools=[
        # 只给它联网这一个工具——其它一概不给(工具限制 = 安全边界)
        {"type": "agent_toolset_20260401",
         "default_config": {"enabled": False},
         "configs": [{"name": "web_search", "enabled": True}]},
    ],
)

# ── 第 2 步:建协调者,把研究员列进它的「手下角色清单」 ──────────
# multiagent 是协调者 Agent 上的「我能派谁」名册,不是 session 上的字段
coordinator = client.beta.agents.create(
    name="主控",
    model="claude-opus-4-8",
    system=(
        "你负责调研多个竞品并写对比。把每个竞品的调研分别委派给「研究员」,"
        "几个竞品互不依赖时就同时派出去(并行)。拿回结论后自己汇总成一句话对比。"
    ),
    tools=[{"type": "agent_toolset_20260401"}],
    multiagent={
        "type": "coordinator",
        "agents": [researcher.id],   # ← 名册:协调者可委派的子代理
    },
)

# ── 第 3 步:开个环境 + 会话,把活丢给协调者 ──────────────────
env = client.beta.environments.create(
    name="biaopai-env",
    config={"type": "cloud", "networking": {"type": "unrestricted"}},
)
session = client.beta.sessions.create(
    agent=coordinator.id,            # 会话只引用协调者,子代理由名册解析
    environment_id=env.id,
)

# ── 第 4 步:跑起来——先开流,再发任务(顺序很重要,见下文坑) ──
stream = client.beta.sessions.events.stream(session.id)
client.beta.sessions.events.send(
    session.id,
    events=[{"type": "user.message",
             "content": [{"type": "text",
                          "text": "同时调研竞品 Cursor 和 Windsurf,写一句话对比"}]}],
)

for event in stream:
    if event.type == "session.thread_created":
        print(f"[派出子代理] {event.agent_name}")     # 看到两个 → 并行生效
    elif event.type == "agent.message":
        for block in event.content:
            if block.type == "text":
                print(block.text, end="")
    elif event.type == "session.status_idle":
        if event.stop_reason.type != "requires_action":
            break                                     # 干完了

骨架的精神,不是这几个方法名,而是这三件事:子代理有自己的指令、自己的工具、自己的会话;它只回结论;主 Agent 因此不被中间料撑爆。 这就是子代理省钱的全部秘密——和上一节成本心智里"子代理便宜"对应的代码长相。

你应该看到什么

跑通之后,盯着输出里这几个信号,它们证明编排真的按你想的在走:

  • 两条 session.thread_created:分别是派去查 Cursor 和查 Windsurf 的子代理。看到两条几乎同时出现,说明并行生效了——主 Agent 没排队,一次把两个都派了出去。如果只看到一条接一条慢慢冒,那是串行(不一定是错,但没吃到并行的红利,往下看变体)。
  • 主 Agent 的最终 agent.message 很短:就一句话对比 + 收尾。它上下文里没有两个竞品的网页原文——那些料烧在子代理的 thread 里,从不回流。
  • 结束在 session.status_idlestop_reason 不是 requires_action:表示协调者真的干完了、在等你下一句,而不是卡在「等子代理结果」的中间态。

如果你想看每个子代理内部到底搜了什么,那是它各自 thread 里的事件——主流程的事件流默认只给你「派出了/收回了」这种概览,不会把子代理的每次工具调用都灌进来。这正是上下文隔离在事件层面的体现。


原理:为什么「独立会话 + 只回结论」就省了

把上面发生的事拆开看,省钱的机制就一句话:子代理的中间上下文,永远不进主 Agent 的账。

主 Agent 调研竞品如果不拆,它得自己联网、自己把两个竞品的网页原文读进自己的上下文,然后在塞满原文的上下文里写对比。每多读一篇长文,它后续每一步调用都要把这堆原文重新塞回去——上一节讲过,你付的钱主要就是"同一段上下文反复进出模型"。

拆成子代理后:

  • 每个子代理在自己的 thread 里读原文、烧 token——这些 token 它自己付,但只在它自己的会话里反复进出
  • 子代理干完,只把一段结论交回主 Agent。主 Agent 的上下文里始终只有「两段结论 + 写对比的指令」,干净、短。

所以同样一个任务,子代理模式下「贵的那部分上下文」被切成了几块互不污染的小账,而不是全堆在主 Agent 一个不断膨胀的大账里。这也是为什么子代理特别适合「中间料多、结论小」的活:调研、读长文档、批量检索——产出的料越大,隔离省得越多。


进阶:串行 vs 并行,两个变体

上面是并行(几块互不依赖、同时派)。但不是所有任务都能并行。看你的子任务之间有没有依赖:

变体一:并行(互不依赖)。 就是上面骨架的样子。协调者一次性把多个委派发出去,几个子代理同时在各自 thread 里跑。适合:查竞品 A/B/C、批量翻译多段、对多个文件分别做摘要。怎么促成并行:在协调者的系统提示词里明说"这几块互不依赖,请同时委派",模型才更倾向一次性派出去而不是排队。

变体二:串行(后一棒依赖前一棒)。 子任务有先后——必须先查清需求,才能据此设计方案,再据方案写文档。这时一个子代理的结论是下一个子代理的输入。协调者会先派研究员、拿到结论、再据结论派写手,天然是串行。代码上你不用改结构,只要在协调者的系统提示词里把依赖讲清楚:

coordinator = client.beta.agents.create(
    name="主控",
    model="claude-opus-4-8",
    system=(
        "流程有先后:先派「研究员」查清用户需求,拿到需求结论后,"
        "再据此派「方案师」出设计,最后你自己据方案写一段总结。"
        "后一步必须等前一步的结论,不要并行。"
    ),
    tools=[{"type": "agent_toolset_20260401"}],
    multiagent={"type": "coordinator", "agents": [researcher.id, designer.id]},
)

判断口诀:互不依赖 → 让它并行(省墙上时间);后一棒要前一棒的产出 → 串行(本质就是 handoff 接力的子代理版)。 别把有依赖的硬并行——下家拿不到上家结论,只会瞎编或返工。


子代理委派失败排查清单

这是本节最该收藏的一张表。多 Agent 调试最常见的不是报错,而是**「子代理压根没被派出去」「派了但没干成」**——主 Agent 自己默默把活干了,或者卡住不动。八成栽在下面几条:

现象 最可能的原因 怎么破
子代理根本不触发,主 Agent 自己把活干了 协调者没拿到「能派谁」的名册,或名册里的 Agent ID 写错 确认子代理 ID 真的进了协调者的 multiagent.agents 名册;ID 拼错=名册为空=只能自己干
子代理不触发(名册没问题) 协调者的系统提示词太泛,没说清「什么活该委派给谁」 在协调者系统提示词里点名:"把调研委派给「研究员」",别指望它自己悟出要委派
委派失败 / 子代理「没有工具可用」 子代理需要的工具没加进它的工具集——这是头号坑 给子代理显式开它要用的工具(研究员要 web_search 就得在它 tools 里 enable),别只在协调者上配
子代理被派出去了,却什么也搜不到 工具开了,但环境网络被限制(limited 没放行) 调研类要联网,环境 networking 用 unrestricted,或把目标域名加进 allowed_hosts
该并行的却在串行、慢 协调者没被告知「这几块互不依赖」 系统提示词明说"同时委派、它们互不依赖",模型才更愿意一次性派出
卡在 session.status_idle 不结束 idle 当成"干完了",但 stop_reason 其实是 requires_action(在等你) 判断结束要同时看 stop_reason:不是 requires_action 才算真干完(见骨架第 4 步)
先发任务后开流,开头的事件全丢了 流只推送「开流之后」的事件 先开 stream,再 send——顺序反了就漏掉开头的 thread_created 等事件

一句话总结这张表:委派不生效,先查名册(ID 对不对)和指令(说没说要派);委派了没干成,十有八九是子代理的工具没给全。


动手挑战

  1. 把上面的并行骨架跑起来,换成你关心的两个工具/竞品。盯着输出里有没有两条 session.thread_created——确认并行真的发生了,而不是悄悄变串行。
  2. 故意制造头号坑:把研究员的 web_search 工具去掉再跑,观察它是怎么"委派了却干不成"的。然后加回来,体会"子代理工具要单独给全"这条。
  3. 改成串行变体:再建一个「方案师」子代理,让协调者先派研究员、据结论再派方案师。对比串行和并行在事件流里的不同长相。
  4. 进阶:给协调者和子代理都保持稳定的系统提示词(别把时间戳/随机 ID 混进去),让重复委派吃上 prompt 缓存,看成本又降多少。

常见问题

子代理之间能互相通信吗? 默认不能直接对话。它们各跑在自己的 thread 里、上下文隔离,协作要靠协调者居中传递——协调者把 A 的结论作为 B 的输入派下去。需要平级"接力"就是 handoff 的思路;需要反复磋商才考虑对话式(最贵,慎用)。

一个协调者最多能派多少个子代理? 名册和并发都有上限,具体数字以官方文档为准。实践上别贪多:拆得过头,光是来回委派的开销就把省下的吃回去了。先确认每一块都「中间料多、结论小」值得拆,再拆。

委派会不会比不拆还贵? 会——如果拆错了。子代理省的是"中间料不进主上下文"那部分;如果某块根本没多少中间料(结论和过程差不多大),拆它纯属多此一举,还多付一层委派开销。判断标准回到四个用武之地:对不上就别拆。

不用托管 Agent,自己写 loop 能实现子代理吗? 能。本质就是:开一个独立的对话会话给子代理跑、拿到它的最终输出、只把这段输出塞回主 Agent 的上下文。托管 Agent 帮你把 thread 隔离、并行调度这些都管了;自己手写就得自己管会话和上下文边界,逻辑一样,活多一些。


小结 · 你现在掌握了什么

  • 你知道了子代理的四个用武之地:上下文隔离、并行、专门指令、工具限制——对上一条再拆,别为拆而拆。
  • 你看懂了那条铁律:每个子代理独立会话、只回结论,中间过程不占主 Agent 上下文,这就是它省钱的全部机制。
  • 你拿到了一段主 Agent 派两个子代理并行干活再汇总的完整骨架,以及"你应该看到什么"的验证信号。
  • 你能区分串行(有依赖)和并行(无依赖) 两个变体,靠协调者的系统提示词控制。
  • 你有了一张子代理委派失败排查清单:不触发先查名册和指令,干不成八成是子代理工具没给全。

编排不是非套框架不可。裸 SDK + 子代理原语,就能把最省的那条路落到实处。

下一步:手搓的子代理跑通了,接着可以看 Agent 之间更结构化的 RPC 式通信。继续看 AI Agent 智能体阶梯 的 L5 后续;想看全貌就对照三支柱路线图

👉 看看 AI 数字员工落地指南,或了解 数字员工搭建实战课。需要为企业落地方案,欢迎找我们聊 企业服务

📄 来源 / 自校链接

本文为学习整理,关键步骤与代码请结合下列官方来源验证。

内容有错、看不懂、或想看下一期?告诉我们 →

本文为学习与落地整理,AI 工具与平台更新较快,关键步骤请结合官方最新资料验证。见免责声明