想象你是警局新来的侦探,接手一桩悬案。老刑警递给你两套办案手册:一套教你“把案情在办公室想透彻再出门”——结果你对着卷宗编出了一百种凶手动机,全是想象;另一套教你“多跑现场多问证人”——结果你东奔西跑一整天,收集了一堆用不上的证物。这时老刑警翻开他自己的笔记本,上面每一页都只有三行:一句推测、一个验证动作、一条观察记录,然后又是下一句推测。他靠这个简单的循环,把悬案一桩桩破掉。 这正是大模型 Agent 的 ReAct 模式:Reason 与 Act 交替推进。模型每走一步,先写下 Thought(推理笔记),再发出 Action(行动指令,通常是调用工具),然后读取 Observation(工具返回的观察结果),再进入下一轮思考。而这一切的发动机,就是你的 Prompt 模板——它就像那张“推理-行动记录表”,规定了每一行该怎么写。这篇文章带你从零设计这张表,并看懂 AutoGPT、BabyAGI 这类自主 Agent 如何靠它跑起来。

岗位关联

掌握 ReAct 模板设计,你就掌握了让大模型“先想后做、边做边改”的提示词引擎,直接提升工具调用准确率与任务完成率——这是大模型 Agent 工程师的核心竞争力。

目录
  1. 可视化演示
  2. ReAct原理:边想边做才能破案
  3. 模板结构:一本三栏式的办案记录表
  4. Thought提示词:写好侦探的推理笔记
  5. Action提示词:发出标准化行动指令
  6. Observation反馈:把卷宗读成线索
  7. 完整模板实战:一张能直接上手的记录表
  8. 自主Agent应用:无人值守的侦探团队
  9. 模板调优:让记录表越用越顺手
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示ReAct模式中Thought-Action-Observation循环机制,Prompt模板设计流程,以及AutoGPT/BabyAGI框架应用,通过流动粒子直观理解推理与行动交替的核心思想。

本节配有交互动效(进入视口后自动加载,约 3KB)。

ReAct循环 Thought→Action→Observation→Thought,推理与行动交替进行 T→A→O→T→A→O→... Agent在思考后执行行动,观察结果后再思考,形成持续的推理-行动闭环

ReAct原理:边想边做才能破案

老刑警语重心长地告诉你:破案最忌讳两件事——“闭门造车”和“无头乱撞”。只推理不行动,你会被自己的想象带偏,对着错误的方向编出整套故事;只行动不推理,你会在现场跑来跑去,却不知道每一条线索意味着什么。真正的高手,是在笔记本上写下一句有依据的推测,然后立刻出门验证它,回来把看到的结果记下来,再根据结果写下一句推测。

ReAct 论文(Reasoning + Acting)正是把这种“边想边做”写进了大模型的行为模式。它要求模型每一步的输出都包含三个部分:Thought(推理笔记)、Action(行动指令)、Observation(观察结果)。模型不再一口气吐完整个答案,而是与环境交替互动,用真实的工具反馈来校准自己的推理。这条完整的交替轨迹,就是 Agent 的“办案记录”:

这个设计最直接的收益是解决幻觉问题。纯 CoT(Chain-of-Thought)让模型一路推理到底,如果中途某个前提是错的,后面全是空中楼阁;而 ReAct 每推一步就用工具反馈验证一步,就像侦探每次猜测都有目击证人或物证兜底。现在各大 Agent 框架的底层逻辑,几乎都是这条轨迹的变体。

