返回文章列表

上下文工程:喂给模型什么,决定它的上限

June 25, 2026

上下文工程:喂给模型什么,决定它的上限

上下文工程(Context Engineering):决定 AI Agent 上限的不是模型,而是你喂给它的上下文。讲透四大操作——写出/选取/压缩/隔离,RAG 还是长上下文、记忆、KV-cache 优化,附实战与自查清单。

做 Agent 的人迟早会撞上这堵墙:prompt 已经调到极致,效果还是不稳。问题往往不在那句话,而在模型每一步到底看到了什么。这篇讲的就是这件事——怎么管理模型的"视野"。面向工程师与技术决策者,从概念到实战,附照抄清单。


一、一个反直觉的事实

很多人调 Agent 的路径是这样的:效果不好 → 改 prompt → 还是不好 → 继续堆 prompt → 把所有可能用到的资料、历史、工具说明一股脑塞进去 → 效果反而更差。

问题往往不在 prompt 写得好不好,而在模型这一步看到的那段上下文是否对

2025 年开始,业界有了一个共识性的词来命名这件事。Karpathy 把它讲得最直白:

"上下文工程"胜过"提示工程"。人们一提到 prompt,想到的往往是日常里随手给模型的一句简短指令;可在任何工业级的 LLM 应用里,上下文工程才是真功夫——它是一门精细的艺术与科学:在上下文窗口里,为下一步恰到好处地填入正确的信息

「+1 for "context engineering" over "prompt engineering". People associate prompts with short task descriptions you'd give an LLM in your day-to-day use. When in every industrial-strength LLM app, context engineering is the delicate art and science of filling the context window with just the right information for the next step.」

Shopify 的 CEO Tobi Lütke 也公开表达过同样的偏好——他更喜欢"上下文工程"胜过"提示工程",因为它更准确地描述了那项核心技能:"为任务提供全部上下文,让大模型能合理地把事做成"("the art of providing all the context for the task to be plausibly solvable by the LLM")。

一句话区分:

提示工程:写好一段相对静态的指令。 上下文工程:在一个多步骤、不断变化的 Agent 循环里,动态地决定每一步往有限的上下文窗口里放什么、不放什么

提示工程是上下文工程的一个子集。当任务从"一问一答"变成"自主跑几十步、调一堆工具、读一堆返回结果"时,主战场就从"那句话"转移到了"那整个窗口"。


二、为什么上下文是稀缺资源

直觉上,上下文窗口越大越好,1M token 听起来什么都装得下。但实践里,上下文是最稀缺的资源,原因有三:

1)注意力是有限的,且会"中间失忆"。 经典研究《Lost in the Middle》早就发现:把关键信息放在长上下文的中间,模型经常视而不见——它对开头和结尾敏感,对中段迟钝。后来 Chroma 等团队用更系统的实验把这个现象命名为 context rot(上下文腐坏):随着上下文变长,模型在同一任务上的表现会持续、平滑地下降,哪怕"大海捞针"测试还显示它"找得到"。能找到 ≠ 能用好。

2)无关信息会主动干扰。 上下文里多塞的每一段无关内容,都是在和正确答案抢注意力。常见三种病症:

  • 干扰(distraction):被无关历史带偏;
  • 污染(poisoning):一个早期的错误结论留在上下文里,后面一路将错就错;
  • 冲突(clash):塞进去的资料彼此矛盾,模型无所适从。

3)成本和延迟随 token 线性增长。 每多一个 token,都要花钱、花时间。一个把上下文堆到满的 Agent,又慢又贵又不准。

结论很反直觉,但极其重要:

上下文不是越多越好,而是"信噪比"越高越好。上下文工程的本质,是在每一步只留下"刚好够用"的高信号信息。


三、上下文里到底有什么

先把"上下文"拆开。模型推理时看到的,远不止用户那句话,而是一整个被拼装出来的窗口:

成分 说明 谁来控制
系统提示 / 角色设定 身份、规则、输出格式 工程师,相对静态
工具定义 有哪些工具、怎么调 工程师 + 动态筛选
用户输入 当前这一轮的请求 用户
对话历史 之前几轮的来回 需要管理(压缩/裁剪)
工具返回结果 检索到的文档、API 结果、报错 高度动态,最易爆炸
记忆 跨会话的长期信息 需要写入/取回

上下文工程,就是对这张表里每一格做"加什么、减什么、留多久"的决策。其中最容易失控的是"工具返回结果"——一次网页抓取、一次数据库查询,就可能糊上几千 token。


