Context Engineering 到底是什么?比 Prompt Engineering 重要10倍的 AI Agent 核心技能
最近在折腾 Hermes Agent 的时候,我发现自己花在写 prompt 上的时间越来越少了。不是因为 prompt 不重要了,而是因为真正影响 Agent 表现的,根本不是那一句 prompt。
你给 Agent 的系统提示词写得再漂亮,如果它不知道你的项目结构、不记得上次对话的结论、工具返回了一堆没用的信息——它照样会翻车。
这就是 Context Engineering 要解决的问题。
Karpathy 最近发了条推,说得挺到位:Context Engineering 是"把恰好需要的信息填进上下文窗口的精妙艺术和科学"。注意,他说的是"精妙",不是"堆砌"。很多人把一堆东西塞进 context window 就觉得完事了,结果模型越用越蠢。问题不在模型,在你的 context 策略。
从 Prompt Engineering 到 Context Engineering:不是换了个名字
先说清楚,Context Engineering 不是 Prompt Engineering 的马甲。虽然两者有交集,但关注的层面完全不同。
Prompt Engineering 关心的是:怎么写一句话,让模型给出好答案。
Context Engineering 关心的是:在 Agent 执行的每一步,应该给模型看什么信息。
区别在哪?Prompt 是静态的,你写一次就完事了。Context 是动态的,它随着 Agent 的执行不断变化——工具返回了新数据、对话历史越来越长、用户的意图可能发生了偏移。你得在整个过程中不断调整模型"看到"的东西。
举个我自己踩过的例子。之前给 Hermes Agent 加了一个功能,让它能自动写文章上传到网站。第一版的实现很简单:system prompt 里写清楚"你是文章写手,按格式写好上传",然后把任务丢给它。
结果呢?它写出来的文章格式不对、上传用错了 API、甚至连已有的文章列表都不查就开始写。我在 prompt 里明明写了要查已有文章、要用特定 API,但它就是不听。
后来我才想明白——不是 prompt 写得不够清楚,而是 Agent 在执行到第 5 步的时候,system prompt 里那些指令已经被淹没了。工具返回的 JSON 有几千行,对话历史拉了几十轮,模型的注意力早就飘了。
这就是 context 失败的典型场景。
Context 失败的四种方式
在说怎么做好 Context Engineering 之前,得先搞清楚 context 是怎么出问题的。Drew Breunig 总结了四种 context 失败模式,我觉得挺准确的:
Context Poisoning(上下文投毒):幻觉进入了 context。Agent 在某一步产生了一个错误的判断,这个判断被写进了 context,后面的步骤都基于这个错误继续执行。越走越偏。
我遇到过这种情况。Agent 在读一个配置文件的时候把一个值读错了,然后基于这个错误的值去做后续操作。因为错误信息一直在 context 里,后面所有步骤都引用这个错误值,最后搞出一个完全不对的配置。
Context Distraction(上下文分散):context 太长,模型的注意力被稀释了。特别是 Agent 执行了几十步之后,context window 里塞满了各种工具返回值、中间结果、历史对话,模型开始抓不住重点。
这在用 Claude Code 写长代码的时候特别明显。一个 session 搞了半小时以上,context 快满了,模型开始犯低级错误——之前明确说过不要用某个 API,它转头就用了。不是模型蠢,是它真的"看不见"那条指令了。
Context Confusion(上下文混乱):不相关的 context 影响了模型的判断。你给 Agent 提供了太多工具,每个工具都有描述,模型在选择工具的时候搞混了。
这个在 MCP 工具多的时候特别常见。你接了十几个 MCP server,每个 server 暴露好几个工具,模型面对几十个工具描述,选错的概率就上去了。
Context Clash(上下文冲突):context 里不同部分的信息互相矛盾。比如 system prompt 说"用简洁风格",但 few-shot examples 里的回答都很长,模型就不知道该听谁的。
为什么 2026 年突然都在聊 Context Engineering
说"突然"其实不准确。这个问题一直都存在,只是以前大家把锅甩给模型——"GPT-4 太笨了"、"Claude 不听话"。2026 年模型能力上来了,大家发现同样的模型,有人用得好有人用得烂,区别就在 context 策略。
Cognition(做 Devin 的那家公司)直接说了:Context Engineering 是构建 AI Agent 的工程师的头号工作。Anthropic 也发了篇文章,说 Agent 经常跨越几百轮对话,需要精细的 context 管理策略。
这些不是学术论文里的空话。你去看实际产品——Claude Code 的 auto-compact、Cursor 的 rules 系统、Windsurf 的 memories 功能——全是在做 Context Engineering。
Karpathy 自己也从 Vibe Coding 转向了 Agentic Engineering。他在回顾的时候说,以前 LLM 能力不够,vibe coding 只能玩玩。现在 Agent 已经强到可以搞真正的工程了,但前提是——你得管好它的 context。
这就像给一个聪明但没记忆的人安排工作。你不能指望他每次都从零开始理解任务,你得在他需要的时候把关键信息递到手边。
Context Engineering 的四个核心策略
LangChain 把 Context Engineering 的策略分成了四类:Write、Select、Compress、Isolate。我觉得这个分类挺清晰的,结合我的实际经验展开讲讲。
策略一:Write —— 把信息存到 context window 之外
Write 的核心思想是:不是所有信息都需要一直待在 context window 里。有些信息可以先存起来,需要的时候再取。
最常见的形式就是 scratchpad(草稿本)。Agent 在执行任务的过程中,把重要的中间结果写到一个文件或者状态对象里。后面需要的时候再读回来。
Anthropic 的多 Agent 研究系统就用了这个策略。他们的 LeadResearcher 在开始工作前会先把研究计划写到 Memory 里。为什么?因为 context window 超过 200K tokens 就会被截断,如果不把计划存起来,执行到后面可能就忘了最开始要干嘛。
在 Hermes Agent 里,memory 工具就是干这个的。Agent 可以把关键信息存到持久化的 memory 里,下次对话的时候自动加载。比如用户的偏好、项目的技术栈、之前踩过的坑——这些信息不需要每次都从头交代。
另一个例子是 Cursor 和 Windsurf 的 rules 文件。它们让 Agent 在每次会话开始时自动读取 .cursorrules 或类似文件,把项目级别的指令注入 context。Claude Code 的 CLAUDE.md 也是同样的思路。
这些 rules 文件本质上就是一种 Write 策略——你把信息写到文件里,Agent 按需读取,而不是全部塞进 system prompt。
这里展开讲讲几个主流 AI 编程工具的 rules 文件对比,因为这是目前最普遍的 Context Engineering 实践:
Claude Code 的 CLAUDE.md:这是 Claude Code 的"项目说明书"。你可以放在项目根目录、子目录、甚至用户 home 目录。Claude Code 每次启动会自动读取当前目录和父目录的 CLAUDE.md。它支持写项目的技术栈、编码规范、常用命令、踩坑记录等。我目前的项目里,根目录的 CLAUDE.md 写的是整体架构和部署方式,子目录的写的是模块特定的注意事项。
Cursor 的 .cursorrules:Cursor 的方案更灵活一点。你可以在 settings 里配置全局 rules,也可以在项目里放 .cursorrules 文件。它还支持按文件类型匹配不同的 rules——比如 TypeScript 文件用一套规则,Python 文件用另一套。这个粒度比 CLAUDE.md 细。
Copilot 的 instructions 文件:GitHub Copilot 用的是 .github/copilot-instructions.md,格式和 CLAUDE.md 类似。但 Copilot 的 instructions 在 GitHub.com 上也能用(PR review、issue 回复等),不只是 IDE 内。
Hermes Agent 的 skills 系统:跟上面几个不同,Hermes 不是用一个大文件,而是把指令拆成多个独立的 skill 文件。Agent 根据用户的请求动态加载相关的 skill。好处是不用一个巨型文件塞所有东西,坏处是需要 Agent 自己判断该加载哪些 skill。
这些方案各有优劣,但本质都是同一个思路:把项目级的 context 从 system prompt 里拆出来,放到文件系统里,让 Agent 按需读取。
策略二:Select —— 精确选择需要的信息
Write 解决了"存"的问题,Select 解决的是"取"的问题。Agent 需要从大量的可用信息中,精确选出当前步骤需要的那一部分。
这个策略在 RAG(检索增强生成)里最常见。你有一个知识库,用户问了一个问题,你需要从知识库里找到最相关的几段内容,塞进 context window 给模型看。
但 Select 不只是 RAG。在 Agent 场景下,Select 还涉及工具选择。
当你的 Agent 有几十个可用工具的时候,你不能把所有工具的描述都塞给模型。研究表明,对工具描述做语义搜索(类似 RAG 的方式),只返回当前任务最相关的几个工具,可以把工具选择准确率提高 3 倍。
Windsurf 的 CEO Varun 说过一段话,我觉得挺有启发:代码索引不等于上下文检索。光是把代码库 embedding 了还不够,随着代码库变大,embedding 搜索变得不可靠,你得结合 grep、知识图谱、重排序等一堆手段。
这个挑战我深有体会。在 Hermes Agent 里,技能(skills)系统就是一种 Select 策略。不是所有技能都需要加载——用户说"帮我写文章",那加载文章写作相关的技能就够了,不用把所有技能都塞进 context。
策略三:Compress —— 压缩 context,只保留必要的
Agent 执行的时间越长,context 越膨胀。Compress 策略就是定期给 context "瘦身"。
最直接的方式是总结(summarization)。Claude Code 有个 auto-compact 功能——当 context 使用量超过 95% 的时候,自动把整个对话历史压缩成一段摘要。这样既保留了关键信息,又释放了 context window 的空间。
但总结也有风险。你压缩的过程中可能会丢掉重要细节。比如 Agent 在第 3 步的时候做了一个关键决策,压缩之后这个决策的上下文可能就没了,后面的步骤就不知道为什么当时做了那个选择。
Cognition(Devin 的公司)为了解决这个问题,专门微调了一个模型来做总结。这说明 context 压缩不是随便让 GPT 总结一下就行的,它本身就是一个需要精心设计的工程问题。
另一种压缩方式是修剪(trimming)。不靠 LLM 总结,直接用规则过滤。比如删掉 10 轮之前的对话、只保留最近几次工具调用的结果、移除已经被后续信息覆盖的旧数据。
在实际开发中,我倾向于两种方式结合:对工具返回的大段数据用 trimming(直接截断或只保留关键字段),对对话历史用 summarization(让 LLM 帮忙提炼要点)。
策略四:Isolate —— 把 context 拆开
Isolate 是我觉得最有意思的策略。它的核心思想是:与其在一个巨大的 context window 里管理所有信息,不如把 context 拆成多个小的、独立的部分。
最典型的应用就是多 Agent 架构。你把一个复杂任务拆成几个子任务,每个子任务交给一个专门的 sub-agent。每个 sub-agent 有自己的 context window、自己的工具集、自己的指令。它们之间不共享 context,只通过结构化的结果传递信息。
Anthropic 的多 Agent 研究系统就是这么做的。他们发现,多个拥有独立 context 的 sub-agent,比一个塞满信息的单 Agent 表现好得多。原因是每个 sub-agent 的 context window 可以专注于一个更窄的子任务,不会被无关信息干扰。
当然,多 Agent 也有代价。Anthropic 报告说,多 Agent 系统的 token 使用量是普通对话的 15 倍。你得在 context 隔离带来的质量提升和 token 成本之间做权衡。
HuggingFace 的 deep researcher 用了另一种 Isolate 方式——用代码沙箱隔离 context。Agent 输出的不是直接的工具调用,而是代码。代码在沙箱里执行,只有执行结果(比如变量的值)返回给 LLM。中间那些巨大的数据对象(图片、音频、长文本)都存在沙箱的变量里,不会进入 context window。
这个思路很巧妙。有些工具返回的数据量巨大(比如一次数据库查询返回几千行),你不需要把这些原始数据都塞给模型看。把它存在变量里,模型需要的时候再通过代码去访问特定的部分。
我在 Hermes Agent 上的 Context Engineering 实践
说了这么多理论,聊聊我的实际经验。
Hermes Agent 是一个开源的 AI 智能体框架,我在用它构建各种自动化工作流的过程中,踩了不少 context 相关的坑。
技能系统的 Select 策略
Hermes Agent 有一个技能(skills)系统,本质上就是一个 Select 策略的实现。每个技能是一个 markdown 文件,包含特定任务的指令和流程。
Agent 不会把所有技能都加载到 context 里。它先看用户的请求,判断需要哪些技能,然后只加载相关的。比如用户说"帮我写文章",Agent 会加载 totb0311-article-writer 和 totb0311-writing-style 这两个技能,其他的不加载。
这看起来简单,但解决了很大的问题。之前试过把所有技能描述都塞进 system prompt,结果 Agent 经常搞混——用户要写文章,它却去执行了部署流程。
Memory 系统的 Write 策略
Hermes Agent 的 memory 系统是另一个关键的 context engineering 实现。Agent 可以把持久化的信息存到 memory 里,每次会话开始时自动注入。
但这里有个坑:memory 注入太多会污染 context。我发现如果 memory 里存了太多琐碎的信息(比如"上次执行了 XX 命令"、"文件在 /tmp/xxx"),反而会干扰 Agent 的判断。
后来我定了一个规则:只存会跨 session 有用的信息。比如"用户偏好简洁回复"、"项目用的是 Next.js + Vercel"、"API key 存在 .env 里"。临时性的东西不存。
子代理的 Isolate 策略
delegate_task 工具是 Isolate 策略的典型应用。当任务复杂的时候,主 Agent 可以把子任务拆给 sub-agent 执行。每个 sub-agent 有自己的 context,不会被主 Agent 的历史对话干扰。
我用这个功能做过批量文章重写——把 10 篇文章分给 3 个 sub-agent 并行处理。每个 sub-agent 只需要关注自己负责的那几篇文章,不需要知道其他文章的内容。效果比让一个 Agent 从头到尾处理好得多。
但也有失败的案例。有一次让 sub-agent 去上传文章到网站,它不知道 API key 藏在环境变量里(主 Agent 的 context 里有这个信息,但 sub-agent 没有)。后来我学乖了,关键信息必须显式传给 sub-agent 的 context 参数里。
Context Engineering 的常见坑
在实际做 Context Engineering 的过程中,有一些坑是我自己踩过的,也有一些是看别人踩的。分享一下。
坑一:把所有东西都塞进 context,觉得"多就是好"
这是最常见的错误。你给 Agent 的 system prompt 写了 3000 字的指令,附带了 5 个 few-shot examples,又把整个项目的 README 也塞进去了。结果 Agent 反而变笨了。
为什么?因为信息太多,模型的注意力被分散了。它不知道该重点看哪部分。就像你给一个新员工 100 页的入职手册,他反而不知道从哪开始。
解决办法:精简。每个 context 元素都要问自己"这真的是当前步骤需要的吗?"如果不是,删掉或者延后加载。
坑二:只管写入,不管清理
Agent 在执行过程中会产生大量的中间数据——工具返回值、临时计算结果、错误日志。如果你不主动清理这些数据,context window 会越来越满,直到触发截断或者 auto-compact。
我之前在 Hermes Agent 上跑一个自动化任务,Agent 执行了 80 多步,context 直接爆了。Claude 触发了 auto-compact,但压缩之后丢失了关键的配置信息,后面的操作全乱了。
解决办法:定期清理不需要的中间结果。在 LangGraph 里可以用 trimming 函数,在 Claude Code 里可以用 /compact 命令手动触发压缩(这样你能控制压缩的时机)。
坑三:Memory 注入不加筛选
很多 Agent 框架都有 memory 系统,会自动把记忆注入 context。但如果你不筛选,可能会注入一堆不相关的东西。
ChatGPT 就出过这个问题。Simon Willison 在 AI Engineer World's Fair 上分享了一个例子:ChatGPT 从 memory 里读取了他的地理位置,然后在生成图片的时候莫名其妙地把位置信息加进去了。用户觉得 context window "不再属于自己了"。
解决办法:对 memory 的注入做筛选。不是所有 memory 都需要在每次对话中出现,只注入和当前任务相关的。
坑四:忽略工具描述的质量
很多人花大量时间优化 prompt,却忽略了工具描述的质量。但对 Agent 来说,工具描述就是它理解"我能做什么"的关键信息。
一个写得烂的工具描述会导致:Agent 不知道什么时候该用这个工具、用错了参数、或者在该用的时候没用。
我的经验是:工具描述要写清楚三件事——这个工具是干嘛的、什么时候该用它、它的参数是什么意思。别写太长,也别太短。100-200 字一个工具描述是比较合适的长度。
坑五:Rules 文件写了不更新
CLAUDE.md 或 .cursorrules 这种文件,很多人写了一次就不管了。但项目是会变的——技术栈升级了、新增了模块、踩了新的坑——rules 文件如果不更新,就会给 Agent 提供过时的信息。
我现在的习惯是:每次踩了跟 Agent 相关的坑,就把教训写进 CLAUDE.md。这样下次 Agent 就不会再犯同样的错。这其实就是 Write 策略的持续迭代。
实际上手:怎么在你的项目里做 Context Engineering
讲了这么多,给你几个可以马上动手的建议。
1. 先搞清楚你的 context 花在哪了
做 Context Engineering 的前提是知道你的 context 都用在了什么地方。如果你在用 LangChain/LangGraph,LangSmith 可以帮你追踪每一步的 token 使用情况。如果不用这些框架,至少要自己 log 一下每次 LLM 调用的 input tokens。
你可能会惊讶地发现,大部分 token 被工具返回值占了,而不是你的 prompt。
2. 对工具返回值做后处理
这是一个很容易忽略但效果立竿见影的优化。很多工具返回的数据量远超模型需要的。比如一个搜索 API 返回了 10 条结果,每条有标题、URL、摘要、日期、作者等一堆字段。但模型真正需要的可能只是标题和摘要。
在把工具返回值塞进 context 之前,先过滤掉不需要的字段。这一招可以轻松省下 30-50% 的 token。
3. 用 rules 文件替代长 system prompt
如果你在做代码相关的 Agent,用 CLAUDE.md、.cursorrules 之类的文件来管理项目级别的指令。好处是:
- 可以按目录拆分(项目根目录一个,子目录各一个)
- 可以版本控制
- Agent 按需加载,不用每次都全塞进 context
4. 设计好你的记忆系统
如果你的 Agent 需要跨会话记住东西,设计一个记忆系统。但要注意:
- 区分短期记忆(当前会话内)和长期记忆(跨会话)
- 短期记忆用 context window 或 scratchpad
- 长期记忆用外部存储,按需检索
- 不是所有信息都值得记,设定一个筛选标准
5. 考虑多 Agent 拆分
如果你的 Agent 任务越来越复杂,context 越来越长,考虑拆成多个 sub-agent。每个 sub-agent 专注一个子任务,独立的 context window。
但别过度拆分。Agent 之间的协调也有成本,拆得太细反而效率低。一般来说,如果一个 Agent 的 context 经常超过 50K tokens,就该考虑拆分了。
Context Engineering ≠ Prompt Engineering,但也不需要吓到你
最后说点大实话。
Context Engineering 这个词听起来很 fancy,但本质上就是在回答一个问题:在 Agent 执行的每个时刻,模型应该看到什么?
你不需要学什么新框架、新技术。你需要的是:
- 理解你的 Agent 在干什么
- 知道它的 context window 里都有啥
- 想清楚哪些信息有用、哪些是噪音
- 在合适的时候把合适的信息给它
这跟写好 prompt 不矛盾。Prompt 还是要写好的,但光有好 prompt 不够。你还得管好整个 context 的生命周期——写入、选择、压缩、隔离。
Karpathy 说 Context Engineering 是"精妙的艺术和科学"。我觉得他说得对。它不是一套固定的公式,而是一种思维方式。
下次你的 Agent 表现不好的时候,别急着改 prompt。先看看它的 context window 里都有什么,是不是有些东西不该在那里,或者有些东西该在那里却不在。
大概率,答案就在 context 里。
后面我打算写一篇 Context Engineering 的实战进阶,具体讲讲怎么在 Hermes Agent 里实现 memory 系统和 sub-agent 的 context 隔离。有啥想看的评论区聊。
参考资料
- LangChain: Context Engineering — LangChain 对 Context Engineering 四大策略的系统梳理
- Anthropic: Building Effective Agents — Anthropic 的 Agent 构建指南
- Cognition: Don't Build Multi-Agents — Cognition 关于长运行 Agent 的 context 管理策略
- Drew Breunig: How Contexts Fail — Context 失败模式的详细分析
- Karpathy on Context Engineering — Karpathy 对 Context Engineering 的定义