跳到主要内容

框架、通用工具协议与锁定的代价

这一章讲三件事: 第 13 章那个循环该自己写还是交给框架、 交给框架之后你得到什么又赔上什么、 以及工具本身要不要从你的代码里搬出去。

它在全书链条上的位置:第 13 章那个循环的外围。 机制上不添新东西,它全部在谈代价。

1. 这一章讲什么

三句话:

  1. 第 13 章那个 while 循环,你已经能自己写了。这一章问的是:该不该自己写? 书把答案摊成三层——不写代码的、写代码但用框架的、从零搭的;
  2. 书在这一章给了全书最硬的两句判断,而且它们都是关于代价的: 「每加一层抽象都遮蔽行为、让调试更难,每加一个依赖都扩大你的攻击面」; 「框架锁定会随时间复利」;
  3. 最后一节讲一件方向相反的事:把工具从你的代码里搬出去,变成一个独立的服务, 让任何框架都能用同一个工具。它有名字,叫 MCP,而它只在一种情况下划算。

2. 顶层全景:同一个需求,三层实现

需求:一个"天气助手" —— 用户问哪个城市,它去查天气,再照天气给建议

第 3 层 从零搭 你自己写第 13 章那个 while 循环
控制最大,什么都得自己实现(日志、追踪、护栏)

第 2 层 代码优先的框架 一个装饰器把函数变成工具,一个跑法把循环跑起来
代码级控制还在,但循环是别人的

第 1 层 不写代码的平台 拖拽连线,预置连接器
最快,定制最少,按订阅收费而不是按用量

图说:三层是同一件事的三种做法,不是三种功能。
越往上越省事,越往下越可控 —— 而这一章的正文,是那些"省事"各自要付什么。

书自己声明了一件事,值得先说清楚1: 「这一节不推荐具体的框架,它给的是评估标准。」 这一章我们也照这个口径写——你读完拿到的是判据,不是选型结论。

3. 三层各自是什么、各自在哪种情形下是对的

三层的定义

书用一张表给了三层1:

它是什么计价方式与适用面
不写代码的平台拖拽式的流程搭建器,带一堆预置的连接器,几乎不写代码适合两到五步的内部流程、团队里没有能写代码的人手的时候;通常按订阅收费(每月交固定的一笔钱,和你实际用了多少无关),而不是按用量
代码优先的框架提供 agent 基本件的库:工具、记忆与持久化、追踪,外加一些成型的写法想比从零搭快,又要保住代码级的控制
从零搭你直接调模型接口,自己实现编排、工具、状态、记忆和可观测性需要最大灵活性或健壮性,而且团队有能力扛下整个栈(含日志、追踪、护栏)

「可观测性」在这里指「系统在跑的时候,你能不能看见它内部发生了什么」—— 调了哪些工具、每一步花了多久、哪一步出的错。 从零搭的时候,这一整套没有人替你做。

五种情形各该选哪层

书还给了一张情形对照表,这是这一节最实用的部分2:

你的处境书的建议理由
几周内要把系统推上生产高抽象的框架内置功能多,能快;从零搭更久,但可能更健壮
很多经验中低的开发者在维护框架(轻量或高抽象)「只有团队经验很足、并且已经清楚 agent 该长什么样时,才从零搭。」 框架给的是一套标准做法,新手照着走比自己写高质量基础设施容易
要服务几千到几百万用户,要健壮和可扩展从零搭,或轻量框架依赖越少,要维护的越少,能坏的部件也越少
要一个为某个特定需求定制的 agent从零搭,或轻量框架从零搭能完全控制工具怎么定义、什么时候怎么互动
要实时调试、可观测性、审计合规日志三种都行两家框架各自带追踪能力;从零搭就得自己实现日志与追踪

注意第二行和第三行是相反方向的建议,而它们并不矛盾: 第二行管的是「谁来写和维护」,第三行管的是「它要扛多大的量」。 真实项目里这两件事经常同时成立,那时候书给的答案就是中间那一层。

4. 承重词一:锁定 —— 它为什么会「随时间复利」

这一章第一个承重词。一句话先给结论:锁定就是「你的代码和某个框架长在了一起, 以后想换,要重写的不只是调用它的那几行,而是整套结构」。

书给的两条账

这两句是全书关于框架最硬的判断3:

① 早期避开重型框架。先从直接调接口或轻量框架开始,把需求摸清楚。 每加一层抽象都会遮蔽行为、让调试更难。每加一个依赖都扩大你的安全攻击面。

