技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

ReAct:让大模型把「想」和「做」缝进同一个循环

项目背景与痛点

2022 年前后,大模型应用基本分成两条路。一条是 Chain-of-Thought:让模型先把推理过程写出来,再给答案。它的问题很直接——推理链再漂亮,也是闭卷考试,模型手里没有证据,只能靠参数记忆硬编,多跳问题上一旦中间事实记错,整条链子跟着塌。另一条是纯 Action 路线,比如 WebGPT、SayCan:模型直接输出搜索、点击、移动等动作,拿环境反馈。这条路能接触真实信息,但模型缺少显式的规划层,几步之后就容易在长流程里迷路,失败也说不清为什么失败。

ReAct 的切入点就是把这两条路焊在一起:每一步先写一句 Thought 说明"我为什么这么做",再发一个 Action,环境回一个 Observation,Observation 又成为下一步 Thought 的依据。推理负责规划和纠错,行动负责提供事实和推进状态。论文在 HotpotQA、FEVER、ALFWorld、WebShop 四个任务上验证了这套循环,而这个仓库,就是那批实验的可复现代码。

核心技术揭秘

先说清楚定位:ysymyth/ReAct 不是一个 Agent 框架,它是实验脚本集合。没有 LangChain,没有插件抽象,没有 YAML 配置。技术栈是 Python 3 + OpenAI 早期 Completion API(text-davinci-002 一代)+ 四个任务各自的环境包装。它的价值恰恰在于这种"裸"——把 ReAct 还原成一件事:字符串拼接 + 一次 API 调用 + 一段正则解析。

真正值得看的是数据流。每个任务目录里都躺着几份手工写好的 prompt_*.txt,内容是若干条完整的 Thought / Action / Observation 示例轨迹,构造成 few-shot 上下文。运行时,脚本把当前 episode 已积累的轨迹前缀接到示例后面,调用模型,用 stop token 截在 Action 那一行,再解析出动作名和参数,路由到对应的工具或环境,把返回的 Observation 拼回上下文,开始下一轮。

graph TD A[任务输入<br/>HotpotQA / FEVER / ALFWorld / WebShop] --> B[Few-shot Prompt 组装<br/>示例轨迹 + 当前轨迹前缀] B --> C[调用 LLM 生成下一步] C --> D[原始文本输出] D --> E{"解析器识别 Action"} E -->|"成功"| F[路由到对应工具或环境] E -->|"失败:截断或格式非法"| G[兜底重试 / 补终止符] F --> H[Observation 写回上下文] H --> I{"是否为 finish 动作"} I -->|"否"| J[上下文预算裁剪] J --> B I -->|"是"| K[输出答案并计算 EM / F1] G --> C

这套设计里有三个隐含的技术难点,仓库代码基本都花在它们上面:

其一是动作空间的设计。 HotpotQA 只用 search[...]、lookup[...]、finish[...] 三个动作,ALFWorld 是一组文本化的家务指令。动作空间刻意做得极窄,因为动作越少,模型越不可能输出解析器吃不下的东西。这是范式层面的取舍:牺牲通用性换可控性。

其二是输出解析的鲁棒性。 GPT-3 时代没有 function calling,模型会输出多行、会自作主张续写、会把 Action 写成中文。早期脚本里大量 if/else 就在做截断、正则匹配、非法动作的降级处理。这部分代码不好看,但它决定了整个循环跑不跑得下去。

其三是上下文预算。 2048 token 的窗口,既要装 few-shot 示例,又要装越来越长的轨迹。实际做法是保留开头的示例和最近若干步,丢掉中间历史——这意味着 Agent 会"遗忘"早期搜到的证据,是长任务里最隐蔽的失败源。

功能亮点与差异

对比 CoT,ReAct 的关键差异是推理链里嵌入了外部证据,幻觉显著下降,因为模型的每一句判断都能指向一条 Observation。对比纯 Act 路线,它的杀手锏是那句 Thought:Thought 不调用任何 API、不消耗工具配额,只作为自然语言留在上下文里,却让整个决策过程可读、可审计,也让模型在 Observation 说"Nothing happens"之后有能力换策略而不是原地打转。

还有一点容易被忽略:ReAct 不需要训练。few-shot 提示即可生效,这是它能迅速成为后续 Agent 系统事实标准的原因。后来 LangChain 的 ReActAgent、AutoGPT 的循环骨架,本质上都是这个 prompt 模板的工程化放大。

应用场景与落地建议

适合的场景很明确:多跳问答、事实验证、需要检索的知识库客服、文本游戏与具身任务规划——共同点是任务需要外部信息、且过程需要多步决策。

真上生产,有几件事必须动手改:把文本解析换成结构化输出(JSON schema 或 function calling),这是对原仓库最大的现代化改造,能消灭掉一半的异常分支;做上下文管理,现在有 prompt caching 和更长的窗口,但每步重发全量 prompt 的 token 成本依然随步数线性增长;加护栏,最大步数、重复动作检测、死循环熔断,缺一不可;评估体系换掉,仓库里的 EM/F1 只适合论文对比,生产环境要看工具调用成功率、平均步数、人工抽检准确率。另外,模型生成的查询串会直接打到检索 API,注入和限流都得在工具层兜住。

综合评价

优点:用最少的代码把 Agent 的本质说清楚了——LLM 加工具加循环,剩下的都是工程细节。prompt 全部明文可见,实验可复现,指标可对齐,是极好的基线。

缺点:它是研究脚本,不是库。任务逻辑硬编码、模块之间强耦合、几乎零抽象;API 调用层停留在旧 Completion 接口,直接拿来用要重写;上下文裁剪粗糙,长任务上会丢证据。

一句话结论:别把它当框架依赖,把它当教科书。真正要落地,抄它的循环结构,换掉它的解析器和调用层。

关于

GitHub 原始描述(英文)

[ICLR 2023] ReAct: Synergizing Reasoning and Acting in Language Models

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

简要分析

热度分
5119
价值分
2691
活跃状态
活跃

语言占比

Jupyter Notebook
Python