Learning LangChain — 本课题摘录
读了哪几章: 第 6 章(agent 架构)、第 7 章(agent 进阶)。 全书十一章,其余本轮没读。
这本书对本课题的价值集中在两个定义上,而且这两个定义比前面所有材料都更准。
它对本课题回答了什么
最准的一句定性:唯一的区别是模型控制停止条件
它的原话大意:循环人人都写过——同一段代码反复跑,直到撞上一个停止条件。
agent 架构的关键,是让模型来控制那个停止条件,也就是由它决定什么时候不再转。 (依据:书 · Learning LangChain (for True Epub) §Chapter —— 书指出 agent 架构与其它架构的唯一区别是「模型驱动的循环」——循环就是同一段代码反复跑直到撞上停止条件,关键在于让 LLM 来控制那个停止条件、由它决定什么时候停止循环)
这句话应该原样进讲义,而且应该放在最前面。
本课题的四个决定里,第四个("什么时候停")到这里被提升成了定义本身: 不是"agent 有一个停止条件",而是"停止条件由模型定"才叫 agent。
反过来说:如果停止条件是我们写死的(跑三轮就停),那它就退化成一条流水线,不是 agent。 这条判据很锋利,可以用来检查我们自己的原型有没有跑偏。
第二个定义:"行动"这个词拆开有三层
| 层 | 说的是 |
|---|---|
| 要有决定做什么的能力 | — |
| 要有不止一个可选项 | 没有选项的决定不算决定 |
| 要拿得到外部环境的信息 | 否则无从决定 |
所以一个有能动性的应用,就是用模型从多个可选动作里挑一个,依据是关于当前世界状态或期望状态的一些上下文。 (依据:书 · Learning LangChain (for True Epub) §Chapter —— 书 把「act」拆成三层——要有决定做什么的能力、要有不止一个可选项(没有选项的决定不算决定)、要能拿到外部环境的信息;由此定义 agentic 应用为「用 LLM 从多个可选动作里挑一个」)
中间那条"没有选项的决定不算决定"是一条可用的检查: 如果我们的最小原型只有一个工具,那它其实没在做决定,只是在决定"调不调"。 这也解释了为什么最小可用的工具数是二,不是一。
它把这个架构拆成两种提示技术的组合:工具调用(把可选动作列进提示并规定输出格式)与链式思考(把复杂问题拆成有序小步)。
并指出:较新的模型已经为这两件事做过微调,不再需要在提示里专门交代。
这跟 hands-on 那本的"约束采样"、oh-my-pi 的"方言层"是同一件事的三个角度: 格式这件事正在从提示词往模型权重和接口里下沉。
一条早期做法,今天仍然有用
它演示了用停止序列保证模型一次只产出一个动作——换行符一到就停。
于是模型没机会一口气编出后面几步。 (依据:书 · Learning LangChain (for True Epub) §Chapter —— 早期做法用换行符作为 stop sequence,让 LLM 一次只产出一个动作;示例中输出被截在第一条 CSV 行「search,30th president of the United States」处)
这跟 deepanalyze 的"停在代码收尾标签"、tongyi 的"切掉工具结果标签之后的内容"完全同源。 三份材料撞在一起,说明这是自定义格式方案的必修一课,而不是某一家的技巧。
两个扩展,以及它们各自的适用条件
| 扩展 | 收益 | 它自己给的适用条件 |
|---|---|---|
| 强制某个工具永远第一个调 | 省掉一次模型调用(降延迟);防止模型误判为不需要调它 | 只在确实存在"永远该先调它"这条规则时才该加;没有这条规则还硬加,应用会变差 |
| 工具太多时先过一个"选工具"节点 | 进循环前先把工具集缩小 | 工具多到模型选不准时 |
(依据:书 · Learning LangChain (for True Epub) §Chapter —— 强制某工具先调的两条收益是省掉一次 LLM 调用降低延迟、以及防止模型对某些查询错误地判断为不需要调它;但书明确写道:若应用没有「永远该先调这个工具」这类清晰规则,加这个约束反而会让应用变差)
第一行右边那一栏才是重点。 前面读的材料里,"强制某个工具"这件事出现过三次 (beeai 的强制开关、cline 的必调工具、kun 的软必调),但没有一家写下"什么时候不该用它"。
这条提醒对我们有用:每一个"约束模型"的机制都在拿灵活性换确定性, 只有当那份确定性确实存在(你真的知道该先调谁)时,这笔交换才划算。
第二个扩展跟 cherry-studio 的"折叠成元工具"、qwen-code 的"按需披露"是同一族,但更朴素:先检索出相关工具,再进循环。
决定四的一个变体:反思是一个两点之间的回路
反思是在"生成"与"批评"两个提示之间建一个回路。书里让它固定转 N 次,并指出另一种做法是让批评方自己决定什么时候结束。 (依据:书 · Learning LangChain (for True Epub) §Chapter —— 反思被实现为 generate 与 reflect 两个节点之间的回路,书里固定转 N 次,并指出一种变体是让 reflect 节点自己决定什么时候结束)
"让批评方决定什么时候结束"这个变体正好呼应第 6 章那句定性: 停止条件交给谁,决定了这个回路是不是 agent。 固定转 N 次的反思是流水线;让批评方决定的反思才是 agent。
它还提了拆成多 agent 的三个信号:工具太多以致选不准、上下文复杂到单个 agent 跟不住、某个领域需要专门的子系统。
这三条是"什么时候该越过本课题的边界"的判据。 记下来,但本轮不追。
它没回答什么
- 循环的工程细节——轮数上限、连错熔断、打转检测、超时,这两章一句没讲。
- 结果怎么回填、并发怎么处理——都被框架吸收了,书里看不到。
- 上下文压缩——留给了别的章。
坑与代价
- 它是一本框架书。 第 6 章之后的代码全是那个框架的写法,剥掉框架名之后剩下的是那两个定义和几条判据。
- "让模型控制停止条件"这条定性很锋利,但它没配任何护栏。 模型控制停止条件的代价就是它可能永远不停——
前面 kun 的四类打断、mirothinker 的连续回滚上限、hermes 的十三种出口,全是在给这条定性打补丁。
判断(无锚): 这两句应该在讲义里连着出现:先立"停止条件归模型",再立"所以必须有一层不归模型的兜底"。 只讲前半句会教出一个跑不完的循环;只讲后半句会教出一条流水线。 如果错,会错在: 如果任务本身有硬性的外部终止信号(测试跑通、编译成功),那兜底层可以就是那个信号,不必额外设计。