三分钟说清楚 ReAct Agent 的技术实现

ReAct Agent 技术实现主要依赖于精心设计的 Prompt 模板输出解析器执行循环三大核心机制。


1. 核心 Prompt 工程

LangChain 使用特定的 Prompt 模板引导 LLM 按 Thought → Action → Observation 格式输出:

python 复制代码
# 简化的 Prompt 结构
template = """
用以下工具回答问题:

工具: 
- search: 搜索引擎, 输入: "查询词"
- calculator: 计算器, 输入: "算式"

现在开始!

问题: {input}
Thought: {agent_scratchpad}
"""

关键设计:

  • agent_scratchpad :存储历史 Thought-Action-Observation 链,确保上下文连续
  • 工具描述:每个工具都有标准化描述,帮助 LLM 理解何时使用
  • Few-shot 示例:内置典型交互样例,教会 LLM 输出格式

2. 输出解析机制

LLM 输出纯文本后,通过 AgentOutputParser 解析结构化数据:

python 复制代码
# LLM 输出示例文本
"""
Thought: 需要计算 2+2*2
Action: calculator
Action Input: "2+2*2"
"""

解析过程:

  1. 正则匹配 :提取 Thought:/Action:/Action Input:
  2. 格式验证:确保符合预定 schema,否则触发格式错误处理
  3. 工具映射:将 Action 字符串映射到具体工具实例

关键代码(简化):

python 复制代码
class ReActParser:
    def parse(self, text: str):
        thought = re.search(r"Thought: (.*?)\n", text).group(1)
        action = re.search(r"Action: (.*?)\n", text).group(1)
        action_input = re.search(r"Action Input: (.*?)\n", text).group(1)
        return AgentAction(tool=action, input=action_input, log=thought)

3. AgentExecutor 循环控制

这是 ReAct 的"大脑",管理整个执行流程:

python 复制代码
class AgentExecutor:
    def run(self, query):
        # 初始化
        scratchpad = ""  # 交互历史
        steps = 0
        
        while steps < max_iterations:
            # 1. 调用 LLM 生成下一步
            llm_output = self.llm(
                prompt.format(input=query, agent_scratchpad=scratchpad)
            )
            
            # 2. 解析输出
            action = self.output_parser(llm_output)
            
            # 3. 判断终止条件
            if isinstance(action, AgentFinish):
                return action.return_values["output"]
            
            # 4. 执行工具
            observation = self.tools[action.tool].run(action.input)
            
            # 5. 更新 scratchpad
            scratchpad += f"{action.log}\nObservation: {observation}\nThought: "
            
            steps += 1
        
        return "达到最大迭代次数"

关键设计模式:

  • while 循环 :实现 Thought-Action-Observation 循环
  • scratchpad 累积:将每轮结果追加,形成完整上下文
  • 终止判断 :当解析出 AgentFinish 时返回最终结果

4. 工具调用架构

工具通过标准化接口集成:

python 复制代码
class BaseTool:
    name: str  # 工具唯一标识
    description: str  # 给 LLM 看的说明
    args_schema: BaseModel  # 参数结构
    
    def _run(self, input: str) -> str:
        # 具体实现
        pass

动态注册机制:

python 复制代码
# 工具自动发现
tools = [
    Tool(name="search", func=search_api, description="搜索引擎..."),
    Tool(name="calculator", func=calculate, description="计算器...")
]

# 传递给 Agent
agent = create_react_agent(llm, tools, prompt)

5. 错误处理与鲁棒性

常见错误类型:

  • 格式错误:LLM 未按指定格式输出 → 捕获异常并重新提示
  • 工具不存在:LLM 幻想了不存在的工具 → 返回错误 Observation
  • 参数错误:工具调用参数格式不对 → 捕获异常并反馈

自我修复机制:

python 复制代码
except OutputParserException:
    # 将错误信息加入 scratchpad,让 LLM 自我纠正
    scratchpad += f"解析错误,请严格遵循格式:Action: tool_name\nAction Input: input\n"
    continue  # 重新循环

6. 记忆管理

ReAct Agent 的记忆体现在两个层面:

短期记忆(核心):

  • agent_scratchpad:当前任务的交互历史
  • 每轮循环自动清空,任务结束即丢弃

长期记忆(可选):

  • 集成 ConversationBufferMemory 实现多轮对话
  • 在 Prompt 中注入历史对话摘要

技术实现总结

组件 实现方式 关键技术
推理生成 Prompt Engineering + LLM 调用 Few-shot、Scratchpad
行动解析 正则/结构化输出解析 Pydantic、OutputParser
工具执行 标准化接口 + 动态调用 BaseTool、回调机制
循环控制 While 循环 + 状态机 AgentExecutor、终止判断
错误恢复 异常捕获 + 上下文反馈 Try-Except、自我修复

这种设计将确定性代码逻辑 (循环、解析)与非确定性 LLM 生成完美结合,既保证了流程可控,又充分发挥了 LLM 的灵活性。

相关推荐
Halo咯咯3 分钟前
无限免费 OpenClaw:接入本地模型后,你的 AI Agent 就可以 24 小时自动干活(Mac Mini 可用)
人工智能
NAGNIP12 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab13 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab13 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP17 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年17 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼17 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS17 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区19 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈19 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能