τ=(T1,A1,O1,T2,A2,O2,…,Tn,An,On)\tau = (T_1, A_1, O_1, T_2, A_2, O_2, \ldots, T_n, A_n, O_n)
τ 是一条从开始到结束的完整交互轨迹,看起来很长,其实每个轮次都只是“想、做、看”三个动作的重复。
  1. τ 的含义希腊字母 tau 表示整条轨迹,也就是 Agent 从接收任务到完成任务的完整记录。
    τ\tau
  2. T_t 代表 Thought下标 t 表示第几轮,T 是模型在每轮写下的推理笔记,记录“我知道了什么、我要查什么”。
    TtT_t
  3. A_t 代表 Action第 t 轮模型发出的行动指令,通常是调用某个工具的规范化命令。
    AtA_t
  4. O_t 代表 Observation第 t 轮工具执行后返回的结果,是模型下一轮思考的事实依据。
    OtO_t
  5. 三元组循环推进三个符号一组,从 t=1 一直排到 t=n,强调顺序永远是“想→做→看”,不能颠倒。
    (Tt,At,Ot)(T_t, A_t, O_t)

模板结构:一本三栏式的办案记录表

你翻开老刑警的笔记本,每一页都印着整齐的三栏表格:第一栏写想法,第二栏写动作,第三栏写结果。他告诉你,这表格不是随便画的——栏目的顺序就是思维的顺序,每一行都是一次完整的“想-做-看”循环。Prompt 模板的作用,就是给大模型也发一本这样的空白记录表,并告诉它每栏该写什么、按什么顺序写。

一份标准的 ReAct Prompt 模板由三个段落组成。系统段负责定义角色和格式规则,比如“你是一个会用工具的助手,必须按 Thought/Action/Observation 的格式输出”;任务段把用户的问题注入到模板里,相当于在表格抬头写下案件名称;循环段最关键,它把模型过去所有的 Thought、Action、Observation 拼接成历史上下文,让模型在每一轮都能看到自己之前的办案记录。

模型在每一轮看到的上下文,可以用一个简单的式子表达:

理解了循环段的拼接逻辑,你就知道模板设计的一条铁律:每一轮的 Action 必须以“可被下一轮观察”的方式结束。如果 Action 写得含糊,工具无法执行,Observation 就无从产生,整条链就断了。这也是为什么三个栏目的设计必须环环相扣。

ct=concat⁡(Tt−1,At−1,Ot−1)c_t = \operatorname{concat}(T_{t-1}, A_{t-1}, O_{t-1})
c_t 就是模型在第 t 轮“睁开眼睛”时看到的全部案情笔记——上一轮的思考、行动和结果都被原样拼在了眼前。
  1. c_t 表示本轮上下文小写 c 是 context 的缩写,指模型生成第 t 轮输出前看到的所有历史内容。
    ctc_t
  2. concat 表示拼接concat 是拼接函数,把多个文本段按顺序连成一长串,就像把三栏表格压成一行文字。
    concat⁡\operatorname{concat}
  3. 下标 t-1 指上一轮模型只能引用已经发生过的内容,上一轮的三个字段就是它能依赖的全部新信息。
    t−1t-1
  4. 三元组是记忆单元每次循环产生的 (T, A, O) 三元组会被追加进上下文,轮次越多,记录表越长,Agent 的记忆越完整。
    (Tt−1,At−1,Ot−1)(T_{t-1}, A_{t-1}, O_{t-1})

Thought提示词:写好侦探的推理笔记

老刑警给你看了他的笔记示范:“昨晚死者手机最后一条消息是发给妻子的,但妻子说手机当晚不在身边——这两条口供矛盾,所以我下一步要查手机信号的基站记录。”注意,他没有写“我觉得很奇怪”这种废话,而是写了已知事实(两条口供矛盾)和行动动机(所以要查基站)。Thought 的设计,就是训练模型写出这样有用的笔记。

在 Prompt 模板里,Thought 部分通常用一两句指令来约束。效果拔群的写法是这样的:

这套提示词背后的设计智慧有四点。表达思考动机:要求模型说明“为什么这一步值得做”,避免随机行动;引用事实依据:强制模型把 Thought 挂在 Observation 的事实上,而不是凭空捏造;控制推理节奏:要求“先复述再行动”,让推理步骤短而密,每步只推进一点点;避免空想:明确禁止无关联想,把模型从“脑内小剧场”拉回案件本身。

