Context Engineering:比提示词工程更底层的那件事
📎 说明:这篇文章是我在准备搭agent时学习过程的整理跟 《Agentic 入门:让 AI 不再一把梭,而是像人一样反复干活》 一起整理的。按理说这篇应该更早发,但当时一直没整理顺,所以拖到了后面。内容还是以我自己的学习理解为主。
我最早注意到 Context Engineering(上下文工程),大概是在 Prompt Engineering 被聊得很热之后。
Context Engineering(上下文工程)最早接触是Prompt Engineering 概念火了一段时间之后。
在这之前好像AI应用开发的核心焦点一直是“提示词工程(Prompt Engineering)”。然而,随着大语言模型(LLM)从单次问答向能够自主运行的智能体(Agent)演进,上下文工程(Context Engineering)变得更加重要。
很多时候,真正决定模型表现的,不是你那句话写得漂不漂亮,而是它在那一刻到底看到了什么,没看到什么。
所以我现在更愿意把这件事理解成:做大模型应用,重点正在从“怎么把话说漂亮”,慢慢转到“怎么把上下文组织对”。
一、先说问题:Prompt Engineering 到底卡在哪儿?
只要你认真用过一段时间 AI,大概率都会碰到这种情况:
你写了一个很长的 Prompt,感觉已经把话说明白了,结果模型要么没懂,要么回答得很飘。可你换个问法,它又突然正常了。
你开始怀疑:是我 Prompt 写得不好,还是模型本身忽强忽弱?
这个现象背后,其实是个更底层的问题:模型能不能干好活,很大程度上取决于它当下到底能看到什么。
Prompt Engineering 解决的是“怎么把问题问清楚”。这当然重要,但它管不了另一件更麻烦的事: 当你要处理的信息,已经不是一轮对话能装下的时候,该怎么办?
比如:
- 你有一本 500 页的技术文档,想让 AI 帮你答用户问题
- 你的系统里有十几个上下文来源(用户历史、实时数据、业务规则、代码片段……)
- 你的 Agent 要跑十几步任务,中间状态要一直传下去
到了这些场景里,“怎么问”就不是最核心的问题了,“怎么喂”才是。
这就是 Context Engineering 要解决的事。
二、那 Context Engineering 到底是什么?
Anthropic 的说法是,它可以看成是从 Prompt Engineering 往前走了一步《Effective context engineering for AI agents》,但两者盯的东西并不一样:
- Prompt Engineering:怎么写好这一句话
- Context Engineering:怎么组织整个信息环境
如果用我自己的话讲,后者更像是在做“信息架构”,你要决定:
- 哪些信息该放进上下文
- 这些信息按什么结构组织
- 什么时机、以什么方式把它们喂给模型
- 超出上下文窗口时,怎么选择性地保留和丢弃
这件事听起来像工程,不是因为这个词高级,而是它真的就是工程问题。它不是让你背几个提示词套路,而是要把整个信息流理清楚。
有一个比方我觉得很贴:
Prompt Engineering 是教你怎么跟一个人说话;Context Engineering 是在他开口之前,帮你决定他今天能看到哪些材料、能记得哪些背景、桌上摆的是什么资料。
三、它真正卡住的,不只是窗口大小,而是“注意力预算”
很多人第一次接触上下文工程,都会先盯着“上下文窗口够不够大”。
这个视角没错,但还不够。
但我现在越来越觉得,更准确的说法应该是:模型真正稀缺的,不只是 token 容量,而是注意力预算。
你可以把上下文窗口理解成模型工作的“临时内存”。窗口大,确实代表理论上能塞进去更多东西;但塞得进,不等于它就能稳定地理解、提取、关联这些内容。
这时候会出现一个很现实的问题:上下文腐烂(Context rot)。
说白了就是,上下文越长、信息越杂,模型越容易出现下面这些毛病:
- 前面明明给过规则,后面还是忘
- 中间插入很多工具输出后,开始抓不住重点
- 看起来“都读了”,但真正回答时只抓住开头和结尾
- 局部结论没问题,一到多步任务串起来就开始漂
所以 Context Engineering 的核心不是“拼命往里塞”,而是:用尽量少、但信号强的信息,占住模型最宝贵的注意力。
所以很多 AI 系统上线以后表现不稳,问题不一定出在模型不够聪明,很多时候就是上下文里混进了太多低信号内容。
四、底层是什么?先聊 Self-Attention
要真正理解”上下文”对模型意味着什么,绕不开一篇 2017 年的论文:《Attention Is All You Need》《Attention Is All You Need》,也就是提出 Transformer 架构的那篇。
它里面最核心的东西是 Self-Attention(自注意力机制)。
粗暴一点讲,模型在生成每一个词的时候,都会去“扫一眼”上下文里别的词,算一遍“谁跟我现在最相关”,再决定往下吐什么。
这意味着:模型的能力,很大程度上取决于窗口里装了什么。
你给它看的内容越准确、越有结构、越聚焦,它的注意力就越能集中在真正重要的部分。你塞一堆无关信息进去,它不会自动过滤掉,它只会”稀释”它的注意力。
所以“上下文工程”这件事,如果往底层追,本质上就是在跟 Self-Attention 的工作方式打交道。
五、系统提示词也有讲究:别太死,也别太飘
很多人一提上下文工程,第一反应还是去改 System Prompt。
这当然要改,但我现在觉得,问题通常不是“写得不够长”,而是写得那个劲儿不对。
我现在更认同一个判断:好的系统提示词,应该在“规则足够清楚”和“保留模型推理空间”之间找到平衡。
两个极端都不行:
- 写成 if-else 说明书,模型像被绑住手脚,遇到复杂情况反而不会变通
- 写得过于抽象,只说“请你专业、严谨、友好”,基本等于没说
我现在更倾向于把系统提示词拆成几个清楚的区块,比如:
- 背景信息:这个 Agent 是干什么的
- 目标:这次任务最终要达成什么结果
- 约束:哪些事情不能做,哪些风险要优先规避
- 工具说明:什么时候该调用什么工具
- 输出要求:最后结果要长什么样
你会发现,这时候你做的已经不只是“写一句提示词”了,而是在给模型搭一个小型运行环境。
六、RAG 里最容易踩的坑,Anthropic 想了个解法
现在很多 AI 应用都在做 RAG(检索增强生成)——就是把一堆文档切片,存进向量数据库,等用户提问时捞出相关片段塞给模型。
这条路当然没错,但里头有个很容易被忽略的问题:文档一切片,背景信息很容易丢。
举个例子:你有一份技术文档,里面有一段话:
“这个接口的超时时间配置建议设为 5 秒。”
这句话单独拿出来是完整的,但如果你不知道这是在说”内网服务调用”而不是”公网 HTTP 请求”,这条建议可能直接坑掉你。
Anthropic 在 2024 年提出了 Contextual Retrieval《Contextual Retrieval》 来解这个问题。核心思路其实不复杂:
在切片存储之前,先让模型给每个片段加一段 **”上下文注释”**,说明它来自哪个文档、属于哪个章节、要解决什么问题。然后把这个带注释的片段再做向量化。
这样检索出来的内容,就不只是一句话,而是“一句话 + 它原本待着的语义背景”,命中质量会明显好一些。
配合 BM25 关键字检索(而不是单纯依赖语义向量),精确度进一步提升。
简单来说:不是切得多就能捞得准,要让每一块碎片都知道自己是从哪来的。
七、真正有用的方式,不是预加载全部,而是按需取用
很多系统在早期都会很自然地走一条路:既然上下文重要,那就多塞一点。
比如:
- 用户资料全塞进去
- 历史对话全塞进去
- 检索结果 top 10 全塞进去
- 工具执行日志原样全塞进去
一开始看起来确实会有一种“信息很全”的安全感,但很快就会遇到两个问题:
- 模型越来越贵
- 模型越来越乱
更像样一点的做法,其实是 Just-in-time context,也就是“即时上下文”。
它的思路是:默认只保留索引、摘要、标识符,真正需要的时候再去取原文。
比如不要把整个代码库文档直接扔进上下文,而是先给模型:
- 文件路径
- 模块索引
- 函数签名
- 哪些文档可能相关
然后让它在任务执行过程中,通过检索、搜索、读取工具,一步步把真正需要的信息拿进来。
这种方式本质上是在做“渐进式披露”。不是一上来把整个图书馆砸给模型,而是先把目录递给它,再让它决定该翻哪几页。
这比一次性预加载所有材料,更接近人类真正工作的方式。
八、长任务为什么特别容易翻车?因为上下文会被历史污染
上面说的 Contextual Retrieval,主要解决的是“单次检索”的质量问题。但到了更复杂的 Agent 场景里,还会多出另一个麻烦:上下文不是一开始就完整的,它是任务跑着跑着一点点堆起来的。
多步 Agent 工作流最烦人的地方,不一定是某一步直接做错,而是前面做过的所有事,最后都会变成后面的上下文负担。
比如一个任务跑了二十几步之后,上下文里可能已经混着:
- 早期已经失效的假设
- 很长但价值不高的工具输出
- 中途试错留下来的噪音
- 真正关键但只出现过一次的结论
这时候问题就不是“窗口够不够”,而是历史信息正在污染当前决策。
所以长周期任务里,通常就得想办法处理这件事。常见做法大概有三类:
① 压缩(Compaction)
当窗口快满时,不是简单截断,而是把已经完成的阶段总结成高保真摘要,把冗长原始过程替换掉。
② 外部记忆(Structured note-taking / Agent memory)
把待办、关键决策、阶段性结论写到上下文窗口外,比如 NOTES.md、状态文件或者数据库。后续即使重新开一个新窗口,也能快速续上。
③ 子智能体隔离(Sub-agent)
把特别耗 token 的探索任务丢给独立子智能体去做,让它在自己的“干净窗口”里完成搜索、归纳,再把浓缩后的结论返回主智能体。
这三件事,本质上都在解决一个问题:别让历史细节一直赖在窗口里,持续污染当前判断。
九、Anthropic 的工程实践:XML 标签、工具边界和 Prompt Caching
具体到工程实践,Anthropic 在这篇文章里《Effective context engineering for AI agents》 给了几个我觉得挺接地气的抓手:
① XML 标签
当你需要在上下文里放多个来源的信息(用户资料 + 业务规则 + 代码片段 + 历史记录),用纯文本堆在一起,模型很容易把它们”混为一谈”。
用 XML 标签把它们显式分开,能让模型更清楚哪块是哪块:
1 | <user_profile> |
这玩意儿不是什么魔法,说白了就是把结构摆明白,别让模型自己猜。
② 工具边界要清楚
很多 Agent 失败,不是因为工具不够多,而是因为工具太多、定义太像、边界太模糊。
如果一个工具库里同时有:
search_docslookup_docsfind_doc_contextquery_knowledge
那别说模型,人都得先愣一下。
我现在越来越觉得,工具其实就是模型和外部世界的契约。契约越清楚,模型越稳;契约越含糊,它越容易瞎试。
③ Prompt Caching(提示词缓存)
如果你的系统里有一段很长的固定上下文(比如一份 300 页的产品手册),每次用户提问都要把这段内容完整喂给模型,成本很高。
Prompt Caching 允许你把这段内容缓存在 API 层,后续调用直接复用,不重复计算。
这事看起来像纯工程优化,但很关键。因为它会直接决定:“长期带着一大坨稳定上下文工作”这件事,在成本上到底能不能成立。
十、Karpathy 的那个比喻:上下文窗口是模型工作的“临时内存”
在 OpenAI 前首席科学家 Andrej Karpathy 的一个演讲里《Software Is Changing (Again)》演讲,他把上下文窗口比作大模型的”有限内存”。
这个比方我觉得挺好懂:
模型本体里存的是”知识”,但它在干活时看到的,只有上下文窗口里的内容。超出窗口的东西,它看不见,也不存在。
这就是为什么:
- 你聊了很长一段时间之后,模型开始”忘事”
- 你让它处理一个超长文档,它只抓住了开头和结尾
- 你的多轮 Agent 任务执行到一半开始乱套
根本原因都一样:窗口装不下了,或者装的东西不对。
上下文工程要做的,说到底就是在这个有限空间里,把最该放进去的东西,用合适的方式放进去。
十一、整理一张表:四个角度看上下文工程
| 来源 | 核心关键词 | 解决的问题 |
|---|---|---|
| Anthropic | Contextual Retrieval / XML 标签 / Prompt Caching | 如何结构化组织海量背景,避免信息丢失和成本失控 |
| Transformer 论文 | Self-Attention | 模型如何在机制层面消费上下文 |
| Agentic Workflow | 动态上下文 / 外部记忆 / 多步传递 | 如何在多轮任务里持续维护有效上下文 |
| Karpathy | Context Window / Working Memory | 上下文为什么像“临时内存”,以及为什么会忘事 |
把这四个角度放在一起看,我自己现在的理解是,Context Engineering 其实横跨了四层:
- 模型层:注意力到底怎么分配
- 检索层:拿进来的资料到底准不准
- 工作流层:多步任务怎么传递状态
- 工程层:成本、延迟、缓存、工具契约怎么控制
也正因为它跨层,所以它不是一个“提示词小技巧”,而是 AI 系统设计里绕不过去的一部分。
十二、我目前的几个实际感受
老实说,我自己学这块之前,踩过的坑还真不少:
把所有背景信息一股脑塞进 System Prompt。当时总觉得“多给一点总没错”,结果就是模型越来越飘。后来才明白,不是信息越多越好,是相关信息越准越好。
以为 RAG 就是检索 + 拼接。直接切片、存向量、捞出来就完事。后来真碰到上下文断裂的问题,才意识到:片段不能只被捞出来,它还得“知道自己是谁、从哪来”。
把 Prompt Engineering 和 Context Engineering 混在一起。一开始总觉得问题问对了就行,后来才发现,一到 Agent 场景里,“信息怎么组织”很多时候比“问题怎么问”更靠前。
误以为长上下文天然更强。后来越做越发现,长上下文只是给了你“可以多放点东西进去”的机会,但如果没有筛选、压缩、分层和按需取用,它反而更容易把模型带偏。
说白了,上下文工程是软件工程在 AI 时代的一个延伸——你不只是在写 Prompt,你在设计信息流。
结尾
这篇还是偏学习整理,没有往代码实现那层展开太多,主要先把我自己脑子里这套概念骨架搭起来。
如果你也在做 AI 应用,或者已经开始搭 Agent / AI 系统,我现在会更建议先盯住这几个问题:
- 你给模型的,到底是不是“最小但高信号”的信息?
- 你的检索结果,是不是保留了足够的背景语义?
- 你的多步任务里,有没有一套压缩、记忆、续跑机制?
- 你的工具和提示词结构,是否清晰到让模型不用猜?
这些问题如果没想清楚,模型就算再聪明,系统表现也还是会一阵一阵的。