react 模式需手动实现推理-行动闭环:生成文本→解析动作→调用工具→注入结果→循环,而非依赖现成库;须统一工具签名、严格匹配prompt格式、截断长输出、兜底异常并显式拼接换行。

ReAct 模式在 Python 中不是现成库,得自己搭骨架
Python 没有叫 react 或 ReAct 的标准库或主流包来直接实现推理-行动(Reasoning-Action)闭环。所谓“ReAct 模式”,本质是把大模型的输出拆解为「思考步骤 + 可执行动作」,再由代码控制流程走向——它是个模式,不是 API。
常见错误现象:AttributeError: module 'llm' has no attribute 'react'、盲目 pip install react(装的是 React.js 的 Python 绑定,完全无关)、或把 LangChain 的 AgentExecutor 当成开箱即用的 ReAct 实现(它只是其中一种封装,底层逻辑仍需你定义)。
- 真正要做的,是写一个循环:生成文本 → 正则/结构化解析出动作(如
search("量子计算"))→ 调用对应函数 → 把结果喂回模型 → 继续推理 - LangChain 的
ReActSingleActionAgent或 LlamaIndex 的ReActAgent是可复用的骨架,但必须提供tools列表和明确的prompt模板,否则它根本不知道该“行动”什么 - 别跳过 parser:模型输出格式稍有偏差(比如多一个空格、少一个引号),
re.search(r"Action: (\w+)\((.*)\)", text)就会返回None,整个链路静默失败
手动实现 ReAct 循环时,必须隔离模型调用与工具执行
核心陷阱在于把 LLM 推理和工具调用混在同一作用域里——比如在 generate() 函数里直接 os.listdir(),这会导致不可控副作用、无法 mock 测试、且难以调试哪一步崩了。
使用场景:你要让模型查天气、搜维基、读本地 CSV,每种操作都应封装为独立函数,并统一接受字符串参数、返回字符串结果。
立即学习“Python免费学习笔记(深入)”;
- 工具函数签名必须一致,例如全部是
def tool_name(query: str) -> str:,不能有的要path参数,有的要city和unit - 模型 prompt 里要明确写出工具列表和调用格式,例如:
Available tools: search, read_file. Use Action: search("xxx") to query.—— 少一个句点或引号类型(中文引号 vs 英文)都可能让 parser 失效 - 超时和异常必须兜底:工具函数内部加
try/except,返回类似"Error: file not found"而非抛异常,否则整个 loop 会中断
LangChain 的 ReAct Agent 不自动处理工具返回值长度
LangChain 的 ReActSingleActionAgent 默认把工具返回内容原样塞进下一步 prompt,但大模型上下文窗口有限。如果 read_file("log.txt") 返回 2000 行日志,下一轮 prompt 很可能被截断,导致模型“忘记”刚读过的内容。
性能影响:没做截断或摘要,token 消耗翻倍,响应变慢,还容易触发 context length exceeded 错误。
- 在工具函数里主动限制输出长度,例如
return content[:1000] + " [truncated]" - 或改用
Tool类的return_direct=False+ 自定义handle_tool_result做摘要(比如用小模型抽三句话) - 别依赖
max_iterations=6就万事大吉——如果每次工具返回都超长,第 2 轮就卡死,根本跑不到第 6 次
本地运行时,Observation 字段名大小写和空格极易错
ReAct 标准 prompt 里,模型输出后,你拼接的 observation 必须严格匹配模板中定义的字段名。LangChain 默认用 Observation: xxx(冒号后一个空格),但如果你手写 prompt 写成 OBSERVATION:xxx 或 Observation:(无空格),parser 就找不到位置。
常见错误现象:模型明明返回了结果,但 agent 下一轮还是重复调用同一个工具,像卡在循环里——大概率是 observation 插入位置错位,或者字符串拼接时漏了换行符。
- 永远用
print(repr(observation_line))看实际字符串内容,而不是只看终端渲染效果 - 拼接时显式加换行:
f"\nObservation: {result}\nThought:",避免因前序输出没结尾换行导致粘连 - 如果换模型(比如从 gpt-3.5-turbo 换到 llama3),prompt 模板里的关键词(
Thought/Action/Observation)最好全小写并加方括号,比如[thought],降低对大小写的敏感度