Template 里 Thought 设计得越克制,模型就越不会“自言自语”。很多初版模板失败,都是因为 Thought 指令写得太开放,模型吐出一大段感慨,却不指向任何一个具体动作——就像侦探在笔记本上写了一整页“人心难测”,却没有写下要去查哪个证人。记住:Thought 的唯一使命,是为下一行的 Action 提供理由。

text3 行
Thought: 基于上一条 Observation,先复述你掌握的关键事实,再说明你打算做什么、为什么这么做。不要重复已知信息,不要展开无关联想。

Action提示词:发出标准化行动指令

老刑警又翻开本子,指着“动作”一栏:上面永远写着格式化的命令,比如“调取监控:昨晚 9 点到 10 点,案发街道东侧摄像头”,而不是“我去看看有啥线索”。标准化的好处是,任何人都能立刻执行,执行结果也能准确对应到这一条动作上。Action 的设计,就是让模型的行动命令像警用调度单一样规范。

Prompt 模板对 Action 的格式必须做硬性规定,常见的写法是:

工具名必须来自本模板声明的工具清单,参数必须按该工具的规范填写。比如 Action: calculator[15 * 23],而不是 Action: 帮我算一下。这里还有三条设计要点:单动作聚焦——每一轮只允许输出一个动作,不能同时调两个工具,否则 Observation 无法判断结果对应哪个动作;参数格式规范——模板里要给每个工具的参数示例,就像给新手侦探展示“证物袋标签怎么填”;终止条件判断——模板必须声明一个特殊动作 Action: Finish[最终答案],模型一旦确认答案就调用它结束循环,否则 Agent 会永远查下去。

模型如何决定选哪个动作?从数学上看,每一轮的动作都是在一个条件概率分布中采样得到的:

在设计模板时,你可以让这个“动作概率”变得更稳:把工具清单和每个工具的示例写清楚,模型选择正确工具的概率就会显著上升。不少工程师把模板里的工具说明写得像说明书一样详尽,效果反而好过放手让模型自由发挥——因为标准化的指令减少了歧义,也就减少了采样时的摇摆。

at∼πθ(a∣ct)a_t \sim \pi_\theta(a \mid c_t)
意思是:模型拿着当前全部案情笔记 c_t,按策略 π_θ 给出的概率,从所有可选动作里挑一个 a_t。模板的作用,就是引导这个概率分布偏向“正确的工具”。
  1. a_t 是第 t 轮动作它既可以是某个工具的调用,也可以是 Finish 终止指令。
    ata_t
  2. 模拟符号 ∽波浪号表示“按照某个分布随机抽取”,模型不是每次都选概率最大的动作,而是带一定随机性地采样。
    ∼\sim
  3. π_θ 是模型策略π 是策略函数,θ 代表模型的权重参数——也就是大模型本身;给定同样的上下文,不同的模型会给出不同的动作倾向。
    πθ\pi_\theta
  4. 竖线后是条件a 和 c_t 之间的竖线表示“在已知 c_t 的条件下”,动作永远取决于当前看到的事实,而不是凭空产生。
    a∣cta \mid c_t
text1 行
Action: 工具名[参数]

Observation反馈:把卷宗读成线索

侦探查案最耗时的一步,是坐在档案室里翻卷宗。卷宗里堆满了冗长的证词、监控截图、法医报告的原始文本,老刑警的做法是:只把与当前问题相关的两三句话摘出来,抄到记录表第三栏,其余的翻过不记。Observation 的设计正是这个“摘抄”动作——不要让模型把工具返回的一大段原文都吞进去,而是把关键信息提炼成下一轮可用的线索。

模板里可以这样引导模型处理 Observation:

