☰
AI Agent设计模式入门到精通!ReAct、Reflection、LATS一篇搞定,收藏这篇就够了(TaoToken 统一 Key 接入版)
2026/10/11 5:07:55 网站建设 项目流程

1. 从零跑通一个可观测的 Agent 循环:ReAct、Reflection、LATS 到底怎么落地

很多人第一次接触 AI Agent 设计模式,都会被 ReAct、Reflection、LATS 这三个词绕晕。它们听起来像三套完全不同的框架,实际上解决的是同一个问题的三个层次:模型怎么在“想”和“做”之间循环,怎么从错误里学习,怎么在多个可能路径里选最优。ReAct 是最基础的“思考—行动—观察”闭环,Reflection 是在闭环外面加一层自我批判,LATS 则是把闭环扩展成一棵树,用搜索算法在多个分支里找最优解。

这篇文章面向的是想从零搭建可运行 Agent 的开发者。你不需要先精通 LangChain 或 LlamaIndex,我会用最少的依赖、最直白的 Python 代码,把三种模式各跑一遍。更重要的是,我会说明如何通过 TaoToken 统一 Key/API 通道完成模型调用接入——这样你不需要在多个模型供应商之间来回切换配置,一个 Key 就能覆盖 ReAct、Reflection、LATS 三种模式所需的模型调用。

读完你手里会有三份可复制的配置片段、三套可运行的验证请求,以及一份常见报错对照表。预期结果是:你能在自己的机器上跑通一个带日志输出的 Agent 循环,并且知道每种模式适合什么场景、不适合什么场景。

先说清楚一个前提:Agent 的本质不是“更聪明的模型”,而是“模型 + 工具 + 循环控制”。模型负责推理,工具负责和外部世界交互,循环控制负责决定什么时候继续、什么时候停止。ReAct、Reflection、LATS 的区别,本质上就是循环控制策略的区别。理解了这一点,后面所有配置都不会觉得陌生。

我试过用同一个任务——让 Agent 查一个城市的天气并决定要不要带伞——分别用三种模式实现。ReAct 最快跑通,Reflection 多花了一轮自我检查,LATS 则探索了三条不同路径。下面按顺序拆解。

2. TaoToken 统一 Key 接入:为什么 Agent 开发需要一个稳定通道

做 Agent 开发最烦的事情之一,是模型调用通道不稳定。ReAct 循环一次可能调用模型 5 到 10 次,Reflection 要翻倍,LATS 因为树搜索可能调用几十次。如果每次调用都要换 Key、换 Base URL、处理不同的鉴权格式,调试成本会高到让人放弃。

TaoToken 在这里的角色是一个统一的模型调用通道。你只需要在环境变量里配置一次 Base URL 和 API Key,之后所有 Agent 循环里的模型请求都走同一个入口。官网地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api 。

具体来说,你需要准备三样东西:

第一,一个 API Key。在控制台里创建,地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite 。创建后复制出来,后面所有配置都用它。

第二,确认 Base URL。Agent 代码里通常需要填base_url,这里填https://taotoken.net/api即可。注意 API 地址不加 UTM 参数,保持干净。

第三,选一个 Model ID。ReAct 和 Reflection 对模型推理能力要求中等,LATS 因为要做价值评估,建议选推理能力更强的模型。你可以在模型对话页面先试一下目标模型是否可用: https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 。

如果你用的是 Claude Code 这类编码 Agent,TaoToken 也提供了对应的接入文档: https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。文档里会说明 Base URL、Key、Model ID 三件套怎么填。

这里有一个关键点:Agent 循环里的模型调用是高频的,所以通道的稳定性比单次调用的速度更重要。统一 Key 的好处是,你不需要在代码里维护多个供应商的配置分支,也不需要因为某个通道抖动就改代码。所有请求走同一个入口,出错时排查范围也小很多。

配置环境变量的时候,建议用.env文件管理,不要硬编码在代码里。下面是一个最小示例:

# .env TAOTOKEN_API_KEY=sk-你的key TAOTOKEN_BASE_URL=https://taotoken.net/api TAOTOKEN_MODEL_ID=你的模型ID

然后在 Python 里用os.getenv读取。这样你在本地调试、在服务器部署、在 CI 里跑测试,都只需要改环境变量,不用动代码。

如果你还没有 Key,先去 API Keys 页面创建一个: https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。创建时注意权限范围,Agent 开发通常只需要模型调用权限,不需要开其他高危权限。

3. ReAct 模式可复制配置:Thought-Action-Observation 循环怎么写

ReAct 的核心是三步循环:Thought(思考)、Action(行动)、Observation(观察)。模型先输出一段思考,决定下一步调用什么工具;工具执行后返回结果;模型看到结果后继续思考,直到任务完成。

下面是一个最小可运行的 ReAct 配置片段。我用 JSON 格式定义工具和循环参数,你可以直接复制到自己的项目里改。

