跳到主要内容

反思安慰剂:为什么“计划-反思-重新计划”循环最终总是回到第一版

· 阅读需 11 分钟
Tian Pan
Software Engineer

打开一个智能体在长程规划任务中的追踪记录(trace),数一数模型写了多少次“让我重新考虑一下”、“经反思”或“更好的方法是”。现在,将它最终确定的计划与最初起草的计划进行对比。在我审计过的大多数追踪记录中,第二个计划其实就是换汤不换药的第一个计划 —— 同样的分解方式、同样的工具调用、同样的操作顺序,只是重命名了一些步骤标签并重新组织了理由的措辞。反思确实运行了。模型输出了看起来像是在重新考虑的 token。但计划本身纹丝不动。

这很重要,因为“带有反思”已悄然成为一种质量等级。团队在发布规划器时会加入一轮、两轮或三轮反思,并为此支付额外的成本。推理开支是真实且可衡量的。但计划层面是否真的发生了改变,几乎没有人去进行检测,而答案往往是:没有。

为什么第二个采样看起来和第一个如出一辙

当你要求模型起草一个计划时,第一个采样是从该提示词(prompt)输出分布的高概率区域中提取的。这就是采样的含义。当你随后要求同一个模型 —— 权重相同、上下文窗口相同、系统提示词也相同 —— 去“重新考虑上述计划并提出改进建议”时,后续的采样依然来自同一个分布,只是现在以第一个计划为条件。提示词变了,但模型对于“此任务的优秀计划长什么样”的先验认知并没有变。最可能的修订版本往往是验证初稿的版本,因为训练数据教会了模型在面对一个看起来合理的产出物时该怎么做:为它辩护。

这里主要有两种失败模式。第一种是确认偏误(confirmation bias)。当同一个模型同时担任规划者、评估者和反思者时,评估过程通常只是重述初始推理,并贴上更有信心的标签,而不是揭示真正的缺陷。第二种是模式坍缩(mode collapse):尽管收到了反馈,执行者在多次尝试中仍会产生近乎相同的方案,因为训练后的对齐(alignment)缩小了模型在给定提示词形式下认为可能的响应分布。最近关于言语化采样(verbalized sampling)的研究在数据层面记录了这一点 —— 偏好训练中的标注者系统性地青睐熟悉的输出,因此对齐后的模型学会了“熟悉的答案就是首选答案”,即使明确指令是要求产生不同的内容。

结果就是,在同一个模型、同一个提示词、同一个上下文中进行反思,其实是一种非常昂贵的让模型自我认同的方式。

检测反思究竟产出了什么

大多数团队没有注意到这一点的原因是他们没有对其进行衡量。他们衡量的是反思是否输出了(确实输出了)以及最终答案是否正确(有时是正确的,但有多少次是因为反思才正确的?)。他们几乎从不衡量反思前计划与反思后计划之间在关键层面上的差异(diff)。

在任何声称拥有反思功能的生产级规划器上,都值得运行以下三项测量:

  • 结构化差异率:在运行样本中,顶层分解 —— 即忽略措辞的主要步骤有序列表 —— 在反思后发生变化的频率是多少?不是指“是否有 token 改变”,而是指“计划的形态是否改变”。在我审计过的规划器中,这个数字通常低于 15%。
  • 仅词汇变化率:在计划发生变化的运行记录中,有多少变化仅限于词汇层面 —— 例如将步骤从“获取用户数据”重命名为“检索用户信息”,调整了要点的顺序,或者在不改变实际运行内容的情况下重写了理由。应单独追踪仅词汇的变化;它们是伪装成信号的噪声。
  • 工具调用增量:如果你已将计划序列化为一系列工具调用,那么该序列在反思后发生变化的频率是多少?如果从系统其余部分实际消耗的接口来衡量,许多反思轮次其实都是昂贵的空操作(no-ops)。

如果不到五分之一的反思轮次产生了结构性变化,而其余大部分只是表面修饰,那么你是在为“心理安慰”买单,而不是为了规划质量。

“堆砌更多反思”的陷阱

面对陷入困境的规划器,人们的可预见反应是加大力度:进行两轮反思,然后是三轮,接着是一个“反思再反思”的元循环(meta-loop)。Token 账单节节攀升。但计划却止步不前。每一轮额外的反思都会使下一个采样基于一个越来越长的上下文,而这个上下文现在被模型自身的先前输出所主导 —— 其中每一个输出都来自与第一个输出相同的分布。第 N 次反思并没有利用新信息;它是在通过第一个计划的辩护视角、通过第二个计划的确认视角,来利用第一个计划。

