--- title: Context Engineering:比提示词工程更底层的那件事 author: Gamehu date: 2026-03-26 20:25:43 tags: - AI - Context Engineering - 大模型 - Prompt Engineering - RAG categories: - AI ---
AI Context Engineering 大模型
> 📎 **说明**:这篇文章是我在学习 [《Agentic 入门:让 AI 不再一把梭,而是像人一样反复干活》](Agentic-入门:让-AI-不再一把梭,而是像人一样反复干活.md) 时一起整理的。其实这篇关于 Context 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》](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents),但两者的关注点不同: - Prompt Engineering:**怎么写好这一句话** - Context Engineering:**怎么组织整个信息环境** 后者更像是在做"信息架构",你要决定: 1. 哪些信息该放进上下文 2. 这些信息按什么结构组织 3. 什么时机、以什么方式把它们喂给模型 4. 超出上下文窗口时,怎么选择性地保留和丢弃 这件事听起来像工程,因为它**就是工程**。它不是让你背几个提示词公式,而是要你把整个信息流设计清楚。 有一个比方我觉得很贴: > Prompt Engineering 是教你怎么跟一个人说话;Context Engineering 是在他开口之前,帮你决定他今天能看到哪些材料、能记得哪些背景、桌上摆的是什么资料。 --- ## 三、它真正卡住的,不只是窗口大小,而是“注意力预算” 很多人第一次接触上下文工程,会把重点放在“上下文窗口够不够大”上。 这个视角没错,但还不够。 更准确的说法是:**模型真正稀缺的,不只是 token 容量,而是注意力预算。** 你可以把上下文窗口理解成模型工作的“临时内存”。窗口越大,理论上能放进去的信息越多;但信息一多,不代表模型就能同样稳定地理解、提取、关联这些内容。 这时候会出现一个很现实的问题:**上下文腐烂(Context rot)**。 也就是上下文越长,信息越杂,模型越容易出现下面几种情况: - 前面明明给过规则,后面还是忘 - 中间插入很多工具输出后,开始抓不住重点 - 看起来“都读了”,但真正回答时只抓住开头和结尾 - 局部结论没问题,一到多步任务串起来就开始漂 所以 Context Engineering 的核心不是“拼命往里塞”,而是:用尽量少、但信号强的信息,占住模型最宝贵的注意力。 这也是为什么很多 AI 系统上线后,问题并不出在模型不够聪明,而是出在上下文里混进了太多低信号内容。 --- ## 四、底层是什么?先聊 Self-Attention 要真正理解"上下文"对模型意味着什么,绕不开一篇 2017 年的论文:《Attention Is All You Need》[《Attention Is All You Need》](https://arxiv.org/abs/1706.03762),也就是提出 Transformer 架构的那篇。 它里面最核心的东西是 **Self-Attention(自注意力机制)**。 用一句话说:模型在生成每一个词的时候,会同时"扫一眼"上下文窗口里所有其他的词,计算"哪些词跟当前词最相关",然后根据这个相关性来决定输出。 这意味着:**模型的能力,很大程度上取决于窗口里装了什么**。 你给它看的内容越准确、越有结构、越聚焦,它的注意力就越能集中在真正重要的部分。你塞一堆无关信息进去,它不会自动过滤掉,它只会"稀释"它的注意力。 所以"上下文工程"这件事,在模型层面的物理底层,就是在跟 Self-Attention 机制博弈。 --- ## 五、系统提示词也有讲究:别太死,也别太飘 很多人一提上下文工程,第一反应还是去改 System Prompt。 这当然要改,但问题通常不是“写得不够长”,而是**写得不在正确高度**。 我现在更认同一个判断:好的系统提示词,应该在“规则足够清楚”和“保留模型推理空间”之间找到平衡。 两个极端都不行: - 写成 if-else 说明书,模型像被绑住手脚,遇到复杂情况反而不会变通 - 写得过于抽象,只说“请你专业、严谨、友好”,基本等于没说 更靠谱的做法是把系统提示词拆成几个清晰区块,比如: - 背景信息:这个 Agent 是干什么的 - 目标:这次任务最终要达成什么结果 - 约束:哪些事情不能做,哪些风险要优先规避 - 工具说明:什么时候该调用什么工具 - 输出要求:最后结果要长什么样 你会发现,这其实已经不是“写一句提示词”,而是在设计一个小型运行环境。 --- ## 六、RAG 里最容易踩的坑,Anthropic 想了个解法 现在很多 AI 应用都在做 RAG(检索增强生成)——就是把一堆文档切片,存进向量数据库,等用户提问时捞出相关片段塞给模型。 这条路方向没错,但有一个很隐蔽的问题:**文档切片会丢掉背景信息**。 举个例子:你有一份技术文档,里面有一段话: > "这个接口的超时时间配置建议设为 5 秒。" 这句话单独拿出来是完整的,但如果你不知道这是在说"内网服务调用"而不是"公网 HTTP 请求",这条建议可能直接坑掉你。 Anthropic 在 2024 年提出了 **Contextual Retrieval**[《Contextual Retrieval》](https://www.anthropic.com/news/contextual-retrieval) 来解这个问题。方案的核心是: 在切片存储之前,先让模型给每个片段加一段 **"上下文注释"**,说明它来自哪个文档、属于哪个章节、要解决什么问题。然后把这个带注释的片段再做向量化。 这样检索出来的内容,就不只是一句话,而是"一句话 + 它所在的语义背景",命中质量会好很多。 配合 **BM25 关键字检索**(而不是单纯依赖语义向量),精确度进一步提升。 简单来说:不是切得多就能捞得准,要让每一块碎片都知道自己是从哪来的。 --- ## 七、真正有用的方式,不是预加载全部,而是按需取用 很多系统早期都会走一条很自然的路:既然上下文重要,那我就尽量多塞一点。 比如: - 用户资料全塞进去 - 历史对话全塞进去 - 检索结果 top 10 全塞进去 - 工具执行日志原样全塞进去 这样做一开始看着“信息很全”,但很快就会遇到两个问题: 1. 模型越来越贵 2. 模型越来越乱 更成熟的做法其实是 **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》](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents) 给了几个很实用的抓手: **① XML 标签** 当你需要在上下文里放多个来源的信息(用户资料 + 业务规则 + 代码片段 + 历史记录),用纯文本堆在一起,模型很容易把它们"混为一谈"。 用 XML 标签把它们显式分开,能让模型更清楚哪块是哪块: ```xml 用户是一个年营收 500 万的 SaaS 创业公司 CTO 禁止直接推荐未上线的功能 我们应该怎么设计权限系统? ``` 这不是魔法,就是**把结构显式化**,让模型不用猜。 **② 工具边界要清楚** 很多 Agent 失败,不是因为工具不够多,而是因为工具太多、定义太像、边界太模糊。 如果一个工具库里同时有: - `search_docs` - `lookup_docs` - `find_doc_context` - `query_knowledge` 那别说模型,人都得先愣一下。 工具其实是模型和外部世界的契约。契约越清楚,模型越稳定;契约越暧昧,决策就越容易发散。 **③ Prompt Caching(提示词缓存)** 如果你的系统里有一段很长的固定上下文(比如一份 300 页的产品手册),每次用户提问都要把这段内容完整喂给模型,成本很高。 Prompt Caching 允许你把这段内容缓存在 API 层,后续调用直接复用,不重复计算。 这是一个纯工程优化,但它非常关键——**它让"维持一个丰富的长期上下文"在成本上变得可行**。 --- ## 十、Karpathy 的那个比喻:上下文窗口是模型工作的“临时内存” 在 OpenAI 前首席科学家 Andrej Karpathy 的一个演讲里[《Software Is Changing (Again)》演讲](https://www.youtube.com/watch?v=yIPgptGZmDY),他把上下文窗口比作大模型的"有限内存"。 这个比方很直接: 模型本体里存的是"知识",但它在干活时看到的,只有上下文窗口里的内容。超出窗口的东西,它看不见,也不存在。 这就是为什么: - 你聊了很长一段时间之后,模型开始"忘事" - 你让它处理一个超长文档,它只抓住了开头和结尾 - 你的多轮 Agent 任务执行到一半开始乱套 根本原因都一样:**窗口装不下了,或者装的东西不对**。 上下文工程要做的,就是在这个有限的空间里,把最该出现的东西,用最合适的方式装进去。 --- ## 十一、整理一张表:四个角度看上下文工程 | 来源 | 核心关键词 | 解决的问题 | |:--|:--|:--| | **Anthropic** | Contextual Retrieval / XML 标签 / Prompt Caching | 如何结构化组织海量背景,避免信息丢失和成本失控 | | **Transformer 论文** | Self-Attention | 模型如何在机制层面消费上下文 | | **Agentic Workflow** | 动态上下文 / 外部记忆 / 多步传递 | 如何在多轮任务里持续维护有效上下文 | | **Karpathy** | Context Window / Working Memory | 上下文为什么像“临时内存”,以及为什么会忘事 | 这四个角度拼起来,你会发现 Context Engineering 其实横跨了四层: - 模型层:注意力到底怎么分配 - 检索层:拿进来的资料到底准不准 - 工作流层:多步任务怎么传递状态 - 工程层:成本、延迟、缓存、工具契约怎么控制 也正因为它跨层,所以它不是一个“写提示词的小技巧”,而是 AI 系统设计本身。 --- ## 十二、我目前的几个实际感受 老实说,我学这块内容之前,犯过不少低级错误: 1. **把所有背景信息一股脑塞进 System Prompt**,然后发现模型越来越"飘"。后来才明白:不是信息越多越好,是**相关信息越精准越好**。 2. **以为 RAG 只是检索 + 拼接**,直接切片存向量就完事了。后来真碰到上下文断裂的 bug 才明白:检索出来的片段需要"知道自己是谁"。 3. **把 Prompt Engineering 等同于 Context Engineering**,以为把问题问好了就够了。后来才意识到在 Agent 场景里,问题怎么问已经排在"信息怎么组织"后面了。 4. **误以为长上下文天然更强**。后来越做越发现,长上下文只是给了你“有机会放更多东西进去”,但如果没有筛选、压缩、分层和按需取用,它反而更容易把模型带偏。 说白了,上下文工程是软件工程在 AI 时代的一个延伸——你不只是在写 Prompt,你在设计信息流。 --- ## 结尾 这篇是我的学习整理,没有深入展开代码实现,主要是先把概念层面的骨架搭清楚。 如果你也在做 AI 应用,或者在带团队搭 AI 系统,我现在会更建议你把注意力放在这几个问题上: 1. 你给模型的,到底是不是“最小但高信号”的信息? 2. 你的检索结果,是不是保留了足够的背景语义? 3. 你的多步任务里,有没有一套压缩、记忆、续跑机制? 4. 你的工具和提示词结构,是否清晰到让模型不用猜? 如果这几个问题都没想明白,模型即使再聪明,系统也很容易忽好忽坏。