上下文工程(Context Engineering):大模型长上下文优化与 Agent 实践
概述
在大语言模型(LLM)和人工智能对话系统中,Context(上下文)、Memory(记忆)、Prompt(提示)和 Token(标记) 是四个密切相关但含义不同的核心概念,是大模型应用开发的基础认知。
Token(标记)
Token 是模型处理文本时的最小单位。它可以是一个字、一个词,甚至是一个标点符号,具体形态取决于所使用的分词器(Tokenizer)。
所有输入和输出文本都会被转换为 Token 序列,供模型计算处理。模型存在最大上下文长度限制(如 8192、32768 tokens),
输入内容超过限制会被截断或触发报错。
换算经验参考:
在实际开发中,开发者常通过字符数估算 Token 量,换算比例会随模型分词器实现略有差异,通用经验值为:
- 1 个 Token 约对应 3~4 个英文字符
- 1 个 Token 约对应 1.5~1.8 个中文字符,工程开发中常取 1.7 个中文字符作为估算值
Prompt(提示)
Prompt 是用户输入给模型的指令或问题,用于引导模型生成期望的输出。
Prompt 本身由 Tokens 构成,内容可包含指令、示例、问题等。
Prompt 是单次交互中的 “输入部分”,其内容质量直接影响模型的响应效果。
Prompt 通常由三部分组成:
- 指令:提示词(系统提示词 + 用户提示词)
- 知识:记忆(长期 + 短期)、外部知识
- 工具:工具定义描述、工具调用结果
Context(上下文)
Context 指的是模型在生成当前回复时,所能 “看到” 的全部信息总和,是模型理解当前任务、生成回答的完整依据。
Context 通常包含以下内容:
- 用户当前的 Prompt(System Prompt + User Prompt)
- 历史对话记录(包含模型输出、工具执行结果)
- 工具清单(MCP & Function Calling)
- ReAct Agent 的 Thought/Action/Observation 等推理过程内容
- 外部知识注入(如 RAG 检索返回的知识库内容)
Context 由多个 Token 组成完整的输入序列,其总长度受模型最大上下文长度(max context length)的硬性限制。
类型:
- Instructions – prompts, memories, few‑shot examples, tool descriptions, etc
说明——提示、记忆片段、少量示例、工具描述等 - Knowledge – facts, memories, etc
知识——事实、记忆等 - Tools – feedback from tool calls
工具——对工具调用的反馈

