第 21 课:从 Prompt 到 Agent

前三部分我们把一个模型"训练好、调好、发出去、评明白"了——但它始终只会做一件事:接到一段输入,吐出一段输出。这一课换一个问题:一次问答怎么变成循环?一个能自己跑起来的循环必须有哪些零件?为什么"多轮对话"不等于 Agent?为什么每步 95% 正确、十步之后却只有约六成能全对?这一课把 Agent 的四件套、错误累积的数学、ReAct(推理与行动交错,边做边拿外部结果纠错)的"边想边做"算清,最后回答一个最容易被忽略的问题:什么时候根本不该用 Agent。

🎯 学完这 6 步你将能够:
① 说清一次问答与一次任务的结构差异,并算出多步循环的输入量为什么二次增长
② 用「模型 / 工具 / 状态 / 终止条件」四件套检查任何一个 Agent,并算出缺了终止条件的代价
③ 用 p^N 算出错误累积、用 ReAct 的「边想边做」解释怎么把它拦回来,并判断一个需求该用 workflow 还是 Agent
🗺 本节推理链(6 步逻辑递进:从"一次调用"到"该不该用 Agent")
1要让模型完成一个任务而不只是给出一句回答,这就要求先看清两者的结构差:一次问答只有一次调用、一个 token 流;任务却要"做了再看、看了再做"。任务天然是多步的。
↓
2既然「任务天然是多步的」,所以必须有一个循环把每步结果带回来——这就要求循环里齐全四件东西:谁决策(模型)、谁能改变世界(工具)、结果放哪(context 里的状态)、什么时候停(终止条件)。四件套缺一不可。
↓
3既然「四件套缺一不可」,所以要看清"多轮对话"缺的是哪一件——它只是不断追加 token,没有工具去改变世界、也没有外部观察回来。多轮对话没有"动作"这一环。
↓
4既然「多轮对话没有"动作"这一环」划出了真正的 Agent,所以接下来必须正视这个"真正的多步循环"独有的风险——每步 95% 正确,十步连乘只剩 60%;错误还会写进 context,被后面每一步继承并放大。错误会沿步数累积。
↓
5既然「错误会沿步数累积」,所以需要一种把外部观察插进推理的做法——ReAct 让模型"想一步、做一步、看 token 回来的观察再想",用真实反馈打断错误传播。想一步做一步。
↓
6既然「想一步做一步」要付出延迟与 token 成本,这就要求把选择摆开:步骤能提前写死就用 workflow、写不死但可验证才用 Agent;能用一次调用解决就别开循环。先问能不能不用 Agent。
Agent 循环工具调用状态管理终止条件错误累积ReAct
1
一次问答和"完成一个任务",到底差在哪?
提示:数两件事——一次问答里模型"改变过世界的任何东西"吗?一次任务要经过几步、每一步又怎么知道上一步做没做对?
▾
知识背景
前三部分我们一直在优化一个函数:给定一段输入,输出一段文本——一次调用、无状态、无副作用。而「Agent」这个词在工程上是有明确定义的:Anthropic 的《Building Effective Agents》(Schluntz & Zhang,2024-12-19)把"模型 + 工具"系统分成两类——workflow(由代码预先编排好每一步)与 Agent(由模型自己决定下一步、并依据环境反馈行动)。这一张先讲清:为什么"完成任务"天然逼出一个循环。

先回顾一下我们手上的东西:前三部分训练、微调、部署、评测的那个模型,本质是"一次输入、一次输出"。它不会自己再问一句、也不会去动任何外部系统。

因为一次问答是"封闭"的:模型只看当前这段输入,答完就结束,世界没有任何变化。而一个任务("帮我把这批客诉工单按严重度分好并回复")往往要经过好几步、每步都要看上一步的结果才能决定下一步——就像"点一次外卖"和"做一桌菜":前者一个动作,后者要买菜、下锅、尝味、补救,中间任何一步都要根据现场情况调整。所以下面用一笔账,把"多步"这个结构带来的第一个后果算出来。

