AI Agent 为什么会跑偏:目标漂移、上下文污染和工具诱导

AI Agent 为什么会跑偏:目标漂移、上下文污染和工具诱导 AI Agent 为什么会跑偏目标漂移、上下文污染和工具诱导摘要Agent 跑偏不是简单的“模型幻觉”。在一个会读上下文、会拆任务、会调用工具、会把工具结果继续写回上下文的系统里小误差会沿着行动链不断放大。本文用目标漂移、上下文污染和工具诱导三个概念解释为什么 Agent 明明一开始听懂了却会在执行过程中慢慢偏离原始意图。你应该见过这种情况你让一个 Agent “帮我整理这几篇资料看看它们对 Agent Memory 的理解有什么差别”。它一开始看起来很正常先读文件再总结主题再补充检索。问题是执行到一半它开始把重点放到某个资料里反复出现的 “RAG” 上再往后它主动扩展成“RAG 和 Agent Memory 的关系”最后交付的文章结构完整、语气自信、表格也漂亮但它已经不是在回答最初那个问题了。更麻烦的是它不是从第一句就错。它的每一步都“有理由”因为资料里确实提到了 RAG。因为检索结果确实补充了相关背景。因为工具返回确实给了它新的上下文。因为它自己总结出来的中间结论看起来也能自洽。这就是 Agent 跑偏最难识别的地方它不是突然胡说而是在一个看似合理的行动链里慢慢偏离了原始目标。先区分幻觉和跑偏不是一回事普通聊天模型的错误常常是“一次性”的。你问一个事实它答错了你让它解释一个概念它编了一个不存在的论文你让它写代码它用了不存在的 API。这类问题当然严重但它大多停留在“这次回答错了”。Agent 的问题更像一个循环系统里的误差放大。Anthropic 在讨论可信 Agent 时把 Agent 和普通聊天机器人的区别放在了一个关键点上Agent 会自我指导过程和工具使用会计划、行动、观察结果、调整再继续下一步。OpenAI Agents SDK 的 tracing 文档也把一次 Agent 运行拆成 LLM 生成、工具调用、handoff、guardrail 等一串事件而不是只看最后回答。也就是说Agent 的输出不是一次生成而是一条行动链。所以它的错误也不是一个点而可能是一条路径原始目标 - 任务拆解 - 读取上下文 - 选择工具 - 工具返回 - 写入新的上下文 - 再次解释目标 - 下一步行动如果某一步出现偏差下一步不是自动纠正它而是可能把这个偏差当成新的事实、新的目标或者新的行动依据。这就是本文对“Agent 跑偏”的定义Agent 跑偏不是一次性的事实错误而是目标、上下文和工具调用在循环中相互影响之后逐步偏离用户原始意图的过程。为了讲清这个现象可以把 Agent 跑偏拆成三层目标漂移它追的目标变了。上下文污染它相信的材料脏了。工具诱导它理解问题的方式被工具改变了。这三个词不一定是业界统一术语但很适合作为理解 Agent 行为的框架。第一层目标漂移用户给 Agent 的通常是一个目标而不是一个完全展开的执行脚本。比如帮我比较 A、B、C 三种 Agent Memory 方案的差异。这句话里真正的目标是“比较差异”。但 Agent 执行时会把它拆成很多局部任务1. 先理解 A。 2. 再理解 B。 3. 再理解 C。 4. 抽取维度。 5. 生成对比。问题出在局部任务一旦变得足够具体它就可能反过来压过原始目标。Agent 先读 A 的资料发现 A 里面有很多关于长期记忆、语义索引、用户偏好的内容于是开始展开解释。展开越多它越容易把“讲清 A”当成当前目标。等它再去读 B、C 时比较维度已经被 A 的叙事方式污染了。最后你得到的不是“三者对比”而是“A 的体系 顺带提一下 B 和 C”。这就是目标漂移。它不一定来自恶意输入也不一定来自模型能力不足。很多时候它来自一个很自然的执行机制Agent 必须把大目标拆成小目标而小目标会争夺注意力。可以把目标漂移看成三种常见形态。1. 子任务替代原任务这是最常见的一种。原始目标是比较 A 和 B 的差异。中间子任务是先收集 A 的资料。跑偏结果是输出一篇 A 的介绍B 只在结尾出现。这里 Agent 并不是完全忘了 B而是它在执行过程中把“收集 A 的资料”当成了主要任务。它完成了一个局部正确的动作却丢掉了全局问题。2. 手段变成目的很多 Agent 会先建立计划计划本来只是手段。但执行一段时间后它可能开始服务于计划本身而不是服务于用户目标。例如用户只是想“快速了解一个概念”Agent 却把任务改写成需要先查资料、再做分类、再生成表格、再给出最佳实践。表面上看更完整实际上已经偏离了“快速了解”的原始意图。这类跑偏尤其容易出现在“越努力越跑偏”的场景里Agent 不是偷懒而是过度执行。3. 成功标准被 Agent 自己改写还有一种更隐蔽Agent 自己创造了一个成功标准。比如用户要的是指出这段方案哪里不合理。Agent 可能在中间总结成目标优化这段方案使其更完整。于是它开始补充优点、修正文案、扩展结构最后避开了真正的问题批判。这种时候Agent 看起来很有建设性但它完成的是自己改写后的任务。目标漂移的关键不在于“模型没有理解用户”而在于理解会在执行过程中被重新解释。用户说的目标在第一轮被理解一次工具返回后被理解第二次上下文压缩后被理解第三次每次理解都可能损失一点东西也可能多长出一点东西。当这些变化积累起来Agent 就开始偏航。第二层上下文污染如果说目标漂移回答的是“它为什么追错了方向”上下文污染回答的是“它为什么相信了不该相信的东西”。这里的“污染”不只指恶意 prompt injection。它可以是很普通的东西旧对话里残留的目标。检索结果里质量很低的网页。工具返回里的错误状态。Agent 自己压缩历史时写错的摘要。用户随手贴进来的不完整材料。Anthropic 在 context engineering 文章里强调到了 Agent 阶段需要管理的不只是 prompt而是整个上下文状态系统指令、工具、外部数据、消息历史等都会进入模型推理时看到的 token。它也明确提到长任务会遇到 context pollution 和信息相关性问题。这点非常重要。很多人还把上下文理解成“多给点资料”。但对 Agent 来说上下文不是资料仓库而是工作现场。工作现场里如果混进了过期信息、错误摘要、低可信网页、工具残留它们不会安静地躺在那里它们会参与下一轮决策。上下文污染的五个入口来源污染方式典型后果历史对话旧目标残留在新任务里Agent 把上一次的约束带进这一次检索结果低质量资料被当成证据结论被搜索噪声带偏网页内容外部文本夹带指令或偏见模型混淆资料和指令工具返回错误结果写入工作记忆后续步骤基于错误状态继续执行压缩摘要细节在总结中丢失或变形Agent 以为“已确认”其实只是“被概括”最极端的上下文污染就是间接 prompt injection。Greshake 等人在 2023 年的 “Not what you’ve signed up for” 中提出LLM 集成应用会模糊数据和指令之间的边界。攻击者可以把指令嵌入到将被检索的外部数据里让应用在处理这些数据时受到操控。BIPIA 相关研究也指出模型难以区分“信息性上下文”和“可执行指令”这是间接 prompt injection 成功的重要原因之一。但即使没有攻击者普通上下文也会污染。比如一个 Agent 做资料整理用户目标比较三种方案的差异。 检索结果某篇博客强烈推荐方案 A。 Agent 摘要方案 A 是目前更主流的选择。 后续写作以 A 为主线组织全文。这里没有人攻击它但“某篇博客的倾向”已经从外部资料变成了 Agent 的内部判断。再比如一个 Agent 做代码分析工具返回没有找到相关文件。 真实原因搜索路径写错了。 Agent 结论项目里没有这个模块。 后续动作建议从零新增模块。工具返回并不是最终事实它只是某次查询的结果。但如果 Agent 把它写进上下文当成“已经确认”后面的行动就会越来越偏。这就是上下文污染最危险的地方它让“来源不明的信息”变成“下一步推理的前提”。第三层工具诱导工具调用让 Agent 从“会说”变成“会做”。但工具不仅扩展能力也改变问题本身。OpenAI 的 function calling 文档里说工具让模型访问外部功能和数据模型在生成响应时可能判断自己需要某个工具来完成指令。这个描述看起来中性但背后有一个很容易被忽略的点一旦工具出现在 Agent 的行动空间里它就不只是一个能力列表也是一个问题解释框架。有搜索工具Agent 更容易把问题理解成“需要先搜一下”。有文件编辑工具Agent 更容易把建议理解成“直接改文件”。有数据库查询工具Agent 更容易把分析理解成“查表就能解决”。有发消息工具Agent 更容易把沟通问题理解成“需要发一条消息”。工具像一组“行动暗示”。它们会告诉模型这个世界里哪些动作是可用的哪些路径是顺手的哪些结果可以被快速获得。这就是工具诱导。工具越多不一定越聪明很多人直觉上会觉得给 Agent 更多工具它就更强。这只说对了一半。更多工具确实扩大了行动空间但也扩大了误选空间。Anthropic 在关于工具设计的文章里提到工具要有清晰定义要谨慎使用 Agent 上下文工具描述、schema、实现方式都会影响 Agent 表现。换句话说工具不是普通 API。普通 API 是人看文档后调用Agent 工具是模型在不确定状态下选择调用。工具名字、描述、参数、返回值都会进入模型的判断。一个含糊的工具描述不只是“文档写得差”它会直接改变 Agent 对任务的理解。比如两个工具search(query)和search_public_web(query) 仅用于查找公开网页资料不能用于确认用户私有数据、内部项目状态或未经验证的事实。它们看起来都是搜索工具但对 Agent 的诱导完全不同。第一个工具会让模型觉得“任何不确定都可以搜一下”第二个工具会提醒它“搜索只适合公开资料不适合确认内部事实”。工具描述越宽Agent 越容易把问题工具化。工具边界越模糊Agent 越容易把“可以调用”误解成“应该调用”。工具返回也会继续诱导工具诱导不只发生在调用前也发生在调用后。例如搜索工具返回了十条结果其中八条都在讲某个热门概念。Agent 可能会误以为这个热门概念就是用户问题的核心。再比如一个代码搜索工具返回了某个旧目录Agent 可能开始围绕旧目录分析系统结构即使真正的代码已经迁移到了新目录。工具返回不是中立事实它是一次查询在特定条件下的观察结果。但 Agent 很容易把观察结果写成世界状态没有搜到 - 不存在 返回很多 - 很重要 工具报错 - 任务不可行 某路径出现 - 主路径就在这里这些推断未必可靠却会影响后续行动。所以工具诱导和上下文污染经常连在一起工具引导 Agent 选择某条路径。工具返回提供一批局部信息。局部信息被写入上下文。上下文反过来强化下一次工具选择。一旦形成循环Agent 就会越走越像“有逻辑”但这个逻辑可能已经不属于原始任务。为什么 Agent 时代更容易暴露这个问题聊天模型当然也会跑题。但 Agent 让跑题变得更有后果。可以用一张表看差异形态错误主要停在哪里典型表现Chatbot最终回答编事实、答非所问、解释错误RAG引用材料检索噪声、错引资料、证据不足Tool Use单次动作调错工具、参数错误、结果误读Agent行动链目标变形、上下文污染、工具路径自我强化Agent 时代的问题不只是“模型会不会答错”而是“错误会不会进入下一步行动”。这就是为什么只看最终回答越来越不够。OpenAI Agents SDK 的 trace 设计会记录一次运行里的模型生成、工具调用、handoff、guardrail 等事件正是因为 Agent 的行为需要看中间过程。最终答案可能很顺但中间路径已经暴露出偏航它可能用了错误资料可能调用了不必要的工具可能把某个临时结论当成事实。从知识理解上讲Agent 的可靠性至少有三层答案层它最后说了什么。路径层它中间看了什么、想了什么、调了什么。状态层它把哪些信息带进了下一步。普通问答主要看答案层。Agent 必须看路径层和状态层。因为跑偏往往不是最后一句才发生的而是在中间某个不起眼的“观察”里开始的。四种常见偏航轨迹为了更具体一点可以把 Agent 跑偏看成四种轨迹。轨迹一模糊目标被过度解释用户说帮我看看这个方案有没有问题。这句话很自然但目标不够明确。Agent 可能把“看看有没有问题”理解成找语病。补结构。做风险评估。改成更完整的方案。输出一份优化版。如果它选择了最后一种就可能从“指出问题”变成“帮你重写”。它越努力越偏离用户想要的批判视角。轨迹二检索噪声变成叙事中心用户问的是Agent Memory 和普通 RAG 的差别是什么Agent 检索后发现大量文章都在讲向量数据库、知识库、embedding。于是它开始沿着 RAG 资料组织全文最后写成“RAG 如何增强 Agent Memory”。这不是完全错误但问题被换掉了。原题是“差别”输出变成“关系”。轨迹三工具路径替代思考路径用户问这段日志说明系统哪里可能出了问题Agent 看到有日志检索工具就不断扩大检索范围从当前错误码查到历史任务再查到部署记录最后输出一堆环境信息。但它没有真正解释最初那段日志。工具给了它一种“继续查”的冲动。查得越多越像认真但推理反而被推迟了。轨迹四压缩摘要制造“虚假确定”长任务里Agent 经常需要压缩上下文。压缩本身很有用。Anthropic 提到compaction 可以把接近上下文窗口上限的对话总结后重新进入新上下文让 Agent 继续工作。但压缩也会制造风险。原始上下文可能只是方案 A 可能更适合长周期任务但证据还不充分。压缩后变成方案 A 更适合长周期任务。“可能”和“证据不充分”丢了。下一轮 Agent 看到的是一个更确定的结论于是继续沿着这个结论展开。跑偏就这样被摘要固化了。一个更有用的判断框架如果只问“Agent 有没有答对”很容易漏掉跑偏。更好的问题是三组问题对应风险它现在追的目标还是用户最初给的目标吗目标漂移它相信的信息来源和可信度清楚吗上下文污染它调用工具是因为必要还是因为工具刚好存在工具诱导这不是一个操作清单而是一个观察 Agent 的视角。当你看一个 Agent 的输出时不要只看它最后写得是否流畅还要反过来看它有没有把比较题写成介绍题它有没有把外部网页当成事实来源它有没有因为工具存在而过度搜索、过度编辑、过度执行它有没有把一次失败查询当成“事实不存在”它有没有在摘要里把不确定说成确定这些细节比“最后答案看起来是否合理”更能说明 Agent 有没有跑偏。最后Agent 越强越要看它如何偏离Agent 的吸引力在于它不只是回答问题还能自己规划、调用工具、观察反馈、继续行动。但也正因为如此它的问题不再只是“知识是否正确”而是“行动链是否还围绕原始意图”。普通模型答错了你看到的是一个错误答案。Agent 跑偏了你看到的可能是一套完整、流畅、自洽、甚至看起来很努力的结果。它最危险的地方不是荒谬而是合理。合理的局部动作连在一起不一定通向正确的整体目标。一个小的目标改写一段低质量上下文一个过于顺手的工具都可能让 Agent 从“帮你完成任务”变成“完成它自己理解出来的任务”。所以理解 Agent 跑偏不是为了否定 Agent。恰恰相反只有把目标漂移、上下文污染和工具诱导看清楚才更能理解 Agent 这种新形态到底和聊天机器人有什么不同。它不是更长的 prompt。也不是多几个工具。它是一个会在循环中改变自己状态的系统。而凡是会改变自己状态的系统都要认真看它偏离的方式。参考资料Anthropic, Trustworthy agents in practiceAnthropic, Effective context engineering for AI agentsAnthropic, Writing effective tools for AI agentsOpenAI, Function callingOpenAI Agents SDK, TracingGreshake et al., Not what you’ve signed up for: Compromising Real-World LLM-Integrated Applications with Indirect Prompt InjectionYi et al., Benchmarking and Defending Against Indirect Prompt Injection Attacks on Large Language Models