Memory(记忆)
Memory 并非大模型的原生能力,通常指由开发者人为实现的长期或短期记忆功能,作用是在多轮对话中留存关键信息。
记忆的两类划分:
- 短期记忆:即对话上下文(Context),仅在当前会话内生效,随对话结束而消失。
- 长期记忆:通过外部数据库、向量存储等方式持久化保存用户偏好、历史行为等数据,可在后续对话中检索复用。
关键注意:标准 LLM 本身不具备持久记忆能力,每次请求都是无状态的,必须由开发者显式接入 Memory 机制,才能让模型具备跨对话的记忆能力。
对比
- Token 就像字母或音节,是构成文本的最小计算单元;
- Prompt 是你此刻提出的问题;
- Context 是聊天时对方记得的、你们刚刚聊过的全部内容;
- 长期 Memory 是对方写在笔记本上的信息,下次见面还能回忆起来,需要主动记录和查询。
上下文过长
长上下文的底层效应:Lost in the Middle(中间迷失)现象
上下文(Context)包含提示词、工具、知识、记忆等内容,在复杂的 Agent 场景中,随着工具、指令、知识增多,上下文规模会快速膨胀。
早在 2023 年,论文《Lost in the Middle: How Language Models Use Long Contexts》就提出:长上下文会影响模型效果,核心现象是语言模型对长上下文中的信息位置高度敏感,更关注开头和结尾的内容,容易忽略中间部分的信息,
该现象被命名为 “Lost in the Middle”(过程中迷失 / 遗忘初始目标)。
针对主流大语言模型的实验结论如下:
- 位置偏差显著:几乎所有模型在关键信息位于上下文开头或结尾时表现最好,关键信息处于中间位置时性能会急剧下降。
- 增加上下文长度 ≠ 提升效果:即便模型声称支持超长上下文(如 32K tokens),其实际有效利用信息的能力也不会线性提升;上下文越长,“迷失在中间” 的问题越严重。
- 指令微调和推理策略影响有限:部分模型经过专门的长上下文微调,仍无法完全克服位置偏差问题。
长上下文引发的四类典型输出故障
在大模型应用开发中,上下文变长除了会导致 token 爆炸、超出上下文窗口限制外,还会引发四类典型的输出质量问题:
上下文中毒、上下文分散、上下文混乱、上下文冲突。
Context Poisoning(上下文中毒)
- 定义:当一个模型生成的 “幻觉” 内容被当作真实信息存入上下文后,后续的回答会持续基于这个错误前提推理,最终导致错误被不断放大。
- 例:用户询问 “世界上国土面积最大的国家是哪个”,模型产生幻觉错误回答 “是加拿大”;当用户继续追问 “那它的国土面积具体是多少” 时,模型会继续基于 “加拿大面积最大” 这个错误前提进行推理,编造对应的数据,让错误进一步放大。
Context Distraction(上下文分散)
-
定义:上下文内的信息过多、过杂,会让模型忽略真正核心的指令或问题,最终出现答非所问的情况。
-
研究数据:根据 Gemini 2.5 技术报告,当上下文达到 32k token 后,模型性能开始下降;
超过 100k tokens 后,该现象会显著出现 ——Agent 不再针对当前情况推理,而是寻找相似的历史模式并重复。
-
示例
:你要求模型总结一篇短文,但提示词中混入了大量无关内容:
你给模型发送指令:“昨天和客户的沟通录音转文字在这里,帮我提炼出对方的核心合作诉求。对了,昨天的咖啡太苦了,下班顺路取的快递摔坏了,周末想去爬山,记得提炼完用分点形式输出。”
大量无关的生活碎碎念混入指令后,模型很可能转而和你聊 “爬山推荐路线”“快递理赔方法”,却没有完成提炼客户诉求的核心任务。
-
类比:信息过载会让模型 “分心”
Context Confusion(上下文混乱)
- 定义:当上下文中包含大量无关、冗余或非必要的信息(尤其是过多的可用工具 / 选项)时,模型被迫处理全部内容,会出现注意力分散、决策偏差,甚至错误调用不相关功能的情况,最终显著降低响应质量与任务成功率。
- 典型场景:在搭载大量工具的 Agent(如 MCP 工具集)中,即便绝大多数工具和当前任务无关,它们的存在也会干扰模型对正确工具的选择。
- 类比:让厨师在 100 把刀里选一把切菜 —— 即使他知道最合适的是哪一把,但面对锯子、水果刀、手术刀、砍骨刀等大量选项,他也可能犹豫、选错,甚至用错工具;如果只提供 3 把常用刀,效率和准确率会立刻提升。
- 研究数据:研究表明,将可用工具从 46 个减少到 19 个后,任务成功率会显著提升。
Context Clash(上下文冲突)
-
定义:在同一个对话或任务上下文中,同时存在相互矛盾、不一致的信息
(比如早期的错误假设、过时的状态、冲突的工具说明等),会导致模型无法正确推理,最终生成混乱、自相矛盾或错误的输出。
-
类比:就像导航时一开始误判了方向,系统记录下 “正在向东行驶”;即便后续车辆掉头向西,导航仍会基于 “向东行驶” 的错误前提规划路线,导致路线越走越偏 —— 因为系统把自己的错误判断当成了既定事实。
-
情景:rag检索的信息与web检索的信息冲突
上下文工程
概述
大语言模型就像一种新型的操作系统。大语言模型相当于中央处理器,而其上下文窗口则类似于内存,充当模型的工作内存。
就像内存一样,大语言模型的上下文窗口也有有限的处理能力,无法同时处理多种上下文信息。
而就像操作系统会合理分配资源到中央处理器的内存中一样,所谓的“上下文工程”也发挥着类似的作用。
产生背景
过长的上下文会引发幻觉、token 爆炸、超出上下文窗口限制、输出不稳定、推理效果差、运行性能下降等一系列问题。
这些问题无法通过传统的提示词工程解决 —— 因为上下文的范畴远不止提示词本身。
核心定义
上下文工程是针对大模型的完整上下文进行系统性优化的技术方向。
- 提示词工程的核心是关注和大模型说什么,聚焦于输入指令的措辞与结构;
- 上下文工程的核心是关注让大模型看到什么,聚焦于上下文内容的筛选、组织与管理。
上下文组成要素
上下文是大模型推理时可访问的全部信息集合,主要包含 7 类核心元素:
- Instructions / System Prompt:指令与系统提示词,定义模型的角色、规则与边界
- State / History (short-term Memory):状态与对话历史,即短期记忆,对应当前会话内的交互轨迹
- User Prompt:用户输入的当前请求与问题
- Retrieved Information (RAG):通过检索增强生成召回的外部知识信息
- Long-Term Memory:长期记忆,跨会话持久化存储的信息
- Available Tools:模型可调用的工具集
- Structured Output:结构化输出约束,定义输出的格式规范
核心理念
-
输入质量决定输出质量(Garbage in, Garbage out)
上下文工程的核心目标是持续优化上下文内容,让智能体(LLM)只看到恰到好处、与当前任务相关的信息,避免无效、冗余、错误信息干扰推理。
-
内存管理类比
可以将大语言模型(LLM)类比为一种新型操作系统,它的上下文窗口就相当于计算机的 RAM(工作内存);而上下文工程就相当于操作系统的内存管理器,负责决策哪些数据需要加载进上下文窗口、哪些数据需要移出或压缩。
-
官方方法论框架
LangChain 在 2025 年 7 月发布的《Context Engineering for Agents》一文中,从 Agent 开发视角将上下文工程的核心方法归纳为四大流程:Write(写入)、Select(选择)、Compress(压缩)、Isolate(隔离)。
四大核心方法

