Context Engineering(上下文工程)
通过精心设计 prompt 上下文(系统提示、示例、检索结果、工具定义)来最大化 LLM 表现的工程方法论。
什么是 Context Engineering
Context Engineering(上下文工程)是 Prompt Engineering 的进化版。不再只关注"怎么写提示词",而是关注怎么组装喂给模型的全部上下文——系统提示、对话历史、检索结果、工具定义、few-shot 示例等。
核心理念:LLM 的能力上限不取决于模型本身,而取决于你给它什么上下文。
上下文窗口的组成
一个完整的 LLM 调用,上下文通常包含:
┌─────────────────────────────────┐
│ System Prompt(系统提示) │ ← 角色设定、行为规范
├─────────────────────────────────┤
│ Tool Definitions(工具定义) │ ← 可调用的函数签名
├─────────────────────────────────┤
│ Few-shot Examples(示例) │ ← 输入输出范例
├─────────────────────────────────┤
│ Retrieved Context(检索内容) │ ← RAG 检索的文档
├─────────────────────────────────┤
│ Conversation History(对话历史) │ ← 之前的对话
├─────────────────────────────────┤
│ Current Query(当前问题) │ ← 用户本次输入
└─────────────────────────────────┘
顺序不是随便摆的。稳定的、重复出现的内容放最前面,让 prompt cache 命中率高;动态变化的(用户当前问题)放最后。这一条规则单独就能为高频应用省下 60-90% 的 input token 成本。
核心原则
1. 信号最大化
上下文中每一条信息都应该对完成任务有贡献。删掉无关内容,让模型聚焦。
❌ 把整个项目代码塞进上下文
✅ 只塞当前修改的文件 + 相关接口定义
2. 噪音最小化
无关信息会分散模型注意力,降低输出质量。
❌ "你是一个 AI 助手,你有强大的能力,你的任务是..."
✅ "Review this PR for security issues." (直接给任务)
3. 结构化
用清晰的格式让模型快速理解上下文结构:
<context>
<file path="src/auth.ts">
... file content ...
</file>
<file path="src/db.ts">
... file content ...
</file>
</context>
<task>
Review the auth module for security vulnerabilities.
</task>
XML 和 Markdown 都行。Anthropic 的训练数据里 XML 标签出现频率更高,对 Claude 而言 XML 略胜;OpenAI 模型对 Markdown 表头敏感。在生产里挑一种坚持用,不要随机混搭。
4. 上下文缓存
对于重复出现的上下文(系统提示、工具定义),使用 prompt caching 避免重复计算:
| 平台 | 机制 | 命中后价格 |
|---|---|---|
| Anthropic Prompt Caching | 显式 cache_control 标记 | Input 价格 -90% |
| OpenAI Cached Input | 自动缓存前缀(≥ 1024 token) | Input 价格 -50% |
| Gemini Context Caching | 显式 cachedContent API | Input 价格 -75%(按时间收存储费) |
| DeepSeek Context Caching | 自动缓存 | Input 价格 -90% |
实测对比:一个 50K token 的 system prompt,每次调用,开缓存与不开缓存的 input 成本差距 5-20 倍。高频调用的场景一定要开。
中间遗忘(Lost in the Middle)
上下文不是越长越好。论文与实测都显示模型对首尾内容记得更牢,中间段容易被忽略。
[ system | 检索结果1 | 检索结果2 | ... 检索结果10 | history | query ]
↑ 强 ↑ 弱 ↑ 强
防御套路:
- 把关键信息放上下文开头或结尾,不要藏在中段
- 检索结果按相关度排序,最相关的放最前 / 最后
- 长 history 周期性总结压缩,不要原文堆积
- 用「关键指令重复」——重要约束在 system prompt 开头说一遍、结尾再说一遍
实战技巧
Cursor 的上下文管理
Cursor 在 Vibe Coding 时会智能组装上下文:
@file引入特定文件@folder引入整个目录@web搜索网络内容@docs引入文档
Claude Code 的上下文策略
Claude Code 在处理大型项目时:
- 用
ls/grep探索项目结构(不盲目加载全部文件) - 只读取相关文件
- 用 CLAUDE.md 文件保存项目约定(每次自动加载)
- 长对话时自动压缩历史
Token 预算管理
200K 上下文不等于应该用满 200K。最佳实践:
| 上下文用量 | 效果 |
|---|---|
| < 50% | 最佳质量 |
| 50%-80% | 轻微退化 |
| 80%-95% | 明显退化("中间遗忘") |
| > 95% | 严重退化、可能超限报错 |
调试上下文
线上效果不对,先排查上下文而不是 prompt:
- 把实际发给模型的完整上下文 dump 出来——很多框架会偷偷塞东西、截断中段。先看到真实输入。
- 数 token——是不是已经过 80%?过了就先压缩。
- 关掉一半内容跑一遍——如果效果不降反升,说明里面有噪音。
- 变换顺序——把检索结果挪到 query 之后,对比效果。Claude 对"指令在 context 之后"特别敏感。
与 Prompt Engineering 的区别
| 维度 | Prompt Engineering | Context Engineering |
|---|---|---|
| 关注点 | 怎么写提示词 | 怎么组装全部上下文 |
| 范围 | 单条 prompt | 系统+工具+检索+历史+示例 |
| 复杂度 | 简单 | 工程化 |
| 适用 | 单次调用 | Agent / 复杂应用 |
| 时代 | 2023 | 2025+ |
Prompt Engineering 是 Context Engineering 的子集。
延伸阅读
- 基础:Prompt Engineering——写好单条 prompt
- 计费视角:Token——上下文长短直接对应账单
- 上下文来源:RAG、Embedding
- Agent 上下文:AI Agent中的 working memory