② 框架锁定会随时间复利。

「攻击面」指的是「别人能从哪些地方攻进来」的总和—— 你装的每一个第三方包,都是一段你没读过、但会在你机器上执行的代码。

「复利」这个词是这一节的重点

书用了「compound」这个词,而它不是修辞。

第 1 个月: 你用框架写了 3 个 agent。迁走 = 重写 3 个。
第 6 个月: 20 个 agent、一套状态结构、一堆围着它写的测试和监控。
迁走 = 重写 20 个 + 重新设计状态怎么传 + 重写测试和监控。
第 12 个月: 团队里有人只会这个框架的写法。
迁走 = 上面全部 + 重新培训。

(这三行的数是为演示编的;"锁定会随时间复利"是书里的说法。)

图说:注意增长的不是"agent 的个数",是"依赖它的东西的种类"。
这才是"复利"的意思 —— 每多一个月,可迁走的窗口就窄一点。

书还点名说了两家的差别3:

锁定程度原因
图框架那一家它的状态管理强加了一种结构,很难迁走
轻量框架那一家抽象更简单,所以锁得浅

把这一条和第 09 章那条对照着看,全书的形状就出来了: 换存放向量的库很便宜(要重建索引,但不必重算那些数); 换框架很贵(要重写整套结构)。 这两处不对称,正是第 19 章那条「方向不可逆」的两个端点。

5. 承重词二:状态图 —— 把控制流写成看得见的东西

这一章第二个承重词。一句话先给结论:状态图就是把「现在进行到哪了」和 「下一步允许去哪」这两件事,从代码逻辑里拎出来,写成三样明确的东西—— 状态、节点、边。

三样东西各是什么

书给的定义4:

名字它是什么
状态记录现在发生了什么,装着共享的数据。 书那个例子里,状态就是一路累积的对话记录
节点干活的函数:接过当前状态 → 做一件事 → 返回更新后的状态
连接节点,决定下一个跑哪个

画出来,正好就是第 13 章那个循环

这是这一节最该带走的一句。

┌───────────────┐
│ 节点:问模型 │ ←──────────────┐
└───────┬───────┘ │
│ │
条件边:它要求调工具吗? │
├── 要 ──→ ┌──────────────┐ │
│ │ 节点:执行工具 │────┘
│ └──────────────┘ (把结果并进状态,回到上面)

└── 不要 ──→ 结束,输出最终答案

图说:把这张图和第 13 章第 2 节那个循环并排看 —— 它们是同一个东西。
差别只在:那里是一个 while 循环加一个 if;
这里是"两个节点 + 一条条件边",而且这张图可以直接画出来给人看。
书自己也点破了这一点:那张图画的就是第 13 章说的 ReAct。

「条件边」就是「下一步去哪,取决于当前状态」的那种边。 上图里那条「它要求调工具吗」就是条件边。

它换来什么

书给的收益是一句话5:

它把 agent 的状态和控制流变成显式的东西。你精确地定义了在什么状态下下一个跑哪个节点; 边定义了合法的转移,从而防止出现未定义的状态或者无限循环。

「防止无限循环」这半句要和第 13 章连起来读: 那一章说循环唯一的刹车是「最多调几次工具」这个上限。 而在图里,刹车变成了结构性的——不合法的转移根本连不出边来。

还有一条收益是给人看的5:那张图可以画出来, 显示所有可能的执行路径,以及这一次实际走了哪一条——这在调试意外决策时很有用。

什么时候别用它

书给的反面判据很干脆5:

固定顺序、没有分支逻辑、也不需要共享状态的简单流程,别用图。 那时候这层抽象只增加复杂度,不带来好处。

代价也写得明白5:它的状态管理和图执行会深深嵌进你的代码结构里。 迁走意味着把整套状态流转和转移逻辑重新实现一遍。

6. 把 agent 本身包装成工具

这一节讲多个 agent 怎么协作,而书给的手法比「自己写一套调度」省得多。

手法:一个 agent 对外只暴露「进文本、出文本」

书的做法是6:把 agent 包装成工具,让别的 agent 像调函数一样调它。

主持人 agent
├─ 工具 A:其实是"客户"这个 agent
└─ 工具 B:其实是"销售"这个 agent

主持人不知道 A 和 B 内部是什么 —— 它只知道
"把一段文字交进去,会拿回一段文字"。

