Skip to content
On this page
字数:2.5k 字
预计:8 分钟
阅读量:

智能体经典范式(二):ReAct、Plan-and-Solve 与 Reflection

作者:winches
更新于:14 天前

本文内容整理自 Datawhale Hello-Agents 第四章《智能体经典范式构建》,重点围绕 ReActPlan-and-SolveReflection 三种经典范式的原理、流程与适用场景进行总结。


1. 本章目标与为何「亲手造轮子」

在掌握大语言模型作为智能体「大脑」的基础上,本章将推理能力与外部世界联通:理解用户意图、拆解任务,通过代码解释器、搜索引擎、API 等工具获取信息并达成目标。

智能体同样面临:大模型幻觉、复杂任务中的推理循环、工具误用等能力边界。为组织「思考」与「行动」,业界形成了多种架构范式。本章聚焦三种最具代表性的范式并从零实现:

  • Reflection:通过自我批判与修正优化结果
  • Plan-and-Solve:先生成完整计划再严格执行
  • ReAct:思考与行动紧密结合,边想边做、动态调整

尽管已有 LangChain、LlamaIndex 等框架,亲手实现有助于:理解设计机制与工程挑战(输出解析、重试、防死循环)、从「使用者」升级为「创造者」,在标准组件不满足时能深度定制或从零构建。


2. 环境准备与基础工具定义

2.1 依赖与配置

  • 使用 Python 3.10+,安装 openaipython-dotenv
  • 在项目根目录创建 .env,配置 LLM_API_KEYLLM_MODEL_IDLLM_BASE_URL(可指向 OpenAI 或兼容接口)

2.2 基础 LLM 封装

定义 HelloAgentsLLM 类:

  • 从环境变量加载模型 ID、API Key、Base URL、超时
  • 提供 think(messages, temperature=0),内部调用 client.chat.completions.create,支持流式响应并汇总返回完整文本

便于后续各范式复用同一套模型调用。

2.3 工具三要素