更早、更自然的做法是「把要求一次全写进一段提示,让模型一口气输出完整结果」。但一次调用没有任何中间反馈:只要 10 个字段里有一个填错,整段结果就得整份重来——设单字段正确率 0.95,一次全对只有 0.95¹⁰ ≈ 0.599。循环把「一次全对」拆成「每步可检查」,错的那一步可以单独重来,不必推倒重来。

🧮 第一笔账:从"一次调用"到"一个循环"
Step 1:一次问答 = 一次调用
项数值
模型调用次数1
送入的输入问题本身 ≈ 200 token
总输入量200 token
算术:一次问答只发生一次调用,输入就是问题本身(约 200 token)。模型读完就直接产出答案,没有"看结果、再决定"的机会。
Step 2:多步任务会把历史一次次重发
步 k该步送进模型的输入累计
第 1 步200200
第 2 步200 × 2 = 400600
………
第 10 步200 × 10 = 2,00011,000
算术:循环每走一步,都要把"到目前为止的全部历史"重新送进模型(第 k 步的输入正比于 k)。10 步的总输入 = 200 × (1+2+…+10) = 200 × 55 = 11,000 token——单次问答的 55 倍。增长不是线性的:总输入 ∝ N(N+1)/2,是步数的平方。
Step 3:步数再翻一倍,成本翻几倍
步数 N总输入(200 token/步)相对单次问答
10200 × 55 = 11,00055×
20200 × 210 = 42,000210×
算术:步数从 10 翻到 20(×2),总输入从 11,000 涨到 42,000(≈ ×3.8)——因为 1+…+20 = 210 ≈ 55 × 3.8。这就是"多步"的第一个硬后果:成本和延迟随步数平方增长。(注:若命中 prompt caching,重发的前缀单价会下降,但计费的 token 计数不变。)
🎯 关键认知

一次问答是函数调用:输入→输出,结束。一次任务是一个循环:做一步 → 看结果 → 再决定。这两者不是"复杂度不同",而是结构不同——循环带来了状态、带来了外部动作,也带来了随步数平方增长的成本(命中 prompt caching 可降前缀单价,但 token 计数不变)。后面五张卡片都在处理这个循环带来的新问题。

AI 助教
👋 对"问答 vs 任务"有疑问?比如「为什么总输入是平方增长」「多步一定要重发历史吗」?

告诉我你的任务大概几步、每步多少 token,我帮你估算成本。
2
一个能自己跑起来的循环,少了哪一样都会转不动?
提示:把循环从头到尾摊开,逐段问它"靠什么才能继续下去"——尤其问一句:它凭什么知道该停?
▾
知识背景
上一张卡片把"任务"逼成了一个循环。工程上,一个能自主运行的 Agent 被拆成四件东西:模型(做决策)、工具(唯一能改变世界的接口)、状态(把历史与观察存进上下文,即 context)、终止条件(决定何时停)。ReAct(Yao 等,arXiv:2210.03629)正是把"推理"与"行动"交错起来的早期范式;而各家工程指南反复强调的一点是:工具接口的设计,比提示词更值得投入。

上一张卡片我们看到一次问答只有一次调用;一旦要跑多步,就必须有一个循环,把每一步的结果带回给模型。这一张把这个循环拆开,看它由哪几件东西组成。

因为循环要能持续运转,四件事缺一不可:谁决定下一步(模型)、谁能真的改变世界(工具)、上一轮发生了什么放在哪里(状态)、以及什么时候该停(终止条件)。好比一台自动售货机:选货、出货、找零、复位,少任何一环都会卡住——尤其"复位"(终止)最容易被忽视。所以下面重点算一笔"缺了终止条件"的账。

更笨的做法是「只写语义终止条件、不设步数上限」,赌模型自己会判断「已完成」。若每步判断已完成的概率只有 1%,期望步数 E ≈ 1 ÷ 0.01 = 100 步;而每步都要重发全部历史(第 1 张卡片口径),100 步累计输入约 1,010,000 token(量级示意)。没有步数上限,就等于把成本交给运气。