{ "agent_mode": "react", "max_iterations": 8, "model": { "base_url": "https://taotoken.net/api", "api_key_env": "TAOTOKEN_API_KEY", "model_id_env": "TAOTOKEN_MODEL_ID", "temperature": 0.2 }, "tools": [ { "name": "get_weather", "description": "查询指定城市的当前天气", "parameters": { "city": "string" } }, { "name": "calculate", "description": "执行数学计算", "parameters": { "expression": "string" } } ], "stop_condition": "模型输出 FINAL_ANSWER 标记" }

这个配置里几个参数值得说明。max_iterations控制循环上限,防止模型陷入死循环。ReAct 最常见的坑就是模型一直调用同一个工具不停止,所以必须设上限。temperature设低一点,0.2 左右,因为 Agent 需要稳定推理,不需要创意发散。

工具定义部分,description要写清楚,因为模型是根据描述决定调用哪个工具的。描述模糊会导致模型选错工具。parameters用 JSON Schema 格式,模型会按这个格式生成调用参数。

循环控制的伪代码逻辑是这样的:

while iteration < max_iterations: response = call_model(messages) if "FINAL_ANSWER" in response: break action = parse_action(response) observation = execute_tool(action) messages.append({"role": "assistant", "content": response}) messages.append({"role": "user", "content": f"Observation: {observation}"})

注意messages是累积的,每一轮都把之前的思考和观察带上。这就是为什么 ReAct 的 Token 消耗会随轮次增长。如果你发现 Token 消耗太快,可以在messages里只保留最近 N 轮,但这样会丢失早期上下文,需要权衡。

工具执行部分,execute_tool要做异常处理。工具调用失败时,不要把异常直接抛给模型,而是返回一个结构化的错误信息,比如{"error": "城市名称无法识别"}。模型看到这个信息后可以调整参数重试。

还有一个细节:模型输出的 Action 格式需要严格解析。建议在系统提示词里明确要求模型按固定格式输出,比如:

你必须按以下格式输出: Thought: 你的思考 Action: 工具名称 Action Input: JSON 格式的参数

解析时用正则提取,如果解析失败,把原始输出返回给模型并提示格式错误,让它重新输出。这个重试机制能显著提高 ReAct 的稳定性。

配置写好后,下一步是验证请求。不要一上来就跑复杂任务,先用一个最简单的任务验证循环能转起来。

4. 验证请求与成功结果:三种模式各跑一遍看日志

验证 ReAct 最简单的方式是让它做一个两步任务:先查天气,再根据天气决定是否带伞。下面是一个验证请求的示例:

import os import json from openai import OpenAI client = OpenAI( base_url=os.getenv("TAOTOKEN_BASE_URL"), api_key=os.getenv("TAOTOKEN_API_KEY") ) messages = [ {"role": "system", "content": "你是一个 ReAct Agent。按 Thought/Action/Action Input 格式输出。"}, {"role": "user", "content": "查一下北京天气,然后告诉我要不要带伞。"} ] for i in range(8): resp = client.chat.completions.create( model=os.getenv("TAOTOKEN_MODEL_ID"), messages=messages, temperature=0.2 ) content = resp.choices[0].message.content print(f"--- 第 {i+1} 轮 ---") print(content) if "FINAL_ANSWER" in content: break messages.append({"role": "assistant", "content": content}) # 这里应该解析 Action 并执行工具,示例中简化为模拟观察 messages.append({"role": "user", "content": "Observation: 北京晴,25度"})

成功跑通后,你会看到类似这样的日志:

--- 第 1 轮 --- Thought: 我需要先查询北京天气 Action: get_weather Action Input: {"city": "北京"} --- 第 2 轮 --- Thought: 北京晴天25度,不需要带伞 FINAL_ANSWER: 北京今天晴天,25度,不需要带伞。

关键观察点:第一轮模型输出了 Action,第二轮看到 Observation 后输出了 FINAL_ANSWER。如果模型在第一轮就直接输出 FINAL_ANSWER,说明它没有调用工具,可能是工具描述不够清晰,或者系统提示词没有强调必须调用工具。

Reflection 模式的验证稍微不同。它需要在 ReAct 循环结束后加一轮反思。你可以在FINAL_ANSWER之后追加一条消息:

messages.append({"role": "user", "content": "请检查上面的答案是否有遗漏或错误,如果有请修正。"}) resp = client.chat.completions.create(model=..., messages=messages) print("反思结果:", resp.choices[0].message.content)

成功时你会看到模型指出自己可能遗漏的信息,比如“没有考虑紫外线强度”或“没有说明温度单位”。如果模型只是重复原答案,说明反思提示词不够具体,可以改成“请从准确性、完整性、可操作性三个角度检查”。

LATS 的验证最复杂,因为它涉及树搜索。一个简化的验证方式是:让模型生成三个不同的行动方案,然后对每个方案打分,选最高分的执行。日志里你会看到三条分支的评分和最终选择。

