资讯动态

从符号规划到ReAct:LLM Agent中Planning的回归与工程实践

发布时间:2026/10/20 7:56:39 来源:尧图企业网站定制
1. 一个老概念突然翻红背后到底发生了什么如果你这两年一直在跟大模型应用打交道大概率会有一种恍惚感Planning规划这个词明明是上世纪六七十年代符号主义人工智能的看家本领怎么突然又成了热门话题更让人意外的是它这次回归的姿势跟当年完全不一样——不是靠逻辑推理引擎硬算而是跟强化学习、ReAct 这些新范式搅在一起变成了 LLM Agent 的核心能力之一。我自己是从传统任务调度系统一路做到现在的 Agent 应用开发的中间经历过符号主义那套规划器被统计学习方法按在地上摩擦的年代也见证过强化学习在决策问题上大杀四方。说实话前几年要是有人跟我聊“用规划来做智能体”我第一反应就是这东西状态空间一爆炸就没法用。但这两年情况完全变了LLM 把语义理解和常识推理这块补上了Planning 反而成了让 Agent 从“能聊天”变成“能干活”的关键拼图。这篇文章想聊清楚三件事第一Planning 为什么在符号主义时代兴起、又为什么衰落第二强化学习路线解决了什么问题、又留下了什么坑第三ReAct 这类范式是怎么把 Planning 重新拉回舞台中央的以及在实际工程里怎么落地。适合正在做 Agent 应用、对任务编排和决策链路感兴趣的开发者也适合想理解“为什么我的 Agent 总是跑偏”这个问题的朋友。全文会尽量用生活化的类比把原理讲透同时给出可以直接参考的实现思路和踩坑经验。2. 符号主义时代的 Planning辉煌与天花板2.1 从“积木世界”说起规划最初要解决什么问题要理解 Planning 为什么死而复生得先搞清楚它当年是怎么活的。符号主义时代的规划核心场景可以用一个经典例子概括一个机器人手臂面前有若干积木目标是把积木 A 放到积木 B 上面中间可能还有积木 C 挡路。系统需要输出一个动作序列比如“移开 C、抓起 A、移动到 B 上方、放下 A”。这个问题的本质是给定初始状态、目标状态和一组可执行动作找到一条从初始到目标的动作路径。听起来简单但难点在于动作之间有依赖关系、有前置条件、有副作用。比如“抓起 A”的前提是 A 上面没有东西而“放下 A”会改变 A 的位置状态。符号主义规划器就是把这些状态和动作用形式化语言描述出来然后用搜索算法在状态空间里找解。那个年代的代表性方法包括 STRIPS、PDDL 这些规划描述语言以及各种前向搜索、后向搜索、偏序规划算法。它们的共同特点是状态是离散的、动作是确定的、世界是封闭的。只要你能把问题形式化清楚规划器就能给你一个逻辑上正确的解。2.2 为什么符号主义规划后来不香了问题出在“把问题形式化清楚”这七个字上。真实世界太脏了。状态空间随变量数量指数级膨胀这就是著名的维度灾难。一个稍微复杂点的场景比如物流调度涉及几十个包裹、十几辆车、多个时间窗状态空间大到根本搜不完。更致命的是符号主义规划要求你把所有前提条件、所有副作用都写清楚但现实里大量知识是隐性的、模糊的、需要常识的。我举个具体例子。你让规划器安排“给客户送生日蛋糕”它会问你蛋糕是不是易碎品路上堵车怎么办客户不在家要不要放门口这些在符号系统里都得显式建模而建模成本高到离谱。于是从上世纪九十年代开始概率方法、统计学习、强化学习逐渐接管了决策问题Planning 这个词在主流视野里慢慢边缘化了。但这里有个关键点被很多人忽略了符号主义规划衰落不是因为“规划”这个思想错了而是因为它当时缺少一个能处理开放世界语义的“前端”。它需要一个能把自然语言目标翻译成形式化问题、能在执行中根据反馈动态调整的模块。而这个模块恰恰是 LLM 最擅长的事情。3. 强化学习路线从试错中学会决策但代价是什么3.1 RL 怎么把 Planning 挤到一边强化学习的思路跟符号主义完全不同。它不要求你预先写清楚状态转移和动作前提而是让智能体在环境里不断试错通过奖励信号来学习策略。你不需要告诉它“抓起 A 之前要确保 A 上面没东西”它自己撞几次墙就学会了。这种端到端的学习方式在游戏、机器人控制、推荐系统里取得了巨大成功。从决策角度看RL 其实也在做规划只不过它的规划是隐式地编码在策略网络参数里的。AlphaGo 下棋时每一步都在做长远规划但它不是用搜索树显式枚举而是用价值网络和策略网络来近似。这种方式的好处是能处理高维、连续、随机的环境坏处是样本效率极低训练一个能用的策略往往需要几百万甚至几十亿次交互。3.2 RL 在 LLM Agent 场景下的三个硬伤把 RL 直接套到 LLM Agent 上会遇到几个很现实的问题。第一个是奖励设计难。你让 Agent 帮你订机票什么叫“好”价格低、时间合适、转机少、不退改签方便这些目标之间还有冲突。设计一个能覆盖所有偏好的奖励函数本身就是个无底洞。第二个是样本效率。LLM 的推理成本本来就高你不可能让它在真实环境里试错几万次来学一个订票策略。第三个是可解释性差。RL 学出来的策略是个黑盒Agent 为什么选这个动作、为什么不选那个你很难跟用户解释。而在企业级应用里可解释性往往是刚需。所以 RL 虽然在决策领域很强但它没法直接解决 LLM Agent 的规划问题。它需要跟符号主义的显式规划思想结合才能发挥价值。这就引出了 ReAct 这类范式的出现。4. ReAct 范式让 Planning 以新形态回归4.1 ReAct 的核心机制思考与行动交替ReAct 这个名字来自 Reasoning Acting它的核心思想非常朴素让 LLM 在每一步先输出一段“思考”Thought说明当前应该做什么、为什么这么做然后输出一个“行动”Action调用工具或执行操作接着观察结果Observation再进入下一轮思考。这个循环一直持续到任务完成。这个机制为什么重要因为它把 Planning 从“一次性生成完整计划”变成了“滚动式规划”。传统符号主义规划要求你一开始就把所有步骤算好但 ReAct 允许 Agent 边走边看根据每一步的反馈调整后续计划。这就像你开车去陌生地方不需要一开始就记住所有转弯而是跟着导航一段一段走遇到封路再重新规划。从工程实现上看ReAct 的 prompt 结构通常包含几个部分任务描述、可用工具列表、历史思考-行动-观察记录、当前状态。LLM 根据这些信息生成下一步的思考和行动。关键在于思考部分不是装饰它实际上是让模型把隐式的规划过程显式化从而提高决策质量。4.2 为什么 ReAct 让 Planning 重新变得重要在 ReAct 框架下Planning 不再是独立的模块而是嵌入在每一轮思考里的能力。Agent 需要判断当前处于任务的哪个阶段、下一步该做什么、是否需要调用工具、调用哪个工具、参数怎么填。这些判断本质上就是规划。我实测下来ReAct 相比直接让 LLM 输出最终答案在复杂任务上的成功率有明显提升。原因在于第一显式思考让模型不容易跳步第二工具调用让模型能获取外部信息减少幻觉第三滚动式规划让模型能根据反馈纠错。这三点加起来正好补上了符号主义规划缺的语义前端和 RL 缺的样本效率。但 ReAct 也不是银弹。它的问题在于思考链可能跑偏、工具调用可能失败、多轮循环可能陷入死胡同。这些问题需要额外的规划约束和兜底机制来解决这也是当前 Agent 工程的重点方向。5. 从符号规划到 LLM Agent三条路线的融合实践5.1 把任务拆解成可执行的子目标在实际项目里我通常会把 Planning 分成两层高层任务拆解和低层动作执行。高层用 LLM 做语义规划把用户目标拆成若干子目标低层用工具调用或代码执行来完成具体动作。这种分层设计的好处是高层规划可以容忍一定的模糊性低层执行则要求精确。举个例子用户说“帮我安排下周去某地出差的行程”。高层规划会拆成确定出差日期、查询交通方式、预订往返票、安排住宿、生成行程单。每个子目标再交给低层执行模块处理。这种拆解方式跟传统符号规划里的层次任务网络HTN很像只不过拆解过程由 LLM 完成不需要人工写规则。5.2 用状态机约束 Agent 的行为边界ReAct 的自由度很高但自由度太高就容易失控。我在多个项目里发现给 Agent 加一个轻量级状态机能显著降低跑偏概率。状态机定义任务有哪些阶段、每个阶段允许哪些动作、什么条件下进入下一阶段。LLM 在每个阶段内做规划但不能跳出阶段边界。这个思路其实就是把符号主义规划里的“动作前提条件”用状态机的方式重新引入。比如“预订机票”这个动作前提是“已确定日期和目的地”状态机就会确保 Agent 不会在日期都没定的情况下就去查航班。这种约束不限制 LLM 的语义理解能力但给它划定了安全边界。5.3 用反思机制做执行后的规划修正Agent 执行完一步之后不能直接进入下一步而应该先反思这一步的结果符合预期吗如果不符合是计划错了还是执行错了需不需要调整后续计划这个反思机制是 ReAct 循环里最容易被忽略但价值最高的部分。我的做法是在每轮 Observation 之后强制 LLM 输出一段“评估”判断当前进度、识别异常、决定是否修正计划。这段评估会作为下一轮思考的输入。实测下来加了反思机制之后Agent 在遇到工具报错、信息缺失、结果异常时的恢复能力明显增强。这其实就是把强化学习里的“价值评估”思想用自然语言的方式轻量化地实现了。6. 实操落地一个可复现的 Agent 规划框架6.1 整体架构与模块划分下面这套框架是我在多个项目里迭代出来的核心模块包括任务解析器、规划器、执行器、反思器、状态管理器。任务解析器负责把用户输入转成结构化目标规划器负责生成和调整子目标序列执行器负责调用工具反思器负责评估执行结果状态管理器负责维护当前任务状态和历史记录。这套架构的关键设计原则是规划与执行分离、状态与逻辑分离、反思与行动交替。规划器不直接调用工具执行器不负责决策反思器不修改状态各模块通过状态管理器通信。这样做的好处是每个模块都可以独立替换和测试比如你可以把规划器从 ReAct 换成 Plan-and-Execute而不影响其他部分。6.2 关键参数与配置说明在规划器配置上有几个参数需要重点调整。第一个是最大规划步数我一般设 10 到 15 步太少容易半途而废太多容易绕圈子。第二个是反思触发条件可以设为“每步都反思”或“仅在异常时反思”前者质量高但成本高后者成本低但可能漏掉隐性问题。第三个是工具调用超时时间建议设 30 秒左右避免单个工具卡死整个流程。还有一个容易被忽略的参数是历史记录截断长度。ReAct 的历史会越来越长如果不截断很快就会超出上下文窗口。我的做法是保留最近 N 轮完整记录更早的记录压缩成摘要。摘要由 LLM 生成保留关键决策和结果丢弃冗余的思考过程。6.3 一个完整的执行流程示例假设用户任务是“帮我找一篇关于 Agent 规划的论文并总结”。任务解析器输出结构化目标查找论文、下载论文、提取内容、生成总结。规划器生成初始计划第一步搜索论文第二步筛选结果第三步获取全文第四步总结。执行器第一步调用搜索工具返回若干结果。反思器评估结果是否相关数量是否合适如果相关进入第二步如果不相关调整搜索关键词重新搜索。第二步筛选出最相关的一篇第三步获取全文第四步生成总结。每一步的 Observation 和反思都会写入状态管理器供后续步骤参考。这个流程看起来简单但实际跑起来会遇到各种问题搜索结果质量差、全文获取失败、总结偏离主题。这些问题的处理方式就是下一节要讲的排查技巧。7. 常见问题与排查技巧实录7.1 规划跑偏的三种典型表现第一种是目标漂移。Agent 一开始说要找论文搜着搜着变成在浏览相关博客最后输出了一堆不相关的内容。这种问题的根源通常是规划器缺少目标锚定机制。我的解法是在每轮思考里强制复述原始目标让 LLM 自己检查当前动作是否服务于目标。第二种是步骤循环。Agent 反复执行同一个动作比如反复搜索同一个关键词因为每次都觉得结果不够好。这种问题的根源是缺少终止条件判断。解法是给每个子目标设置明确的完成标准比如“找到至少三篇相关论文”或“连续两次搜索结果重复”。第三种是过早收敛。Agent 找到一个勉强能用的结果就停止没有继续优化。这种问题的根源是反思器过于宽松。解法是引入质量评分机制让反思器对结果打分低于阈值就要求重新规划。7.2 工具调用失败的排查思路工具调用失败是 Agent 落地时最常见的问题。排查时我一般按这个顺序检查第一工具描述是否清晰LLM 是否理解了这个工具能做什么、参数怎么填第二参数格式是否正确比如日期格式、枚举值范围第三工具本身是否稳定有没有超时或报错第四失败后 Agent 是否有重试或降级策略。这里有个经验工具描述要写得像给新人看的文档而不是像 API 文档。API 文档说“参数 type 为 string”但 LLM 需要知道“type 填 flight 表示查航班填 hotel 表示查酒店”。把枚举值的语义写清楚能大幅降低参数填错概率。7.3 上下文超限的压缩策略上下文超限是长任务绕不开的问题。我的压缩策略分三级第一级是丢弃冗余的思考过程只保留结论第二级是把多轮 Observation 合并成摘要第三级是把已完成的子目标压缩成一句话状态。压缩由 LLM 执行prompt 里明确要求保留“已确认的事实、已做出的决策、待解决的问题”。实测下来这套压缩策略能把上下文长度控制在原始长度的 30% 左右同时保留关键信息。但要注意压缩本身也有信息损失风险所以关键决策点最好在状态管理器里单独存一份结构化记录不依赖 LLM 摘要。8. 一些个人体会和后续可扩展的方向我在实际项目里最大的体会是Planning 在 LLM Agent 时代回归本质上是因为 LLM 补上了符号主义缺的语义层同时 ReAct 补上了 RL 缺的样本效率。三者不是替代关系而是互补关系。符号规划提供结构约束RL 提供优化目标LLM 提供语义理解和灵活决策。后续可以扩展的方向有几个。一是把规划器做成可学习的用少量人工反馈来微调规划策略这相当于把 RL 的思想轻量化地引入。二是引入多 Agent 协作让不同 Agent 分别负责规划、执行、评估通过角色分工提升整体可靠性。三是把规划过程可视化让用户能看到 Agent 的思考链路方便调试和建立信任。最后分享一个小技巧在规划器的 prompt 里加一句“如果你不确定下一步该做什么先输出你目前已知的信息和未知的信息”能显著减少 Agent 在信息不足时的胡乱决策。这个技巧成本极低但效果立竿见影。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