这段指令涵盖了三个关键设计。结果摘要改写:模板告诉模型“只引用相关事实”,避免模型被无效信息带偏;错误信息容错:工具报错不等于任务失败,模板把报错包装成“此路不通”的线索,让模型有机会换一条路;观察驱动决策:Observation 永远排在下一轮 Thought 之前,让决策严格建立在事实基础上。如果信息缺失,模板还应引导模型发起补查,比如“结果不完整时,请再次调用工具获取缺失字段”。

一个常见的模板缺陷,是 Observation 环节没有任何说明,导致模型面对工具报错时直接崩溃或重复同一个失败的 Action。好的 Observation 设计,让 Agent 拥有“从失败中学习”的能力——就像侦探发现一条线索断了,会平静地在第三栏写下“此路不通”,然后翻到下一页继续写新的推测。这种容错能力,正是 ReAct Agent 比一次生成式回答稳健得多的重要原因。

text4 行
Observation: (系统自动填入工具返回结果)你的任务:阅读上面的原始结果,在下一轮 Thought 中只引用与当前目标相关的事实。若结果报错,把错误信息视为"此路不通"的信号,换个工具或换个方向继续。

完整模板实战:一张能直接上手的记录表

前面四节拆开了讲,现在把它们拼成一张能直接使用的完整模板。以单工具(计算器)为例,一份最小可用的 ReAct Prompt 长这样:

模板的最后一个词是“Thought:“,这是给模型的起手式——告诉它从思考开始,而不是直接输出答案。任务注入方式就是替换 {用户问题} 这个占位符,系统段和循环段的格式保持不变。多工具模板在此基础上扩展:在系统段声明工具清单,并给每个工具配一行使用说明和参数示例,Action 的”工具名”一栏就只能在清单里选。

设计多工具模板时要注意“选择路径”的清晰度。比如同时有 web_search 和 calculator,模板里应写明“需要事实信息用 web_search,需要数值计算用 calculator”。这样模型在 Action 一步就不容易选错工具。整套模板最终形成这样的效果:Thought 决定方向,Action 执行动作,Observation 反馈结果,周而复始,直到出现 Finish。

模板拼好后,你可以先用一两个小任务做冒烟测试。若模型频繁输出非法格式,就在系统段加一句“不允许输出任何除上述格式以外的内容”,或用 Few-shot 示例把正确格式演示一遍。记住:模板是给模型看的“行为规范”,措辞越像规章条例,模型的输出就越守规矩。

text15 行
你是一个擅长数学计算的助手,只能使用计算器工具。每轮必须严格按以下格式输出: Thought: 你的推理笔记(引用已知事实,说明下一步动机)Action: calculator[表达式] 表达式必须是四则运算式,例如 calculator[15 * 23]。系统会返回结果,你在下一轮继续输出 Thought。当你已经得到最终答案时,输出: Thought: 我已得到最终答案Action: Finish[答案] Question: {用户问题}Thought:

自主Agent应用:无人值守的侦探团队

老刑警办案时,助手会替他跑腿、查档案、整理线索;而 AutoGPT 这样的自主 Agent,等于把“侦探 + 助手”全交给了大模型——给它一个目标,它自己拆解、自己执行、自己验证。这套机制的内核正是 ReAct 模板,只是把它放进了循环:模型生成的 Action 不是一句话,而是真实的函数调用、文件读写、网络请求,Observation 是这些操作的真实返回。

AutoGPT 的循环里,Thought 升级成了“自我任务规划”:模型每完成一步,会问自己“离目标还差什么、下一步该做什么”,然后把子任务排进队列。BabyAGI 则把 ReAct 模板和任务队列管理结合得更明确:先有一个大目标,Agent 把它拆成若干子任务,逐个执行,每完成一个子任务,就根据它的结果生成新的子任务。新任务不是凭空冒出来的,而是对已完成任务及其结果的函数:

这套自主循环有一个必须提防的隐患:失控。如果任务永远能生成新任务,Agent 就会陷入无限循环烧光 token。所以工程上一定要给 Agent 套上“受限执行环境”:限制最大步数(比如最多 20 轮)、要求每个子任务必须声明验收标准、把生成新任务的动作也做成一个受限的 Action。这些约束写进模板,等于给侦探团队定了一条铁律——破不了案也得回来汇报,不许在外面无限查下去。

Tnew=gen⁡(Tdone,Rdone)T_{\text{new}} = \operatorname{gen}(T_{\text{done}}, R_{\text{done}})
新任务 T_new 由已完成任务 T_done 和它的执行结果 R_done 共同生成——就像侦探发现证物指向新嫌疑人,于是给自己派发新的调查任务。
  1. T_done 是已完成任务它是队列里刚被取出并执行完的那个子任务,比如“查询嫌疑人 A 的航班记录”。
    TdoneT_{\text{done}}
  2. R_done 是执行结果对应 ReAct 里的 Observation,是任务执行后的真实回报,可能带来新线索。
    RdoneR_{\text{done}}
  3. gen 是任务生成器通常由同一个大模型承担,它基于“任务 + 结果”推断下一步该查什么,产出新的子任务。
    gen⁡\operatorname{gen}
  4. T_new 是排队中的新任务生成后会被插入任务队列,等待下一轮执行,如此不断滚动,直到大目标达成。
    TnewT_{\text{new}}

模板调优:让记录表越用越顺手

老刑警的笔记本不是印出来就完事的,他会根据每次失败的案子在表格旁添批注:“下次记得查不在场证明”“这条街的监控要写清编号”。ReAct 模板同样需要迭代调优。第一阶段是建立评测指标:任务成功率(Agent 是否在限制步数内给出正确答案)、工具调用准确率(Action 选对工具且参数合法)、平均步数(效率如何)。没有这三项数字,优化就是盲人摸象。

第二阶段是分析错误类型,常见的有四类:幻觉工具名——模型调用了一个不存在的工具,说明工具清单不够醒目或示例不足;参数格式错——工具选对了但参数写错,说明参数示例不够具体;重复循环——模型反复执行同一个失败的 Action,说明 Observation 没有引导它从错误中学习;提前终止——模型过早输出 Finish,说明终止条件写得太宽松。每一种错误都对应一个模板修改动作。

调优的具体手段包括:加 Few-shot 示例(把一次成功的完整轨迹贴进模板当示范);强化格式约束(用“必须”“禁止”等强指令收窄输出空间);精简冗余措辞(模板越长,模型越容易忽略关键指令);以及采样参数——把温度调到 0 附近,让输出更确定、更守格式,等基础跑通后再逐步升温提升灵活性。每一次修改后重新跑评测集,用数字说话,而不是凭感觉。

模板调优的本质,是让模型的“行为规范”越来越贴合真实任务。就像老刑警的笔记本越写越厚、批注越来越多,最终成为一本破案宝典。你的 ReAct 模板也是一样:它是活的文档,会随着你在真实 Agent 任务中的每一次踩坑而进化,最终成为团队里最高效的“推理-行动”引擎。

AI 应用场景

企业客服工单自动处理 Agent

阶段:Agent 任务执行与工具调用

解决的问题:传统客服机器人只能按关键词给出固定话术,遇到需要查订单、查物流、改状态的复合问题就束手无策。用 ReAct 模板搭建的 Agent,可以把“查询订单状态”拆成 Thought(先确认用户订单号)、Action(调用订单查询工具)、Observation(读取返回的物流信息),再决定答复内容。

具体案例:某电商平台的售后 Agent 收到工单“我的快递三天没动”,它先 Thought 判断需要查物流接口,Action 调用 get_logistics[order_id],Observation 看到“包裹滞留中转站”,于是下轮 Thought 决定调用 create_complaint[order_id] 发起催件,最终生成安抚话术。全程由 ReAct 模板驱动,无需人工干预。

数据分析与报表自动生成 Agent

阶段:多工具协同与循环决策

