文章摘要
2026 年,AI Agent 的核心竞争力从「模型选择」转向「上下文工程」。上下文窗口从 128K 扩展到 2M token,但更大的窗口并没有简化问题——它创造了新的工程权衡。本文系统讲解上下文工程的四层架构(原始上下文、检索上下文、压缩上下文、持久化上下文)、六种窗口管理策略、以及 RAG vs 长窗口 vs 混合方案的实战选型指南。
一、上下文工程:2026 年 Agent 的核心学科
2024 年,我们谈论「Prompt Engineering」——如何写好一个提示词。 2026 年,我们谈论「Context Engineering」——如何为 Agent 构建完整的上下文系统。
为什么上下文工程如此重要?
Andrej Karpathy 在 2026 年 3 月的演讲中提出:「上下文工程是 LLM 应用的核心,比模型选择更重要。」 他的论点是:给定同一个基础模型,上下文工程做得好的团队,其 Agent 的任务完成率比做得差的团队高 3-5 倍。
上下文工程的定义: 上下文工程是设计、构建和优化 Agent 上下文的工程学科。它包括四个层面:
- 原始上下文(Raw Context):用户输入、系统提示词、工具描述
- 检索上下文(Retrieved Context):从外部知识库检索的信息(RAG)
- 压缩上下文(Compressed Context):历史对话的摘要、关键信息提取
- 持久化上下文(Persistent Context):跨会话的记忆、用户偏好、长期知识
2026 年的核心变化: 上下文窗口从 128K(2024 年初)扩展到 2M token(Gemini 2.5 Pro, 2026 年 5 月)。更大的窗口并没有消灭上下文工程的需求,而是改变了权衡:
核心洞察: 上下文窗口的扩大不是替代上下文工程,而是改变了上下文工程的优化目标——从「如何在有限窗口中塞入最多信息」变为「如何在充裕窗口中选择最优信息」。
💡 一句话理解
理解上下文工程的层次: 不要只关注「如何写更好的 Prompt」,要关注「如何构建完整的上下文系统」。2026 年的 Agent 竞争力在于上下文工程,而不是模型选择。
⚠️ 常见踩坑
上下文窗口变大 ≠ 可以忽略上下文工程。2M 窗口的注意力稀释问题可能导致 Agent 性能下降 20-30%。上下文工程的目标不是「填满窗口」,而是「优化信息密度」。
二、上下文窗口的工程权衡:大 vs 小的真实代价
2026 年 5 月,Gemini 2.5 Pro 发布 1M token 上下文窗口,Claude 3.5 支持 200K token,GPT-5.5 Turbo 达到 512K token。 更大的窗口看起来是好事,但它带来了三个工程权衡:
权衡 #1:注意力稀释(Attention Dilution)
核心问题: Transformer 的自注意力机制在处理超长上下文时,会出现「注意力稀释」现象——模型对上下文中每个 token 的关注度下降,导致关键信息被忽略。
实证数据:
Stanford 在 2026 年 4 月发布的「Long Context Benchmark」显示:
- 在 32K 上下文中,GPT-5.5 的「 Needle in a Haystack」准确率是 98.2%
- 在 512K 上下文中,准确率下降到 91.5%
- 在 1M 上下文中,准确率进一步下降到 84.3%
这意味着什么? 即使上下文窗口有 1M token,模型也无法完美利用所有信息。关键信息如果放在上下文的中间位置,被忽略的概率比放在开头或结尾高 3-5 倍(「Lost in the Middle」效应)。
工程应对策略:
- 关键信息前置:将最重要的指令、约束、上下文放在 system prompt 的开头
- 结构化标记:使用 XML 标签(如
<important>,<context>)标记关键信息,帮助模型定位 - 分层摘要:将长上下文分为多个段落,每段开头有摘要,避免模型「迷失在中间」
核心问题: 上下文越长,LLM 的首 Token 延迟(TTFT)越高,因为需要处理更多的输入 token。
实证数据:
vLLM 在 2026 年 5 月的基准测试(H100 + Llama 3.3 70B):
- 32K 上下文:TTFT = 120ms
- 128K 上下文:TTFT = 380ms
- 512K 上下文:TTFT = 1,450ms
- 1M 上下文:TTFT = 2,900ms
延迟与上下文长度的关系: TTFT 与上下文长度近似呈线性关系(因为需要处理更多 token),但输出速度(tokens/s)几乎不受影响(因为 KV Cache 已经构建完成)。
工程应对策略:
- 预计算 KV Cache:对于固定的 system prompt,可以预计算 KV Cache 并缓存,避免每次请求都重新处理
- 异步上下文加载:将上下文检索和压缩放在异步流程中,不阻塞用户交互
- 分层上下文:只在第一轮加载完整上下文,后续轮次只加载增量信息
权衡 #3:成本上升(Cost Escalation)
核心问题: LLM 的定价按 token 计算,上下文越长,每次请求的成本越高。
实证数据:
2026 年 6 月的主流模型定价(输入 token):
- GPT-5.5 Turbo(512K 上下文):$0.50 / 1M tokens
- Claude 3.5 Sonnet(200K 上下文):$0.25 / 1M tokens
- Gemini 2.5 Pro(1M 上下文):$0.35 / 1M tokens
成本计算示例:
假设一个 Agent 每次请求需要 100K 上下文的输入:
- 每天 1,000 次请求 × 100K tokens = 1 亿 tokens/天
- 使用 GPT-5.5 Turbo:$50/天 = $1,500/月
- 使用 Claude 3.5 Sonnet:$25/天 = $750/月
工程应对策略:
- 上下文压缩:使用摘要模型(如 Claude 3.5 Haiku)将长上下文压缩为短摘要,再输入给主模型
- 选择性加载:只在需要时加载相关上下文,而不是一次性加载所有信息
- 缓存复用:对于重复的上下文(如 system prompt),使用 KV Cache 复用,避免重复计费
核心洞察: 上下文窗口的扩大不是免费的午餐。更大的窗口带来了注意力稀释、延迟增加、成本上升三个工程权衡。上下文工程的核心目标是在窗口容量和信息密度之间找到最优平衡。
💡 一句话理解
上下文窗口的权衡不是「大 vs 小」,而是「容量 vs 密度」。 2M 窗口可以容纳更多信息,但信息密度下降会导致性能下降。工程目标是优化信息密度,而不是简单填满窗口。
⚠️ 常见踩坑
不要盲目追求最大上下文窗口。对于大多数 Agent 场景,128K-256K 窗口已经足够,关键是上下文的质量和组织方式,而不是容量。
三、RAG vs 长窗口 vs 混合方案:2026 年实战选型指南
2026 年,Agent 的上下文构建有三种主流方案:RAG、长窗口、混合方案。 三者不是替代关系,而是互补关系。选择哪种方案取决于你的场景、成本、延迟要求。
方案 #1:RAG(Retrieval-Augmented Generation)
核心思想: 将知识库存储在外部向量数据库中,每次请求时检索最相关的 top-k 片段,注入到上下文中。
适用场景:
- 知识库规模大(>100K tokens),无法全部放入上下文窗口
- 知识更新频繁,需要实时检索最新信息
- 成本敏感,希望控制每次请求的 token 消耗
技术栈(2026 年主流):
- 向量数据库:Pinecone、Weaviate、Qdrant、Milvus
- Embedding 模型:OpenAI text-embedding-3-large、Cohere embed-v4.0、BGE-M3
- 检索框架:LangChain、LlamaIndex、Haystack
优势:
- 成本可控:每次请求只检索 top-k 片段(通常 5-10K tokens)
- 知识实时:更新向量数据库即可,无需重新训练模型
- 可解释性:可以追踪 Agent 使用了哪些检索片段
劣势:
- 检索质量:如果检索不到相关信息,Agent 无法回答
- 上下文碎片:检索结果是片段,缺乏全局视角
- 延迟开销:检索需要额外时间(通常 100-500ms)
方案 #2:长窗口(Long Context)
核心思想: 将整个知识库直接放入上下文窗口,利用 LLM 的长上下文能力。
适用场景:
- 知识库规模小(<200K tokens),可以全部放入上下文
- 需要全局视角,不能依赖片段检索
- 延迟敏感,希望避免检索开销
技术栈(2026 年主流):
- 模型选择:Gemini 2.5 Pro(1M)、Claude 3.5(200K)、GPT-5.5 Turbo(512K)
- 上下文管理:LangChain Context Manager、LlamaIndex Context Builder
优势:
劣势:
- 成本高昂:每次请求都要处理完整知识库(可能 100K+ tokens)
- 注意力稀释:关键信息可能被忽略(「Lost in the Middle」效应)
- 知识更新困难:每次更新都需要重新加载上下文
方案 #3:混合方案(Hybrid)
核心思想: 结合 RAG 和长窗口的优势——用 RAG 检索相关信息,用长窗口处理复杂推理。
适用场景:
- 知识库规模中等(100K-500K tokens)
- 既需要全局视角,又需要成本控制
- 复杂任务需要多步推理
技术栈(2026 年主流):
- 检索层:RAG 检索 top-k 片段
- 推理层:长窗口模型处理复杂推理
- 压缩层:摘要模型压缩历史对话
优势:
- 平衡成本与性能:RAG 控制成本,长窗口保证质量
- 灵活性强:可以根据任务动态调整检索策略
- 可扩展性:可以逐步增加知识库规模
劣势:
- 架构复杂:需要管理向量数据库、检索器、摘要模型等多个组件
- 调优难度高:需要优化检索质量、压缩比例、窗口分配等参数
选型决策树(2026 年 6 月版):
💡 一句话理解
没有「最好」的方案,只有「最适合」的方案。 2026 年的最佳实践是混合方案——用 RAG 检索相关信息,用长窗口处理复杂推理,用摘要模型压缩历史对话。
四、上下文压缩与摘要:长对话的工程实践
2026 年,Agent 的对话历史可能长达数十轮,累积数十万 tokens。 如果直接将完整历史放入上下文,会导致延迟和成本问题。上下文压缩是解决这个问题的关键技术。
上下文压缩的核心思想: 使用摘要模型(如 Claude 3.5 Haiku、GPT-5.5 Mini)将长对话历史压缩为短摘要,保留关键信息,丢弃冗余细节。
压缩策略 #1:滑动窗口摘要(Sliding Window Summarization)
核心思想: 将对话历史分为多个窗口(如每 10 轮为一个窗口),对每个窗口生成摘要,然后将所有摘要拼接为压缩后的上下文。
代码示例:
压缩策略 #2:关键信息提取(Key Information Extraction)
核心思想: 不是生成摘要,而是从对话中提取关键信息(如用户偏好、决策、待办事项),以结构化格式保存。
代码示例:
压缩策略 #3:分层压缩(Hierarchical Compression)
核心思想: 对对话历史进行多层压缩——第一层生成段落级摘要,第二层生成章节级摘要,第三层生成全局摘要。
代码示例:
压缩策略的选择:
| 策略 | 适用场景 | 压缩比 | 信息损失 |
|---|---|---|---|
| 滑动窗口摘要 | 长对话、多轮交互 | 10:1 - 20:1 | 中等 |
| 关键信息提取 | 任务导向对话、客服场景 | 20:1 - 50:1 | 低(结构化) |
| 分层压缩 | 超长对话(>100 轮) | 50:1 - 100:1 | 较高 |
核心洞察: 上下文压缩不是简单的「截断」,而是信息密度的优化。好的压缩策略可以在保留 90% 关键信息的同时,将上下文长度减少 10-20 倍。
from langchain.chat_models import ChatOpenAI
from langchain.chains import SummarizationChain
class ConversationCompressor:
def __init__(self):
self.llm = ChatOpenAI(model="gpt-5.5-mini", temperature=0)
self.summary_chain = SummarizationChain.from_llm(self.llm)
self.window_size = 10 # 每 10 轮为一个窗口
def compress(self, conversation_history):
"""将对话历史压缩为摘要"""
summaries = []
# 按窗口分割对话历史
for i in range(0, len(conversation_history), self.window_size):
window = conversation_history[i:i + self.window_size]
# 生成窗口摘要
summary = self.summary_chain.run(
input=f"Summarize the following conversation in 3-5 sentences:\\n\\n{window}"
)
summaries.append(summary)
# 拼接所有摘要
compressed_context = "\\n".join(summaries)
return compressed_contextimport json
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
class KeyInfoExtractor:
def __init__(self):
self.llm = ChatOpenAI(model="gpt-5.5-mini", temperature=0)
self.prompt = ChatPromptTemplate.from_template("""
Extract key information from the following conversation:
- User preferences
- Decisions made
- Action items
- Important facts
Output as JSON:
{{
"preferences": [...],
"decisions": [...],
"action_items": [...],
"facts": [...]
}}
Conversation:
{conversation}
""")
def extract(self, conversation_history):
"""提取关键信息"""
chain = self.prompt | self.llm
response = chain.invoke({"conversation": conversation_history})
# 解析 JSON
key_info = json.loads(response.content)
return key_info
def format_for_context(self, key_info):
"""将关键信息格式化为上下文"""
formatted = []
if key_info.get("preferences"):
formatted.append("User Preferences:")
for pref in key_info["preferences"]:
formatted.append(f"- {pref}")
if key_info.get("decisions"):
formatted.append("\\nDecisions Made:")
for decision in key_info["decisions"]:
formatted.append(f"- {decision}")
if key_info.get("action_items"):
formatted.append("\\nAction Items:")
for item in key_info["action_items"]:
formatted.append(f"- {item}")
return "\\n".join(formatted)class HierarchicalCompressor:
def __init__(self):
self.llm = ChatOpenAI(model="gpt-5.5-mini", temperature=0)
self.summary_chain = SummarizationChain.from_llm(self.llm)
def compress(self, conversation_history):
"""分层压缩对话历史"""
# 第一层:段落级摘要(每 5 轮)
paragraph_summaries = []
for i in range(0, len(conversation_history), 5):
paragraph = conversation_history[i:i + 5]
summary = self.summary_chain.run(
input=f"Summarize in 2-3 sentences:\\n\\n{paragraph}"
)
paragraph_summaries.append(summary)
# 第二层:章节级摘要(每 3 个段落摘要)
section_summaries = []
for i in range(0, len(paragraph_summaries), 3):
section = "\\n".join(paragraph_summaries[i:i + 3])
summary = self.summary_chain.run(
input=f"Summarize in 3-4 sentences:\\n\\n{section}"
)
section_summaries.append(summary)
# 第三层:全局摘要
full_summary = "\\n".join(section_summaries)
global_summary = self.summary_chain.run(
input=f"Summarize in 5-7 sentences:\\n\\n{full_summary}"
)
return global_summary💡 一句话理解
选择合适的压缩策略: 对于任务导向对话(如客服、代码助手),推荐使用关键信息提取;对于通用对话(如聊天、咨询),推荐使用滑动窗口摘要;对于超长对话(>100 轮),推荐使用分层压缩。
⚠️ 常见踩坑
上下文压缩会导致信息损失。压缩比越高,信息损失越大。建议在压缩后保留原始对话的引用,以便在需要时回溯。
五、上下文工程的最佳实践:2026 年实战经验
2026 年,上下文工程已经从「最佳实践」演变为「工程学科」。 以下是经过验证的上下文工程最佳实践,来自 Anthropic、OpenAI、Google 的官方文档和一线团队的实战经验。
最佳实践 #1:关键信息前置(Front-Load Critical Information)
核心原则: LLM 对上下文的开头和结尾关注度最高,对中间部分关注度最低(「Lost in the Middle」效应)。
实战建议:
System Prompt 开头:放置最重要的指令和约束
✅ 好的做法:将核心指令放在 system prompt 第一行,明确列出必须遵守的规则。
❌ 不好的做法:将关键约束放在 system prompt 中间或末尾,容易被模型忽略。
关键约束用 XML 标签标记:
示例:使用
<important>你必须在与用户讨论退款前,先验证用户的订单号。</important>包裹关键约束。工具描述放在 system prompt 的末尾:工具描述通常较长,放在末尾可以避免稀释关键指令。
最佳实践 #2:结构化上下文(Structured Context)
核心原则: 使用清晰的结构(标题、列表、表格)组织上下文,帮助模型定位信息。
实战建议:
使用标题分层:
将上下文按「用户信息」「当前问题」「可用工具」等模块组织,每个模块用二级标题分隔,帮助模型快速定位。使用列表组织多个要点:
将政策、规则等多条信息用编号列表呈现,避免大段文字堆砌。使用表格对比信息:
对于结构化数据(如订单列表),使用 Markdown 表格呈现,模型解析效率更高。
最佳实践 #3:动态上下文加载(Dynamic Context Loading)
核心原则: 不要在第一次请求时加载所有上下文,而是根据对话进展动态加载。
实战建议:
- 第一轮对话:只加载用户基本信息和当前问题
- 第二轮对话:根据用户回答,加载相关信息(如订单详情、历史记录)
- 后续对话:只加载增量信息,避免重复
代码示例:
最佳实践 #4:上下文版本控制(Context Versioning)
核心原则: 上下文应该像代码一样进行版本控制,以便追踪变更和回滚。
实战建议:
代码示例:
最佳实践 #5:上下文性能监控(Context Performance Monitoring)
核心原则: 监控上下文的质量指标,如检索准确率、压缩比、任务完成率。
实战建议:
- 监控检索准确率:RAG 检索的片段是否与用户查询相关?
- 监控压缩质量:压缩后的上下文是否保留了关键信息?
- 监控任务完成率:上下文变更是否影响了 Agent 的任务完成率?
代码示例:
核心洞察: 上下文工程不是一次性的工作,而是持续的优化过程。你需要不断监控、评估、迭代上下文策略,以适应不断变化的场景需求。
class DynamicContextLoader:
def __init__(self):
self.loaded_context = set()
def load_context(self, user_query, conversation_state):
"""根据用户查询和对话状态动态加载上下文"""
context = []
# 第一轮:加载用户基本信息
if "user_info" not in self.loaded_context:
user_info = self.get_user_info(conversation_state.user_id)
context.append(f"## 用户信息\\n{user_info}")
self.loaded_context.add("user_info")
# 根据查询内容加载相关信息
if "退款" in user_query and "refund_policy" not in self.loaded_context:
refund_policy = self.get_refund_policy()
context.append(f"## 退款政策\\n{refund_policy}")
self.loaded_context.add("refund_policy")
if "订单" in user_query and "order_history" not in self.loaded_context:
order_history = self.get_order_history(conversation_state.user_id)
context.append(f"## 订单历史\\n{order_history}")
self.loaded_context.add("order_history")
return "\\n".join(context)class ContextVersionControl:
def __init__(self):
self.context_versions = {}
self.current_version = "v1.0"
def update_context(self, new_context, reason):
"""更新上下文并记录版本"""
version = f"v{len(self.context_versions) + 1}.0"
self.context_versions[version] = {
"context": new_context,
"reason": reason,
"date": datetime.now().isoformat()
}
self.current_version = version
return version
def rollback(self, version):
"""回滚到指定版本"""
if version in self.context_versions:
self.current_version = version
return self.context_versions[version]["context"]
raise ValueError(f"Version {version} not found")
def compare_versions(self, v1, v2):
"""比较两个版本的差异"""
context1 = self.context_versions[v1]["context"]
context2 = self.context_versions[v2]["context"]
return diff(context1, context2)class ContextMonitor:
def __init__(self):
self.metrics = {
"retrieval_accuracy": [],
"compression_ratio": [],
"task_completion_rate": []
}
def log_retrieval_accuracy(self, query, retrieved_chunks, relevant_chunks):
"""记录检索准确率"""
accuracy = len(set(retrieved_chunks) & set(relevant_chunks)) / len(retrieved_chunks)
self.metrics["retrieval_accuracy"].append({
"query": query,
"accuracy": accuracy,
"timestamp": datetime.now().isoformat()
})
return accuracy
def log_compression_ratio(self, original_length, compressed_length):
"""记录压缩比"""
ratio = original_length / compressed_length
self.metrics["compression_ratio"].append({
"ratio": ratio,
"original_length": original_length,
"compressed_length": compressed_length,
"timestamp": datetime.now().isoformat()
})
return ratio
def log_task_completion(self, task_id, completed, context_version):
"""记录任务完成率"""
self.metrics["task_completion_rate"].append({
"task_id": task_id,
"completed": completed,
"context_version": context_version,
"timestamp": datetime.now().isoformat()
})
def get_report(self):
"""生成上下文性能报告"""
report = {
"avg_retrieval_accuracy": sum(m["accuracy"] for m in self.metrics["retrieval_accuracy"]) / len(self.metrics["retrieval_accuracy"]),
"avg_compression_ratio": sum(m["ratio"] for m in self.metrics["compression_ratio"]) / len(self.metrics["compression_ratio"]),
"task_completion_rate": sum(1 for m in self.metrics["task_completion_rate"] if m["completed"]) / len(self.metrics["task_completion_rate"])
}
return report💡 一句话理解
上下文工程是一个持续优化的过程。 不要期望一次就设计出完美的上下文策略。你需要不断监控性能指标、收集用户反馈、迭代优化上下文。
⚠️ 常见踩坑
忽视上下文工程会导致 Agent 性能下降 30-50%。即使你使用了最好的模型,如果上下文质量差,Agent 的表现也会很差。
六、上下文工程的未来:2026 年下半年趋势
2026 年下半年,上下文工程将朝着三个方向演进:自适应上下文、多模态上下文、上下文即服务(CaaS)。
趋势 #1:自适应上下文(Adaptive Context)
核心思想: Agent 能够根据任务需求,自动调整上下文的组成、压缩比、检索策略。
技术方向:
- 元学习(Meta-Learning):Agent 学习如何为不同类型的任务选择最优上下文策略
- 强化学习(Reinforcement Learning):Agent 通过试错,学习最优的上下文压缩比和检索策略
- 神经架构搜索(NAS):自动搜索最优的上下文工程架构
预期效果: 自适应上下文可以将 Agent 的任务完成率提升 20-30%,同时降低 30-40% 的成本。
趋势 #2:多模态上下文(Multimodal Context)
核心思想: Agent 的上下文不再只是文本,还包括图像、音频、视频等多模态信息。
技术方向:
预期效果: 多模态上下文可以让 Agent 处理更复杂的任务(如视觉问答、音频分析、视频理解),应用场景扩大 3-5 倍。
趋势 #3:上下文即服务(Context-as-a-Service, CaaS)
核心思想: 上下文工程抽象为独立的服务,提供 API 接口,供多个 Agent 共享。
技术方向:
- 上下文存储:统一的上下文存储服务(如 ContextDB)
- 上下文检索:提供标准的检索 API(如 Context API)
- 上下文缓存:提供上下文缓存服务,避免重复计算
预期效果: CaaS 可以降低上下文工程的重复开发成本,提高 Agent 开发效率 50-70%。
核心洞察: 上下文工程在 2026 年已经从「最佳实践」演变为「工程学科」,到 2026 年下半年,它将进一步演变为「基础设施」。自适应上下文、多模态上下文、CaaS 将成为 Agent 架构的标准组件。
💡 一句话理解
关注上下文工程的未来趋势: 自适应上下文、多模态上下文、CaaS 将在 2026 年下半年成为主流。提前布局这些技术,可以在竞争中占据优势。
⚠️ 常见踩坑
上下文工程的快速演进意味着你需要持续学习。2024 年的最佳实践可能在 2026 年已经过时。保持对新技术的敏感度,及时更新你的上下文工程策略。