🧮 第二笔账:四件套里最容易漏的那一件
Step 1:终止条件为什么不能省
件作用缺了会怎样
模型决定下一步做什么循环没有大脑
工具真正改变世界只能空想、答不出事实
状态记住已经做过什么每步从零开始、反复做同一件事
终止条件决定何时停可能永远停不下来
算术直觉:假设每一步"判断任务已完成并停下"的概率只有 1%(人为设定的下限示例,并假设每步停下概率恒定),那么循环期望要走的步数 E ≈ 1 ÷ p = 1 ÷ 0.01 = 100 步。没有上限,就等于把成本交给了运气。
Step 2:补一个步数上限就把尾巴截断
项无上限加"最多 20 步"
步数期望 100 步≤ 20 步
总输入(200 token/步、重发历史,同第 1 张卡片口径)200×(1+…+100) ≈ 1,010,000200×(1+…+20) = 42,000
算术:这里沿用第 1 张卡片的口径——每步把所有历史重发,所以 N 步总输入 = 200×N(N+1)/2(不是 200×N)。把"期望 100 步"直接代入求和(作量级示意),无上限时约 1,010,000 token;口径提醒:若严格按几何分布算期望 E[N(N+1)/2],无上限时的期望总输入会更大(约 2,000,000 token 量级),所以 1,010,000 是偏保守的下界示意。加"最多 20 步"硬上限后最坏 42,000 token(约 1/24)。终止条件=两条:任务完成的语义判据 + 一个兜底的步数/时间上限。只写前者,等于没有刹车。
Step 3:四件套齐了,循环才闭合
回合模型工具状态终止
1决定"查库存"调用查询接口写下查询结果未完成,继续
2决定"下单"调用下单接口写下订单号未完成,继续
3判断目标达成不再调用收尾满足终止,结束
算术:一个闭合循环 = "决策 → 动作 → 观察 → 判断"重复执行。注意工具是唯一能改变世界的接口——没有它,模型再会推理,也只是一个在上下文里自言自语的多轮对话(这正是下一张卡片要区分的事)。
🎯 关键认知

审查任何一个 Agent,只要问四个问题:① 谁在决策?② 它能不能改变世界(工具)?③ 过去发生过什么放在哪(状态)?④ 它凭什么停? 四个里最常被漏的是第四件——很多"跑飞了"的 Agent 不是不够聪明,而是没有终止条件。

AI 助教
👋 对 Agent 四件套有疑问?比如「状态该放上下文还是外部」「终止条件怎么写才不跑飞」?

描述你的场景,我帮你把四件套逐件对照检查。
3
多轮对话也是"模型一轮轮往下接",它和 Agent 的分界线到底在哪?
提示:看每一轮之后"世界有没有被改变"——有没有工具被调用、有没有外部结果真的回到上下文里。
▾
知识背景
「多轮对话」和「Agent」都能"一轮轮往下接",所以常被混为一谈。工程上的分界线很清楚:Agent 的每一轮里,模型可以调用工具去改变外部状态,并把外部返回的观察重新放进上下文;而多轮对话只是把用户与助手的话不断追加进上下文,世界没有任何变化。另一条现实约束:对话历史全部塞在上下文里,而上下文是有限的——轨迹一长,状态就必须外置。

上一张卡片说,循环里必须有一件"能改变世界的工具"。这一张就用这条线,把最容易混淆的两个东西分开。

因为多轮对话的每一轮都只是"追加一段文字",它没有动作、也没有观察——你问十句,世界一句都没变。就像打电话咨询(只动嘴,账户没变)和真的去柜台办业务(会改变账户状态)的区别。所以判断标准不是"轮数多少",而是"这一轮有没有工具调用、世界有没有被改变",再用一笔轨迹长度的账说明为什么 Agent 必须把状态外置。

更省事的做法是「把 Agent 的历史全部堆在上下文里,只追加不整理」。但 Agent 每步的轨迹(推理 + 观察)约 2,000 token,10 步就累积 20,000 token,早已超过 8k 窗口——所以状态不能只靠上下文,必须能外置。

