拆的是上下文,不是工作量——总工作量不减,每一刻要装的东西减。 看峰值,不看总量:上下文窗口是上限,不是账单。 Demo 里峰值从一百八十五降到六十一,合计也从五百五十五降到一百八十。
上一篇讲把脚本升级成能力。这一篇讲另一种扩容:把一件事拆给几个子 Agent。 为什么需要拆?因为上下文有上限。 一个任务要读十个文件时,全塞进去会超;拆开之后每份只读两三个。 Demo 真起三个子进程,每个只看自己那一段文档,各回一份结论。 峰值和合计两个数都算出来,和「一个 Agent 顺序做」对比。
一、拆的是上下文,不是工作量
这句话容易听成文字游戏,但它决定了你怎么拆。 如果你按「工作量」拆——三件事分给三个人做——每个人还是要读全部背景,因为三件事互相依赖。 那拆分只增加了沟通成本。 如果你按「上下文」拆——每个人只看自己那段——每个人读的东西少了,而且不需要知道别人那段。 这才是有效的拆。 Demo 里就是这么拆的: 一段文档切成三份,判空、判情绪、选回复各看一份,各回一行结论。 三个子进程之间互不知道对方存在。
二、一个主 Agent 三个子 Agent 的信息流
| 环节 | 发生什么 | 经过谁 |
|---|---|---|
| 拆分 | 主 Agent 把任务切成三份 | 主 |
| 分发 | 每份带自己的上下文出去 | 主到子 |
| 各自判断 | 只看自己那份,回一行结论 | 子 |
| 汇总 | 三行结论合成一个答复 | 主 |
关键在于「回一行结论」这个约定。 子 Agent 不把读到的原文带回来,只带判断结果。 这是峰值能降下来的原因——如果它把原文一起带回来,主 Agent 的上下文又满了。 所以子 Agent 的输出格式要提前定死。 Demo 里定的是 JSON,三个字段:任务名、结论、状态。 定死之后,汇总就是拼三个 JSON,不需要理解内容。
三、拆分失败的两种样子
| 样子 | 症状 | 原因 |
|---|---|---|
| 拆得太碎 | 合计暴涨、结论互相矛盾 | 每份都不足以独立判断 |
| 拆得不彻底 | 每个子 Agent 还是要读全文 | 只是换了个壳 |
「拆得太碎」的表现很好认:合计比不拆还多。 因为每个子 Agent 都要写一份结论,结论本身也是 token。 拆成十个,就是十份结论——比原文还长。 「拆得不彻底」更隐蔽。 形式上你起了三个子 Agent,实际上每个都读了全文。 判断方法只有一个数:子 Agent 拿到的上下文,比主 Agent 少多少。 没少,就是白拆。 一个实用的拆法:按「能不能独立判断」切。 一份上下文如果单独给出去,那个子 Agent 能自己得出结论,就算切对了; 如果它还得回来问「那另一段呢」,就切错了。
四、动手 Demo:Subagent:拆的是上下文,不是工作量
一份三百字的流程文档,两种做法:一个 Agent 顺序做三件事,或者三个子 Agent 各看一段。 子 Agent 是真起的子进程:主进程往 stdin 写 JSON,子进程算出结论写回 stdout。 三种做法的上下文量都是真算的。
for i, (name, goal) in enumerate(three):
chunk = parts[i]
r = subprocess.run([PY, u"sub.py"], cwd=base,
input=json.dumps({"name": name,
"text": chunk}).encode())
out = json.loads(r.stdout.decode(u"utf-8").strip())
subs.append((name, tokens(chunk), tokens(json.dumps(out))))
实跑输出:
--------------------------------------------------------------------
Subagent:拆的是上下文,不是工作量
--------------------------------------------------------------------
① 一个主 Agent 顺序做三件事
--------------------------------------------------------------------
文档 185 token,顺序做三件事,每件都要带全文
峰值上下文 185 token,合计 555 token
② 三个子 Agent,各看一段
--------------------------------------------------------------------
判空 只看 61 token,回了 10 token 的结论
判情绪 只看 32 token,回了 12 token 的结论
选回复 只看 53 token,回了 12 token 的结论
峰值上下文 61 token,合计 180 token
③ 两种做法对比
--------------------------------------------------------------------
| 做法 | 峰值上下文 | 合计 | 结果怎么来 |
|---|---:|---:|---|
| 一个 Agent 顺序做 | 185 | 555 | 三件事在同一份上下文里做 |
| 三个子 Agent 并行 | 61 | 180 | 各自出结论,主 Agent 汇总 |
峰值从 185 降到 61,降了 3.0 倍;合计从 555 降到 180,降了 3.1 倍。
! 这两个数一起降,是因为「各看一段」比「每件都带全文」省。所以拆对了,峰值和合计是同时降的。
如果拆完之后每个子 Agent 还是要读全文,合计会涨回去——那是「拆得不彻底」,⑤ 里会讲。
④ 为什么峰值比总量重要
--------------------------------------------------------------------
上下文窗口是一个上限,不是账单。
装不下就是装不下——所以你要看的是「最挤的那一刻」,不是「一共花了多少」。
! 这也解释了为什么「拆得越细越好」是错的:拆得越细,每个子 Agent 都要写一份结论,合计涨得很快。
拆到「每份都能独立判断」就够,再细就是浪费。
⑤ 拆分失败的两种样子
--------------------------------------------------------------------
| 样子 | 症状 | 原因 |
|---|---|---|
| 拆得太碎 | 合计暴涨、结论互相矛盾 | 每份都不足以独立判断 |
| 拆得不彻底 | 每个子 Agent 还是要读全文 | 只是换了个壳,没减上下文 |
! 判断拆对了没有,看一个数:子 Agent 拿到的上下文,比主 Agent 少多少。没少,就是白拆。
顺序做:峰值一百八十五、合计五百五十五。 三个子 Agent:峰值六十一、合计一百八十。 两个数都降了三倍。 为什么合计也降了? 因为「各看一段」比「每件都带全文」省。 顺序做的时候,三件事每件都带着全文,等于读了三千;拆开之后,三份加起来才一百八十五。 注意子 Agent 回的结论只有十来个 token。 这就是「只带判断,不带原文」的具体样子。 如果它把原文带回来,主 Agent 的峰值立刻回到一百八十五。 最后那句判断标准要记住:子 Agent 拿到的上下文,比主 Agent 少多少。 没少,就是白拆。
30 秒实验
- 找一个你嫌大的任务,试着按「能不能独立判断」切一次。 切完看每一份是不是都能自己得出结论。
- 给你的子 Agent 定一个输出格式,只允许结论。 一旦允许它带原文回来,拆分就白做了。
- 量一下拆分前后的峰值上下文。 没降一半,说明拆得不够彻底。
常见误区
- 「拆得越细越好。」 拆得越细,结论越多,合计涨得很快。 拆到「每份能独立判断」就够。
- 「子 Agent 应该把读到的都带回来,方便主 Agent 判断。」 那峰值立刻满。 拆分的全部收益就在「不带回来」这一条上。
- 「拆分能提高总吞吐。」 拆分降的是峰值,不是总量。 总量甚至可能上升,因为多了写结论这一步。
自测三问(点开对答案)
1. 「拆上下文」和「拆工作量」有什么不同? —— **拆工作量:每个人还是要读全部背景,因为任务互相依赖。** **拆上下文:每个人只看自己那段,不需要知道别人那段。** **只有后者能降峰值。** 2. 为什么子 Agent 只该回结论,不该带原文? —— **因为带回来主 Agent 的上下文又满了。** **拆分的全部收益就在「不带回来」这一条上。** 3. 怎么判断拆分失败了? —— **看子 Agent 拿到的上下文比主 Agent 少多少。** **没少就是白拆;如果合计比不拆还多,就是拆得太碎。**下一篇 8.3 讲 MCP:先问是否值得接,再问怎么接——顺便看一次真的握手报文。
- ☐ (本篇完,下一篇 8.3 MCP:先问是否值得接,再问怎么接)