一个良好定义的工具应包含:

  1. 执行逻辑:真正执行任务的函数
  2. 描述:自然语言说明用途——LLM 依赖此描述决定何时用哪个工具
  3. 名称:唯一标识符,供智能体在 Action 中调用(如 Search

2.4 工具执行器(ToolExecutor)

  • registerTool(name, description, func):注册工具
  • getTool(name):按名称获取执行函数
  • getAvailableTools():返回所有工具的格式化描述字符串,用于拼进提示词

为 ReAct 等范式提供统一的工具注册与调度基础。


3. ReAct(Reasoning and Acting)

3.1 核心思想

ReAct(Yao et al., 2022)将推理行动显式结合,形成「思考 → 行动 → 观察」循环,模仿人类解决问题的方式。

  • Thought:分析当前情况、拆解任务、规划下一步或反思上一步结果
  • Action:调用外部工具,如 Search[查询词],或 Finish[最终答案]
  • Observation:执行 Action 后从工具返回的结果

形式化:每步 (t),策略 (\pi) 根据问题 (q) 与历史 ((a_1,o_1),\ldots,(a_{t-1},o_{t-1})) 生成 ((th_t, a_t));环境执行 (a_t) 得到 (o_t = T(a_t));循环直到模型在 Thought 中判断任务完成。

适用场景:需与 API 交互、需精确计算(计算器)、需外部知识(天气、新闻、搜索)等。

3.2 工具定义与实现示例

以「华为最新手机及卖点」为例,需要网页搜索工具。示例使用 SerpApi:

  • 实现 search(query):调用 SerpApi,解析 answer_boxknowledge_graphorganic_results 前几条摘要
  • 将该函数以名称 Search、一段清晰描述注册到 ToolExecutor

工具描述要写清「何时使用」,以便 LLM 正确选择。

3.3 ReAct 智能体实现要点

  • 提示词模板:包含可用工具列表 {tools}、用户问题 {question}、历史 {history},并严格约定输出格式:
    • Thought: ...
    • Action: ToolName[input]Finish[答案]
  • 主循环
    格式化提示 → 调用 LLM → 解析 Thought / Action → 若为 Finish 则返回答案;否则执行对应工具 → 将本次 Action 与 Observation 追加到 history,进入下一步。设置 max_steps 防止死循环。
  • 解析:用正则从模型输出中抽取 ThoughtAction,再从 Action 中解析出工具名与输入(如 Search[华为最新手机]Search, 华为最新手机)。

3.4 特点、局限与调试

特点:工具与推理协同、根据 Observation 动态规划与纠错、Thought 链带来高可解释性。

局限:易陷入局部最优或循环、强依赖提示词与格式遵循、多步任务调用次数多(延迟与成本)、高度依赖底层 LLM 能力。

调试建议:换模型或调 temperature、在提示中加入 Few-shot 示例、检查工具输入输出格式、打印原始 LLM 输出与完整提示词以便排查解析与决策问题。


4. Plan-and-Solve(先规划后执行)

4.1 核心思想

Plan-and-Solve(Wang et al., 2023)将流程分为两阶段:先规划 (Plan),后执行 (Solve),以缓解纯思维链在多步复杂问题中「偏离轨道」的问题。

  • 规划阶段:根据用户问题 (q) 生成计划 (P = (p_1,\ldots,p_n)),由 (\pi_{\text{plan}}) 完成
  • 执行阶段:按计划逐步执行,第 (i) 步的解 (s_i = \pi_{\text{solve}}(q, P, s_1,\ldots,s_{i-1})),最终答案为 (s_n)

适合:结构清晰、可分解的任务——如代码结构设计、多源报告撰写、多步数学应用题。

4.2 规划阶段

  • 使用 Planner:提示词要求模型将复杂问题分解为可执行的步骤列表,并强制输出 Python 列表格式,例如
    ["步骤1", "步骤2", ...]
    便于用 ast.literal_eval 等稳定解析。
  • 从模型输出中提取 ```python ... ``` 之间的内容并解析为 list[str]

4.3 执行阶段与状态管理

  • Executor:对计划中每一步,构造提示词,包含:原始问题、完整计划、历史步骤与结果、当前步骤。只要求模型输出当前步骤的答案
  • 每步执行后将「步骤 i:…」「结果:…」追加到 history,作为下一步的上下文,实现状态在步骤间的传递。
  • PlanAndSolveAgent:组合 Planner + Executor,run(question)plan(question)execute(question, plan)

示例任务:多步数学应用题(如三天苹果销量),先分解为「周一 15、周二 30、周三 25、总和 70」等步骤,再逐步执行并汇总。

4.4 与 ReAct 的对比

  • ReAct:边想边做,每步依赖上一步的 Observation,更灵活、偏探索
  • Plan-and-Solve:先谋后动,计划静态、执行按图施工,更稳定、适合逻辑路径确定的推理密集型任务

5. Reflection(执行–反思–优化)

5.1 核心思想

Reflection(如 Reflexion, Shinn et al., 2023)为智能体增加事后自我校正:执行 → 反思 → 优化,循环迭代直到满意或达到迭代上限。

  • 反思:由「评审员」模型审视当前输出,从逻辑漏洞、事实错误、遗漏信息、效率等维度给出结构化反馈
  • 优化:根据任务、当前输出与反馈,生成修订版输出
    形式化:(F_i = \pi_{\text{reflect}}(\text{Task}, O_i)),(O_{i+1} = \pi_{\text{refine}}(\text{Task}, O_i, F_i))

价值:内部纠错回路、从「一次性执行」变为「持续优化」、可形成短期记忆轨迹,适合对质量与可靠性要求高、对实时性要求相对宽松的场景。

5.2 记忆模块

  • Memory:按顺序存储每轮「执行」与「反思」记录
  • add_record(record_type, content):记录类型为 executionreflection
  • get_trajectory():将记录格式化为可放入提示词的文本(上一轮代码 + 评审员反馈)
  • get_last_execution():取最近一次执行结果,供反思使用

便于反思与优化阶段都能看到完整历史。

5.3 Reflection 智能体实现要点

  • 初始执行:用「资深程序员」类提示词生成初版代码(或其它产物)
  • 反思提示词:角色为「严格的代码评审/算法专家」,针对算法效率等维度分析复杂度、指出瓶颈并给出可操作改进建议;若已最优则明确说「无需改进」
  • 优化提示词:根据「原始任务 + 上一版代码 + 评审反馈」生成优化版代码
  • 终止条件:反馈中出现「无需改进」或达到 max_iterations

示例任务:编写「1 到 n 的素数」函数——初版可能是试除法,反思指出复杂度高并建议筛法,优化后得到埃拉托斯特尼筛法等实现。

5.4 成本与收益

  • 成本:每轮至少两次额外 LLM 调用(反思 + 优化)、串行导致延迟增加、提示工程与角色设定更复杂
  • 收益:从「合格」到「优秀」的质量跃迁、发现并修复逻辑与事实错误、提高鲁棒性

适合:关键代码、技术报告、深度分析与决策支持等重质量场景;轻量或实时场景可优先 ReAct / Plan-and-Solve。


6. 本章小结与范式选择

范式核心策略优势典型场景
ReAct思考–行动–观察循环,边想边做环境适应与动态纠错、可解释探索性、需外部工具与实时信息的任务
Plan-and-Solve先规划后执行,计划静态结构清晰、目标一致、稳定可分解的多步推理、代码结构、报告撰写
Reflection执行–反思–优化迭代质量与可靠性提升、自我纠错对正确性与性能要求高的代码、报告、决策

实际选型取决于任务需求:是否需要外部工具、是否需要长远规划、是否值得用多轮迭代换质量。三种范式也可以组合使用(例如先 Plan-and-Solve 定步骤,再对关键步骤用 Reflection 优化,或单步内用 ReAct 调用工具)。


7. 参考

  • 原文:第四章 智能体经典范式构建
  • [1] Yao et al., ReAct: Synergizing Reasoning and Acting in Language Models, ICLR 2023.
  • [2] Wang et al., Plan-and-Solve Prompting, arXiv:2305.04091, 2023.
  • [3] Shinn et al., Reflexion: Language Agents with Verbal Reinforcement Learning, NeurIPS 2023.

Made with ❤️