解决的问题:分析师每天花大量时间重复“查数→算数→做表→核对”,且 SQL 写错很难察觉。ReAct Agent 将每一步操作都变成可验证的循环:先 Thought 确定统计口径,Action 执行 SQL 查询,Observation 检查返回行数和字段,异常则自动修正 SQL 重试。

具体案例:某增长团队的日报 Agent 每天自动连接数仓,先用 query_db[昨日DAU] 取数,Observation 发现返回为空,模板内的错误容错机制引导它换一个分区参数重试,成功后继续计算环比并生成图表,最后 Action: Finish[推送日报]。整个流程是标准的 Thought-Action-Observation 交替循环。

AutoGPT 式市场调研 Agent

阶段:自主任务规划与目标拆解

解决的问题:人工调研竞品要开十几个网页、整理几十条信息,耗时数小时。基于 ReAct 模板的自主 Agent 能把“调研竞品定价”这个大目标拆成搜索、抓取、汇总、对比等子任务,以任务队列形式逐个执行。

具体案例:给 Agent 一个目标“调研三款竞品的定价策略”,它先拆出子任务一“搜索竞品 A 定价”,执行时用 web_search 获取结果,Observation 摘要关键价格区间,再生成子任务二“对比竞品 B/C”,最后汇总成表格输出。每一次搜索与摘录都是 ReAct 循环的一次迭代。

Python 演示

python42 行
import re class ReActAgent:    def __init__(self):        self.tools = {            "calculator": lambda expr: str(eval(expr)),            "get_weather": lambda city: "晴,25度" if city == "北京" else "多云,22度"        }        self.trajectory = []     def think(self, obs):        if obs is None:            return "需要数值计算,先调用计算器工具"        if "345" in obs:            return "得到最终答案 345,不需要再行动"        return "观察未达预期,继续推理"     def act(self, thought):        if "天气" in thought:            return "get_weather", "北京"        return "calculator", "15 * 23"     def observe(self, tool, arg):        return self.tools[tool](arg)     def run(self, max_steps=3):        obs = None        for i in range(max_steps):            thought = self.think(obs)            print("Thought {}: {}".format(i + 1, thought))            if "最终答案" in thought:                print("Answer: {}".format(thought))                return            tool, arg = self.act(thought)            print("Action {}: {}({})".format(i + 1, tool, arg))            obs = self.observe(tool, arg)            print("Observation {}: {}".format(i + 1, obs))            self.trajectory.append((thought, tool, arg, obs))        print("达到最大步数,停止") if __name__ == "__main__":    ReActAgent().run()
目的:用一个自带计算器工具的小型 Agent,演示 ReAct 的 Thought→Action→Observation 循环如何在代码层面跑通,并在观察到"345"后通过 Finish 逻辑终止。
  1. self.tools = {...}注册工具清单,对应模板里 Action 的可选工具范围,是“Action: 工具名[参数]”的合法集合。
  2. def think(self, obs):生成 Thought 的核心函数,根据上轮 Observation 决定下一步推理,对应模板中的 Thought 指令。
  3. if "345" in obs:Observation 驱动终止判断,工具返回结果满足条件时,Thought 转向收尾,不再发起新行动。
  4. def act(self, thought):从思考内容里解析出工具和参数,对应模板要求的结构化 Action 输出。
  5. obs = self.observe(tool, arg)真正执行工具并拿到返回结果,这一行完成后,循环回到 think,形成闭环。
  6. self.trajectory.append((thought, tool, arg, obs))把每轮三元组追加进历史,对应模板循环段拼接上下文的设计。
  7. if __name__ == "__main__":可执行入口,保证脚本能直接运行演示完整的 ReAct 循环。

常见误区

误区我以为模板里的 Thought 指令应该鼓励模型把推理过程全部写出来,写得越详细,推理就越严谨,所以我把 Thought 部分设计成“请尽最大可能展开你的思考过程”。