🧮 第三笔账:多轮对话 vs Agent 的判据
Step 1:用"工具调用次数"当判据
任务工具调用次数世界状态改变次数是多轮对话还是 Agent
咨询"退票规则是什么"00多轮对话
"帮我把这张票退掉"3(查询/下单/确认)2Agent
算术:判据一眼可见——咨询类 0 次工具调用、世界不变;退票类需要 3 次工具调用、2 次真实的状态改变。有没有"动作 + 观察"这一环,才是多轮对话与 Agent 的分水岭。
Step 2:轨迹一长,状态就装不进上下文
项数值
步数10
每步轨迹(推理 + 观察,示意)≈ 2,000 token
轨迹总长10 × 2,000 = 20,000 token
以 8K 小窗口模型为例8,000 token
算术:10 步就累积 20,000 token 的轨迹——在 8K 小窗口的模型上早已放不下(注意:现代模型窗口已到 200K–1M+,这里只以小窗口模型为例说明"轨迹会超过窗口")。所以 Agent 的状态必须能"外置"(写进文件、数据库、或做摘要压缩),而不能像多轮对话那样只依赖上下文。
Step 3:把"状态放哪"的两种做法对比
做法状态载体能撑多长风险
多轮对话仅上下文受上下文上限约束超长即丢历史
Agent上下文 + 外部存储理论上可长跑要自己管读写与一致性
算术:这就是 Agent 比多轮对话"贵"和"难"的第二处——它多了一份状态管理的工程量。多轮对话的上限是上下文长度;Agent 的上限变成了"你怎么设计外部状态"。
🎯 关键认知

区分多轮对话与 Agent,不看轮数、只看两件事:这一轮有没有工具调用(动作),有没有外部观察回来(反馈)。没有这两样,再多轮也只是"聊得更久";有了这两样,你就必须承担状态外置与一致性管理的工程成本。

AI 助教
👋 对"多轮对话 vs Agent"有疑问?比如「我的客服机器人算 Agent 吗」「状态该存哪」?

说清你的系统有没有工具调用,我帮你判断它处在哪一档。
4
如果每一步都有 95% 是对的,为什么一个 10 步的任务经常做不完?
提示:任务要求的是"每一步都对"——在概率上,该用哪种运算把每步的正确率合起来?
▾
知识背景
单步正确率很高,并不等于多步任务能做成——这是 Agent 最反直觉的一点,也是各家工程指南反复警告的 error compounding(错误累积)。原因很朴素:多步任务要求每一步都对,而独立事件同时发生的概率是相乘的。前面的错误还会写进上下文(context,即模型每一步能看到的全部文本),被后面每一步当作"既成事实"继承。下面的连乘默认各步相互独立;若错误彼此相关(Agent 的步间错误常同源),实际全对率会更极端。

上一张卡片把"多轮对话"和"Agent"分开了。一旦进入真正的多步循环,一个反直觉的问题立刻出现:单步看起来都不错,为什么整体经常失败?

因为任务要求的是"每一步都对",而这是把每步的正确率连乘起来——步数越多,乘积掉得越快。就像多米诺骨牌:每一块倒错的概率只有 5%,但十块之后整体还站着的概率只剩六成。所以下面把这条"错误累积曲线"算出来。

更自然的想法是「单步错一点、平均一下就没事」。但任务要求的是「每一步都对」,独立事件的联合概率是相乘而不是取平均:0.95¹⁰ ≈ 0.599,而不是 95%。这就是为什么「单步 95%」听起来很高,十步之后却只剩约六成能全对、约四成会翻车。

🧮 第四笔账:错误是怎么沿步数累积的
Step 1:单步 95%,十步全对只剩六成
步数 N全对概率 = 0.95^N直观
10.9595%
100.599约 60%
200.359约 36%
500.077约 7.7%
算术:0.95¹⁰ ≈ 0.599——十步全对只有 60%;到 20 步掉到 36%;50 步只剩 7.7%。单步看起来很稳,整体却像在赌。这就是为什么"每步 95% 分"的 Agent 在长任务上经常失败。
Step 2:单步再提高一点,长任务也能救回来
单步正确率10 步全对20 步全对
0.950.5990.359
0.990.9040.818
算术:把单步从 0.95 提到 0.99,10 步全对从 0.599 升到 0.904——从"六成"变成"九成"。结论:提升单步可靠性的收益,在长任务上被步数放大。这也是工程上宁可少几步、也不要多几步的原因。
Step 3:错误一旦写进上下文,就被后续继承
情形第 3 步出错之后每一步
无纠错把错误结论写进上下文都在错误前提上继续 → 全盘偏
有外部校验外部结果与预期不符立刻在这一步停下重来
算术直觉:纯靠上下文推进时,第 3 步的错误会变成第 4 步的"输入",等于把 0.95 的连乘又叠了一层"错误传播"。要打断它,必须让某一步的外部结果能否定前面的判断——这正是下一张卡片 ReAct 要解决的问题。
🎯 关键认知