图说:这正是第 13 章那个工具清单的形状。
区别只在于:那里工具背后是一个 Python 函数,这里是另一个完整的 agent。

书给的收益是两条6: 每个 agent 只暴露一个简单的接口(进文本、出文本), 所以它们可以互换、也可以单独测试。

在那套轻量框架里,「把函数变成工具」只要在函数上面加一行标记就行—— 这种写在函数上方、用来改变这个函数行为的标记,Python 里叫装饰器7

补充(不在书里,依据我们的 frontier 书架):书的正文和它自己的代码对不上。 正文说「加上 @tool 装饰器」,而紧接着的代码写的是 @function_tool; 同一节的讨论段里写的也是 @function_tool我们去核了那套 SDK 的源码,里面定义的是 function_tool,没有 tool 照正文抄会直接报错。7

另起一处走查:议价 agent

这是这一章另起的第一处走查,因为它落不到主走查上(主走查只有一个 agent)。 用的是书那个跑例8

场景(书给的原样):
客户想买 15 台笔记本,每台不超过 950 欧元
零售价是 1 299 欧元
销售给了 12% 折扣 → 1 299 × 0.88 ≈ 1 143 欧元(这个乘法是我们算的)
客户说不够,并称别家能给到 1 000 欧元
对话到这里停住

系统怎么搭(书给的):
① 先把这段邮件往来灌进一个向量库(集合名 email_history)
② 写一个查这个库的工具,加上那行装饰器
③ 建两个 agent:
"客户" 指令:为最好的笔记本报价谈判,礼貌但坚持
"销售" 指令:代表销售方回应
④ 把这两个 agent 各自包装成工具
⑤ 建"主持人" agent,把这两个工具给它,并写清流程:
收到邮件记录(最后一条来自客户)
→ 用"销售"工具生成销售方的回复
→ 把回复追加进邮件记录
→ 用"客户"工具生成客户的回复
→ 交替下去,直到达成一致或者谈崩

图说:注意第 ⑤ 步 —— 主持人手里那两个"工具",
每调用一次都是一次完整的模型调用,不是一次函数调用。

它的代价:每一次交接都是一次完整的模型调用

书给的反面判据是这一节最该记的6:

延迟关键时别用这个模式。每一次 agent 交接都需要一次完整的模型调用, 而多轮对话的成本会线性累加。 只是简单的任务委派、不需要来回对话的话,直接调函数或者用选路更划算。

上面那个议价跑五个来回:
主持人调销售 → 一次模型调用
主持人调客户 → 一次模型调用
…… 五个来回 = 10 次
加上主持人自己每一轮的判断 = 再来 10 次左右
─────────────────────────────
一次"谈判"总共约 20 次模型调用

(5 个来回和这个总数是为演示编的;"每次交接都是一次完整调用"
和"多轮对话成本线性累加"是书里的。)

判断(我们的,不是书里的):书把「主持人把对话记录传给每个子 agent」 说成这个模式的做法,而这句话描述的其实是另一种机制。 我们核了那套 SDK 的源码:把 agent 变成工具的那个方法, 文档注释里明确写着它和「交接」有两点不同—— 交接会让新 agent 拿到整段对话记录,而当成工具调用时,新 agent 拿到的是生成出来的输入。 也就是说,书描述的传递方式对应的是「交接」,不是它正在演示的「当成工具」。 如果错,会错在: 如果书说的「传对话记录」指的是主持人把记录写进那段输入文字里 (它的提示词确实是这么写的),那这句话在效果上成立,只是措辞让人误以为是框架自动做的。 判据是:看主持人的提示词——历史是写在传给工具的那段文字里,还是框架替你带过去的。9

7. 承重词三:MCP —— 把工具从你的代码里搬出去

这一章第三个承重词,也是这一节唯一的新机制。 一句话先给结论:MCP 是一套约定,规定「模型这边怎么问工具有哪些、怎么调它们」; 约定之后,同一个工具不必为每个框架各写一遍。

它解决的问题

书给的问题陈述极其清楚10:

没有 MCP 的时候,每个框架都要求工具用它自己的格式写。

你写了一个"查数据库"的工具。

── 没有通用约定 ──
用轻量框架: 按它的写法写一遍
换图框架: 按图框架的写法再写一遍
换成别的: 再写一遍
每次外部数据库改了字段,这几份都要各改一次