正解ReAct 的 Thought 追求的是“克制有用”而非“长篇大论”。Thought 的唯一使命是为下一步 Action 提供理由,它应该简短地引用事实、说明动机,然后立刻结束。写得过长的 Thought 会消耗上下文窗口,稀释关键信息,还容易让模型在“想”的阶段自我陶醉,迟迟不进入“做”的阶段。就像侦探笔记本上写满人生感悟,却没有一条可执行的行动指令。

为何常见:受 CoT 的影响,很多人默认“推理链越长越好”,没意识到 ReAct 里思考必须为行动服务,长度要服务于效率。

误区我认为让模型在一轮里同时调用搜索和计算两个工具能节省时间,所以模板里允许 Action 输出多行,每行一个工具调用。

正解ReAct 模板的核心纪律是“每轮单一动作”。如果一轮发出两个工具调用,Observation 就不知道该对应哪个结果,上下文拼接会错位,模型在下一轮很可能拿着 A 工具的结果去修正 B 工具的失误。单一动作保证了“一个行动对应一个观察”,反馈链清晰,错误也容易定位。想调用多个工具,就多走几个循环,而不是挤在一轮里。

为何常见:直观上觉得“并行更快”,忽略了 ReAct 的价值恰恰在于严格的因果对应,而非效率上的一时取巧。

误区我以为工具返回什么,Observation 就原样写什么,模板里不需要特别说明,反正模型能自己看懂原始结果。

正解工具返回的原始结果往往夹杂大量无关字段、日志甚至报错堆栈,直接送入上下文会污染模型的下轮推理。好的模板会引导模型在 Observation 阶段做“摘要改写”:只提炼与当前目标相关的关键事实,把错误信息当作“此路不通”的信号。这就像侦探不会把整个法医报告抄进笔记,只摘录死亡时间和致命伤两行。

为何常见:把 Observation 想成“系统自动填充”的占位符,忽略了它其实是需要模板引导模型主动加工的推理素材。

误区我写模板时恨不得把注意事项、边界情况、几十个示例全塞进去,认为指令越全面,模型就越不会犯错。

正解Prompt 模板是一份“行为规范”,不是一本百科全书。冗余的指令会稀释核心格式约束的权重,模型反而更容易忽略关键信息。设计哲学是“最少必要约束”:说清楚角色、格式、工具清单、终止条件,顶多给一两个高质量示例,就够了。后面发现具体错误,再针对性补一条规则,逐步迭代,而不是一次堆满。

为何常见:出于“多做总比少做强”的心理补偿,加上对模型理解能力的低估,导致模板越写越臃肿。

面试题

Q1. 在 ReAct 模式中,Thought 对应侦探办案的哪个环节?

单选题 · easy

  • A.出门走访证人
  • B.在笔记本上写推理← 正确答案
  • C.记录证人证词
  • D.给警长写结案报告

答案:B。Thought 是模型下笔写下的推理笔记,记录“我知道了什么、下一步为什么这样做”,对应侦探写推测的环节。走访证人是 Action,记录证词是 Observation,结案报告是最终答案输出。

Q2. ReAct 模板通常要求 Action 以什么格式输出?

单选题 · easy

  • A.写成自然语言长段落
  • B.只输出工具名不带参数
  • C.缺少括号也能正常解析
  • D.固定为 工具名[参数] 结构← 正确答案

答案:D。Action 必须结构化输出,常见规范是 工具名[参数],例如 calculator[15 * 23]。自然语言段落难以解析,缺少参数会让工具无法执行,“缺少括号也能解析”属于错误认知,格式容错恰恰是模板要避免的。

Q3. 模板里 Observation 是用来做什么的?

单选题 · easy

  • A.模型自己的内心独白
  • B.用户提供的任务描述
  • C.工具返回结果的回填← 正确答案
  • D.下一轮 Action 的草稿