这也是 token 成本复利增长最严重的地方。智能体循环中的 token 消耗已经是二次增长的,因为每一步都会携带完整的历史记录。反思轮次会将这一基数乘以轮次数量,而且是在每一轮都在增长的上下文基础上进行的。一个十步智能体循环中的三轮反思链,其消耗的 token 很容易比原始计划多出一个数量级 —— 而产出的计划却与原始计划无异。如果你的财务团队在询问推理费用都花到哪儿去了,而你的规划器追踪记录中充满了反思块,那么很有可能你已经找到了答案。

停滞不前的规划器在向你传递某种信号,而这个信号并不是“更多地反思”。它是“这个模型在当前提示词下无法实现多样化”。解决办法并不是增加更多导致失败的操作。

究竟是什么产生了发散式计划

四种源自近期多样化规划研究的技术,在生成真正具有替代性的计划方面,表现始终优于单模型反思链。这些技术并不深奥,但它们都要求你停止要求同一个模型自我否定。

带有显式发散约束的 N-best 规划。 与其生成一个计划再让模型重新考虑,不如在单次调用中通过强制结构化差异的指令生成 K 个计划。“生成三个顶层分解方式不同、而不仅仅是措辞不同的计划”与“生成一个计划,然后对其进行反思”是完全不同的请求。显式发散约束让模型从一开始就从其分布的更广范围内进行采样,而不是陷入某种众数(mode)后再试图摆脱它。言语化采样(Verbalized sampling)——即要求模型列举候选方案及其相对可能性——所产生的语义多样性可靠地达到了单样本提示的两到三倍,且无需任何训练改动。

采用不同系统提示词的规划者与评论者分离。 如果你想要真正的批评,评论者就不能共享规划者的系统提示词。给评论者一个缩小角色的提示词——例如对抗性审查者、红队评审员、约束检查员——并提供一个排除掉规划者自我辩护逻辑的上下文。在 Planner-Actor-Critic 架构中的实证结果表明,一个狭窄、专业的评论者(即使运行在较小的骨干模型上),产生出的反馈也比共享完整上下文的评论者更具实质性差异,因为它不会被诱导去验证规划者已经说过的话。

变温重采样。 如果你要生成多个计划,不要在相同的温度下提取它们。在接近众数的低温度下提取一些作为保守基准,在高温度下提取一些作为探索性替代方案,然后让独立的评分环节进行排名。这比反思轮次更便宜,且每消耗一个 token 产生的结构多样性更高,因为每个高温样本都是独立的抽样,而不是对前一次抽样的条件式修正。

跨模型规划者集成。 打破确认偏误最廉价的方法是使用不同的模型。来自不同家族的两个规划者独立起草,在结构上产生分歧的频率远高于一个规划者自我反思三次。成本对比通常也是有利的——第二个模型的完整计划往往比已经在膨胀的上下文中进行的第三轮反思更便宜——而且这种多样性是本质上的,而非表面上的。跨家族集成是“这个模型有偏见;绕过它”在操作层面的体现。

对于已经上线反思功能的团队来说,这是一个令人不安的发现

如果你已经将反思作为一项质量特性上线,并衡量了上述三项指标,你可能会发现大部分反思支出只产生了润色性的输出,模型实际上是在收你的钱来安抚它自己。这是一个沉重的发现。它涉及产品主张、提示工程指南,在某些情况下,还涉及在添加反思功能后从未重新运行过的内部基准测试性能数据。

坦诚的回应是,根据问题难度分桶,重新运行带有和不带有反思功能的基准测试。常见的模式是:反思对于模型本来就能做对的问题有一点帮助(噪声输入,噪声输出,最终答案不变);对于处于模型能力边界的问题毫无作用;而对于那些第一版计划正确但反思却诱导模型做出了听起来合理但错误的修正的问题,反思有时反而有害。

修复方法并不是完全移除反思。单模型反思有其实际用途——格式纠错、显式不变性检查、约束违反捕获,在这些情况下,不变性是机械可验证的,不依赖于模型的判断。这些用途看起来一点也不像“重新考虑计划”。它们更像是“验证计划中的每个工具调用是否指向一个存在的工具”或“确认计划已终止”。这里的准则是,停止将结构化重新规划宣传为单模型反思所不具备的能力,并将预算转向那些真正能产生发散式计划的技术。

周一该做什么

如果你在生产环境中运行带有反思功能的规划器,以下是具体的下一步行动。从上周的追踪记录中抽取一百个反思轮次。对于每一个轮次,在工具调用序列级别(而非正文级别)对比反思前后的计划。将差异分为三类:结构性变化、仅词汇变化和无变化。如果结构性变化的分桶比例小于 20%,那么反思功能就是一个安慰剂,它消耗的预算应该被重新分配。如果结构性变化的分桶比例健康但结果没有改善,说明反思改变了计划但没有向有益的方向改变,那么评论者的提示词需要与规划者分离。无论哪种情况,你现在都有了一个数据。“带有反思”作为一个营销词汇,只有在有人愿意去量化时才具有支撑力。

References:Let's stay in touch and Follow me for more thoughts and updates