智能体经典范式深度解析:ReAct、Plan-and-Solve 与 Reflection 的工程实践与未来思考
当大语言模型从"问答工具"走向"自主决策者",智能体(Agent)范式成为真正落地的桥梁。本文系统拆解 ReAct、Plan-and-Solve、Reflection 三大经典范式的工作机制,并探讨未来多智能体系统的演进方向。
一、引言:为什么需要"范式"?
大语言模型(LLM)本身存在两个先天短板:幻觉与无法与外部世界交互。把 LLM 装进一个"感知—思考—行动"的循环里,就得到了智能体(Agent)。但循环不是随便设计的——错误的循环会让 LLM 陷入死循环、产生错误累积、或者干脆无法收敛。
过去两年,业界沉淀出三种最具代表性的范式:
| ReAct | Reasoning + Acting 交替 | 想一步做一步,边走边看 |
| Plan-and-Solve | 先规划后执行 | 出门前画好路线图 |
| Reflection | 加入反思与自我批评 | 做完再复盘,哪里错了改哪里 |
这三种范式不是互相替代,而是层层递进——ReAct 解决"能动起来",Plan-and-Solve 解决"别乱动",Reflection 解决"动完能进步"。
二、ReAct:思考与行动的交响曲
2.1 工作流程
ReAct 由 Shunyu Yao 等人在 2022 年提出(论文 ReAct: Synergizing Reasoning and Acting in Language Models),其核心是让 LLM 在每一步生成两种输出:
Thought_1 → Action_1 → Observation_1
↓
Thought_2 → Action_2 → Observation_2
↓
…
Thought_n → Action_n → Observation_n → Final Answer
关键设计:
- Thought:推理当前状态、决定下一步行动。不直接暴露给用户,只进入下一轮上下文。
- Action:调用外部工具(搜索、计算器、API、代码执行器等)。
- Observation:工具返回的结果,作为下一轮 Thought 的输入。
这种"思考-行动-观察"的闭环,让 LLM 能够:
2.2 工具的定义与实现
工具的本质是带 JSON Schema 描述的函数。业界标准做法(LangChain、OpenAI Function Calling、Qwen-Agent 都是同一思路):
# 1. 定义工具:必须包含 name、description、parameters 三个要素
TOOLS = [
{
"name": "search",
"description": "搜索引擎。当需要查询实时信息或未知事实时调用。",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "搜索关键词"}
},
"required": ["query"]
}
},
{
"name": "calculator",
"description": "数学计算器。处理任何算术或代数表达式。",
"parameters": {
"type": "object",
"properties": {
"expression": {"type": "string", "description": "数学表达式"}
},
"required": ["expression"]
}
}
]
# 2. 工具实现:Python 字典,key 是工具名,value 是可调用对象
TOOL_IMPL = {
"search": lambda query: real_search_api(query),
"calculator": lambda expression: eval_safe(expression) # 真实场景禁用 eval
}
# 3. ReAct 提示词模板(简化版)
REACT_PROMPT = """请按以下格式回答问题,可用工具:
{tools}
格式:
Thought: 你的推理过程
Action: 工具名(参数)
Observation: 工具返回结果
… (可循环多次)
Thought: 我已经得到答案
Final Answer: 最终答案
问题:{question}
历史:{history}
"""
2.3 编码实现核心逻辑
def react_agent(question: str, max_steps: int = 8) –> str:
history = ""
for step in range(max_steps):
# 1. 让 LLM 决定 Thought + Action
prompt = REACT_PROMPT.format(
tools=format_tools(TOOLS),
question=question,
history=history
)
response = llm_call(prompt) # 返回结构化文本
# 2. 解析 Action(生产环境用正则 + JSON 解析双保险)
action_name, action_args = parse_action(response)
if action_name == "FINISH":
return extract_final_answer(response)
# 3. 执行工具,拿到 Observation
observation = TOOL_IMPL[action_name](**action_args)
# 4. 把这一轮追加到历史,进入下一轮
history += f"Thought: {extract_thought(response)}\\n"
history += f"Action: {action_name}({action_args})\\n"
history += f"Observation: {observation}\\n"
raise RuntimeError("ReAct 超出最大步数,可能陷入死循环")
2.4 ReAct 的特点、约束与调试技巧
优势:
- 简单直观,易于上手;
- 决策链路透明,便于 debug;
- 适合短链路、多工具切换的任务。
约束:
- 单步规划能力弱:每一步只看眼前,难以完成"先 A 再 B 最后 C"的复杂任务;
- 易陷入循环:没有全局状态,LLM 可能重复调用同一工具;
- Token 消耗大:每步都要把历史重新塞进 prompt。
调试技巧:
三、Plan-and-Solve:先谋后动的工程美学
3.1 工作原理
ReAct 的"边想边做"在长任务上很容易"走着走着就忘了要去哪"。Plan-and-Solve(Lei Wang 等人 2023 年提出,论文 Plan-and-Solve Prompting)的解决思路是两阶段分离:
阶段 1:规划(Planning)
输入:用户问题
输出:子任务列表(step-by-step plan)
阶段 2:执行(Executing)
输入:原始问题 + 子任务列表
输出:逐步求解
用一个具体例子说明。问题:“2020 年 NBA 总冠军球队的主教练,在哪所大学读书?”
- ReAct:搜索"2020 NBA 总冠军" → 搜到湖人 → 搜索"湖人主教练" → 弗兰克·沃格尔 → 搜索"沃格尔 大学"……(4-5 步)
- Plan-and-Solve:
- 查询 2020 年 NBA 总冠军球队;
- 查询该队的主教练;
- 查询该教练的教育背景。
3.2 规划阶段:让 LLM 当架构师
规划阶段的核心是结构化输出。实践中两种方式:
方式 A:提示词约束
PLANNER_PROMPT = """请将以下问题分解为可执行的子任务列表。
要求:
1. 每个子任务必须独立可解;
2. 子任务之间存在明确的输入输出依赖;
3. 标注每个子任务所需的工具类型。
问题:{question}
输出格式(JSON):
{{
"subtasks": [
{{"id": 1, "task": "…", "tool_hint": "search", "depends_on": []}},
{{"id": 2, "task": "…", "tool_hint": "search", "depends_on": [1]}}
]
}}
"""
方式 B:专用规划模型
- 用一个"规划专用"的 LLM(可以是更小的模型,比如 GPT-3.5)专门生成 plan;
- 另一个"执行专用"的 LLM 负责求解。
- 优点:解耦、专业化;缺点:增加系统复杂度。
3.3 执行器与状态管理
执行阶段的关键是状态机。每个子任务执行完后,状态要更新:
class PlanExecutor:
def __init__(self, plan: dict):
self.plan = plan["subtasks"]
self.results = {} # id -> answer
self.status = {st["id"]: "pending" for st in self.plan}
def run(self):
while not all(s == "done" for s in self.status.values()):
# 找到所有依赖已满足且未完成的任务
ready = [
st for st in self.plan
if self.status[st["id"]] == "pending"
and all(self.status[dep] == "done" for dep in st["depends_on"])
]
if not ready:
raise RuntimeError("死锁或循环依赖")
# 并行执行可并行的子任务
for st in ready:
self.status[st["id"]] = "running"
context = self._build_context(st)
answer = llm_call(EXECUTOR_PROMPT.format(
task=st["task"],
context=context
))
self.results[st["id"]] = answer
self.status[st["id"]] = "done"
def _build_context(self, st):
# 收集依赖任务的结果作为上下文
return "\\n".join(
f"[Task {dep}] {self.results[dep]}"
for dep in st["depends_on"]
)
3.4 Plan-and-Solve 的工程价值
- 可观测性:plan 是显式的,用户/产品/PM 都能看懂;
- 可控性:可以人为修改 plan,比如删掉某些步骤、补充背景;
- 可中断性:执行到一半可以暂停、恢复、人机协同;
- Token 效率:规划一次、执行 N 次,避免 ReAct 的重复决策开销。
代价是规划成本:如果规划错了,整个执行链都会错。所以生产环境往往采用"RePlan"——执行中发现问题,重新规划。
四、Reflection:让智能体学会自我进化
4.1 反射机制核心思想
ReAct 和 Plan-and-Solve 都有一个隐含假设:第一次规划/执行就接近正确。但现实是复杂的,LLM 一次性输出的答案往往有瑕疵。
Reflection 范式(Shinn 等人 2023 年 Reflexion 论文)引入一个反思循环:
Actor ──→ Environment
↑ ↓
└── Critic ←─┘
↓
Reflection Memory (写入经验)
↓
下次 Actor 决策时读取
关键洞察:错误本身是宝贵的训练数据。把"哪里错了、为什么错、下次怎么改"沉淀到记忆模块,下次决策时主动避免。
4.2 案例设定与记忆模块设计
以"代码生成"任务为例:
class ReflectionMemory:
def __init__(self):
self.short_term = [] # 当前任务的反思轨迹
self.long_term = [] # 跨任务积累的经验(向量库存储)
def add_reflection(self, task, output, error, reflection):
entry = {
"task": task,
"output": output,
"error": error,
"reflection": reflection, # LLM 生成的反思文本
"timestamp": now()
}
self.short_term.append(entry)
self.long_term.append(entry) # 实际生产用 embedding 存入向量库
def retrieve_relevant(self, current_task, k=3):
# 用 embedding 相似度检索历史反思
query_emb = embed(current_task)
scores = cosine_sim(query_emb, [embed(e["task"]) for e in self.long_term])
top_k = sorted(zip(scores, self.long_term), reverse=True)[:k]
return [e for _, e in top_k]
4.3 Reflection 智能体的编码实现
def reflection_agent(task: str, max_trials: int = 3) –> str:
memory = ReflectionMemory()
for trial in range(max_trials):
# 1. Actor 阶段:参考历史反思,生成答案
relevant = memory.retrieve_relevant(task)
actor_prompt = ACTOR_PROMPT.format(
task=task,
lessons="\\n".join(f"- {r['reflection']}" for r in relevant)
)
output = llm_call(actor_prompt)
# 2. 评估阶段:让 Critic 判断是否成功
success, error = evaluator(task, output)
if success:
return output
# 3. 反思阶段:让 LLM 分析失败原因
reflection_prompt = REFLECT_PROMPT.format(
task=task,
output=output,
error=error
)
reflection = llm_call(reflection_prompt)
# 4. 沉淀到记忆
memory.add_reflection(task, output, error, reflection)
return output # 达到最大次数,返回最后一次结果
4.4 成本收益分析
Reflection 不是免费的——每多一轮反思,就要多消耗一次 LLM 调用。什么场景值得用?
| 任务价值 | 高(医疗诊断、金融决策) | 低(闲聊、简单 QA) |
| 错误代价 | 高(不可逆操作) | 低(错了也无妨) |
| 任务可复现 | 强(同一类问题反复出现) | 弱(一次性任务) |
| LLM 一次性准确率 | 60%-80%(有提升空间) | >95%(接近天花板) |
经验值:Reflection 通常能把准确率从 70% 拉到 85%-90%,但成本是 2-3 倍的 token 消耗。
五、三大范式的对比与融合
5.1 对比矩阵
| 规划时机 | 每步 | 任务开始 | 任务结束后 |
| 适合任务长度 | 短(3-5 步) | 中(5-10 步) | 长(需要迭代) |
| 可控性 | 中 | 高 | 高 |
| Token 成本 | 中 | 低-中 | 高 |
| 调试友好度 | 高 | 高 | 中 |
| 学习曲线 | 低 | 中 | 高 |
5.2 工业实践中的融合模式
真实的智能体系统几乎都是混合范式:
用户输入
↓
[Plan-and-Solve] 生成初始 plan
↓
[ReAct] 每一步执行时边思考边行动
↓
[Reflection] 关键节点后反思
↓
[RePlan] 发现问题时重新规划
↓
最终输出
这就是 LangGraph、AutoGen、CrewAI 等现代框架的设计哲学——不站队某个范式,而是提供组合原语。
六、对未来的思考
6.1 从"单体智能"到"多智能体协作"
三大经典范式解决的是"一个 LLM 怎么完成任务"。未来 3-5 年的演进方向,必然是多智能体系统(Multi-Agent System):
- 专业化分工:规划 Agent、执行 Agent、反思 Agent 各司其职;
- 协作协议:Agent 之间通过消息传递(Message Passing)或共享黑板(Blackboard)通信;
- 冲突解决:多个 Agent 给出不同意见时,需要辩论、投票或仲裁机制。
OpenAI 的 Swarm、Anthropic 的 Multi-Agent Research、字节的 Coze 都在押注这个方向。
6.2 记忆机制的范式转移
当前 Reflection 的"向量库 + 相似度检索"是初级形态。未来的智能体需要:
- 分层记忆:工作记忆(当前任务)、情节记忆(最近经历)、语义记忆(长期知识)、程序记忆(技能);
- 可遗忘机制:人脑不是全量存储,而是有选择地遗忘——LLM 也需要类似机制避免记忆过载;
- 跨会话人格延续:今天的反思能影响明天的决策,跨越 session 边界。
6.3 工具生态的标准化
现在的工具调用各家一套(OpenAI Function Calling、Anthropic Tool Use、LangChain Tools),未来必然走向标准化。MCP(Model Context Protocol) 已经是 Anthropic 推动的尝试,类似"Agent 领域的 USB-C"。
标准化意味着:
- 工具可以跨模型复用;
- 工具市场会出现,类似今天的 npm/pypi;
- 智能体的"手"和"脚"会越来越强壮。
6.4 可信与可解释
工业落地最大的拦路虎不是能力,而是可信:
- 决策可追溯:每一步 Thought/Action 都要留痕;
- 失败可回滚:Agent 干了错事能 undo;
- 偏见可审计:定期检查 Agent 是否产生歧视性决策;
- 成本可预测:Token 消耗要可控,避免一次调用烧掉一个月预算。
这意味着**智能体可观测性(Agent Observability)**会成为新赛道——类似 LangSmith、Langfuse 这样的工具会越来越重要。
6.5 我的判断:范式会消失,"能力"会留下
三年后回头看,ReAct、Plan-and-Solve、Reflection 这些名字可能就像今天的"循环神经网络"一样被淡忘。但它们解决的核心问题——规划、执行、反思——会沉淀为 LLM 的内生能力,就像今天的 LLM 天然能做 In-Context Learning 一样。
未来的竞争不是"谁的范式更优雅",而是:
七、写在最后
学习智能体范式,最大的收获不是记住三个名词,而是建立"分解-执行-反思"的问题分析框架:
- 这个任务能不能拆解?(→ 考虑 Plan-and-Solve)
- 每一步是否需要外部信息?(→ 考虑 ReAct)
- 错误能不能避免重复?(→ 考虑 Reflection)
技术迭代飞快,但底层的工程思维是稳定的。愿我们都能在范式变迁中保持定力,在能力成长中保持谦逊。