── 有了通用约定 ──
写成一个独立的服务,只写一遍
任何支持这套约定的 agent 都能用它
改一次,所有地方一起变

书打了一个比方:它之于模型和工具,就像 HTTP 之于浏览器10—— 比方到这里为止,下面一律用「客户端」「服务器」「协议」这些正式说法。

三件东西

书给的三件10:

名字它是什么
客户端你的 agent 应用——想用工具的那一方
服务器提供工具和数据源的那一方,可以跑在本地,也可以跑在远端。你也可以为自己的工具写一个
协议两边之间那套约好的说话规矩

补充(不在书里,依据我们的协议书架):书只讲到这三件为止,而规范实际规定的比这多。

服务器能提供的不止工具一种。 规范里是三类:给模型调的工具、 给模型读的资料、给用户点的快捷指令——三者分别由模型、应用和用户来控制。

连接方式也有两种。 一种是把服务器当子进程启动、通过标准输入输出说话 (就是「父程序往它的输入里写一行、从它的输出里读一行」这种最朴素的管道); 另一种是走普通的网络请求11

两条代价

书给了两条,而且都很具体12:

代价一:它是额外的基础设施。

服务器是独立的进程,要部署、要监控,还要处理网络层面的错误。 你的 agent 必须自己应付「连不上」「超时」「返回的数据是畸形的」这三种情况。

进程」就是操作系统里一个正在运行的程序实例。 「独立的进程」意味着它可能没起来、可能崩了、可能跑在另一台机器上—— 而第 13 章那种直接调 Python 函数,不存在这些情况。

代价二:安全性质变了。

和本地的函数调用不同,这种服务器接受网络请求, 所以认证、授权和输入校验一样都不能少。每一个这样的服务器都扩大你的攻击面。

(「本地的函数调用」就是第 13 章那种:工具是你自己进程里的一个 Python 函数, 调它不经过网络,别人也够不着它。)

三个词各一句:

它管什么
认证你是谁——来的这个请求是不是你说的那个人发的
授权你能干什么——这个人有没有权限调这个工具
输入校验你传进来的东西合不合法——别让一段构造过的参数把服务器搞坏

什么时候值得,什么时候是纯开销

书给的分界线只有一句,但它很硬12:

值得工具要跨项目、跨团队复用的时候。 一个查数据库的工具做成这样一个服务器,任何支持这套协议的框架都能用它;更新一次,而不是维护好几个各框架专用的版本
纯开销单一用途的 agent,工具和 agent 的逻辑本来就紧紧绑在一起。 「协议的开销只有在工具复用或者跨框架兼容真的重要时才划得来」

8. 主走查:同一个「天气助手」,在三层上各写一遍

这是本章的主走查,前面每个机制都在它上面占一步。

(三层的划分、那三样图组件、装饰器、把 agent 包装成工具、 MCP 三件与两条代价,都是书里的;下面每一层的代码行数、迁移工作量, 以及最后那张对照表,是我们为演示估的。)

需求固定不变: 用户问「我明天去慕尼黑,穿什么、怎么去?」 系统要查天气,再照天气给出行和穿衣建议。

第 3 层:从零搭(第 13 章已经走完)

你要写的东西:
① 两个 Python 函数:查经纬度、查天气,各带一段说明文字
② 一份工具清单(名字 / 描述 / 参数)
③ 第 13 章那个 while 循环
④ 自己打日志:哪一步调了什么、花了多久

← 循环、状态、追踪,全是你的代码
锁定了什么:什么都没锁。换模型厂商就是改一行接口地址。
(约 120 行,是我们估的。)

第 2 层:轻量框架

你要写的东西:
① 同样两个函数,但每个上面加一行装饰器,它们就变成工具了
② 建一个 agent:给它指令、模型名、工具列表
③ 用框架的跑法把它跑起来

← 循环不见了 —— 它在框架里
白得的东西:追踪(在厂商网站上能逐步看这次跑了什么)、护栏、防死循环
锁定了什么:agent 的建法和跑法。迁走要改这两处,函数本身不用动。
(约 40 行,是我们估的。)

第 2 层的另一种:图框架

你要写的东西:
① 一个状态:装着这一路的对话记录
② 两个节点:"问模型" 和 "执行工具"
③ 一条条件边:模型要求调工具就走向"执行工具",否则结束
④ 从"执行工具"连一条边回到"问模型"

