跳到主要内容

自省与分工 — 反思回路、子图与多 agent

这一章讲三件事: 「让它检查自己」为什么能涨质量、实现时有什么反直觉的技巧; 几个 agent 组队时有哪四种队形、书里最推荐哪种; 以及把一张图装进另一张图的接插件(子图)。 读完你会明白:第 7 章的循环是「一个人反复干活」,本章的变体是「先干活再复盘」 和「一群人分头干活」——增量只有这两句,但代价与收益都要重新算。

1. 先看现象:写完就交,vs 写完先挨一顿批

同一个写作任务,单次生成的输出是什么水平就定什么水平; 而人类产出高质量文本的标准流程里,「初稿」后面永远跟着「审稿意见→修改」。 作者拿本书自己的成书过程举例:作者、审稿人、编辑来回拉锯若干轮才定稿1

把这道工序搬给机器,就是反思(reflection,别名 self-critique): 在生成提示修订提示之间接出一个回路。 认知科学给它垫了块理论招牌——Kahneman《思考,快与慢》里的两套思维: 反应式的 System 1 与讲方法的 System 2;书中判断:恰当使用自我批评, 能让应用「更接近 System 2 的行为」2

2. 顶层全景

反思图(本章前半) supervisor 星型(本章后半)

┌─────────────────────────┐ ┌─────────────┐
│ START → generate ──┬──▶ END │ │ supervisor │◀─┐
│ ▲ │ │ └──┬───────┬──┘ │
│ │ 条件边:轮数满? │ 选下一个 │ │ 干完回场
│ └── reflect ◀┘ │ ▼ ▼ │
└─────────────────────────┘ researcher coder ─┘

图说:左图是「同一个人格自我打磨」,右图是「一个工头派活」。

3. 核心原理

3.1 反思图:两个节点,固定三圈

书的实现是一个三段式作文工坊:generate 节点写或改稿,reflect 节点以教师人设挑毛病, 两节点之间用条件边判圈数——messages 超过 6 条就停(3 轮,每轮 2 条)3

第一版提示词直白:generate 的系统指令是「写出最好的三段式文章;若用户给了批评,按批评修改」; reflect 的指令是「你是给作文打分的老师,给出含长度、深度、风格的具体修改意见」4

先记结局再讲机关:书中实拍的批评意见长这样——五条编号建议(深化主题、联系现实、 扩充例证、引用原文、收束升华),针对一篇《小王子》主题作文; 最终稿的运行数据也一并给全:prompt 2501 tokens,completion 420 tokens(gpt-3.5-turbo)5

3.2 反直觉的机关:把消息角色整个反转

实现里最妙的一步藏在几行代码里:进入 reflect 节点前, AI 消息统统改贴 user 标签,人类消息统统改贴 AI 标签6

为什么非要玩这场变装?两个方向的「骗」缺一不可7:

  • 对批评者:对话模型是被「人问、AI 答」的数据喂出来的,让它批改用户写的文章, 它就进入了熟悉且认真的「教师模式」;让它直接批自己刚生成的消息,它熟悉的节奏就歪了;
  • 对生成者:改稿指令如果来自另一个 AI,说服力打折;伪装成用户意见,它就当成需求认真落实。

书中点破成因:对话微调模型按「人类-AI 消息对」训练, 同一角色连发多条会显著劣化表现7。这个细节是一般教程不会告诉你的实操命门。

为什么循环终点设在 generate 之后而不是 reflect 之后?因为固定圈数下, 最后一轮批评提的修改必须有人执行——停在 generate,才能确保最后一批意见落地8。 变体也存在:让 reflect 自己判断「没有新意见了」再停,灵活但多一层不可预测。

3.3 让批评有牙齿:外部信息落地

纯文本的批评天花板有限。书中给出的增强手段非常工程化: 在 reflect 之前插一步真实世界校验——代码生成场景里,先跑 linter 或编译器, 把报错原文喂给批评者,批评就从「我觉得可以更深」升级成「第 14 行少了个分号」9。 作者的 Tip 值得原样保留:凡是能这么做,强烈建议都做,大概率直接改善产出10

另一个变形是把反思回路接进第 7 章的 agent 循环末尾、用户看到答案之前: 批评伪装成用户输入,让 agent 在你不知情时自检一轮——代价照例是延迟11

3.4 子图:把一张图当零件