四、四种基本操作:写出、选取、压缩、隔离

LangChain 把上下文工程的全部手段,归纳成四类操作。这是目前最好用的一张心智地图:

1. Write —— 写出(把信息存在窗口之外)

不是所有东西都得待在上下文里。把中间结论、计划、笔记写到窗口外部,需要时再取回:

  • 草稿区(scratchpad):当前任务内的临时笔记,让模型记住"我已经做到第几步、得出了什么"。
  • 记忆(memory):跨任务、跨会话的持久信息(用户偏好、项目约定)。

2. Select —— 选取(只在需要时取回相关的那一点)

这是 RAG(检索增强) 的本质,也是工具选择、示例选择的本质:

  • 不把整个知识库塞进去,而是按当前问题检索出最相关的几段
  • 工具太多时,先用一层检索筛出"这一步可能用到的几个工具",而不是把上百个工具定义全摆上;
  • 连 few-shot 示例都可以按相似度动态挑选。

3. Compress —— 压缩(用更少的 token 表达同样的信息)

上下文快满时,不是粗暴截断,而是压缩

  • 摘要 / compaction:把前面几十轮对话总结成一段"目前进展纪要",丢掉原始过程、保留结论和未决事项;
  • 裁剪:按规则删掉最老、最不相关的部分。

4. Isolate —— 隔离(把上下文拆到多个独立空间)

把一个大任务拆给多个子 Agent,每个子 Agent 拿一个干净的、专属的上下文窗口去做子任务,只把"浓缩后的结论"返回给主 Agent。主 Agent 的窗口因此始终清爽。沙箱、独立运行环境也属于这一类——把可能产生海量输出的操作隔离在外。

记住这四个动词——写出、选取、压缩、隔离——你就有了应对几乎所有上下文问题的工具箱。

接下来几节,挑出这套框架里最常被追问、也最容易做错的几处,逐个深入。


五、RAG 还是长上下文?2026 年的答案

长上下文窗口刚出现时,很多人断言"RAG 要死了——既然能把整本书塞进去,何必检索?"两年过去,结论清晰了:长上下文没有杀死 RAG,反而让两者各归其位。

  • 长上下文的软肋就是第二节说的 context rot:塞得越满,越容易中间失忆、越慢越贵。把 50 万 token 全灌进去,不等于模型真的"读懂"了 50 万 token。
  • RAG 的价值恰恰是把"50 万里相关的 5 千"挑出来,喂高信号、低噪声的上下文——这正是上下文工程想要的。

实务上的选择:

场景 倾向
知识库巨大、且持续更新 RAG(检索 + 引用来源)
单份文档、需要全局理解(如审一份长合同) 长上下文直接读
既大又要精 混合:先检索粗筛,再把候选段落放进长上下文精读

更前沿的做法是 agentic retrieval(智能体式检索):不再是"一次检索、拿结果就走",而是让 Agent 自己多轮搜索、自己判断"够不够、要不要再查一次",把检索变成一个有反馈的循环。


六、记忆:让 Agent 跨会话变聪明

记忆是上下文工程里专门处理"时间"的部分,分两层:

  • 短期记忆:单次会话/任务内的连续性,主要靠第四节的 compaction 和 scratchpad 维持。
  • 长期记忆:跨会话保留的信息——用户是谁、偏好什么、项目有哪些约定。你在 ChatGPT、Claude 里看到的"记住了你的偏好",背后就是一套写入(什么值得记)+ 取回(这次该想起什么) 的机制。

记忆的难点从来不是"存",而是两个判断:

  1. 写什么:不是所有对话都值得记,乱记会污染未来的上下文;
  2. 取回什么:这一次该想起哪几条,取多了又是噪声。

说到底,记忆系统就是"Write + Select"这两个操作在时间维度上的应用。


七、一条最容易被忽略的实务:让上下文对缓存友好

前面几节都在谈"放什么、不放什么",还有一条几乎直接决定成本的路径常被忽略——KV-cache(提示缓存)

模型处理上下文时,会把前缀算成一份可复用的中间状态(KV-cache)。只要这一轮的上下文前缀和上一轮完全一致,这部分就能直接命中缓存、不必重算——又快又省(命中的 token 通常只按原价的几分之一计费)。在多步 Agent 里,每一步都带着几乎相同的系统提示和历史,缓存命中率几乎直接决定了账单和延迟。业界甚至有一句话:"KV-cache 命中率,是生产级 Agent 最重要的单项指标。"