← 循环变成了图上的一个环
白得的东西:可以画出来的执行路径、自动维护的共享状态、结构性的死循环防护
锁定了什么:**状态怎么传、流程怎么转,全按它的模型写。**
迁走 = 把整套状态流转和转移逻辑重新实现一遍。
(约 70 行,是我们估的。)

第 1 层:不写代码的平台

你要做的:在界面上拖出四个方块,连上线,填两个接口地址。

白得的东西:不用写代码、不用部署
锁定了什么:**全部。** 这套流程不以代码形式存在,迁走等于从头做一遍。
计价:按订阅,不按用量。

把四种放在一起看

你写的量 循环是谁的 迁走要重写什么 追踪谁来做
从零搭 最多 你的 几乎不用重写 你自己
轻量框架 中 框架的 agent 的建法与跑法 框架带
图框架 中 框架的 整套状态流转 框架生态带
不写代码的平台 最少 平台的 全部 平台带

图说:注意第三列和第一列是反着走的 ——
你写得越少,迁走时要重写的越多。这就是"锁定"这笔账的全貌。

第 5 步:那两个工具要不要搬出去

如果"查天气"这个工具只有这一个助手在用:
→ 留在代码里。搬出去要多养一个进程、多处理三种网络故障、
还要加认证授权和输入校验 —— 纯开销。

如果公司里另外三个团队也要查天气,而且各用各的框架:
→ 搬出去做成一个 MCP 服务器。写一遍,四个团队共用,改一次全都变。

图说:分界线就是"跨不跨项目、跨不跨团队"这一条。
和框架层数无关 —— 上面四层里的任何一层都可以接同一个 MCP 服务器。

9. 作者的判断与证据

说法它是什么
三层抽象的划分是事实描述,和市场现状一致
不写代码的那层「按订阅收费而非按用量」是事实描述
五种情形该选哪层作者的经验归纳,没有数据。 但每一条都给了理由
「每加一层抽象都遮蔽行为、让调试更难」作者的判断,没有实验。 但它是这一章的骨架
「每加一个依赖都扩大你的安全攻击面」是事实,而且是全书唯一一次提到安全
「框架锁定会随时间复利」作者的判断,没有量化。 「复利」这个说法是修辞,但描述的机制成立
「图框架的状态管理很难迁走」「轻量那家锁定更少」作者的判断,没有对照。 两家的抽象厚度确实不同
状态 / 节点 / 边三件是那个框架的实现事实
「边定义合法转移,防止未定义状态和无限循环」是机制事实
「图画出来就是 ReAct」书自己点破的,而且这是全书最好的一次前后呼应
把 agent 包装成工具是那套 SDK 的实现事实
「每一次交接都是一次完整的模型调用」是机制事实,而且是这个模式最硬的代价
「主持人把对话记录传给每个子 agent」和 SDK 源码里的说明对不上——见第 6 节那个判断块
正文写 @tool、代码写 @function_tool书自相矛盾。 源码里只有后者
MCP 三件(客户端 / 服务器 / 协议)是事实描述,但只讲了骨架——协议实际规定的东西比这多
「像 HTTP 之于浏览器」是比方,用来说明「统一接口」这件事,不宜细究
MCP 的两条代价是事实描述,而且安全那条讲得比多数材料实在
「只有工具要复用或跨框架时才划得来」作者的判断,没有数据。 但和前面「别过早上抽象」是同一条原则

10. 边界与局限

  • 没有一处量化。 这一章通篇在谈代价,却没有一个数字—— 抽象层遮蔽了多少、锁定要花多少人天迁走、协议的开销是几毫秒,一律没有;
  • 不写代码的那一层书里没有配方。 书自己说了「本书不覆盖」, 所以第 1 层的判断全部来自作者的经验,没有例子支撑;
  • 图框架那一节只给了状态、节点、边三件。 而真实用它的时候会撞上的东西 (状态怎么持久化、跑到一半崩了怎么恢复、多个 agent 怎么共用一份状态) 书都提了一句名字,没有展开;
  • MCP 那一节的代码依赖一个外部的浏览器控制服务器,而书自己加了一条警告: 它在某些系统上跑不顺,可能要换系统13——这说明那一节的例子不是随手能跑通的;
  • 书没有讲怎么从框架退回去。 它说了锁定会复利、说了迁走要重写, 但没有一句关于「怎么在一开始就把边界划好,让以后退得回来」;
  • 书正文和代码有一处对不上(装饰器的名字),而这类错误照抄会直接报错;
  • 多 agent 那一节的成本没有实测。 「线性累加」是推理, 一次议价到底要多少次模型调用、多少钱,书一个数都没给。