三种模式跑通后,对比日志你会发现:ReAct 轮次最少,Reflection 多一轮但答案更完整,LATS 轮次最多但能覆盖更多可能性。选择哪种模式,取决于你的任务对准确性和成本的要求。

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

Agent 开发过程中最容易遇到的报错集中在模型调用环节。下面按报错类型逐一说明。

401 Unauthorized:这是最常见的错误,原因是 API Key 无效或没有正确加载。排查步骤:第一,确认.env文件里的TAOTOKEN_API_KEY没有多余空格;第二,确认代码里读取环境变量的名称和.env里一致;第三,确认 Key 没有过期或被删除。如果用的是 Claude Code 或 Cline 这类工具,检查配置文件里的 Key 字段是否填对。三件套检查清单:Base URL 填https://taotoken.net/api,Key 填控制台创建的 Key,Model ID 填模型对话页面确认可用的 ID。

local proxy failed:这个报错通常出现在本地开发环境,原因是代码里配置了本地代理,但代理服务没有启动。排查步骤:第一,检查环境变量里是否有HTTP_PROXY或HTTPS_PROXY设置,如果有,确认代理服务是否运行;第二,如果不需要代理,直接清空这两个环境变量;第三,确认base_url没有被错误地指向本地地址。Agent 代码里如果用了requests库,它默认会读取系统代理设置,可以在代码里显式设置proxies={"http": None, "https": None}来绕过。

reading choices 报错:这个报错通常表现为KeyError: 'choices'或IndexError: list index out of range,原因是模型返回的响应结构不符合预期。排查步骤:第一,打印完整的resp对象,看返回的 JSON 结构;第二,确认模型 ID 是否正确,错误的模型 ID 可能导致返回错误结构;第三,检查是否触发了内容过滤,某些请求可能返回空 choices。处理方式是在代码里加防御性判断:

if not resp.choices: print("响应为空,原始返回:", resp) continue content = resp.choices[0].message.content

OAuth 相关报错:如果你用的是 Claude Code 或 Codex 这类工具,可能会遇到 OAuth 认证失败。这类工具通常支持两种认证方式:OAuth 登录和 API Key。在 Agent 开发场景下,建议直接用 API Key 方式,避免 OAuth 流程的复杂性。配置时确认auth.json或settings.json里的认证字段填的是 API Key,而不是 OAuth token。如果工具同时支持两种方式,优先选 API Key。

循环不停止:这不是报错,但比报错更常见。模型一直调用工具不输出 FINAL_ANSWER。处理方式:第一,设max_iterations上限;第二,在系统提示词里明确“如果已经获得足够信息,必须输出 FINAL_ANSWER”;第三,检测重复 Action,如果连续两轮调用同一个工具且参数相同,强制终止并返回当前结果。

Token 消耗过快:ReAct 循环累积上下文导致 Token 线性增长。处理方式:第一,只保留最近 3 到 5 轮消息;第二,把工具返回的长结果截断,只保留关键信息;第三,把 Observation 压缩成简短摘要再放回 messages。

排查时建议打开详细日志,把每一轮的请求和响应都打印出来。Agent 的问题通常不是单点故障,而是循环中某一轮的输出格式不对导致后续全部错乱。看到第一轮异常就停下来检查,不要让它继续跑。

6. 语义一致 CTA:从跑通到长期编码,按需选择入口

三种模式跑通之后,你可能会想把它用到实际项目里。这时候有几个入口可以按需选择。

如果你还在调试接入配置,或者遇到了上面提到的报错,先去 API Keys 页面确认 Key 状态,再看接入文档核对三件套配置。API Keys 入口: https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。接入文档入口: https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。

如果你想先验证某个模型在 ReAct 或 Reflection 任务上的表现,可以直接在模型对话页面测试。输入一个多步任务,看模型是否能正确输出 Thought/Action 格式。模型对话入口: https://taotoken.net/models?utm_source=taotoken_aicg_blog_end&utm_content=models&utm_campaign=rewrite 。

如果你打算把 Agent 用到长期编码任务或复杂 Agent 工作流里,比如让 Agent 自动修 bug、跑测试、提交代码,那建议看一下 Coding Plan。这类场景对通道稳定性和调用配额的要求更高,Coding Plan 入口: https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。

如果你用的是 Claude Code 做编码 Agent,接入方式和普通 API 调用略有不同,参考 Claude Code 接入文档: https://taotoken.net/claude-code?utm_source=taotoken_aicg_blog_end&utm_content=claude-code&utm_campaign=rewrite 。

最后说一个实际经验:Agent 开发最难的不是写循环,而是让循环稳定。ReAct 跑通一次很容易,跑一百次不出错很难。稳定性来自三个方面:严格的输出格式约束、完善的异常处理、合理的循环上限。把这三点做好,再考虑上 Reflection 或 LATS 做增强。不要一上来就追求最复杂的模式,先用 ReAct 把基础链路跑稳,再逐步加反思和搜索。

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

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

立即咨询