Agent 真正的分水岭,不是“会回答”,而是“会稳定做事”:一文讲透推理框架与工程落地
大多数人构建 Agent 失败,不是因为用的模型不够强,而是因为根本没想清楚"怎么让它持续、可靠地把一件事做完"。
一、你遇到的那堵墙,叫"会回答"与"会做事"之间的鸿沟
很多团队第一次做 Agent 的过程是这样的:
用一个强模型,写几条 system prompt,加上几个工具调用,demo 跑起来了,看起来相当聪明——能搜索、能写代码、能总结。然后上线,开始出问题。任务中途卡住,工具调用失败没有恢复,执行路径陷入循环,最终状态不知道在哪里。
这不是模型不够强。换成更贵的模型,问题依然存在。
根本原因是:聊天和做事是两件截然不同的事。
聊天是无状态的一问一答。做事是有状态的、多步骤的、需要在不确定中持续推进的过程。中间有工具、有失败、有依赖、有反馈、有分支。光靠"更智能地生成下一个 token",不足以撑起这个过程。
这就是推理框架存在的意义。它不是让模型"更聪明",而是给模型提供持续完成任务的结构:怎么拆解问题,怎么规划步骤,怎么调用工具,怎么判断结果,怎么在失败后恢复。
二、推理框架解决的不是"智力"问题,而是"工程"问题
我们先把几个主流推理框架过一遍,但不是为了背概念——而是搞清楚它们各自在解决什么具体的工程问题。
CoT:把复杂问题拆成中间步骤
Chain-of-Thought 的核心洞察很简单:语言模型在"一步到位"时容易出错,但如果强迫它逐步推导,准确率会显著提升。
工程上怎么理解?CoT 本质上是把一次高风险的大跳跃,拆成多次低风险的小推断。每一步都是可审查、可调试的。
适合的场景:推理密集型的单次任务——数学、逻辑、分析、判断。它是基础,几乎所有复杂推理框架都内嵌了 CoT。
不适合的场景:多轮工具调用、需要外部反馈的动态任务。CoT 是"想清楚再说",不是"边做边想"。
ReAct:推理与行动交替,专为工具调用设计
这是目前工程落地最广的框架之一。结构是 Thought → Action → Observation → Thought → Action……循环往复,直到任务完成。
它解决的核心问题:工具调用不是瞬间完成的,外部世界的反馈(Observation)会影响下一步的推理(Thought)。ReAct 把这个"感知-思考-行动"的循环显式地建模出来。
工程上需要注意的:
- Observation 的格式化很重要。把工具返回的原始数据整形成模型能有效利用的格式,直接影响后续推理质量。
- 需要设计循环终止条件,否则容易陷入无限 Action 循环。
- Token 消耗随步数线性增长,长任务要考虑上下文压缩。
Self-Consistency:同一问题跑多次,投票选最稳的答案
一次推理可能抽到错误路径。多跑几次、多数路径投票,能显著提升结论的稳定性。
工程上的代价很明显:token 消耗成倍增加,延迟上升。所以不是什么场景都该用——只有当错误代价远大于资源代价时才值得开。高风险判断、分类决策、关键路由,用得上。普通问答,不要上。
Plan-and-Solve:先想好再动手
模型在执行复杂任务时,有一个常见失败模式:漏步。生成过程中"忘了"某个必要环节,结果到最后发现流程不完整。
Plan-and-Solve 的做法是先生成一个显式计划,再逐步执行。计划是可见的、可检查的。
工程价值:让任务的整体结构在执行之前就被显式化。这意味着你可以在执行前做校验,比如检查计划步骤是否覆盖了约束条件、是否有明显遗漏。
注意:计划和执行之间存在"计划漂移"问题——执行过程中遇到新信息,计划可能需要动态调整。系统设计时要考虑计划的可修订性。
ToT:把推理当成搜索问题
Tree-of-Thoughts 把推理路径建模为树结构,在每个节点评估多个候选方向,选择最有价值的分支继续探索。
这在理论上非常优雅——它把推理变成了一个有价值评估的搜索过程。
但工程代价极高:每个节点要生成多个候选并评估,计算量爆炸式增长。ToT 在工程实践中应该只用于极高价值、可以容忍高成本的决策点,比如复杂规划的关键分叉处,而不是整个任务都走 ToT。
实际落地建议:局部 ToT——大多数步骤用 ReAct,遇到关键分叉点时切换到 ToT 做多候选评估。
Reflexion:从失败中学习,而不是重试
大多数系统面对失败的处理方式是:重试。Reflexion 的处理方式是:反思。
失败后,模型生成一段反思文本(“上次哪里错了,为什么错,下次怎么避免”),把这段文字作为记忆存储起来,影响后续任务的执行。
工程价值:在需要迭代改进的任务中,Reflexion 能让系统从错误中积累经验,而不是每次都从零开始犯同样的错。
注意:反思记忆需要管理。错误的反思(比如对一个偶发性错误过度归因)会污染后续判断。记忆需要有清理机制。
三、怎么选框架:按任务类型,不是按概念热度
这是很多团队踩的最大坑之一:看到 ToT 概念新,全系统都套上去,结果成本飞涨、延迟爆表。
选框架的正确逻辑,是先定义任务类型,再匹配框架:
| 任务类型 | 推荐框架 | 原因 |
|---|---|---|
| 单轮推理、分析、判断 | CoT | 够用,代价最低 |
| 工具调用、外部交互 | ReAct | 天然适配感知-行动循环 |
| 高风险决策,需要稳定性 | Self-Consistency | 多路径投票提升可靠性 |
| 强规划、多目标、约束复杂 | Plan-and-Solve | 先显式化整体结构 |
| 关键分叉、高价值决策点 | ToT(局部) | 多候选评估,代价可控 |
| 迭代任务、失败恢复 | Reflexion | 从错误中积累经验 |
| 多 Agent 协作 | 框架 + 编排层 | 不能只靠 prompt |
有一条反直觉的原则值得记住:简单任务不要上复杂框架。CoT 能解决的问题,不要套 ReAct;ReAct 能解决的,不要套 ToT。框架本身会引入复杂性,复杂性本身是成本。
四、推理框架在工程系统里的真实位置
说完框架理论,我们必须谈工程现实。因为推理框架不是独立运行的——它嵌在一个完整的 Agent 系统里,和其他层紧密交织。
一个最小可用的 Agent 闭环是这样的:
输入 → 推理 → 行动(工具调用)→ 结果校验 → 状态更新 → 下一轮
推理框架驱动这个循环,但它不是全部。围绕它还需要:
状态管理层:Agent 执行过程中的状态分三类:
- 短期上下文:当前对话和任务上下文,放在 context window 里
- 任务状态:当前执行到哪一步、哪些子任务完成了、哪些失败了
- 长期记忆:跨任务积累的知识、用户偏好、历史经验
这三层要分开设计,不能全堆在 prompt 里。堆在 prompt 里的结果是:上下文爆炸,信息噪声增加,推理质量下降。
工具层:工具是 Agent 的手。工具设计有几个容易忽略的原则:
- 工具接口要稳定,Schema 版本要管理,避免工具接口变更导致 Agent 行为突变
- 工具调用要有超时和错误码,返回结果要结构化,而不是裸字符串
- 工具权限要最小化,Agent 能调用的范围要做白名单控制
编排层:推理框架决定"怎么想",编排层决定"怎么走"。对于复杂任务,编排层通常是一个状态机或图结构——节点是执行单元,边是转换条件,状态是整个任务的当前快照。
推理框架不是替代编排,而是驱动编排。推理框架的输出(下一步做什么)是编排层的输入(触发哪个节点)。两者协作,才能构成一个可控的执行系统。
五、基于 LangGraph 的工程参考:状态化、可观测、可回滚
为什么谈 LangGraph?因为它的核心设计理念和 Agent 工程的需求高度吻合:把 Agent 执行过程建模为一个有状态的图。节点是可执行单元,边是转换逻辑,状态是可持久化的快照。这让整个执行过程变得可观测、可回滚、可扩展。
一个基本的项目结构应该这样分层:
agent/
├── graph/ # 图结构定义:节点、边、状态 schema
├── nodes/ # 各功能节点实现:规划器、执行器、校验器
├── tools/ # 工具定义与 schema
├── memory/ # 记忆模块:短期 / 长期
├── prompts/ # prompt 模板,与代码分离
├── policies/ # 决策策略,与 prompt 分离
└── evals/ # 评估数据与评测脚本
关键的职责分离:
- 规划器节点:接收任务描述,输出执行计划(结构化的步骤列表)。它不执行,只规划。
- 执行器节点:按计划逐步执行,调用工具,收集 Observation。
- 校验器节点:评估执行结果是否满足任务目标。失败时决定是重试、反思还是上报。
- 记忆模块:在任务结束后更新长期记忆;在任务开始时检索相关历史。
一个完整任务链路的核心代码骨架:
from langgraph.graph import StateGraph, END
from typing import TypedDict, List
class AgentState(TypedDict):
task: str
plan: List[str]
current_step: int
observations: List[str]
reflection: str
result: str
status: str # planning / executing / validating / done / failed
def planner_node(state: AgentState) -> AgentState:
# 调用 LLM,生成结构化执行计划
plan = call_planner(state["task"])
return {**state, "plan": plan, "current_step": 0, "status": "executing"}
def executor_node(state: AgentState) -> AgentState:
step = state["plan"][state["current_step"]]
obs = execute_step(step) # 调用工具
observations = state["observations"] + [obs]
next_step = state["current_step"] + 1
status = "validating" if next_step >= len(state["plan"]) else "executing"
return {**state, "observations": observations, "current_step": next_step, "status": status}
def validator_node(state: AgentState) -> AgentState:
passed, result = validate_result(state)
if passed:
return {**state, "result": result, "status": "done"}
else:
reflection = generate_reflection(state)
return {**state, "reflection": reflection, "status": "failed"}
# 构建图
graph = StateGraph(AgentState)
graph.add_node("planner", planner_node)
graph.add_node("executor", executor_node)
graph.add_node("validator", validator_node)
graph.set_entry_point("planner")
graph.add_edge("planner", "executor")
graph.add_conditional_edges("executor", lambda s: s["status"], {
"executing": "executor",
"validating": "validator"
})
graph.add_conditional_edges("validator", lambda s: s["status"], {
"done": END,
"failed": "planner" # 反思后重新规划
})
这个骨架几百行代码,但它实现了一个完整闭环:规划 → 执行 → 校验 → 反思 → 重规划。每一步都有状态快照,任何节点失败都可以从 checkpoint 回滚,整个执行路径完全可观测。
六、真正的坑在哪里
用推理框架构建 Agent,有几个坑是几乎每个团队都会踩的,值得单独说清楚。
过度推理:链路越长,问题越多
这是最常见的反模式。以为推理链越长、步骤越多,效果越好。实际上:每增加一个推理步骤,都会引入错误积累、延迟增加、成本上升。
原则:用最短的推理链完成任务。能一步解决的,不要三步。能 CoT 解决的,不要 ReAct。
过度自治:工具滥用与任务跑飞
给 Agent 的工具越多、权限越大,出问题时影响范围越不可控。见过 Agent 因为理解偏差,把不该删的数据删掉的案例。
工程防线:工具白名单 + 权限最小化 + 高风险操作的人工确认节点。不要因为"Agent 应该自主"而放弃必要的人工介入点。
状态污染:错误记忆影响后续判断
Reflexion 的记忆如果没有清理机制,错误的反思会固化下来,影响后续任务。短期上下文如果不做压缩,会把噪声信息带进每一轮推理。
工程要求:记忆要有 TTL 和主动清理机制。上下文超过一定长度要做摘要压缩,而不是无限堆叠。
版本漂移:隐性的稳定性杀手
Prompt 改了,Schema 改了,工具接口升级了,模型换版本了——任何一个变化都可能改变 Agent 的行为,而且通常是悄悄改变的。
工程要求:Prompt、Schema、工具接口、模型版本全部纳入版本管理。生产环境的配置要能够冻结和回滚。
七、如何验证推理框架真的有价值:A/B 测试设计
引入推理框架之后,怎么知道它有没有效果?“感觉好像更好了"不是答案,数据才是。
核心指标体系(不是全要,按场景选):
- 任务成功率:端到端地完成任务的比例,这是最重要的指标
- 工具调用成功率:工具层的稳定性指标
- 平均步数:推理效率指标,步数异常增加可能意味着循环或困惑
- 平均耗时 / token 成本:资源效率指标
- 人工接管率:Agent 无法自行完成、需要人工干预的比例
- 恢复成功率:失败后通过 Reflexion 或重规划恢复成功的比例
实验设计:Baseline 是当前系统(通常是没有显式推理框架的 prompt 调用),Treatment 是引入推理框架的版本。按任务难度分层分析——推理框架对简单任务可能没有收益,对复杂任务才有显著提升。
离线 + 在线结合:先用历史任务数据做离线评测,确认指标趋势;再小流量上线做在线 A/B,确认生产环境中的真实表现。不要跳过离线直接上线——生产环境的问题发现成本太高。
八、结语:真正的竞争力是工程化能力
推理框架不是魔法。CoT、ReAct、Reflexion——这些名字本身没有价值,价值来自于把它们正确地工程化,并在生产环境中稳定运行。
很多团队在 demo 阶段表现亮眼,上线后问题不断。根本差距不在模型,也不在框架选择,而在工程化能力:状态怎么管,工具怎么设计,错误怎么恢复,版本怎么控制,效果怎么评估。
把"思考"变成"可靠执行”——这才是 Agent 真正的门槛。
下一阶段的竞争,不会在于谁调用了更强的模型,也不会在于谁用了更复杂的推理框架。竞争在于谁能把 Agent 从"能演示"变成"能交付",谁能让系统跑得稳、可观测、可回滚、可持续迭代。
工程能力,才是真正的护城河。