Context Engineering实战2026:构建让AI Agent稳定运行的上下文管理系统
## 上下文的四个层次理解上下文工程,首先要厘清上下文的构成。一个完整的LLM上下文由以下四个层次组成:### 1. 系统层(System Layer)这是最持久的上下文,定义Agent的身份、能力边界、行为准则和输出格式。优秀的系统层应该:- 明确角色定义(是什么,不是什么)- 声明约束条件(禁止做的事)- 规定输出格式(JSON schema、markdown结构等)- 提供少量高质量示例(f
为什么上下文工程是2026年最重要的工程能力
大模型应用开发领域正在经历一场悄无声息的范式转移。两年前,工程师们还在争论选哪个Prompt模板;如今,在生产环境中稳定运行的AI Agent系统,其核心竞争力已经从"写好Prompt"升维到了"管理好上下文"。Context Engineering(上下文工程)这个词在2025年底由Andrej Karpathy在社交媒体上普及后,迅速成为AI工程界的热词。但很多人对它的理解仍停留在表面——以为不过是把更多信息塞进系统提示词。这种理解是危险的。上下文工程的本质是:在有限的上下文窗口中,精准地控制模型在任意时刻能看到什么信息,从而引导其产生正确的推理和行动。这不是艺术,这是工程。本文将从工程师视角,系统梳理2026年构建上下文管理系统的核心方法论。—## 上下文的四个层次理解上下文工程,首先要厘清上下文的构成。一个完整的LLM上下文由以下四个层次组成:### 1. 系统层(System Layer)这是最持久的上下文,定义Agent的身份、能力边界、行为准则和输出格式。它几乎不随对话改变,是整个系统的"宪法"。优秀的系统层应该:- 明确角色定义(是什么,不是什么)- 声明约束条件(禁止做的事)- 规定输出格式(JSON schema、markdown结构等)- 提供少量高质量示例(few-shot)### 2. 记忆层(Memory Layer)包含Agent在历史交互中积累的信息。分为:- 短期记忆:当前对话历史- 长期记忆:跨会话持久化的用户偏好、历史决策- 工作记忆:当前任务的中间状态### 3. 工具层(Tool Layer)工具定义、函数签名、工具调用历史和返回结果。随着Agent可用工具增多,工具定义本身就能消耗大量token。### 4. 任务层(Task Layer)当前具体任务的输入、中间推理过程和执行状态。—## 核心挑战:上下文污染上下文工程最难处理的问题不是"塞入足够信息",而是"避免上下文污染"。以下几种污染模式在生产环境中最为常见:模式一:噪声累积长对话中,早期的无关信息会持续占用token,且可能干扰当前推理。一个经典案例:用户在第2轮对话中提到了一个错误的前提假设,即便第5轮已经纠正,模型在第10轮仍可能被早期内容"带偏"。模式二:工具输出膨胀Agent调用外部工具后,原始返回结果往往包含大量无关信息。把完整API响应塞入上下文是新手常犯的错误。一个500行的JSON响应,真正有用的可能只有3个字段。模式三:指令冲突系统提示与用户指令产生冲突时,模型的行为不可预测。这种冲突往往不是显式的,而是通过多轮对话中的语义漂移逐渐形成。—## 工程实践:五大上下文管理策略### 策略一:选择性记忆(Selective Memory)不要把所有历史都保留在上下文中。实现一个记忆管理器,根据相关性分数动态决定保留哪些历史:pythonclass ContextMemoryManager: def __init__(self, max_tokens: int = 4000): self.max_tokens = max_tokens self.history: list[Message] = [] def add_message(self, message: Message): self.history.append(message) self._prune_if_needed() def _prune_if_needed(self): """当超出token限制时,移除相关性最低的历史消息""" while self._estimate_tokens() > self.max_tokens: # 保留系统消息和最近N条,其余按相关性评分排序删除 if len(self.history) > 4: self._remove_least_relevant() def _remove_least_relevant(self): """使用TF-IDF或嵌入相似度计算相关性""" # 保留最新的2条和最早的系统消息 candidates = self.history[1:-2] if candidates: scores = [self._relevance_score(m) for m in candidates] min_idx = scores.index(min(scores)) self.history.remove(candidates[min_idx]) def _relevance_score(self, message: Message) -> float: # 简单实现:基于关键词重叠度 recent_keywords = self._extract_keywords(self.history[-3:]) msg_keywords = self._extract_keywords([message]) overlap = len(recent_keywords & msg_keywords) return overlap / max(len(recent_keywords), 1)### 策略二:工具输出压缩(Tool Output Compression)在工具返回结果进入上下文之前,对其进行语义压缩:pythonclass ToolOutputCompressor: def compress(self, tool_name: str, raw_output: Any, task_context: str) -> str: """根据当前任务上下文,提取工具输出的关键信息""" if isinstance(raw_output, dict): return self._compress_dict(raw_output, task_context) elif isinstance(raw_output, list) and len(raw_output) > 10: # 列表过长时,只保留前3个并说明总数 return f"共{len(raw_output)}条结果,前3条:{raw_output[:3]}" return str(raw_output)[:500] def _compress_dict(self, data: dict, task_context: str) -> str: # 使用小模型或规则提取关键字段 relevant_keys = self._identify_relevant_keys(data, task_context) compressed = {k: data[k] for k in relevant_keys if k in data} return json.dumps(compressed, ensure_ascii=False)### 策略三:分层上下文构建(Hierarchical Context Assembly)不同任务需要不同的上下文构成。实现一个动态上下文组装器:pythonclass ContextAssembler: def build(self, task_type: str, user_query: str, session: Session) -> list[Message]: messages = [] # 1. 系统层(必选,不可压缩) messages.append(self._get_system_prompt(task_type)) # 2. 长期记忆(按相关性检索,非全量注入) relevant_memories = self._retrieve_memories(user_query, top_k=3) if relevant_memories: messages.append(Message(role="system", content=f"相关历史信息:\n{relevant_memories}")) # 3. 工具定义(仅注入当前任务需要的工具) needed_tools = self._identify_needed_tools(task_type, user_query) messages.extend(self._format_tool_definitions(needed_tools)) # 4. 近期对话历史(压缩后的滑动窗口) messages.extend(session.get_compressed_history(max_turns=5)) # 5. 当前任务 messages.append(Message(role="user", content=user_query)) return messages### 策略四:任务状态外化(Task State Externalization)复杂任务的中间状态不应该依赖模型的内部记忆,而应该显式地维护在外部数据结构中,并在每次调用时注入:pythonclass TaskStateManager: def __init__(self, task_id: str): self.task_id = task_id self.state = { "status": "in_progress", "completed_steps": [], "pending_steps": [], "artifacts": {}, "errors": [] } def to_context_str(self) -> str: """生成简洁的状态摘要注入上下文""" completed = len(self.state["completed_steps"]) pending = len(self.state["pending_steps"]) return ( f"任务进度:已完成{completed}步,剩余{pending}步\n" f"已完成:{', '.join(self.state['completed_steps'][-3:])}\n" f"下一步:{self.state['pending_steps'][0] if self.state['pending_steps'] else '无'}" ) def update_step(self, step: str, result: Any): self.state["completed_steps"].append(step) self.state["artifacts"][step] = result if step in self.state["pending_steps"]: self.state["pending_steps"].remove(step)### 策略五:上下文版本管理(Context Versioning)在生产环境中,上下文模板的变更应该像代码变更一样被管理:pythonclass ContextVersionManager: """管理不同版本的上下文模板,支持A/B测试""" def __init__(self): self.versions = {} self.active_version = "v1.0" self.experiment_config = {} def register_version(self, version: str, template: ContextTemplate): self.versions[version] = template def get_template(self, user_id: str) -> ContextTemplate: # 实验用户使用新版本 if user_id in self.experiment_config.get("treatment_users", []): return self.versions.get(self.experiment_config["test_version"]) return self.versions[self.active_version] def record_metrics(self, version: str, metrics: dict): """记录各版本的性能指标,支持数据驱动的版本决策""" # 接入监控系统 pass—## 上下文窗口利用率优化优秀的上下文工程还需要关注token效率。以下几点经验值得重点关注:压缩而非截断:当上下文超限时,优先考虑摘要压缩而非直接截断。截断可能丢失关键信息,而摘要可以保留语义核心。结构化优于自然语言:对于工具定义、状态描述等结构化信息,使用JSON或YAML格式比自然语言描述节省30%-50%的token,且模型的解析准确率更高。角色分配有技巧:System消息适合放永久性规则;User消息适合放任务输入;Assistant消息适合放已有的推理过程(few-shot中的示例回答)。不要把所有东西都堆到System消息里。—## 监控与调试:让上下文可观测上下文工程最容易被忽视的环节是可观测性。推荐以下监控指标:1. 上下文利用率:实际使用的token / 最大token限制2. 信息保留率:关键信息在经过压缩/截断后的保留比例3. 上下文命中率:模型在回答中正确引用了上下文信息的比例4. 幻觉率与上下文的相关性:当上下文质量下降时,幻觉率是否上升工具推荐:LangSmith、Langfuse、Phoenix(Arize)都提供了上下文级别的追踪能力。—## 总结Context Engineering 不是一个技巧,而是一套系统性的工程方法论。它的核心命题是:在正确的时机,把正确的信息,以正确的方式,放入模型的视野。掌握上下文工程,意味着你能构建出在生产环境中真正稳定、可靠的AI Agent系统——而不仅仅是一个demo。2026年,这将是区分初级AI应用开发者和高级AI工程师最重要的分水岭之一。
更多推荐




所有评论(0)