Prompt engineering 关心「写什么」,context engineering 关心「整个回合里 LLM 的眼前应该装什么」。 当 agent 在循环里跑很久,token 会越积越多 —— 不是塞越多越好,而是要持续筛掉、精炼、按需取用。
好 context engineering = 在 LLM 有限的注意力预算里,找到最小的、信号最高的那组 token, 让模型最有可能输出你想要的行为。
围绕这个目标,Anthropic 给出三层手段:精炼 system prompt / tools / examples、用 just-in-time 检索按需加载, 以及在长任务里用 compaction、note-taking、sub-agent 三种方式跨越 context 窗口的物理上限。
早期用 LLM 多是单回合的分类或生成任务,所以重心在「写一条好 prompt」。 但当 agent 开始跨多个回合、多个工具调用、长时间连续工作,挑战就变了 —— 要管理的不只是 system prompt,而是「整个时刻 LLM 眼前装着的东西」。
Anthropic 的定义很直接:context engineering = 在推理过程中持续策划那组让 LLM 看到的 token, 包括 system instruction、工具定义、MCP 数据、外部检索内容、过往消息历史 —— 所有可能进入 context window 的东西。
Prompt engineering 是离散的:写一次,调一调,定下来。 Context engineering 是循环的:agent 每跑一步都会产生新数据, 每一回合都要重新回答一个问题 ——「下一回合到底应该让模型看到哪些东西?」
即使模型支持几十万、上百万 token 的窗口,context rot 依然存在 —— token 越多,模型在长程依赖上的精度就越软。这不是某个模型的毛病,是整个家族都有的现象。
像人一样,LLM 也有「注意力预算」。每塞进一个 token,就消耗一点这个预算 —— 于是模型在长 context 上不会突然崩,而是性能渐渐变软:召回不再准,长程推理不再稳。
根本原因来自 transformer 架构:每个 token 都要和其它所有 token 互相 attend。 于是 n 个 token 就有 n² 对关系。context 一长,模型就要把固定容量的注意力摊薄到更多对关系上 —— 加上训练数据中长序列本来就少,模型对「跨 context 的依赖」积累的经验就更少。
位置编码插值(position encoding interpolation)这类技巧能让模型适配更长窗口, 但代价是位置感稍微变模糊。所以「长 context 模型」不是免费午餐,而是一条性能渐变曲线而非悬崖。
下面两张小图:左边是 4 个 token 之间的全连接(4×4),右边是 8 个 token(8×8)。 token 数量翻一倍,关系数量翻四倍 —— 注意力是按平方变稀的。
needle-in-a-haystack 类基准发现:随着 context 变长,模型从其中精确检索信息的能力逐步下滑。 不同模型曲线斜率不同,但都是下滑的。
Anthropic 把指导原则一句话讲清楚:找出最小的、信号最高的 token 集合,最大化你想要的行为出现的概率。 听起来像废话,但落到 system prompt、tools、examples 三件事上,每件都有具体可操作的标准 —— 也都有典型反例。
用清晰、直接的语言,把行为讲到一个 Goldilocks zone —— 既不是把所有 if-else 硬编码成规则,也不是只甩高层口号。
工具是 agent 跟世界的「契约」。Tools 要 token 高效, 也要让 agent 在「该用哪个工具」时不犹豫。
Few-shot 仍然强烈推荐,但不是把所有边界情况列成清单。 examples 是给 LLM 的「图画」,多样、典型、能 portray 期望行为就够。
把每种情况都硬编码成规则。表面看可控,实际上极易失效,每个新边界条件都得加一条规则,最终维护成本爆炸。
具体到能有效引导行为,灵活到允许模型用启发式自己决策。组织成 background / instructions / output 等清晰段落。
只甩「请专业地、按最佳实践回答」这种话。没有提供具体信号,错把"模型应该懂"当成了真的懂。
过去主流是预计算的 embedding 检索:先把可能用到的文本 chunk 化、向量化、丢进 context。 但越来越多团队转向 just-in-time:只放轻量的「文件名 / 路径 / 链接 / 查询」,需要时再让 agent 用工具去取。 这对应了人类的认知习惯 —— 你不会背下整本字典,你会去查。
推理之前先把可能相关的内容 embed、检索、塞进 context。 速度快,但容易塞进无关或过期内容,且对索引质量极度敏感。
只在 context 里放轻量标识符:文件路径、查询语句、URL。 运行时让 agent 用工具动态加载具体内容,看完就放下。 Claude Code 用这种方式分析大型数据库 —— 写 query → 存结果 → 用 head/tail 做局部分析。
预先放一部分高频关键资料保证速度,再把其余交给 agent 自主探索。 Claude Code 就是这么做:CLAUDE.md 一上来就在 context 里,glob/grep 等原语用于 just-in-time 找文件。
关键在于:不预先加载完整对象,只保留指针 + 元数据 + 一组好工具, 让 agent 像人翻文件夹一样渐进披露地拼出理解。
文件路径 / 查询 ID / URL / cache key —— 体积小,但带着语义。
用 read / grep / head / tail / SQL 等工具按需取一个切片,看完即弃。
file 大小暗示复杂度、命名暗示用途、时间戳暗示新旧 —— 像人一样层层探索。
Anthropic 的判断是:随着模型越来越聪明,context 设计会越来越「让模型自己拿」, 人类预先策划的部分会越来越少。但在那之前,「do the simplest thing that works」依然是最稳妥的建议。
长任务(大代码库迁移、多小时研究、长程 agent 训练)会让 token 数远超 context 窗口。 等更大的窗口能解决吗?大概率不能 —— 即使窗口再大,context pollution 和「越长越软」的问题依然存在。 Anthropic 给出三种实战策略,配套相应的适用场景。
| 策略 | 核心动作 | 最适合的任务 | 失败模式 |
|---|---|---|---|
Compaction对话压缩 |
把消息历史摘要后重启 context,保留架构决策与最近文件 | 需要大量回返讨论的对话流(连续多轮 chat、需要保留上下文连续感的工作) | 压缩太狠会丢掉「当时不显要、后来才关键」的细节 |
Note-taking结构化笔记 |
定期写笔记到 context 外的文件 / memory tool,再读回 | 有清晰里程碑的迭代式开发;跨 session 的训练 / 探索类任务 | 笔记结构差时检索不到;过期信息没及时更新 |
Sub-agents子代理架构 |
主代理协调 + 子代理带干净 context深挖,只回传浓缩结论 | 复杂研究 / 分析类任务,可并行探索且子任务相对独立 | 子代理之间难共享上下文;不适合需要密集互通的任务 |
Anthropic 把这篇文章定位成构建可靠 agent 的心智模型,而不是某种新框架。 所有具体技巧都会随模型迭代而进化,但底层判断不会:每一回合送进模型的 token 都不是免费的。
Context engineering 代表了一种根本性的视角转换: 从「精心写一条 prompt」转到「持续策划进入模型注意力的每一个 token」。 无论你在做长任务的 compaction、token-efficient tool 设计,还是 just-in-time 的环境探索 —— 指导原则都是同一个。
随着模型变强,需要的人工策划会变少,agent 的自主性会变高 —— 但即使能力再扩张,把 context 当成「珍贵且有限的资源」这一基本姿态依然是核心。
不管你在用 compaction 跨越窗口、用 token-efficient tool 优化效率, 还是让 agent just-in-time 去探索环境 —— 核心永远是同一句话:
找到最小的、信号最高的那组 token,最大化你想要的行为出现的概率。
— Anthropic Applied AI · Prithvi Rajasekaran 等