☰
Agent经典——ReAct框架:从推理到行动的LLM落地实践
2026/10/2 16:33:58 网站建设 项目流程

1. 为什么你的 Agent 只会“瞎猜”:从 ReAct 框架看推理与行动的闭环

如果你正在搭一个能查资料、能调工具的 Agent,大概率遇到过这种场面:模型一本正经地给出一个答案,你一问“依据呢”,它就开始编。或者更糟,它连续调了五次搜索,每次关键词都差不多,最后卡在同一个地方打转。这不是模型笨,而是你给它的工作方式不对——它要么只在“想”,要么只在“做”,两者没有接上。

ReAct 框架要解决的就是这件事。它是 2023 年普林斯顿和 Google Research 合作的一篇工作,核心思想一句话能说清:让大模型在每一步行动之前,先用自然语言把“我现在在想什么”写出来,然后再决定调哪个工具、传什么参数。这个“想”的动作不会改变外部环境,但它会写进上下文,成为下一步决策的依据。于是模型不再是黑箱式地直接吐答案,而是像人一样边想边做:先规划、再行动、看结果、修正计划。

这套机制特别适合三类人:一是正在做 RAG 但发现检索质量不稳定的开发者;二是想让模型调用搜索、计算器、数据库等外部工具,但苦于调用逻辑混乱的工程师;三是想搭建可调试、可干预 Agent 的团队——因为 ReAct 的思考轨迹是明文,你能直接看到它哪一步想歪了,甚至手动改掉那句思考,它就能走回正轨。

我试过在同一个多跳问答任务上对比纯 CoT 和 ReAct,前者在第二个跳转就编了一个不存在的实体,后者因为每步都写了“我需要先查 A,再从 A 的结果里找 B”,检索路径清晰得多。下面我会把 ReAct 的提示词模板、工具调用配置、以及怎么验证多步推理链是否真的在闭环,一步步拆开讲。你不需要改模型参数,只需要把提示词和工具接口设计对。

2. TaoToken 前置准备:给 ReAct 一个稳定的模型入口

ReAct 的效果高度依赖模型能不能稳定地按格式输出 Thought、Action、Observation 三段结构。如果模型今天输出 JSON、明天输出 Markdown、后天又漏掉 Action,你的解析器就会崩。所以第一步不是写提示词,而是选一个支持长上下文、指令跟随稳定的模型入口。

TaoToken 在这里的角色是提供一个统一的 API 网关,让你可以用同一套 Base URL 和 Key 去切换不同模型,方便对比哪个模型在 ReAct 格式下最听话。它的 API 地址是 https://taotoken.net/api,兼容 OpenAI 风格的请求格式,所以你现有的 LangChain、LlamaIndex 或自己写的 HTTP 客户端基本不用大改。

你需要准备三样东西:Base URL、API Key、Model ID。Base URL 填 https://taotoken.net/api,Key 在控制台的 API Keys 页面生成,Model ID 根据你选的模型填,比如 claude 系列或 gpt 系列。如果你用的是 Claude Code 这类工具,它内部会读 settings.json 或环境变量,配置方式略有不同,但核心三件套不变。

这里有个容易踩的坑:很多人把 Base URL 写成 https://taotoken.net/api/v1,结果请求 404。TaoToken 的兼容层已经处理了路径,你只需要写到 /api 即可,后面的 /chat/completions 由客户端自动拼。另外,Key 不要硬编码在代码里提交到 Git,用环境变量或 .env 文件管理。

如果你还没决定用哪个模型跑 ReAct,可以先在模型对话页面手动试几轮,观察它能不能稳定输出“Thought: ... Action: ... Action Input: ...”的格式。试的时候给一个简单任务,比如“查一下北京今天天气,然后告诉我适合穿什么”,看它会不会先写思考再调工具。这一步花五分钟,能省掉后面两小时的解析调试。

3. 可复制配置:ReAct 提示词模板与工具调用 JSON

这一节直接给可复制的配置。先看提示词模板,它决定了模型输出的结构。我用的格式是 Thought / Action / Action Input / Observation 四段,Observation 由你的代码在执行工具后填入,再拼回上下文。