多 agent 需要的机械基础是子图(subgraph):一张编译好的图,直接当另一个图的节点用12。 三个使用动机:搭多 agent 系统;跨项目复用同一组节点;团队边界—— 只要守住输入输出 schema 的接口承诺,父图不必知道子图内部长什么样13

两种接法,按「状态方言合不合」二选一14:

接法适用机制
直接挂载父子共享状态键共享键直接通信;多余的键进、出两头都被忽略15
函数包裹schema 完全不同包一层函数:invoke({"bar": state["foo"]}) 进,{"foo": response["bar"]} 出,手动搬运翻译16

3.5 多 agent:三个动机,四种队形

什么时候该把一个 agent 拆成几个?书列了三个信号17:

  1. 工具太多,选不准(ch6 的海选旋钮治标,拆分治本);
  2. 上下文复杂到单个 agent 记不住——prompt 的体积与指代物数量超出了所用模型的容量;
  3. 某个领域需要专门子系统(规划、研究、数学……)。

拆出来的零件可轻可重:一个 prompt 加一次调用就算一个 agent,完整的 ReAct 图也行18。 队形有四种19:

队形结构一句话点评
Network全互连,人人可指派下一个灵活到难调试
Supervisor星型,工头统一派活书的选择:能力与易用的平衡点
Hierarchical工头的工头,递归版 supervisor更复杂流程调度的代价版
Custom部分流程写死,局部授权指派混合型,按需裁剪

走查①:工头的一票

supervisor 节点的实现浓缩了全书用过的两件武器——结构化输出与角色提示20:

class SupervisorDecision(BaseModel):
next: Literal["researcher", "coder", "FINISH"] # 只许三选一

model = ChatOpenAI(model="gpt-4o", temperature=0)
.with_structured_output(SupervisorDecision)

系统提示分两段:第一段介绍工人名单和游戏规则(「干完活回报结果,全部完成回 FINISH」); 第二段把「轮到谁?」连同候选名单再问一遍。收到的答案是结构化的三选一, 条件边据此把执行流拨给对应节点21

一个容易被忽视的岗位要求:工人的名字必须自解释且互不相同—— 叫 agent_1agent_2 的话工头无据可依;必要时在提示里补上每人的一段简介22

图上的接线值得注意:researcher 和 coder 干完活都要回到 supervisor 再派下一棒, 所有进展记录在共享的 messages 里,彼此看得见对方的产出23。 两条松动空间书上也都给了:工人可以自持内部状态只交摘要;回工头也不是硬规定, 可以把硬边换成条件边,让某个工人自行决定要不要直接把产出返给用户24

4. 作者的判断与证据

  • 反思有效性的论证是机制式的(多次打磨机会 + 批评者换人设),配合实拍的批评与 token 数据5; 书没有给对照实验数字,这一点要诚实地记住。
  • 「接 supervisor」的推荐语写得很稳:「我们认为它在能力和易用之间平衡得不错」25—— 经验判断,不是评测结论。
  • 章末忠告分量最重:这些扩展不应是你新建 agent 的首选,先用第 7 章的直白架构26

5. 边界与局限

  • 固定三圈是粗糙的预算制:意见可能没用完(改不到位)或早早用尽(空转烧 token); 书给的自适应变体没有展开实现。
  • 多 agent 的成本与延迟账完全没算:每多一个节点就是多几次模型调用, 「拆分解决上下文超载」的同时也成倍放大了调用次数。
  • supervisor 的 FINISH 判断失误(漏 FINISH 空转 / 误 FINISH 早退)没有给防护; Network 与 Hierarchical 两种队形书里只有一句话介绍,没给代码。
  • 反思的「角色反转」依赖对话模型按人-AI 对训练这一现状,若模型行为演进, 这条技巧可能失效(补充(不在书里,来自通用知识):多数主流对话模型仍保持这一训练形态)。

6. 可带走的

  1. 反思=在生成与修订两个提示间建回路;涨质量的两个来源:多轮打磨 + 批评者换人设;
  2. 消息角色反转是让对话模型「认真批改」的关键机关,不做就掉性能;
  3. 固定圈数时终点必须设在 generate 之后,让最后一轮意见兑现;
  4. 给批评装牙齿:编译器/linter 的真实报错是最好的批评素材,能落地就这么干;
  5. 子图两接法看方言:共享键直接挂载,异 schema 函数包裹;多余键会被双向忽略—— 接口瘦身靠 schema,不靠运气;
  6. 拆多 agent 的三个信号:工具超载、上下文超载、领域专属;
  7. 队形默认选 supervisor:星型派活 + Literal 锁死选项 + FINISH 退出票;
  8. 工人名字即文档:agent_1 式命名会让工头失明;
  9. 最后的忠告按原样带走:先写直白循环,扩展是疼了才吃的药