11. 可带走的

  1. 框架的选择是三层:不写代码的平台、代码优先的框架、从零搭。 越往上越省事,越往下越可控;
  2. 不写代码的那层通常按订阅收费,不按用量——这和其余两层的账完全不同;
  3. 五种情形里最该记的两条: 团队经验中低就用框架 (「只有团队经验很足、并且已经清楚 agent 该长什么样时,才从零搭」); 要扛几千到几百万用户就减依赖(依赖越少,能坏的部件越少);
  4. 全书关于框架最硬的两句:每加一层抽象都遮蔽行为、让调试更难; 每加一个依赖都扩大你的攻击面;
  5. 锁定会随时间复利——增长的不是 agent 的个数,是依赖它的东西的种类;
  6. 对照第 09 章:换存放向量的库很便宜(不必重算那些数),换框架很贵(要重写整套结构)。 这两处不对称就是「方向不可逆」的两个端点;
  7. 状态图 = 状态(现在到哪了)+ 节点(干活的函数)+ 边(下一步允许去哪)。 画出来正好就是第 13 章那个循环:两个节点 + 一条条件边;
  8. 它换来的是「显式」: 执行路径能画出来、走过哪条看得见、 不合法的转移根本连不出边,所以死循环是结构性地被挡住的;
  9. 固定顺序、没有分支、不需要共享状态的流程,别上图框架——纯增复杂度;
  10. 多个 agent 协作最省的手法是把 agent 本身包装成工具: 每个只暴露「进文本、出文本」,所以可互换、可单独测;
  11. 它的硬代价:每一次交接都是一次完整的模型调用,多轮对话成本线性累加。 延迟关键时别用;简单的任务委派直接调函数或用选路更划算;
  12. MCP 是把「模型和工具怎么打交道」标准化的那套约定,三件:客户端、服务器、协议。 它解决的是「同一个工具换个框架要重写一遍」;
  13. 它的两条代价:服务器是独立进程,要部署、要监控、要处理连不上/超时/返回畸形; 而且它接受网络请求,认证、授权、输入校验一样不能少;
  14. 分界线一句话:工具要跨项目跨团队复用才划算;单一用途的 agent 上它就是纯开销。

12. 原文地图