多步任务的成功率不是"平均一下"(95% 就不会掉太多),而是连乘:0.95¹⁰ ≈ 60%、0.95²⁰ ≈ 36%。所以设计 Agent 的第一原则是减少步数,第二原则是让每一步都有能被外部验证的机会,把错误按在原地、不让它写进上下文传给下一步。

AI 助教
👋 对错误累积有疑问?比如「我的任务要 15 步,成功率大概多少」「怎么把错误挡住」?

给出步数与单步正确率,我帮你算全对概率和止损方案。
5
既然错误会一步步累积,有没有一种"边做边纠"的做法?
提示:让模型在每一步之间"停下来看一眼外部结果",再决定下一步——把外部观察插进推理的过程中。
▾
知识背景
ReAct(Yao 等,arXiv:2210.03629,ICLR 2023)提出了一种范式:让模型交错地产生"推理轨迹(Thought)"与"动作(Act)",再把外部返回的"观察(Observation)"拼回上下文。论文报告:在 HotpotQA / Fever 上,ReAct 通过与 Wikipedia API 交互,克服了思维链(CoT)里常见的幻觉与错误传播;在两个交互决策基准上,ReAct 以绝对成功率 +34%(ALFWorld)与 +10%(WebShop) 超过模仿学习/强化学习基线,且只需 1–2 个上下文示例。

上一张卡片算出:10 步连乘会从 95% 掉到 60%,错误一旦写进上下文还会被后续继承。要挽回它,就得让每一步都能被外部结果纠正。

因为纯推理(思维链)是"闭着眼睛想完全程",中间没有东西能反驳它;而 ReAct 在每一步做了就看,让真实世界的返回结果来打断错误传播。就像开车时不断看路况微调方向,而不是蒙着眼一路踩到底。所以下面看"插入一个观察"到底能把成功率抬多少。

更早、更自然的做法是「先想完全程、再一次性输出」,也就是纯思维链(CoT,让模型先写推理再给答案)。但 CoT 在生成过程中没有任何外部信息能反驳它:第 3 步想错,第 4 步仍会当成事实继续推,错误一路带到结尾。ReAct 把「想」与「做」交错,每步用外部观察对一次账——等于把判定对错的时机从「结尾一次」提前到「每一步一次」。

🧮 第五笔账:ReAct 靠什么把错误拦住
Step 1:把"每一步都看一眼"折算成单步正确率的提升
做法等效单步正确率(示意)10 步全对
纯推理(CoT,无外部校验)0.950.599
ReAct(每步有外部观察纠错)0.990.904
算术:外部观察的作用,可以近似看成把等效单步正确率从 0.95 抬到 0.99(0.99 是纯演示参数——既非实测也非论文读数,只为演示"每步对一次账"对连乘的影响),于是 10 步全对从 0.599 升到 0.904。这就是"边想边做"的收益:不是让模型更聪明,而是让错误在写进上下文之前就被外部结果否掉(每一步的轨迹都要作为 token 重新送进模型,这也是它的成本所在)。
Step 2:论文里的实际增益
基准相对最强基线(模仿/强化学习)的绝对成功率提升
ALFWorld(交互决策)+34%
WebShop(交互决策)+10%
上下文示例数1–2 个
算术:ReAct 只用 1–2 个示例,就在 ALFWorld / WebShop 上比需要大量训练数据的模仿学习、强化学习高出 34 / 10 个百分点。说明"交错推理与行动"这个结构本身,就值这几十个点。
Step 3:一个 ReAct 回合长什么样
阶段模型输出作用
Thought"我需要先查库存"推理、给下一步定方向
Act调用查询工具改变世界 / 取外部信息
Observation"库存 3 件"真实反馈,拼回上下文
算术结构:Observe → Think → Act → 再 Observe,如此循环。关键在 Observation 是"外部"给的——它不是模型自己编的,所以能作为裁判,把上一步的推理否掉。
🎯 关键认知