7. 原文地图

主题原书章原文位置
两扩展总起Chapter 7text/10-ch07-chapter-7-agents-ii.txt:7(搜「two extensions」)
reflection 定义与成书类比Chapter 7text/10-ch07-chapter-7-agents-ii.txt:21(搜「creator prompt and a reviser prompt」)
System 1/2 引用Chapter 7text/10-ch07-chapter-7-agents-ii.txt:25(搜「Thinking, Fast and Slow」)
反思图规格(三段作文/固定轮数/变体)Chapter 7text/10-ch07-chapter-7-agents-ii.txt:29(搜「three-paragraph essays」)
两个系统提示词Chapter 7text/10-ch07-chapter-7-agents-ii.txt:52(搜「essay assistant」) · text/10-ch07-chapter-7-agents-ii.txt:64(搜「grading an essay submission」)
固定三圈条件边Chapter 7text/10-ch07-chapter-7-agents-ii.txt:83(搜「should_continue」) · text/10-ch07-chapter-7-agents-ii.txt:85(搜「End after 3 iterations」)
角色反转 cls_mapChapter 7text/10-ch07-chapter-7-agents-ii.txt:71(搜「Invert the messages」)
变装的原因(训练分布)Chapter 7text/10-ch07-chapter-7-agents-ii.txt:184(搜「subterfuge」)
终点设在 generate 的理由Chapter 7text/10-ch07-chapter-7-agents-ii.txt:186(搜「terminate after generate」)
批评实拍(五条建议)Chapter 7text/10-ch07-chapter-7-agents-ii.txt:192(搜「Little Prince」)
终稿与 token 实拍Chapter 7text/10-ch07-chapter-7-agents-ii.txt:238(搜「2501」)
有效性解释Chapter 7text/10-ch07-chapter-7-agents-ii.txt:247(搜「multiple attempts at refining」)
接入 agent 末尾的变体Chapter 7text/10-ch07-chapter-7-agents-ii.txt:249(搜「higher latency」)
外部落地(linter/编译器)与 TipChapter 7text/10-ch07-chapter-7-agents-ii.txt:251(搜「linter or compiler」) · text/10-ch07-chapter-7-agents-ii.txt:255(搜「strongly recommend」)
子图用途三条Chapter 7text/10-ch07-chapter-7-agents-ii.txt:259(搜「Subgraphs are graphs」)
多余键双向忽略(Note)Chapter 7text/10-ch07-chapter-7-agents-ii.txt:285(搜「they will be ignored」)
函数包裹接法Chapter 7text/10-ch07-chapter-7-agents-ii.txt:353(搜「completely different schema」)
多 agent 三动机Chapter 7text/10-ch07-chapter-7-agents-ii.txt:435(搜「grow in size, scope, or complexity」)
零件可轻可重Chapter 7text/10-ch07-chapter-7-agents-ii.txt:443(搜「as simple as a prompt」)
四队形Chapter 7text/10-ch07-chapter-7-agents-ii.txt:449(搜「Network」) · text/10-ch07-chapter-7-agents-ii.txt:455(搜「supervisor agent makes decisions」) · text/10-ch07-chapter-7-agents-ii.txt:459(搜「supervisor of supervisors」)
supervisor 选择语Chapter 7text/10-ch07-chapter-7-agents-ii.txt:465(搜「good balance of capability and ease of use」)
SupervisorDecision schemaChapter 7text/10-ch07-chapter-7-agents-ii.txt:29(搜「FINISH」)
两段式提示词Chapter 7text/10-ch07-chapter-7-agents-ii.txt:491(搜「respond with FINISH」)
名字自解释要求(Note)Chapter 7text/10-ch07-chapter-7-agents-ii.txt:539(搜「self-explanatory and distinct」)
回工头与共享 messagesChapter 7text/10-ch07-chapter-7-agents-ii.txt:617(搜「see each other's work」)
松动空间(自持状态/直返用户)Chapter 7text/10-ch07-chapter-7-agents-ii.txt:619(搜「isn't a hard requirement」)
章末忠告Chapter 7text/10-ch07-chapter-7-agents-ii.txt:625(搜「shouldn't be the first thing you reach for」)

Footnotes

  1. 出处:「Chapter 7. Agents II」第 21 段(text/10-ch07-chapter-7-agents-ii.txt:21,搜「authors, reviewers, and editor」)。

  2. 出处:「Chapter 7. Agents II」第 25 段(text/10-ch07-chapter-7-agents-ii.txt:25,搜「System 2 behavior」)。

  3. 出处:「Chapter 7. Agents II」第 29 段(搜「fixed number of times」)与第 83–89 段条件边代码(text/10-ch07-chapter-7-agents-ii.txt:85,搜「End after 3 iterations」)。

  4. 出处:「Chapter 7. Agents II」第 51–57、63–68 段(text/10-ch07-chapter-7-agents-ii.txt:55,搜「revised version of your」)。

  5. 出处:「Chapter 7. Agents II」第 188–245 段(批评全文第 192–226 段,搜「Little Prince」;token 数据在第 238–243 行,搜「2501」)。 2

  6. 出处:「Chapter 7. Agents II」第 72 行(text/10-ch07-chapter-7-agents-ii.txt:71,搜「Invert the messages」)。

  7. 出处:「Chapter 7. Agents II」第 184 段(text/10-ch07-chapter-7-agents-ii.txt:184,搜「tricks the LLM into thinking」);「traced on pairs of human-AI messages」机制句在同段后半。 2

  8. 出处:「Chapter 7. Agents II」第 186 段(text/10-ch07-chapter-7-agents-ii.txt:186,搜「the last set of revisions requested are dealt with」)。

  9. 出处:「Chapter 7. Agents II」第 251 段(text/10-ch07-chapter-7-agents-ii.txt:251,搜「run the code through a linter or compiler」)。

  10. 出处:「Chapter 7. Agents II」第 253–255 段(text/10-ch07-chapter-7-agents-ii.txt:255,搜「likely to increase the quality」)。

  11. 出处:「Chapter 7. Agents II」第 249 段(text/10-ch07-chapter-7-agents-ii.txt:249,搜「adding it as the last node」)。

  12. 出处:「Chapter 7. Agents II」第 259 段(text/10-ch07-chapter-7-agents-ii.txt:259,搜「graphs that are used as part of another graph」)。

  13. 出处:「Chapter 7. Agents II」第 261–265 段(text/10-ch07-chapter-7-agents-ii.txt:265,搜「without knowing any details of the subgraph」)。

  14. 出处:「Chapter 7. Agents II」第 267–276 段(text/10-ch07-chapter-7-agents-ii.txt:271,搜「share state keys」)。

  15. 出处:「Chapter 7. Agents II」第 285 段(text/10-ch07-chapter-7-agents-ii.txt:285,搜「ignored by the subgraph node」)。

  16. 出处:「Chapter 7. Agents II」第 353–381 段(示例代码第 377–381 行)。

  17. 出处:「Chapter 7. Agents II」第 435–441 段(text/10-ch07-chapter-7-agents-ii.txt:439,搜「context grows too complex」)。

  18. 出处:「Chapter 7. Agents II」第 443 段(text/10-ch07-chapter-7-agents-ii.txt:443,搜「as simple as a prompt and an LLM call」)。

  19. 出处:「Chapter 7. Agents II」第 447–463 段(text/10-ch07-chapter-7-agents-ii.txt:451,搜「communicate with every other agent」)。

  20. 出处:「Chapter 7. Agents II」第 473–502 段(text/10-ch07-chapter-7-agents-ii.txt:479,搜「SupervisorDecision」)。

  21. 出处:「Chapter 7. Agents II」第 487–494 段(两段提示词)与第 567–573 段(条件边 lambda state: state["next"])。

  22. 出处:「Chapter 7. Agents II」第 539 段(text/10-ch07-chapter-7-agents-ii.txt:539,搜「agent_1 and agent_2」)。

  23. 出处:「Chapter 7. Agents II」第 617 段(text/10-ch07-chapter-7-agents-ii.txt:617,搜「recorded in the messages list」)。

  24. 出处:「Chapter 7. Agents II」第 619 段(text/10-ch07-chapter-7-agents-ii.txt:619,搜「replace the hard edge」)。

  25. 出处:「Chapter 7. Agents II」第 465 段(text/10-ch07-chapter-7-agents-ii.txt:465,搜「good balance」)。

  26. 出处:「Chapter 7. Agents II」第 625 段(text/10-ch07-chapter-7-agents-ii.txt:625,搜「straightforward architecture we discussed in Chapter 6」)。