LLM Agent上下文污染:重试失效的根源与系统级解决方案

发布时间:2026/8/18 23:18:46
LLM Agent上下文污染:重试失效的根源与系统级解决方案 1. 项目概述当重试机制失效时我们到底在对抗什么如果你正在构建或使用基于大语言模型的智能体LLM Agent系统那么“重试”这个操作对你来说一定不陌生。当一次API调用失败、模型返回了不理想的答案、或者工具调用出错时我们的第一反应往往是“再试一次”。这似乎是一个简单、直接且符合直觉的补救措施——毕竟大语言模型具有概率性一次糟糕的输出可能只是运气不好。然而在实际的Agent流水线Pipeline中我踩过无数坑后发现盲目地重试不仅常常无效有时甚至会“火上浇油”让系统的表现越来越差。问题的核心就藏在这个标题里上下文污染。简单来说上下文污染指的是在一次失败的交互后Agent系统内部的状态包括对话历史、工具调用记录、中间思考过程等被“污染”了。当你基于这个已经被污染的状态发起重试时模型接收到的输入信息本身就是有问题的、有误导性的这导致它更难以生成正确的输出。这就好比让一个学生重做一道题但你给他的题目描述里却夹杂着上一次他做错时留下的错误思路和涂改痕迹他反而更容易再次犯错。这个项目标题“Why Retrying Fails: Context Contamination in LLM Agent Pipelines”精准地指向了当前Agent工程实践中的一个深水区。它不是一个简单的API错误处理问题而是一个关于系统状态管理、信息流设计和认知偏差的复杂课题。本文将从一个一线实践者的角度彻底拆解上下文污染的成因、表现、影响并分享一套经过实战检验的、从架构设计到代码实现的系统性解决方案。无论你是刚开始搭建第一个Agent的开发者还是正在优化复杂生产系统的工程师理解并解决上下文污染都是提升系统鲁棒性和可靠性的关键一步。2. 核心概念拆解什么是Agent流水线中的上下文在深入探讨污染之前我们必须先清晰地定义“上下文”在LLM Agent流水线中具体指什么。这里的上下文远不止是发送给大模型的那一串提示词Prompt它是一个贯穿整个Agent执行生命周期的、动态的、多层次的状态集合。2.1 上下文的构成要素一个典型的Agent流水线上下文通常包含以下几个核心层次对话历史这是最直观的一层即用户与Agent之间一问一答的序列。它不仅包括用户的输入和Agent的最终输出更重要的是包含了Agent在生成最终答案前的内部思考过程Chain-of-Thought。例如Agent可能会先输出“我需要调用搜索引擎工具来查询今天的天气”然后再输出工具调用的结果和最终总结。所有这些文本都构成了对话历史的一部分。工具调用状态当Agent决定使用一个外部工具如计算器、数据库查询、API时会产生一系列状态信息。包括工具选择调用了哪个工具调用参数传递给工具的输入是什么例如搜索关键词“北京今日天气”工具执行结果工具返回了什么可能是结构化的数据也可能是错误信息如“网络超时”工具执行元数据调用耗时、是否成功、错误码等。工作记忆/短期记忆这是Agent为了完成复杂任务而临时维护的信息。例如在一个多步骤的任务中“帮我订机票然后查一下目的地酒店”Agent需要记住第一步“机票已订航班号是CA1234”以便在第二步中作为查询酒店的上下文。这部分记忆通常有容量和时效性限制。系统指令与角色设定即整个对话的“基础设定”它定义了Agent的身份、能力范围和行为准则。例如“你是一个有帮助的旅行助手可以查询航班和酒店信息。你必须先确认用户预算。”这部分内容虽然相对静态但在流水线处理中其放置的位置和方式会影响模型对它的“注意力”。外部知识/向量存储检索结果当Agent需要从知识库中检索信息时检索到的相关文档片段会被注入到上下文中。这些片段的质量和相关性直接影响了模型的判断。2.2 上下文是如何被“组装”并送入模型的理解污染机制必须理解上下文的“组装”流程。通常一个Agent框架如LangChain、LlamaIndex、AutoGen会有一个“上下文组装器”模块。它的工作流程如下收集从上述各个来源历史记录、工具状态、记忆存储、知识库收集当前所有相关的信息片段。格式化按照预定义的模板将这些信息片段拼接成一段连贯的文本。例如一个常见的模板是系统指令{system_prompt} 对话历史 用户{user_input_1} 助手{assistant_thought_1} [调用工具{tool_call_1}] 工具结果{tool_result_1} 助手{final_answer_1} 用户{user_input_2} 当前轮助手思考长度管理关键步骤由于大模型有上下文窗口长度限制如4K、8K、128K Token组装器必须决定保留哪些历史信息裁剪或丢弃哪些。常见的策略有最近N轮对话只保留最近几次交互。关键信息优先尝试保留系统指令、最近的工具调用结果等。摘要压缩将较旧的、冗长的对话历史通过另一个LLM调用总结成简短摘要。污染就发生在这个“组装”过程中。如果上一次交互中包含了错误信息比如一个失败的工具调用返回了Error: Timeout而组装策略又将其保留了下来那么这段错误信息就会作为“历史事实”出现在下一次模型推理的上下文中误导模型的判断。注意很多开发者只关注“当前轮”的用户输入却忽略了组装后的、包含了“历史包袱”的完整提示词。调试Agent问题时第一件事就应该是把这个组装好的、即将发送给模型的完整提示词打印出来仔细审查。3. 上下文污染的典型场景与破坏性分析上下文污染不是一种理论上的可能性而是在实际系统中高频发生的“沉默杀手”。下面我结合几个最常见的场景具体分析它是如何导致重试失效甚至系统崩溃的。3.1 场景一工具调用失败后的“错误信息回声室”这是最经典、破坏力最强的污染场景。污染过程用户问“上海浦东机场到市中心打车多少钱”Agent决定调用“打车价格估算API”但由于网络问题调用失败返回结果{status: error, message: Network timeout. Failed to connect to pricing service.}这个错误结果被完整地写入了对话历史/工具状态。Agent基于这个上下文生成回答“抱歉查询打车价格的服务暂时不可用网络超时无法为您提供估算。”此时用户或系统触发重试。重试的输入上下文包含了第2-4步的所有信息。模型看到的历史是“用户问了价格 - 我调用了API - API返回了‘网络超时’ - 我回复了‘服务不可用’”。现在它被要求再次回答同一个问题。模型的推理逻辑极有可能被这段历史“锚定”。它可能会想“历史记录显示这个服务就是不可用的我再试一次估计也一样。但我必须给出一个回答。”于是它可能复读机再次生成几乎相同的错误回复。强行解释生成一个看似合理但基于错误前提的答案如“根据系统记录打车价格查询服务因网络问题持续异常建议您改用地铁票价约10元。”——这里关于地铁票价的信息可能是对的但整个推理的起点服务持续异常是被污染的错误假设。陷入死循环在更复杂的Agent逻辑中它可能尝试调用另一个相关但错误的工具引发连锁故障。为什么简单的重试无法解决因为重试没有清除污染的上下文。模型不是在“全新地”思考这个问题而是在一个已经被错误信息污染的思维框架里打转。3.2 场景二多轮对话中的“认知偏差累积”在复杂的多步骤任务中早期的微小错误会像滚雪球一样污染后续所有步骤的上下文。污染过程任务“帮我制定一个本周五从杭州到广州的差旅计划包括航班和一家五星级酒店。”步骤1航班Agent成功搜索到航班CA1234时间是周五上午10点。但在格式化输出时不小心将目的地写成了“深圳”一个笔误。这个“周五10点CA1234杭州-深圳”的信息被存入工作记忆。步骤2酒店Agent基于工作记忆搜索“广州的五星级酒店”。这里已经出现了不一致记忆中是深圳查询是广州但假设它还是搜到了一些广州的酒店。步骤3整合Agent生成最终计划“您的航班CA1234将于周五10点从杭州飞往深圳。为您预订的广州XX酒店……” 这个矛盾的计划飞深圳但住广州被写入最终对话历史。用户指出矛盾“等等我要去的是广州怎么飞深圳了”此时进行重试或让Agent修正。修正的上下文里包含了从步骤1到步骤5的全部混乱历史。Agent需要从一团乱麻中理清头绪它需要识别出最初的笔误同时还要处理后续基于笔误产生的矛盾信息。这个认知负荷极大模型很可能无法正确回溯到根源而是试图在现有矛盾的基础上进行“修补”给出更混乱的解释。污染的本质在这里污染不是一次性的错误数据而是一个错误的前提或中间结论它成为了后续所有推理的“地基”。重试相当于在歪斜的地基上继续盖楼只会让楼更歪。3.3 场景三检索增强生成中的“噪声注入”当Agent需要从知识库检索信息时检索到不相关或过时的文档会直接污染生成上下文。污染过程用户问“我们公司最新的差旅报销标准是什么”Agent从向量数据库检索相关文档。由于文档切分或相似度计算问题它同时检索到了相关文档A《2024年差旅报销标准》最新版。无关/过时文档B《2022年差旅报销标准》已废止。无关文档C《员工入职流程》完全不相关。这些文档都被拼接到上下文中送入模型。模型需要自行判断哪些信息是相关的、权威的。尽管最新版标准可能在前面但模型有时会被矛盾或冗余信息干扰。模型可能生成一个混合了新旧标准、甚至夹杂了入职流程信息的混乱回答。重试时如果检索环节没有改变例如没有优化检索策略或查询词那么同样的噪声文档会再次被注入上下文导致重试结果改善有限。更糟糕的是如果第一次的回答被作为“历史”保留那么第二次的上下文就包含了“噪声文档 上一次的错误回答”污染层级更深。4. 构建抗污染Agent流水线的架构设计要根治上下文污染不能只靠事后补救必须在系统架构层面进行预防性设计。下面分享一套我经过多个项目迭代后总结出的核心架构模式。4.1 核心原则状态隔离与纯净上下文管理我们的目标是确保每一次对LLM的核心调用都尽可能基于一个“纯净”的、目标明确的上下文。这需要将Agent的执行视为一个状态机并对状态进行精细化管理。架构蓝图[用户输入] | v [输入解析与意图识别模块] (可选用于路由) | v [上下文管理器] --- 核心组件 | | | | | v | | [工作记忆区] (存储多轮任务关键信息) | | | | | v | | [对话历史记录] (原始记录带污染标记) | | | v | [上下文组装与净化器] | | | v [任务执行引擎] ---- [工具调用层] | | | v | [外部工具/API] | | v v [输出生成与后处理] --- [工具结果过滤器] | v [状态提交与历史更新] (谨慎更新) | v [最终输出给用户]4.2 上下文管理器系统的“免疫中枢”这是对抗污染的最关键组件。它不应只是一个简单的列表追加器而应具备以下功能分层存储原始历史记录完整、按序存储所有交互的原始数据但不作为直接使用的上下文。每条记录需要打上元数据标签如type: user/assistant/tool,tool_name,success: bool,contains_error: bool。净化后的工作上下文这是一个动态的、为下一次模型调用准备的“干净”上下文。它由“上下文组装与净化器”生成。上下文组装与净化器的工作流程输入当前用户输入、原始历史记录、工作记忆、系统指令。步骤1诊断与标记扫描原始历史记录识别潜在的污染源。例如标记所有success: false的工具调用记录。标记所有模型输出中包含“抱歉”、“错误”、“无法”等失败信号的记录。通过一个轻量级分类模型或规则识别逻辑矛盾的历史语句如前面说“飞深圳”后面说“住广州”。步骤2策略性裁剪与重构根据诊断结果应用不同的净化策略生成“工作上下文”。策略包括完全丢弃对于明确的、孤立的失败工具调用及其后续的Assistant错误回应可以直接从工作上下文中移除。相当于让模型“忘记”这次失败。摘要与替换对于包含重要信息但夹杂错误的长段历史可以调用一个快速的总结模型如GPT-3.5-turbo生成一个去除了错误细节、只保留事实核心的摘要。例如将一次失败的工具调用和其回复总结为“用户曾询问X信息但当时未能成功获取。”保留但注释对于某些不能丢弃的失败记录例如用户正在追问这个错误将其保留在工作上下文中但加上明确的注释。例如[历史记录 - 上次尝试调用天气API时发生网络超时此结果可能不准确请重新尝试。]这相当于给模型一个“免责声明”和明确的指令。步骤3动态系统指令注入在组装好的工作上下文开头不仅注入固定的系统角色指令还根据当前诊断结果动态添加本轮的“临时指令”。例如如果诊断发现上次工具调用超时可以添加“注意上一轮对话中获取XX数据的尝试因网络问题失败。请在本轮中重新尝试获取该数据忽略上一轮中的错误状态描述。”4.3 工具调用层的“防火墙”设计工具调用是主要的污染入口必须在这里建立防线。工具结果标准化与过滤所有工具在返回结果时必须遵循统一的响应格式。例如{status: success/error, data: {...}, error_message: ..., metadata: {...}}。在工具结果被写入历史之前必须经过一个结果过滤器。过滤器的职责对于status: error的结果决定其写入历史的“剂量”。是记录完整的错误堆栈对调试有用但对模型是污染还是只记录一个简明的错误类型如“ServiceUnavailable”我推荐的做法是默认不将详细的错误信息放入给模型看的上下文。而是将其记录到系统的应用日志中。给模型的上下文里可以替换为一个更中性、信息量更少的提示如“工具X返回了暂时性错误建议稍后重试或使用替代方案。”重试与降级策略工具调用失败时在工具调用层内部进行低级别重试如HTTP请求重试3次而不是直接将失败结果抛给上层Agent。只有在内置重试都失败后才向上层返回一个明确的错误状态。设计工具链的降级方案。例如主搜索API失败自动切换到备用搜索API计算服务失败尝试让LLM自己进行近似计算。这些降级逻辑在工具层完成对上层Agent透明避免了污染传递。4.4 工作记忆的“版本控制”思想对于需要跨轮记忆的信息引入类似版本控制的概念。关键信息快照在完成一个复杂任务的关键步骤后如确认了航班信息不是简单地将自然语言描述存入历史而是将其结构化存入一个独立的“工作记忆存储区”。例如{ “task_step”: “flight_booking”, “data”: { “flight_number”: “CA1234”, “departure”: “Hangzhou”, “destination”: “Guangzhou”, “time”: “Friday 10:00 AM” }, “confidence”: “high” // 置信度 “source”: “tool_call: flight_search_api” // 来源 “version”: 1 }记忆的验证与更新当后续步骤或用户反馈与工作记忆冲突时如用户说“不我要去深圳”触发一个记忆验证流程。这个流程可以主动询问用户确认或者基于更强证据如重新成功调用工具来更新工作记忆的版本version: 2并标记旧版本为“已覆盖”。这样在组装上下文时总是优先使用最新版本、高置信度的记忆从机制上避免了陈旧、错误记忆的污染。5. 实操为现有Agent系统添加净化能力理论讲完了我们来点实际的。假设你正在使用LangChain框架如何为一个已有的Agent增加上下文净化能力下面是一个简化的代码示例和步骤。5.1 步骤一自定义一个带污染诊断的历史记录类我们首先需要扩展LangChain的ChatMessageHistory为其增加元数据存储和诊断能力。from langchain.schema import BaseMessage, HumanMessage, AIMessage, SystemMessage from typing import List, Dict, Any, Optional import json class ContaminationAwareMessageHistory: 增强的历史记录为每条消息存储元数据并支持诊断。 def __init__(self): self.messages: List[BaseMessage] [] # 原始消息 self.metadata: List[Dict] [] # 每条消息对应的元数据 def add_user_message(self, content: str, **kwargs): msg HumanMessage(contentcontent) self.messages.append(msg) self.metadata.append({ “type”: “user”, “contains_error”: False, “contamination_level”: 0, # 污染等级0为无污染 “custom_tags”: kwargs.get(“tags”, []), }) def add_ai_message(self, content: str, tool_calls: List[Dict] None, **kwargs): msg AIMessage(contentcontent, tool_callstool_calls) self.messages.append(msg) # 诊断AI消息是否包含错误或矛盾 is_error_response any(word in content.lower() for word in [“sorry”, “error”, “fail”, “cannot”, “unable”]) self.metadata.append({ “type”: “assistant”, “contains_error”: is_error_response, “tool_calls”: tool_calls, “contamination_level”: 1 if is_error_response else 0, “custom_tags”: kwargs.get(“tags”, []), }) def add_tool_message(self, content: str, tool_call_id: str, success: bool True, **kwargs): # 注意LangChain中ToolMessage是特殊的AIMessage或单独处理这里为简化使用字典 tool_result {“tool_call_id”: tool_call_id, “content”: content, “success”: success} # 我们可以将其作为一个特殊消息存储或附加到上一个AI消息的元数据中。 # 这里采用附加到上一个AI消息元数据的方式简化模型。 if self.messages and isinstance(self.messages[-1], AIMessage): last_meta self.metadata[-1] if “tool_results” not in last_meta: last_meta[“tool_results”] [] last_meta[“tool_results”].append(tool_result) # 如果工具调用失败提升污染等级 if not success: last_meta[“contains_error”] True last_meta[“contamination_level”] max(last_meta.get(“contamination_level”, 0), 2) def diagnose_contamination(self) - List[Dict]: 诊断历史记录中的污染段落。 contaminated_segments [] for i, (msg, meta) in enumerate(zip(self.messages, self.metadata)): if meta.get(“contamination_level”, 0) 0: contaminated_segments.append({ “index”: i, “message”: msg, “metadata”: meta, “reason”: “contains_error” if meta.get(“contains_error”) else “high_contamination_level” }) return contaminated_segments def get_clean_context(self, window_size: int 10) - List[BaseMessage]: 获取净化后的上下文用于下一次LLM调用。 clean_messages [] diagnosed self.diagnose_contamination() contaminated_indices {seg[“index”] for seg in diagnosed} # 简单的净化策略跳过被标记为污染的消息除非它是最近的用户消息 for i, msg in enumerate(self.messages): if i in contaminated_indices and not isinstance(msg, HumanMessage): # 如果是被污染的AI或Tool消息可以选择跳过或替换 # 这里选择跳过并添加一个系统提示说明 continue clean_messages.append(msg) # 如果跳过了消息在开头添加一个净化说明 if len(clean_messages) len(self.messages): system_note SystemMessage(content“注意部分历史对话因包含临时性错误或无效信息已被系统过滤。请基于当前有效信息继续对话。”) clean_messages.insert(0, system_note) # 只保留最近的N条防止过长 return clean_messages[-window_size:]5.2 步骤二创建一个自定义的上下文组装链我们将创建一个Runnable它负责调用上面的历史管理器组装净化后的上下文。from langchain.schema.runnable import RunnablePassthrough from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain.schema.output_parser import StrOutputParser def create_contamination_aware_chain(llm, message_history: ContaminationAwareMessageHistory): 创建一个具有上下文净化能力的对话链。 # 1. 从历史中获取净化后的消息 def load_clean_context(input_dict: Dict): # input_dict 包含当前的用户输入 current_input input_dict[“question”] # 将当前用户输入添加到历史元数据标记为干净 message_history.add_user_message(current_input) # 获取净化后的历史消息 clean_messages message_history.get_clean_context() return {“clean_messages”: clean_messages, “current_input”: current_input} # 2. 组装最终Prompt def assemble_prompt(data: Dict): clean_messages data[“clean_messages”] # 基础系统提示 system_msg SystemMessage(content“你是一个有帮助的助手。请根据对话历史回答问题。”) # 将净化后的历史消息和系统提示组合 final_messages [system_msg] clean_messages return ChatPromptTemplate.from_messages(final_messages) # 构建链 chain ( RunnablePassthrough.assign(**{“clean_context”: load_clean_context}) | assemble_prompt | llm | StrOutputParser() ) return chain # 使用示例 from langchain.chat_models import ChatOpenAI # 示例需替换为实际模型 llm ChatOpenAI(model“gpt-4”, temperature0) history ContaminationAwareMessageHistory() chain create_contamination_aware_chain(llm, history) # 模拟对话 try: # 第一轮正常 response1 chain.invoke({“question”: “今天北京天气怎么样”}) print(“Assistant:”, response1) # 假设这里Agent调用了天气工具但失败了我们手动添加一个模拟的失败工具消息和AI错误响应 history.add_ai_message(“让我查询一下北京天气。”, tool_calls[{“name”: “get_weather”, “args”: {“city”: “Beijing”}}]) history.add_tool_message(“Error: API timeout”, tool_call_id“call_1”, successFalse) history.add_ai_message(“抱歉查询天气服务暂时不可用。”) # 第二轮用户重试或继续提问 response2 chain.invoke({“question”: “那上海天气呢”}) # 注意这里的历史已经被净化器处理 print(“Assistant (after contamination cleanup):”, response2) except Exception as e: print(f“Error: {e}”)5.3 步骤三实现工具调用的结果过滤中间件在工具被调用和结果返回给Agent之间插入一个过滤层。class ToolResultFilter: 工具结果过滤器防止详细错误信息污染上下文。 staticmethod def filter_error_result(tool_name: str, raw_result: Dict) - Dict: 过滤工具返回的错误结果。 raw_result 格式: {“status”: “error”, “data”: None, “error_message”: “Detailed stacktrace...”, “metadata”: {}} 返回格式: {“status”: “error”, “data”: None, “error_message”: “Service temporarily unavailable.”, “metadata”: {“original_error”: “Detailed...”}} if raw_result.get(“status”) “error”: # 记录原始错误到日志用于调试 import logging logging.error(f“Tool {tool_name} failed: {raw_result.get(‘error_message’)}”) # 返回一个对模型友好的、信息量较少的错误 friendly_error { “status”: “error”, “data”: None, “error_message”: f“The ‘{tool_name}’ service is temporarily unavailable. Please try again later or use an alternative method.”, “metadata”: { “original_error_summary”: raw_result.get(“error_message”, “”)[:100], # 只保留前100字符摘要 “filtered”: True } } return friendly_error return raw_result # 在工具调用后立即使用 # raw_tool_output some_tool.invoke(...) # filtered_output ToolResultFilter.filter_error_result(“weather_api”, raw_tool_output) # 然后将 filtered_output 传递给Agent处理6. 高级策略与未来展望除了上述基础架构在面对更复杂场景时还可以考虑以下高级策略6.1 基于LLM的上下文实时诊断与修复我们可以让一个小型、快速的LLM如GPT-3.5-turbo扮演“上下文医生”的角色。在每次组装工作上下文前让它快速扫描历史执行以下任务矛盾检测识别历史陈述中是否存在事实矛盾如“飞深圳” vs “住广州”。错误定位定位是哪个工具调用或哪轮对话引入了关键错误。上下文摘要与重写直接输出一段“净化版”的历史摘要替代原始的、可能被污染的长篇历史。这相当于将净化过程本身AI化能处理更微妙、更复杂的污染情况。当然这会增加延迟和成本适合对可靠性要求极高的场景。6.2 预测性污染避免在错误发生前干预与其事后净化不如事前预防。可以在Agent决策的关键节点加入预测性检查工具调用前的可行性检查在Agent决定调用某个工具前先让LLM快速评估一下“基于当前上下文调用这个工具可能成功吗有没有已知的限制”这可以避免一些注定失败的调用。输出前的逻辑一致性检查在Agent生成最终答案前让其对自己的答案做一个快速自查“我刚刚的答案与对话历史中的事实有矛盾吗”这能抓住一些由于污染导致的逻辑错误。6.3 面向重试的专用上下文构建当系统明确知道本次调用是一次“重试”时可以构建一个完全不同的上下文策略完全重置上下文丢弃上一次失败交互的所有中间状态只保留最初的用户请求和系统指令让Agent从头开始思考。这是最彻底但也最“浪费”的方式。保留问题丢弃过程保留用户的最初问题但丢弃Agent上次所有的思考过程、工具调用尝试和失败结果。相当于给Agent一个“重新开始思考”的机会。提供重试指令在上下文中明确告诉模型“上一次处理这个问题时在调用X工具时遇到了Y错误。请尝试用不同的方式解决这个问题。” 这给了模型明确的指引避免了它在黑暗中摸索。7. 常见问题排查与实战心得在实施上述方案的过程中你肯定会遇到各种问题。以下是我总结的一些常见坑点和解决思路。7.1 问题净化得太“狠”导致Agent失忆了现象Agent忘记了之前确认过的重要信息比如用户的名字、任务的关键约束。根因净化策略过于激进将包含重要信息的消息也一并过滤掉了仅仅因为那条消息里有一个“抱歉”或者它后面跟着一个失败的工具调用。解决方案精细化标记不要只根据“是否包含错误词”来标记污染。区分“过程性错误”和“结果性错误”。过程性错误如“调用API超时”可以过滤结果性错误如“你要的航班已售罄我推荐了另一个”包含重要事实应保留。基于意图的净化分析用户当前query的意图。如果是继续深入当前任务则谨慎净化尽量保留任务相关上下文。如果是开启一个新话题或明确要求“忘掉刚才说的”则可以更积极地净化。使用工作记忆快照如前所述将关键事实结构化存储在工作记忆中这样即使净化了原始对话历史这些核心事实也能被可靠地保留和调用。7.2 问题净化逻辑引入了新的不一致性现象净化后的上下文看起来干净了但仔细看AI的回应里引用了一些历史上不存在的信息因为被过滤了导致对话逻辑断裂。根因净化操作对模型是不透明的。模型看到了一个被裁剪过的历史但它不知道历史被裁剪过所以它的回应可能基于一个不完整的理解。解决方案显式声明在净化后的上下文开头加入一个系统提示如“注意为简化上下文部分中间步骤和错误信息已被省略。请基于剩余的有效信息进行回应。”这给了模型一个重要的元认知提示。提供摘要与其直接删除大段历史不如用一两句话总结被删除部分的核心内容。例如“用户之前询问了北京天气但查询服务暂时失败。”这样既避免了污染细节又保持了对话的连贯性。7.3 问题性能开销太大现象每次调用都进行复杂的污染诊断和上下文重写显著增加了延迟和Token消耗。解决方案异步与缓存诊断和净化过程可以异步进行或者对净化后的上下文进行短期缓存例如针对相同的最近历史指纹。如果用户连续发言而历史无重大变化可以直接使用缓存的干净上下文。分层净化策略不是每次调用都启动全套净化。可以设置一个“污染置信度”阈值。只有当系统检测到高概率污染如连续工具调用失败、用户表达困惑时才触发更复杂的净化流程。平时只进行基础的错误信息过滤。轻量级规则优先优先使用基于规则的简单过滤如移除status:error的工具消息这些规则开销极低。将基于LLM的复杂诊断作为后备方案。7.4 实战心得从“重试”到“重置”与“重构”的思维转变最后分享一个最重要的心态转变放弃“简单重试”的幻想拥抱“有状态的重置与重构”。简单重试等同于对模型说“你再想想”但给它的是有问题的思考材料。有状态的重置识别出污染源主动清理Agent的工作记忆和对话历史中相关的污染部分然后从一个更干净的状态重新开始执行。这需要系统具备状态管理能力。上下文重构不一定是完全推倒重来。而是分析失败的原因重新组织问题描述和约束条件甚至改变任务分解的策略再交给Agent。例如将“查一下XX产品的价格”在失败后重构为“请通过搜索产品名称和‘官方售价’关键词来查找XX产品的价格信息”提供了更明确的指令。构建一个健壮的LLM Agent系统本质上是在构建一个能够自我管理认知状态、抵御信息干扰的智能体。解决上下文污染问题就是为这个智能体打造一套强大的“免疫系统”和“纠错机制”。这条路没有银弹需要你根据具体的业务场景、工具生态和容错要求不断地调试、观察和迭代。但一旦这套机制建立起来你会发现你的Agent变得更加可靠、稳定真正具备了在复杂环境中持续工作的能力。