答案:C。Observation 是工具执行后返回的真实结果,它被回填进模板,成为模型下一轮 Thought 的事实依据。内心独白属于 Thought,任务描述属于用户输入,Action 草稿则是模型自己要生成的内容。

Q4. 设计 Thought 提示词时,合理的做法包括?

多选题 · mid

  • A.引用已知事实作为依据← 正确答案
  • B.说明下一步行动动机← 正确答案
  • C.要求引用工具内部源码
  • D.控制推理节奏避免跳步← 正确答案

答案:ABD。Thought 设计四要点是引用事实、说明动机、控制节奏、避免空想,对应 A、B、D。C 是错误的,Thought 不需要引用工具内部实现,那是系统工程师关心的事,塞进推理笔记只会浪费上下文。

Q5. ReAct 相比纯 CoT 的主要优势是什么?

单选题 · mid

  • A.生成文字更长更具可读性
  • B.完全不需要任何模板引导
  • C.能借工具反馈修正推理← 正确答案
  • D.推理速度必然更快

答案:C。ReAct 让模型在推理中途调用工具,并用 Observation 校准下一步,即使前期推理有误也能被真实反馈纠正。CoT 是纯推理链,错一步就错到底。A、D 不是本质优势,B 是错误认知——ReAct 恰恰依赖模板约束。

Q6. 模板规定“每轮只做单一动作”的主要目的是?

单选题 · mid

  • A.减少模型输出的 token
  • B.降低模型思考的深度
  • C.让观察与动作一一对应← 正确答案
  • D.方便人类阅读日志

答案:C。单一动作保证每个 Observation 都能精确对应一个 Action,反馈链不混乱。如果一轮调用两个工具,模型无法判断观察结果属于谁,上下文拼接会错位。减少 token 和方便阅读只是附带效果,不是设计目的。

Q7. AutoGPT 使用 ReAct 模板时,防止 Agent 失控的关键机制是?

单选题 · hard

  • A.允许无限生成动作
  • B.禁用观察结果回填
  • C.移除全部思考环节
  • D.限制最大步数并设终止条件← 正确答案

答案:D。自主 Agent 最大的风险是无限循环烧钱,所以工程上必须设置最大步数和明确的终止条件。无限生成动作是危险做法,禁用观察和移除思考等于废掉 ReAct 的反馈闭环,都不正确。

Q8. 当工具返回明显报错时,设计良好的模板会引导模型怎么做?

单选题 · extreme

  • A.忽略错误继续执行原计划
  • B.如实复述错误并调整行动← 正确答案
  • C.立即崩溃退出整个任务
  • D.隐瞒错误伪装成成功结果

答案:B。Observation 的错误信息应被视为“此路不通”的线索。模板引导模型把报错如实摘录进 Observation,并在下一轮 Thought 中换个工具或换种参数重试。忽略错误会重复失败,崩溃退出和隐瞒错误都不符合容错设计思想。

Q9. 一个完整的 Thought 记录通常包含哪些要素?

多选题 · mid

  • A.引用工具返回的事实← 正确答案
  • B.解释下一步行动理由← 正确答案
  • C.完整复述用户的问题
  • D.与上轮观察的因果关联← 正确答案

答案:ABD。Thought 要引用 Observation 中的关键事实(A),说明行动动机(B),并体现与上一轮观察的关联(D)。完整复述用户问题属于冗余信息,模板应引导模型避免重复已知内容,所以 C 不选。

Q10. 下列属于 ReAct 模板调优手段的有?

多选题 · hard

  • A.添加成功案例的示例← 正确答案
  • B.约束 Action 的输出格式← 正确答案
  • C.将采样温度调低至 0 附近← 正确答案
  • D.删除 Observation 引导指令

答案:ABC。调优手段包括 Few-shot 示例、强化格式约束、调低温度让输出更稳定,对应 A、B、C。删除 Observation 引导指令是严重的破坏性改动,会让模型失去对工具结果的加工能力,不是调优。