Write(写入)
核心目的:
把重要信息保存到上下文窗口之外的存储中,供后续推理调用,避免信息占用宝贵的上下文窗口空间。
两类实现方案:
(1)Scratchpad(草稿板 / 短期记忆)
- 定义:不属于最终输出内容,是智能体工作过程中的临时笔记,用于记录中间状态。
- 典型实现:LangGraph 中的 Checkpoint 机制
- 智能体每执行一个 “超步”(super-step,即完成一轮节点计算),LangGraph 会自动将当前完整状态(state)保存为一个 checkpoint(检查点);
- 所有 checkpoint 按
thread_id(线程 ID)归档,对应一次独立的用户会话或任务实例; - 开发者可通过
graph.update_state()主动向状态中写入信息,例如执行计划、工具返回结果、错误日志等。
(2)Long Term Memory(长期记忆)
- 定义:用于跨会话持久化存储信息的机制,保存用户偏好、历史事实、长期知识等需要长期留存的内容,通常结合向量数据库、关系型数据库实现,支持跨多轮对话、多个任务复用信息。
- 与短期记忆的区别:短期记忆仅在单次会话内生效,随会话结束而失效;长期记忆可持久化留存,在多次交互中持续生效。
Select(选择)
核心定义:
从外部存储中精准检索与当前任务最相关的信息,按需注入当前上下文窗口,避免全量信息涌入。
典型应用场景:
- 从长期记忆中召回语义相关的事实信息
- 动态选择与当前任务最匹配的工具,而非向模型暴露全部工具集
- 按需加载特定规则文件,例如
CLAUDE.md、.cursor/rules等配置化规则
Compress(压缩)
核心作用:
直接对现有上下文内容做精简,减少上下文的 token 数量,仅保留必要的核心信息,缓解上下文窗口压力。
三类主要方法:
- Summarization(摘要压缩):对长上下文做总结提炼。例如 Claude Code 在上下文窗口占用率达到 92% 时,会自动运行
auto-compact功能,将整段对话轨迹压缩为简明摘要。 - Trimming(裁剪):按固定规则删除老旧信息,例如规则化保留最近 10 轮对话,更早的对话直接移除。
- 智能修剪(Pruning):使用专用模型识别上下文内容,主动移除对当前任务无用的冗余信息。
Isolate(隔离)
核心思路:
全称为 “拆分并隔离”,通过对庞大的上下文做拆分切割,避免不同类别的信息混杂、冲突,让每部分推理只接触相关信息。
三类典型做法:
- 多智能体架构(Multi-agent):每个子智能体拥有独立的上下文窗口,各自专注单一子任务。Anthropic 的研究结论显示,多智能体系统在复杂任务上的表现优于单智能体,核心原因就是每个智能体的上下文更聚焦。
- 沙盒环境(Sandbox):让代码、多媒体处理等操作在独立的隔离环境中执行,仅将最终的关键结果返回给 LLM,避免图像、音频、长代码日志等高 token 消耗的对象直接污染上下文。
- 结构化状态(State Schema):以 LangGraph 为例,通过明确定义 state 的字段(如
messages、plan、search_results),精准控制哪些字段暴露给 LLM 参与推理,哪些字段仅作为内部数据使用、不送入上下文。
补充方案:渐进式披露
除了上述四类主流的上下文工程方案外,渐进式披露是另一类重要的优化思路,典型的落地实现是 Anthropic 推出的 Agent Skill。
其核心逻辑是不一次性向模型暴露全部信息与能力,而是随着任务推进逐步披露对应的内容,全程控制上下文的信息密度与相关性,避免信息过载。
manus的上下文实战
Manus 曾发布文章《Context Engineering for AI Agents: Lessons from Building Manus》,分享其 AI Agent 构建中的上下文工程落地经验。
Manus 在构建 AI Agent 的过程中,选择了上下文工程的技术路径,而非训练端到端模型,该决策基于对快速迭代、成本效率和与底层大模型解耦的综合考量。
核心实践
围绕 KV 缓存进行设计
- KV 缓存的技术原理:
在 Transformer 架构中,自注意力机制(Self-Attention)需要为每个 token 计算与其他所有 token 的注意力权重,每个 token 会生成三个向量:
- Query (Q):当前 token 的查询向量
- Key (K):其他 token 的键向量
- Value (V):其他 token 的值向量
在自回归生成(逐个生成 token)过程中,生成第 t 个 token 时,模型已经处理了前 t-1 个 token。如果每次都重新计算所有历史 token 的 K 和 V,会产生大量重复计算。
将已处理 token 对应的 K 和 V 向量缓存起来,生成新 token 时可直接复用,无需重复计算:每生成一个新 token,只需计算当前 token 的 Q,并与缓存的 K、V 做注意力运算,可将时间复杂度从 O (n²) 降至 O (n)(n 为上下文长度),显著提升推理速度。
如果每次请求都能复用之前缓存的 KV 状态(例如多轮对话或 Agent 连续动作场景),就只需计算新增部分的 Q,K/V 直接读取缓存。这避免了对整个上下文重新编码,可大幅减少 GPU 计算量和内存带宽压力。
- KV 缓存对 Agent 的特殊价值:
Manus 认为,KV 缓存机制对于 Agent 应用至关重要:
Agent 的典型工作模式是 ReAct 式的 “思考、行动、观察” 循环:模型先思考,然后调用工具,得到观察结果,再把信息追加到上下文中用于下一步决策。
这种模式的特点是输入和输出的规模往往不成比例,Manus 的输入 / 输出比平均达到 100:1,KV 缓存的收益尤为显著。
- 缓存失效的风险
如果上下文前缀发生变化(如系统提示动态插入时间戳、工具列表顺序不一致等),缓存将无法复用,模型必须从头计算所有 token 的 K/V,即便 99% 的内容未发生变化。
- 提升 KV 缓存命中率的最佳实践:
为了提高 KV 缓存命中率,Manus 总结了以下实践规则:
- 避免在 system prompt 中插入
当前时间: {now}这类动态内容。 - 提示词通过 prompt 模板配置,并通过 git 管控,变更时需要走发布流程,做强制流程管控。
- JSON 键按字母排序,避免因不同框架在序列化对象时带来的字段顺序不同,进而导致 token 序列变化。
- 上下文采用 append-only 模式,仅追加新动作 / 观察,不修改历史内容。
- 在分布式部署(如 vLLM)中,保证同一会话的请求路由到相同 GPU 节点,提升缓存复用;Manus 通过会话 ID 固定路由,确保同一 Agent 会话始终使用同一个缓存副本。
- 部分推理框架可自动管理 KV Cache,部分框架或服务需要通过插入特殊标记(如
<|cache_break|>)手动指定缓存边界;将该标记置于系统提示词末尾,可最大化缓存复用范围,同时兼顾系统提示词变更时的缓存重建问题。
遮蔽(Masking)而非移除工具