ReAct 的价值不在于"让模型多写几句推理",而在于把外部观察插进循环:每个回合都拿真实反馈对一次账,错误在写进上下文之前就被拦住。这也解释了为什么 Agent 的工具设计往往比提示词更重要——没有能给出可靠观察的工具,ReAct 就退化成了又一个 CoT。

AI 助教
👋 对 ReAct 有疑问?比如「Thought/Act/Observation 具体怎么写」「它和 CoT 差多少」?

说清你的任务,我帮你拆一个 ReAct 回合。
6
什么时候该用 Agent,什么时候用"多此一举"?
提示:先问"最简单的一次调用能不能解决",再问"步骤能不能提前定好"——把最复杂的方案留到最后考虑。
▾
知识背景
Anthropic 的《Building Effective Agents》(Schluntz & Zhang,2024-12-19)给出的核心建议只有一句:找尽可能简单的方案,只在确实需要时才增加复杂度。它把"模型 + 工具"系统分成 workflow(代码预先编排好路径:提示链、路由、并行、编排-工作者、评估-优化)与 Agent(模型自己决定路径)。并明确提醒:agentic 系统(凡让模型自主决策的系统)用延迟和成本换任务表现,这个交换只在任务确实需要时才划算。

上一张卡片给了 Agent 的核心范式,但它并不便宜——延迟更高、token 更多、还可能因为错误累积而不稳定。最后一张卡片回答:什么时候值得用。

因为Agent 换来的是"灵活性"(路径不用提前写死),付出的却是"不可预测"(步数不定、成本不定、成功率随步数下降)——就像寄一个同城快递,能一步到位就别开一辆卡车跑全程。所以下面用一笔成本账,说明"能用一次调用解决就别开循环"。

🧮 第六笔账:用一次调用能解决时,开循环有多亏(token 与延迟为示意值)
Step 1:成本与延迟都被步数放大
方案输入量相对成本延迟
单次调用200 token1×≈ 1 秒
10 步 Agent11,000 token55×≥ 10 秒
算术:同一件事若一次调用就能做好,改成 10 步循环,输入量变成 55 倍、延迟从约 1 秒升到 10 秒以上,还要额外承担错误累积(0.95¹⁰ ≈ 0.6)。这不是优化,是自找麻烦。
Step 2:一张决策表定"用哪一档"
问题若"是"选它
一次调用 + 好示例能解决吗?是就一次调用
步骤能提前写死吗?是workflow(固定流程)
步骤写不死,但每步可验证吗?是Agent(循环 + 工具)
连验证都无法做吗?是先别上 Agent,补上可验证的反馈
算术化:这四问按"从简到繁"排序,命中越靠前越该用简单方案。真正适合 Agent 的只有第三档——步骤无法预定义、但每一步都能拿到可信的反馈(跑测试、查数据库、看环境状态)。
Step 3:把六张卡片串成一条决策线
卡片结论一句话
21-1任务 = 循环,成本随步数平方增长
21-2四件套:模型 / 工具 / 状态 / 终止条件
21-3有"动作 + 观察"才是 Agent
21-4成功率 = p^N,会随步数衰减
21-5ReAct:把外部观察插进循环、拦住错误
21-6能简单就别复杂,Agent 是最后的选择
算术无关的一句总结:Agent 不是"更高级的用法",而是一个有明确代价的工程选择。先证明简单方案不够用,再上循环。
🎯 关键认知

判断标准只有两条:① 步骤能不能提前写死?能 → workflow;② 步骤写不死,但每一步能不能拿到可信反馈?能 → Agent。如果两条都不满足,缺的不是 Agent,而是"可验证的反馈"——因为 Agent 的全部优势(ReAct 的纠错、错误累积的收敛)都建立在"每步能对账"之上。

AI 助教
👋 对"该不该用 Agent"有疑问?比如「我的需求算哪一档」「为什么说工具比提示词重要」?

描述你的需求,我帮你沿决策表定位该用哪一档。