你是一个可以使用工具的智能体。请严格按照以下格式回应: Question: 用户输入的问题 Thought: 你需要思考当前应该做什么,是否已有足够信息回答,还是需要调用工具 Action: 工具名称,必须是 [search, calculator, finish] 之一 Action Input: 传给工具的输入,字符串 Observation: 工具返回的结果(这一行由系统填入,你不要自己编) ... (Thought/Action/Action Input/Observation 可以重复多轮) Thought: 我现在知道最终答案了 Action: finish Action Input: 最终答案 可用工具: - search: 输入搜索关键词,返回相关文本片段 - calculator: 输入数学表达式,返回计算结果 - finish: 输入最终答案,结束任务 现在开始。 Question: {question}

这个模板的关键在于:Action 必须是有限集合里的一个,Action Input 必须是字符串,Observation 由外部注入而不是模型生成。很多人在这一步让模型自己编 Observation,结果就是幻觉连环套。

接下来是工具调用的配置。如果你用 Python 写,可以定义一个工具注册表,把每个工具的名称、描述、执行函数存起来。下面是一个最小可运行的结构:

import os import requests API_KEY = os.getenv("TAOTOKEN_API_KEY") BASE_URL = "https://taotoken.net/api" MODEL_ID = "claude-3-5-sonnet" # 按你实际选的模型填 def call_llm(prompt: str) -> str: headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } payload = { "model": MODEL_ID, "messages": [{"role": "user", "content": prompt}], "temperature": 0 } resp = requests.post(f"{BASE_URL}/chat/completions", json=payload, headers=headers) resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"] def search_tool(query: str) -> str: # 这里替换成你真实的搜索实现,比如 Wikipedia API 或内部知识库 return f"[搜索结果] 关于 {query} 的模拟返回内容" def calculator_tool(expr: str) -> str: try: return str(eval(expr)) except Exception as e: return f"计算错误: {e}" TOOLS = { "search": search_tool, "calculator": calculator_tool, }

注意 temperature 设成 0,ReAct 需要确定性输出,温度高了格式会飘。另外,如果你用 Claude Code 或 Cline 这类工具,它们有自己的 settings.json 或 MCP 配置,你需要把 Base URL、Key、Model ID 三件套填进去。比如 Cline 的 MCP 配置里,Base URL 填 https://taotoken.net/api,Key 填你的 Key,Model ID 填对应模型名。Codex 的 auth.json 也是类似逻辑,把 api_base 和 api_key 写对即可。

还有一个细节:Action Input 如果是搜索,最好让模型输出纯关键词,不要带引号或多余修饰。你可以在提示词里加一句“Action Input 只输出关键词,不要加引号”。这个小小的约束能减少很多解析失败。

4. 验证请求:跑通一个多步推理链并检查闭环

配置写好后,别急着上复杂任务。先用一个两跳问题验证闭环是否真的在跑。比如问:“苹果遥控器最初设计用来控制哪个软件,这个软件还能被什么设备控制?”这个问题需要先搜“Apple Remote”,从结果里找到“Front Row”,再搜“Front Row software”,最后得出“键盘功能键”。

你运行 Agent 后,期望看到的轨迹是这样的:

Thought: 我需要先搜索 Apple Remote,找到它最初设计用来交互的软件。 Action: search Action Input: Apple Remote Observation: Apple Remote 是 Apple 于 2005 年推出的控制器,最初设计用来控制 Front Row 媒体中心程序。 Thought: 现在我知道是 Front Row,接下来需要搜索 Front Row 软件,看还有什么设备能控制它。 Action: search Action Input: Front Row software Observation: Front Row 是一个已停产的媒体中心软件,可由 Apple Remote 或键盘功能键控制。 Thought: 我已经有足够信息回答,答案是键盘功能键。 Action: finish Action Input: 键盘功能键

如果你看到 Observation 是模型自己编的,而不是你的 search_tool 返回的,说明你的解析逻辑有问题——你可能把模型输出直接当成了完整上下文,没有在执行工具后把真实结果拼回去。正确的做法是:每轮只让模型生成到 Action Input 为止,然后你截断,执行工具,把 Observation 拼到后面,再让模型继续生成下一轮 Thought。