主题原书章原文位置
三层抽象与各自适用面第 8 章 · 配方 8.3(选框架)text/17-fm-solution.txt:16(搜「No-code (extremely high abstraction)」) · text/17-fm-solution.txt:22(搜「Pricing is typically subscription based」) · text/17-fm-solution.txt:38(搜「own the full stack」)
「不推荐具体框架,只给标准」第 8 章 · 配方 8.3text/17-fm-solution.txt:90(搜「does not recommend specific frameworks」)
五种情形对照第 8 章 · 配方 8.3text/17-fm-solution.txt:42(搜「Choosing an agentic framework」) · text/17-fm-solution.txt:62(搜「only if the team is highly experienced」) · text/17-fm-solution.txt:70(搜「Fewer dependencies typically mean less maintenance」)
三层各自的取舍第 8 章 · 配方 8.3text/18-fm-discussion.txt:3(搜「maximizes transparency and debugging」) · text/18-fm-discussion.txt:7(搜「manage state through graph structures」)
避开重型框架、抽象遮蔽行为、依赖扩大攻击面第 8 章 · 配方 8.3text/18-fm-discussion.txt:11(搜「expands your security attack surface」)
锁定会随时间复利第 8 章 · 配方 8.3text/18-fm-discussion.txt:13(搜「Framework lock-in compounds over time」)
状态 / 节点 / 边第 8 章 · 配方 8.8(图框架)text/31-fm-solution.txt:5(搜「state tracks the conversation, nodes perform actions」) · text/32-fm-discussion.txt:3(搜「control flow as a graph」)
图画出来就是 ReAct第 8 章 · 配方 8.8text/32-fm-discussion.txt:17(搜「Figure 8-27 shows the ReAct pattern」)
显式的状态与合法转移第 8 章 · 配方 8.8text/32-fm-discussion.txt:21(搜「preventing undefined states or infinite loops」)
什么时候别用图、以及它的耦合代价第 8 章 · 配方 8.8text/32-fm-discussion.txt:29(搜「Avoid LangGraph for simple linear workflows」) · text/32-fm-discussion.txt:31(搜「Migrating means」)
装饰器与那处矛盾第 8 章 · 配方 8.6(议价 agent)text/26-fm-solution.txt:67(搜「add the @tool decorator」) · text/26-fm-solution.txt:74(搜「@function_tool」) · text/27-fm-discussion.txt:3(搜「@function_tool decorator converts a function」)
把 agent 包装成工具第 8 章 · 配方 8.6text/26-fm-solution.txt:205(搜「customer_agent.as_tool」) · text/27-fm-discussion.txt:10(搜「wraps agents as tools that other agents can invoke」)
议价那个场景第 8 章 · 配方 8.6text/26-fm-solution.txt:137(搜「15 laptops for no more than」)
每次交接都是一次完整调用第 8 章 · 配方 8.6text/27-fm-discussion.txt:14(搜「Each agent hand-off requires a full LLM call」)
MCP 解决什么、三件是什么第 8 章 · MCP 那一节text/29-fm-discussion.txt:3(搜「Like HTTP for browsers」) · text/29-fm-discussion.txt:5(搜「MCP has three components」)
什么时候值得、什么时候是纯开销第 8 章 · MCP 那一节text/29-fm-discussion.txt:9(搜「building tools to share across projects or teams」) · text/29-fm-discussion.txt:11(搜「Avoid MCP for simple single-purpose agents」)
两条代价第 8 章 · MCP 那一节text/29-fm-discussion.txt:13(搜「requiring deployment, monitoring」) · text/29-fm-discussion.txt:15(搜「authentication, authorization, and input validation」)
那条跑不顺的警告第 8 章 · MCP 那一节text/28-fm-solution.txt:7(搜「don't run smoothly on Windows」)

Footnotes

  1. 出处:第 8 章 · 配方 8.3 的解决段,三层的表格从第 16 段起(text/17-fm-solution.txt:16,搜「No-code (extremely high abstraction)」);订阅计价那句见第 22 段(text/17-fm-solution.txt:22,搜「Pricing is typically subscription based」);从零搭那一层见第 38 段(text/17-fm-solution.txt:38,搜「own the full stack」);「不推荐具体框架」见第 90 段(text/17-fm-solution.txt:90,搜「does not recommend specific frameworks」)。说明:原书第 8 章每个配方的解决段与讨论段在我们的清洗文本里各是一个独立文件,所以这一章的每条出处都额外标了配方号。 2

  2. 出处:同一解决段第 42 段起的表 8-2(text/17-fm-solution.txt:42,搜「Choosing an agentic framework」);「只有团队经验很足才从零搭」见第 62 段(text/17-fm-solution.txt:62,搜「only if the team is highly experienced」);「依赖越少越省事」见第 70 段(text/17-fm-solution.txt:70,搜「Fewer dependencies typically mean less maintenance」);追踪那一行见第 88 段(text/17-fm-solution.txt:88,搜「tracing view on the OpenAI website」)。

  3. 出处:第 8 章 · 配方 8.3 的讨论段第 11 段(text/18-fm-discussion.txt:11,搜「expands your security attack surface」)与第 13 段(text/18-fm-discussion.txt:13,搜「Framework lock-in compounds over time」)。三层各自的取舍见同段第 3 段(text/18-fm-discussion.txt:3,搜「maximizes transparency and debugging」)与第 7 段(text/18-fm-discussion.txt:7,搜「manage state through graph structures」)。 2

  4. 出处:第 8 章 · 配方 8.8 的解决段第 5 段(text/31-fm-solution.txt:5,搜「state tracks the conversation, nodes perform actions」)与讨论段第 3 段(text/32-fm-discussion.txt:3,搜「control flow as a graph」)。书那个跑例的状态里装的就是一路累积的对话记录,见解决段第 11 段(text/31-fm-solution.txt:11,搜「stores the ongoing conversation history」)。

  5. 出处:第 8 章 · 配方 8.8 的讨论段第 21 段(text/32-fm-discussion.txt:21,搜「preventing undefined states or infinite loops」)、第 23 段(text/32-fm-discussion.txt:23,搜「graph visualization shows possible execution paths」)、第 29 段(text/32-fm-discussion.txt:29,搜「Avoid LangGraph for simple linear workflows」)与第 31 段(text/32-fm-discussion.txt:31,搜「Migrating means」)。「这张图画的就是 ReAct」见第 17 段(text/32-fm-discussion.txt:17,搜「Figure 8-27 shows the ReAct pattern」)。 2 3 4

  6. 出处:第 8 章 · 配方 8.6 的讨论段第 10 段(text/27-fm-discussion.txt:10,搜「wraps agents as tools that other agents can invoke」)与第 14 段(text/27-fm-discussion.txt:14,搜「Each agent hand-off requires a full LLM call」)。代码里那两行包装见解决段第 205 段(text/26-fm-solution.txt:205,搜「customer_agent.as_tool」)。 2 3

  7. 出处:第 8 章 · 配方 8.6 的解决段第 67 段(text/26-fm-solution.txt:67,搜「add the @tool decorator」)——正文写的是 @tool;紧接着的代码见第 74 段(text/26-fm-solution.txt:74,搜「@function_tool」)——写的是 @function_tool;讨论段第 3 段(text/27-fm-discussion.txt:3,搜「@function_tool decorator converts a function」)写的也是后者。装饰器是什么,书自己在第 70 段解释过(text/26-fm-solution.txt:69,搜「A decorator in Python is a special type of function」)。补充(不在书里,依据我们的 frontier 书架):那套 SDK 的源码里定义的名字是 function_tool。依据: shelf=ai-frontier-reference/openai-agents-python@src:src/agents/tool.py:2458 事实=源码里有 def function_tool( 的定义,没有名为 tool 的装饰器。 2

  8. 出处:第 8 章 · 配方 8.6 的解决段第 137 段起(text/26-fm-solution.txt:137,搜「15 laptops for no more than」)。原文给的条件是:客户要 15 台笔记本、每台不超过 950 欧元,零售价 1 299 欧元,销售给 12% 折扣,客户说别家能给 1 000 欧元,对话到此为止。1 143 欧元这个折后价是我们算的,书没有给。 主持人的流程写在提示词里,见第 225 段(text/26-fm-solution.txt:225,搜「Receive email history with the last message from customer」)。

  9. 出处:第 8 章 · 配方 8.6 的讨论段第 12 段(text/27-fm-discussion.txt:12,搜「The moderator passes conversation history to each sub-agent」)。补充(不在书里,依据我们的 frontier 书架):把 agent 变成工具的那个方法,源码里的说明明确把它和「交接」区分开。依据: shelf=ai-frontier-reference/openai-agents-python@src:src/agents/agent.py:608 事实=as_tool 的文档注释写着「This is different from handoffs in two ways: 1. In handoffs, the new agent receives the conversation history. In this tool, the new agent receives generated input.」

  10. 出处:第 8 章 · MCP 那一节的讨论段第 3 段(text/29-fm-discussion.txt:3,搜「Like HTTP for browsers」)与第 5 段(text/29-fm-discussion.txt:5,搜「MCP has three components」)。说明:这一节的标题在我们的清洗文本里整个丢失了(它夹在上一节的延伸阅读位置上),所以只能写成「第 8 章 · MCP 那一节」。 MCP 是 Model Context Protocol 的缩写,书里给了全称。 2 3

  11. 补充(不在书里,依据我们的协议书架):这套协议的规范本身规定的东西比书讲的三件多。依据: shelf=ai-protocol-reference/mcp-spec#03-server-primitives.md 事实=我们对规范的拆解里写明服务器提供三类基本件——Tools(给模型调的工具)、Resources(给模型读的资料)、Prompts(给用户点的快捷指令),分别由模型、应用和用户控制。传输方式见 shelf=ai-protocol-reference/mcp-spec#05-transports.md 事实=规范定义两种传输:把服务器当子进程启动、走标准输入输出的 stdio,以及走 HTTP 请求的 Streamable HTTP。

  12. 出处:第 8 章 · MCP 那一节的讨论段第 9 段(text/29-fm-discussion.txt:9,搜「building tools to share across projects or teams」)、第 11 段(text/29-fm-discussion.txt:11,搜「Avoid MCP for simple single-purpose agents」)、第 13 段(text/29-fm-discussion.txt:13,搜「requiring deployment, monitoring」)与第 15 段(text/29-fm-discussion.txt:15,搜「authentication, authorization, and input validation」)。 2

  13. 出处:第 8 章 · MCP 那一节的解决段第 7 段(text/28-fm-solution.txt:7,搜「don't run smoothly on Windows」)。原文说某些 MCP 服务器在 Windows 上、尤其是在交互式笔记本里跑不顺,报错太多的话可能要换到 Linux。