破解Agent重复漂移:认知导航如何成为稳定性的关键底座
发布时间:2026/10/15 22:43:37 锦皓数字建站

如果要在 Agent 开发里排一个最让人崩溃的现象我大概率会把重复漂移排在第一位。所谓重复漂移就是 Agent 在长任务执行过程中逐渐偏离原始目标同时开始反复执行同一个动作——像一台卡了带的老式录音机明明已经输出了十次一模一样的中间结果它依然一本正经地继续调用工具、拼接上下文、生成下一轮看起来合理的输出。我这么说的底气来自上个月一次刻骨铭心的终局交付事故。我们小组负责开发一套面向数据自动化处理的 Agent 系统原计划在周五完成最终验收Agent 需要在无人值守的情况下完成数据清洗、指标计算、报告生成和异常复核四个环节。前两周联调测试都很顺利结果就在交付前夜Agent 在其中一个关键分支上陷入循环连续产生了上百次重复的工具调用直到触发资源上限进程才被强制中断。更头疼的是模块没有任何自我修复机制。我们连夜排查、反复重启、调整参数最后还是不得不人工接管交付整整延期了两天。事后复盘我们发现问题并不出在某句提示词或某个工具调用的写法上而是整个系统里缺少了一个关键底座——认知导航。这个概念当时还在我们心里只剩模糊的影子等真正把它想清楚并落地之后我们才意识到它对于应对 Agent 漂移和自愈缺失的价值有多大。1. 事故现场一台复读机式 Agent 是怎么把交付拖垮的1.1 从日志里看到的诡异循环先把事故现场还原一下。当晚我们正在执行一组面向客户日报的批处理任务流程设计得像一条流水线读取数据源 - 清洗字段 - 计算核心指标 - 生成报告章节 - 交叉复核。为了压缩时长任务被拆成若干并发子任务每个子任务由一个 Agent 角色独立推进。问题出现在第 37 步左右。从日志上看Agent 突然进入了一段搜索-总结-再搜索-再总结的循环。我把当时压平后的关键日志抽出来大概长这样step37 actionweb_search query最新季度营收数据 step38 actionsummarize result检索到相关页面3个摘要... step39 actionweb_search query最新季度营收数据 step40 actionsummarize result检索到相关页面3个摘要内容未发生显著变化... step41 actionweb_search query最新季度营收数据 step42 actionsummarize result同上未发现新增信息单独看每一条日志好像都说得通它确实在搜索确实在总结下一轮也确实带着更严谨的意图继续搜索。但把 80 条日志放到一起看就非常诡异了——搜索关键词几乎一样总结文本几乎一样连调用的工具参数都几乎一样。它就钉在同一个节点上一遍一遍重复同一个动作完全没有这件事我已经做完、可以做下一步的意识。1.2 事故造成的实际影响这次事故的代价远比延期两天这四个字要大。交付延期两天客户验收窗口整体后移连带后续排期全部被打乱。部分中间数据文件在循环中被反复写入产生了脏数据回滚时又牵连了其他干净的分区。人工复核工作量翻了数倍团队三个成员轮流值守才把报告手工补齐。最隐性的损失是信心我们对Agent 能不能在关键时刻稳定跑完这件事产生了严重怀疑后续好几周都不敢把复杂的无人值守任务交给它。1.3 当晚的应急处理当晚我们做了所有常规操作先重启任务发现照样卡在同样的位置再回滚数据到半小时前重跑一次之后依然循环最后无奈之下人工接管写了脚本手动完成剩余章节才保住了次日早上的一份临时报告。这一连串操作看起来很朴素但背后暴露了一个事实我们对 Agent 执行过程的监控和干预能力极其薄弱。除了能看到日志之外系统对Agent 是否在真正推进这件事没有任何判断。那种感觉就像把车开了出去却没有任何仪表盘——你只知道发动机在响不知道车到底在不在往前走。2. 为什么 Agent 会漂移从生成的本质讲起2.1 LLM 的每一步都是局部最优的赌博要理解漂移先得理解 Agent 的行动逻辑。Agent 的每一步动作本质上都是 LLM 基于当前上下文做的一次概率采样。它不像传统程序那样有一个确定性的状态转移函数——输入是什么、输出就是什么。它是从概率分布里挑选一个最合理的下一步。这个机制带来一个很微妙的特性每一步的合理性都是局部的。前一步如果偏了后一步就会在偏了的基础上继续推演误差像滚雪球一样越滚越大。对 Agent 本身来说它在第 37 步选择继续搜索的时候并不真的知道第 20 步已经完成过同样的搜索它只知道当前上下文里搜索看起来是一个合理动作。这也是为什么很多人在初步测试时觉得 Agent挺聪明一到长任务、复杂任务就原形毕露——短任务里偏差还没有机会累积长任务里每步微小偏差叠加起来足以让 Agent 彻底偏离航道。2.2 漂移的三条成因链条多年的项目交付经验让我意识到Agent 漂移不是单一原因而是几条因果链共同作用的结果。其一目标遗忘链。LLM 的注意力窗口有限长任务执行到后期最初的目标描述会被大量的中间指令、工具返回结果、历史输出淹没。模型实际上变成了只看得到最近几轮对话的近视眼它确实想完成任务但它对任务到底是什么的记忆已经模糊了。我们的日志里Agent 在第 30 步之后生成的中间结果里已经不再引用初始需求字段这就是目标被遗忘的典型信号。其二上下文污染链。Agent 的每一步输出都会拼接到下一次推理的上下文里。如果前序步骤出现了错误字段、冗余信息或者误导性的中间结论这些污染源会在后续每一轮被反复咀嚼把决策越带越偏。更麻烦的是LLM 分不清上下文里哪句是可信的、哪句是错的它只会一视同仁地当作依据。其三循环自洽链。这是最阴险的一条。当 Agent 陷入循环时它并不是无头苍蝇而是每一轮都能给自己找到继续做这件事的理由——还没找到需要的信息结果可能不完整再搜一次更稳妥。在这种自洽逻辑下它单看每一步都正当无比但整体已经彻底失去推进能力。我们事后分析那 80 条日志发现其中有 70 条的模型推理字段都在强调需要进一步确认数据完整性这就属于典型的循环自洽。2.3 单步正常与全局失控的悖论Agent 工程里最反直觉的地方就是单个步骤完全正常整体却在失控。传统程序的行为可预测性来自状态机执行到哪一行、变量是什么、结果如何每一步都有确定性的结果。Agent 完全不是这套逻辑它每一步都是生成式的天然没有全局一致性保障。这个悖论也是自愈问题变得棘手的原因如果出错的是工具调用参数重试就行了但如果出错的是整个轨迹已经失去靶心那重试一百次只是在同一个错误的道路上来回碾压。认知导航要解决的恰恰是这个全局靶心问题。3. 自愈是个被严重低估的系统工程3.1 自愈能力模型并不只是再试一次很多人一提自愈第一反应是出错了就重试。这其实是把复杂问题过度简化了。真正的自愈至少包含四件事感知系统能够感知当前 Agent 状态知道我走到哪一步了。判断系统能够判断这个状态是否偏离了预期轨道。决策系统能够决定用哪种方式回到轨道。执行系统能够生成纠偏指令并注入执行流程让 Agent 真正回到正轨。四件事缺一不可而且每一件事在 Agent 场景下都不容易做到。感知难因为 Agent 的输出是自然语言没有一个结构化的坐标可以被直接读取判断难因为偏没偏很多时候是语义层面的不是数值层面的决策难因为纠偏策略本身也是概率性的执行难因为它要把外部指令无缝嵌回 Agent 的上下文里还不能打断整体流程。3.2 为什么靠提示词调教实现不了自愈在我接手这个项目之前团队已经花了不少精力在提示词上做文章。比如在系统提示里写请务必检查是否偏离目标如果发现重复请重新规划。这类提示词有没有用有一点但远远不够。原因在于 LLM 的自我评估并不可靠它倾向于对自己生成的输出给出较高置信度。让它自查是否偏离目标它大概率会回答没有偏离一切正常——这不是它有意撒谎而是它在生成的上下文里缺少一把客观的尺子。更深一层的问题是循环中的每一步在 Agent 眼里都是有正当理由的所以用提示词检查是否重复时模型会自动把重复解释为谨慎或深挖而不是故障。这就像让一个迷路的司机自己判断有没有迷路他多半会说没有我只是在找更近的路。3.3 从自动驾驶说起导航是比更聪明的司机更靠谱的工程解那次事故之后我反复在想一个问题同样是复杂环境下的自主决策为什么自动驾驶系统可以在高速上稳定跑几百公里得到的答案很简单——因为自动驾驶不依赖司机更聪明而是依赖一套完整的外部基础设施地图、GPS、传感器、车道线、实时路况。这套基础设施里最核心的是导航系统。导航系统并不负责替司机踩油门打方向盘它只做一件事持续回答三个问题——车现在在哪里要去哪里偏航了没有如果偏航就重新规划路线。我后来逐渐意识到Agent 系统缺的也是这样一套东西。我们太关注让 Agent 更聪明了却忽略了给它配一个中立、客观、独立于生成过程之外的导航层。我们缺的就是认知导航。4. 认知导航Agent 稳定性的关键底座4.1 把 GPS 的思路搬进 Agent 系统所谓认知导航我把它定义为一组横跨 Agent 执行过程的元层控制机制目的是不让 Agent 每一步都听指挥而是保证它始终知道自己在哪里、要去哪里、有没有偏航并在偏航时能够自动回到正轨。它和传统控制流的本质区别在于Agent 的执行仍然是自由的、生成式的导航层不干预它怎么做只负责持续校验做到哪了、偏没偏。这就像 GPS 不会帮你踩油门但它会在你走错路口的时候喊一声您已偏航正在重新规划路线。4.2 认知导航的四个核心组件以我的工程实践来看一套完整的认知导航体系至少要包含四个部分。认知地图Cognitive Map这是对任务空间的建模。一个任务不是含糊的做一份报告而是被拆成若干可验证的里程碑节点比如数据已清洗指标已计算报告初稿已完成异常项已复核。每个里程碑都有可执行的验证函数能够判断是否真的达成了。认知地图解决的是要去哪里、怎么算走到的问题。状态定位State Localization这是从 Agent 每步输出中提取当前位置的能力。Agent 每完成一步导航层需要把这个动作对应的状态更新到地图上比如当前停留在数据已清洗这个节点。定位不是简单打标签而是需要从自然语言输出里抽取语义状态这一步通常要借助结构化输出协议或者小模型分类器。偏差检测Deviation Detection这是把当前位置和预期位置进行对比识别三种典型的异常重复、停滞、漂移。重复是状态的自我复制停滞是状态长时间没有推进漂移是状态偏离了目标相关方向。纠偏引擎Correction Engine这是根据偏差类型和严重程度生成纠偏指令的模块。它不直接修改 Agent 的内部逻辑而是以外部指令的形式介入上下文让 Agent 回到最近一个有效里程碑或者重新规划子任务路径。4.3 认知导航 vs 其他方案有朋友问我提示词约束、规则引擎、人工审核是不是也能实现类似效果我把对比整理了一下方便大家直观理解方案核心思路对长任务漂移的防护自动化水平主要局限提示词约束在系统提示里反复强调目标弱高无法客观判断是否偏离模型自我感觉良好规则引擎用 if-else 拦截重复调用中高规则写多了维护成本爆炸语义层面的漂移拦不住人工审核每跑几步就让人看结果中低不可扩展长任务全程盯人成本不可接受认知导航地图定位检测纠偏强高前期需要建模和协议设计上手门槛略高我并不是说提示词、规则引擎这些手段没有价值它们可以作为认知导航的补充但单独依赖它们很难在无人值守的长任务里保证稳定。4.4 认知导航带来的实际影响把认知导航接入系统之后影响是立竿见影的。最明显的变化是我们第一次可以在 Agent 运行的时候说清楚它现在卡在哪了——以前只能说感觉不对现在系统会直接给出偏差类型和置信度。其次是事故恢复时间大幅缩短从人肉排查数小时降到系统自动触发纠偏几十秒内恢复正常。这两个效果直接决定了我们敢不敢把更复杂的任务交给 Agent 全自动执行。5. 给 Agent 装上认知导航从设计到落地5.1 分层架构设计实践下来我推荐把系统分成四层职责清晰、边界明确任务解析层把用户目标解析成认知地图生成里程碑序列。执行层Agent 本体负责实际调用工具、生成内容、推进步骤。导航层包括定位、检测、纠偏三大模块独立于执行层运行。监控层负责指标采集、告警、可视化面向人类运维者。关键原则是导航层不能和执行层共用同一个模型的同一次推理也就是说它不能在 Agent 的脑子里做判断而要在外部用独立逻辑做校验。只有这样导航才是客观的。好比你不会让考生自己给自己改卷子。5.2 认知地图与目标状态建模认知地图是整个方案的起点。构建步骤如下把目标任务拆成不超过七个里程碑每个里程碑对应一个可验证的状态。给每个里程碑写一个验证函数输入是 Agent 的当前输出输出是布尔值。定义里程碑之间的依赖关系构成一张有向图。数据结构上我用的是类似这样的定义dataclass class Milestone: id: str description: str dependencies: list[str] validator: Callable[[AgentOutput], bool] dataclass class CognitiveMap: milestones: dict[str, Milestone] target_state: str max_steps: int def current_position(self, trajectory: list[AgentOutput]) - str: # 遍历已完成的里程碑返回最近一个完成的节点 id for m in self.milestones.values(): if m.validator(trajectory[-1]): return m.id return start这里有个经验要分享里程碑的验证函数不要太复杂越简单越好。能用输出里是否包含某个关键字段判断的就不要强行上语义模型。因为验证函数一旦复杂本身就会引入误判让导航系统变成新的故障来源。5.3 偏差检测的三板斧偏差检测是认知导航真正的技术核心。根据我的落地经验做以下三类检测基本覆盖了绝大多数漂移场景。重复检测Repetition Detection计算当前输出与最近 N 步输出的语义相似度。如果连续几轮相似度都超过阈值就判定为重复。在实现上我会用文本向量化模型算余弦相似度比直接比对字符串要鲁棒得多。def detect_repetition(trajectory: list[AgentOutput], window: int 5, threshold: float 0.92) - bool: 如果最近连续 window 条输出彼此之间的语义相似度都超过阈值判定为重复漂移 recent trajectory[-window:] if len(recent) window: return False vectors [embed(text) for text in recent] for i in range(len(vectors) - 1): sim cosine_similarity(vectors[i], vectors[i 1]) if sim threshold: return False return True停滞检测Stagnation Detection维护一个里程碑最后推进时间的变量如果当前时间减去最后推进时间超过上限说明 Agent 一直在原地打转但未必完全重复——比如它可能在换着花样做同一件事。阈值设置没有绝对标准我们的经验是取预期单步耗时的 5 到 8 倍作为停滞判定线。漂移检测Drift Detection计算当前输出与目标状态描述的语义相关性。低于阈值就认为 Agent 正在远离目标。这比重复检测更难调因为相关性本身是模糊的。我的建议是不要用一个大而全的语义模型而是分别计算与当前里程碑的相关性和与最终目标的相关性两条曲线分开监控哪个低了就报警哪个。def detect_drift(current_output: str, target_state: str, threshold: float 0.55) - bool: relevance cosine_similarity( embed(current_output), embed(target_state) ) return relevance threshold5.4 分级纠偏策略检测到偏差只是第一步怎么纠才是关键。我把纠偏策略分成四级每一级干预力度不同。经验是能用轻度移动解决的不要直接重来因为频繁重来会浪费大量算力还有可能引入新的问题。一级轻度偏离导航层直接在下一轮上下文里注入一条提示比如注意检测到连续多步重复请基于已有信息直接推进不要再执行相同动作。这种提示不改变任务结构仅仅改变 Agent 的注意力分布通常能解决简单的循环自洽。二级中度偏离回退到最近一个已验证的里程碑把中间未经验证的输出全部丢弃从该里程碑重新执行。这里需要认知地图提供最近有效节点的能力本质上是在局部做一个受限回溯。三级严重偏离放弃当前子任务路径重新规划从当前状态到目标的路径。注意不是回到起点而是从当前位置重新计算后续路径这样能减少不必要的重复开销。四级危急场景导航层判定 Agent 已经无法自行恢复自动冻结任务标记需要人工介入并向监控系统推送完整的偏差报告。千万不要让系统无限循环纠偏见过太多二次故障都是在自动修复阶段反复横跳造成的。def dispatch_correction(deviation: Deviation, state: AgentState) - Correction: if deviation.level DeviationLevel.MILD: return InjectHint(deviation.reason) if deviation.level DeviationLevel.MODERATE: return RollbackTo(milestonestate.last_valid_milestone) if deviation.level DeviationLevel.SEVERE: return Replan(targetstate.target_state) return EscalateToHuman()5.5 配套监控指标认知导航不能只做事中干预还需要给运维者提供事中可观测、事后可复盘的指标。我最终在监控面板上保留了五个核心指标重复率最近 N 步输出中语义相似度超过阈值的比例。停滞时长从最后里程碑推进到当前的时间间隔。里程碑达成率已完成的里程碑数占总数的比例。纠偏触发次数每小时各类偏差被检测到的次数按类型区分。自愈成功率纠偏之后Agent 在预期步数内恢复推进的比例。这里的自愈成功率是两个行为边界的重要参考。如果成功率高于 0.9说明纠偏策略有效如果持续低于 0.7就要认真考虑是不是认知地图建错了而不是继续调检测阈值。6. 常见问题与排查实录6.1 典型症状与根因对照和几个同行交流之后我发现大家遇到的问题高度相似。整理成一张排查表可以帮你在踩坑时少走弯路症状可能的根因优先排查方向Agent 反复执行同一动作循环自洽、缺少外部终止条件检查重复检测是否生效阈值是否过高任务跑到后面越来越偏目标遗忘、上下文污染检查里程碑验证函数是否被正确触发纠偏后依然原地打转纠偏指令太弱、或者模型未真正理解升级到回退策略不要只靠提示自愈后引发二次错误回退点选择不当、数据状态不一致强化里程碑验证函数确保回退点可信导航层本身误报频繁语义相似度阈值过紧放宽阈值引入人工标注样本校准6.2 排查步骤如果正在跑的任务突然表现异常我建议按这样的顺序排查先看监控指标确认是重复、停滞还是漂移。再到日志里定位循环的起始步通常从首次语义相似度超过阈值那一步开始。检查那一步前后的上下文判断是工具返回异常还是目标被遗忘。手动复跑最近一个有效里程碑到异常点之间的路径确认可复现性。最后决定是调检测阈值还是升级纠偏等级。这五步走下来大部分问题都能定位到具体环节。很多时候你会发现问题不在 Agent 本身而在上游——认知地图建得不够细或者目标任务本身描述得就不清晰。6.3 几个我后来才懂的小技巧第一个技巧给里程碑设计明确的结束信号可以大幅减少重复漂移。比如让 Agent 在每个里程碑结束时必须输出一行包含固定标记的 JSON。导航层看到这个标记才知道这个节点走完了。这一步能沉淀结构化状态检测自然就稳定了。第二个技巧检测重复不要只看文本相似度还可以看工具调用参数。文本可能因为改写而变化但工具参数往往高度结构化。在我们的案例里重复循环中的搜索参数几乎完全一致用参数一致性来判断比语义相似度更早、更准。第三个技巧纠偏提示要放在上下文靠前的位置并且用独立的系统消息注入而不是拼在对话历史末尾。实测下来放在末尾的提示容易被最近几轮的长输出淹没放在开头或作为系统插播消息效果会明显好很多。7. 最后说点体会那次终局交付事故之后我对 Agent 工程化的理解彻底变了。以前我总觉得让 Agent 更聪明、理解更复杂的指令才是解决问题的关键现在我认为在长任务里保证稳定推进比在单轮对话里表现得聪明重要得多。聪明是上限稳定是底线底线守不住上限再高也没有交付价值。认知导航这个概念听起来有点像给 Agent 装 GPS但它真正解决的其实是工程上一个非常朴素的问题我们有了一套独立于 Agent 之外的手段来回答它现在到底在干什么、离目标还有多远、要不要帮它拉回来。有了这套手段我才敢把真正关键的任务交给 Agent 全自动去跑。如果让我给正在做类似系统的人一句建议我会说不要等事故发生了才想起做导航层。你可以在设计阶段先定义清楚目标状态和里程碑哪怕只用最朴素的规则检测也能在关键时刻救你一命。别让让 Agent 更聪明的愿望盖过了让 Agent 更可靠的基本功课。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。