由此引出几条和"信噪比"同等重要的构造原则:

  • 稳定的放前面,易变的放后面。 系统提示、工具定义这些每轮不变的内容固定在最前,保证前缀稳定。
  • 只追加,不改写。 新信息往尾部追加;一旦回头去改前面的内容(哪怕只动一个时间戳),其后的缓存会全部失效。
  • 压缩要挑时机。 compaction、裁剪会改写前缀、使缓存失效,所以别太频繁触发,挑划算的点一次性做。

一句话:上下文工程不只决定"模型看得准不准",也直接决定"这套系统跑得贵不贵"。


八、实战:两个最常用的模式

模式一:Compaction(上下文压缩续跑)。 这是长任务的命脉。以 Claude Code 为例,当上下文窗口快满时,它不会直接断档,而是自动把前面的工作总结成一段紧凑纪要(改了哪些文件、当前状态、下一步要做什么),然后用这段纪要"接着跑"。要点是:总结要保留"未决事项和关键决策",丢掉"原始过程"。压缩没做好,Agent 就会"失忆",反复做已经做过的事。

模式二:Sub-agent 上下文隔离。 主 Agent 负责编排,遇到一个重活(比如"把这 20 个文件逐个读一遍找出 bug"),就派一个子 Agent 去做。子 Agent 在自己干净的窗口里读完 20 个文件、得出结论,只把一句话结论返回给主 Agent。主 Agent 的窗口完全不会被那 20 个文件的内容淹没。这正是"隔离"的威力——也是多 Agent 系统最被低估的好处:它本质上是一种上下文管理手段,而不只是"并行干活"。


九、它和这些概念是什么关系

上下文工程周围围着一圈容易混淆的词。不必死记,按"关系的类型"理一遍,边界自然就清楚了:

① 上下游——MCP 在下面供料,Harness 在外面兜底。

  • MCP(模型上下文协议):解决"能接什么",用一套统一协议把外部工具和数据源标准化地接进来,是上下文的"来源"。
  • Harness(智能体的工程外壳):模型权重之外、决定智能能否稳定落地的全部工程(工具、状态、验证、上下文管理……)。上下文管理只是其中一个子系统,却往往是最先翻车的那一个。

② 子集——提示工程和 RAG,都是它的一部分,不是它本身。

  • 提示工程:上下文工程的前身和子集。任务从"一问一答"变成"自主跑几十步",主战场就从"写好那句话"扩大到了"管好整个窗口"。
  • RAG(检索增强):只是"选取"这一类操作里的一个具体手段,负责"按需把相关知识取进来"。它是上下文工程的子集,不是同义词——把两者画等号,就漏掉了写出、压缩、隔离另外三大类。

③ 替代路线——上下文工程 vs 微调。

给模型注入知识和能力,有两条根本不同的路:把它喂进上下文(in-context,本文讲的全部),还是训进权重(in-weights,即微调 fine-tuning)。

  • 知识更新快、要带来源、要随时增删 → 走上下文(RAG / 长上下文);
  • 要固化一种稳定的风格、格式或专有能力,且数据足够 → 考虑微调。

多数成熟系统两者并用:微调定"底色",上下文工程喂"当下这件事"。

一句话收束:上下文工程决定模型每一步的"视野"——提示工程、RAG 是它的局部,微调是它的另一条路,MCP 在下面供料,Harness 在外面兜底。


十、照抄即用:上下文自查清单

  • 我能说清模型在每一步看到的上下文里,到底有哪些成分吗?
  • 工具返回结果有没有做"瘦身"(只留结论、截断超长输出)?还是原样塞回去?
  • 上下文里有没有"已经没用的历史"?有没有定期压缩/裁剪?
  • 长任务有没有 compaction 机制?压缩时保留了未决事项和关键决策吗?
  • 知识检索是"全量塞入"还是"按需检索"?检索结果带不带来源?
  • 工具/示例是不是"全量摆上"?能不能按当前步骤动态筛选?
  • 有没有把重活拆给子 Agent,用独立窗口隔离它产生的海量中间信息?
  • 上下文是不是"稳定内容在前、只在尾部追加",以尽量命中 KV-cache、压住成本?
  • 我有没有在"上下文越长越好"和"信噪比越高越好"之间,站对了队?

模型会越来越聪明,上下文窗口会越来越大。但只要"注意力有限、信息有噪声"这两条还成立,决定 Agent 上限的,就永远不只是模型本身,而是你喂给它的那段上下文。


参考


© 2026