验证成功的标志有三个:一是 Thought 里出现了对上一步 Observation 的引用,比如“根据搜索结果,Front Row 是……所以下一步……”;二是 Action Input 在第二轮发生了变化,从“Apple Remote”变成了“Front Row software”;三是最终 finish 的答案确实来自 Observation 里的信息,而不是模型预训练知识里的猜测。

如果模型在第二轮又搜了一遍“Apple Remote”,说明它没有把 Observation 读进去,可能是上下文拼接时丢了历史,或者提示词里没有强调“Observation 是真实结果,请基于它继续推理”。你可以在提示词里加一句“每一轮 Thought 必须引用上一条 Observation 的内容”。

5. 常见报错排查:401、local proxy failed、reading choices、OAuth

跑 ReAct 的过程中,报错基本集中在接入层和解析层。下面按真实遇到的错误对照排查。

401 Unauthorized:最常见的原因是 Key 没传对。检查你的请求头是不是Authorization: Bearer sk-xxx,注意 Bearer 后面有空格。如果你用的是环境变量,确认变量名和代码里读的一致。还有一种情况是 Key 复制时带了换行或空格,用.strip()处理一下。如果 Key 没问题但还是 401,检查 Base URL 是不是写成了https://taotoken.net/api/带了尾部斜杠,有些客户端会把斜杠拼成双斜杠导致鉴权失败。

local proxy failed:这个报错通常出现在你本地开了代理工具,但代理规则没有放行taotoken.net。你需要把taotoken.net加入直连规则,或者临时关闭代理再试。注意,这里说的是本地网络配置问题,不是让你去用什么特殊工具,只是检查你的请求有没有被本地代理拦截。如果你在公司内网,可能还需要检查防火墙是否放行了 443 端口。

reading choices 报错:典型信息是KeyError: 'choices'或list index out of range。这说明你拿到的响应不是标准的 OpenAI 格式。可能原因有两个:一是模型返回了错误信息,比如{"error": "model not found"},你没有先检查resp.status_code就直接取choices;二是你用的 Model ID 不对,TaoToken 返回了错误结构。解决办法是在解析前先打印resp.json(),确认结构里有choices再往下走。

OAuth 相关报错:如果你用 Claude Code 或类似工具,它可能走 OAuth 流程而不是 API Key。这时候你需要确认工具是否支持自定义 Base URL。有些工具默认连官方端点,你需要找到它的配置文件,把api_base或base_url改成https://taotoken.net/api,同时把认证方式从 OAuth 切到 API Key。具体路径看工具文档,通常在~/.config/或项目根目录的settings.json里。

还有一个非报错但很烦的问题:模型输出格式不稳定,有时候写Action: search,有时候写Action: Search,有时候写Action: 搜索。你可以在解析时做大小写归一化,并且把工具名固定成英文小写。如果模型坚持输出中文工具名,在提示词里加一句“Action 必须从 [search, calculator, finish] 中选择,不要翻译”。

6. 从 ReAct 到可调试 Agent:下一步怎么走

ReAct 的价值不只是让模型多写几行思考,而是给你一个可观测的决策链路。你能看到它在哪一步开始跑偏,也能通过编辑 Thought 来干预。比如在 ALFWorld 的例子里,模型错误地认为第二个钥匙链还在抽屉 4,人类把那条 Thought 删掉,换成“第二个钥匙链可能在梳妆台、垃圾桶、保险箱等位置”,模型就成功完成了任务。这种“改一句话就能纠偏”的能力,是纯端到端 Agent 很难做到的。

如果你想把 ReAct 用到生产环境,下一步可以关注三件事:一是把工具调用做成异步,避免搜索超时阻塞整个循环;二是给 Thought 加长度限制,防止模型在一步里写太多导致上下文爆炸;三是把成功的轨迹存下来做少样本示例,下次遇到类似任务直接塞进提示词。

现在你可以拿上面的模板,在模型对话里先手动跑一轮,确认格式稳定后,再把工具注册表和解析逻辑接上。遇到 401 或格式解析问题,回头对照第 5 节排查。等你跑通第一个多步推理链,就会明白 ReAct 为什么能成为 Agent 领域的经典框架——它把黑箱推理变成了白箱流程,而白箱意味着可调试、可改进、可信任。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询