- 动态调整工具集的弊端:
随着 Agent 挂载的工具越来越多,模型频繁出现选错工具的问题,MCP 工具集这类一次性引入大量工具的场景问题更突出。
很多方案会选择动态调整工具集,但这种做法会破坏 KV 缓存并导致模型混乱:在大多数 LLM 中,工具定义序列化后位于上下文的前部(通常在系统提示词之前或之后),任何对工具集的改动,都会使后续所有动作和观察结果的 KV 缓存全部失效。
- Manus 的方案:保留全量工具 + 遮蔽机制:
Manus 的做法是:在上下文中保留所有工具的定义,不对工具列表本身做修改,避免影响 KV Cache;通过响应预填充 + 统一工具前缀的方案实现工具遮蔽,约束模型的工具选择。
(1)响应预填充机制
在让模型生成回复前,人为写入一部分固定的 token 序列作为生成 “开头”,引导模型后续的生成方向。
基础格式示例:
<|im_start|>user
请帮我查一下量子计算的最新进展。
<|im_end|>
<|im_start|>assistant
模型将从<|im_start|>assistant之后开始生成。基于这个机制,可以精准控制本次回复是否使用工具、使用哪类工具:
- 强制工具调用:预填充工具调用的起始 token,例如预填充
{"name":,模型必须接着填写函数名和参数,无法输出普通文本。 - 限定工具范围:预填充工具名前缀,例如预填充
{"name": "browser_,直接限制模型只能选择浏览器类工具。
(2)统一工具前缀命名
Manus 为所有工具设计了带统一分类前缀的命名方式,例如:
- 浏览器类:
browser_search、browser_navigate - 文件类:
file_read、file_write - 终端类:
shell_run、shell_check
这种命名方式下,当模型输出browser_前缀时,绝对不会选择非浏览器相关的工具,进一步收窄工具选择范围、降低选错概率。
将文件系统作为外部上下文
- 超长上下文的现实痛点:
尽管现代 LLM 支持超长上下文(如 128K+ tokens),但在真实 Agent 场景中仍面临三大问题:
- 观察数据体量过大(如网页、PDF 等内容);
- 长上下文下模型性能下降;
- 调用成本高昂,即使有缓存,仍需消耗传输和预填充成本。
- Manus 的落地策略:
Manus 的整体策略是:赋予 Agent 读写能力 + 大内容外存 + 上下文仅保留指针 + 可恢复压缩,具体分为 4 步:
- Agent 可主动创建、读取、修改沙盒中的文件(如
research.txt、page.html),类似人类使用笔记或硬盘的方式管理信息。 - 网页 HTML、PDF 文本、日志输出等体积庞大的非结构化数据,不直接塞入上下文,而是写入文件存储。
- 上下文中只记录轻量引用指针,例如:
- “已保存搜索结果到 results.html”
- “参考文档: /docs/quantum.pdf”
- " 原始 URL: https://example.com/kv-cache"
- 保证信息不丢失:只要保留关键元数据(URL、文件路径),原始内容就可以按需重建或重新访问。
- 方案收益:
该方案能显著缩短上下文的长度,提升推理速度,降低调用成本;同时可以避免传统上下文压缩方案容易丢失重要信息的问题。
通过复述操控注意力
- 问题背景:
Manus 作为通用智能体,发现在长任务场景(平均 50 + 次工具调用)中,模型很容易出现 “Lost in the Middle” 问题,也就是遗忘初始目标。
- 解决方案
Manus 通过动态维护todo.md文件解决该问题:在 Agent 运行的每一个步骤之后,都会更新任务清单,并且在上下文末尾持续不断地复述任务目标,避免模型丢失注意力、偏离初始目标。
保留错误内容以促进学习
- 认知前提:
失败是 Agent 运行的常态。很多时候出现失败,就将问题归因于幻觉、模型能力、temperature 参数,
这本质是掩盖问题,而非解决问题。
-
Manus 的三大实践原则
-
保留失败痕迹:上下文中保留错误动作、异常堆栈、无效观察等所有失败相关的内容。
-
让模型隐式更新信念:通过上下文中的失败案例,让模型自行总结经验,降低重复犯错的概率。
-
视错误恢复为智能体现:真正鲁棒的 Agent,核心能力之一是能从错误中调整策略、完成自我修正。
更多推荐
所有评论(0)