上下文工程:管理100万token的窗口,同时避免上下文退化
高级12 分钟阅读提示词工程

上下文工程:管理100万token的窗口,同时避免上下文退化

100万token的上下文窗口已经成为现实,但远未达到上限时,质量就会开始下降。上下文工程研究如何有效使用上下文窗口:该纳入什么、该总结什么、该实时检索什么,以及如何在上下文不断增长时维持高质量。

您应该能够做到的事情

长上下文窗口是一种工具,而不是现成的解决方案。远未达到技术上限时,质量就会开始下降。只有做好上下文工程——决定纳入什么、总结什么、动态检索什么——大上下文系统才能真正发挥良好性能。

AI Expert Team发布日期: 2026年5月15日
仅在此浏览器中保存。
本文内容

到了2026年,我们已经拥有100万token的上下文窗口。Gemini、GPT-5和Claude(配合扩展思考)都支持这种规模。演示中,模型可以一次读完整本书。那个梦想似乎终于成真了:只要把所有内容都塞进上下文,让模型自己处理即可。

但现实一如既往,要复杂得多。100万token只是技术容量,并不保证实际性能。现实场景中的模型通常在5K–50K token的上下文范围内表现最佳。达到100K以上后,细微的质量问题便会出现;达到500K以上后,模型会反复漏掉重要信息;到了1M,模型就会不堪重负。

这种现象称为“上下文退化”,它确实存在,已有充分研究记录,也能在评估中观察到。这意味着你不能只是把所有内容一股脑塞进上下文,就认为万事大吉。你需要上下文工程:有意识地决定该纳入什么、该总结什么、该动态检索什么,以及如何组织最终形成的上下文。

本文将介绍面向严肃生产系统的有效上下文工程模式与实践方法。

什么是上下文退化

“上下文退化”是一种经验现象:即使上下文仍在技术上限之内,LLM的性能也会随着上下文增长而下降。

具体的失效模式包括:

中间信息遗失Liu et al., 2023)。模型会更多关注上下文开头和结尾的内容,对中间信息的利用则不那么可靠。同一个事实放在100K token上下文中的50K位置,比放在1K或99K位置时更容易被遗漏。

近因偏差。 模型会过度重视较新的内容。在对话历史中,较早的上下文实际上会逐渐变得不可见。

容易受干扰项影响。 即使任务根本不需要某些内容,把这些无关内容放进上下文也会降低性能。模型必须进行筛选,而筛选过程中难免会受到干扰。

推理质量下降。 随着上下文增长,多步推理会变得不那么可靠。模型需要追踪的内容更多,追踪质量也会随之下降。

成本与延迟。 这与质量无关:大上下文按token计费,成本高;对许多模型而言,延迟会随token数量线性增加,因此速度也更慢。

这些并非理论上的担忧。生产实践反复表明,直接使用未经筛选的大上下文,其效果始终不如经过精心整理的上下文。

核心原则:少即是多

核心认识是:上下文是一种宝贵且会随使用量增加而退化的资源,应当有策略地使用。

经过精心筛选的30K token上下文,通常胜过把所有内容全部塞入的300K token上下文。无论质量、成本还是延迟,较小的上下文通常都更有优势。

这会改变工程工作的重点。问题不再是“想办法往上下文里放入更多内容”,而是“确定哪些内容确实需要放入上下文,并以恰当方式放进去”。

上下文预算

把上下文看作一项需要分配的预算。

下面是一个客户支持智能体的典型分配:

上下文总预算:30K token

- 系统提示词:1500 token(5%)
- 工具描述:1000 token(3%)
- 用户资料/上下文:500 token(2%)
- 对话历史摘要:1000 token(3%)
- 近期完整对话轮次:4000 token(13%)
- 检索到的相关知识:12000 token(40%)
- 用户当前消息:500 token(2%)
- 输出token预算(回复):10K token(33%)

每个组成部分都在争夺空间。随着上下文增长,你必须作出取舍。

关键纪律是明确规定各部分的分配,不让任何一部分无限增长。

模式1:分层对话记忆

在多轮对话中,完整历史会无限增长。大多数生产系统都会采用分层记忆:

第1层:完整保留近期轮次。 原样保留最近5–10轮交流。

第2层:总结较早轮次。 将对话中更早的内容压缩成简短摘要。

第3层:提取事实。 从对话中提取关键信息,例如用户姓名、偏好和已作出的决定,并存为结构化事实。

实现方式如下:

每一轮执行:
1. 获取对话历史。
2. 原样保留最近10轮。
3. 将第11–30轮总结为200字(“此前,用户讨论了X,我们一致决定Y”)。
4. 将第31轮及更早内容缩减为提取出的事实(“用户偏好Python。用户使用企业版套餐。”)。
5. 无论对话多长,记忆总量都维持在约2K token。

这是所有长时间对话的基础模式。缺少这套机制,对话质量就会随着长度增加而下降。

需要注意的是,摘要必须保留智能体后续会用到的信息。如果用户在第5轮提到账户号码,而智能体没有将其纳入长期记忆,那么到第50轮时,这个账户号码就会丢失。

执行总结时,应明确说明需要保留哪些内容:

总结截至目前的对话。保留:
- 关于用户的所有事实(姓名、角色、偏好、账户信息)。
- 已作出的所有决定。
- 所有尚未履行的承诺或待跟进事项。
- 当前对话目标。

舍弃:
- 寒暄。
- 重复信息。
- 已经解决的问题所涉及的详细推理过程。

模式2:即时检索

不要预先加载上下文,而要在内容变得相关时再检索。

一种反模式是把用户的所有文档都塞进上下文,“以防模型需要”。大多数查询只需要其中很小一部分,这样做既浪费上下文,也会损害性能。

更好的方式是根据当前查询检索文档。不同查询获得不同文档,每次调用的上下文总量保持较小,相关性则保持较高。

这其实就是严谨地运用RAG。关键在于,不要因为“放得下”就忍不住把所有内容都放进去。长上下文模型出现后,即使经验丰富的团队也很容易受到这种诱惑。

模式3:压缩表示

对于确实需要长期保留在上下文中的信息,应使用压缩表示。

原文(冗长):

这名用户从事软件工程已有8年,最初在一家名为Acme Corp的小型初创公司负责后端系统。3年后,这名用户跳槽到规模更大的Beta Inc,从事前端工作,目前在Gamma LLC负责机器学习系统。

压缩后:

用户:软件工程师,8年经验,目前在Gamma LLC从事机器学习。此前:Acme后端(3年),Beta前端。

压缩版本用更少的token保留了相关事实。对于大多数用途,模型使用两个版本的效果相当。

这种方法可以用于:

  • 用户资料。
  • 文档摘要。
  • 过往对话上下文。
  • 知识库条目(不需要完整内容时)。

代价是压缩会丢失细节。需要保留细节时使用全文,不需要时再使用压缩版本。

模式4:分层检索

面对非常庞大的知识库,应采用分层检索。

第1步: 根据查询检索大类或文档摘要。

第2步: 在最相关的类别中检索具体文本块。

第3步: 最终只把第2步选出的文本块放入上下文。

这样可以避免“我有10K份文档,那就把它们全嵌入上下文”的做法。通过逐层收窄范围,上下文可以保持精简。

还有一种变体:在文本块进入主要调用之前,先让一个小型LLM调用筛选出最相关的内容。这样会增加少量成本,却能显著减少上下文膨胀。

模式5:反思上下文

对于执行长期任务的智能体,应定期检查当前上下文中有什么,以及真正应该保留什么。

智能体每执行10个步骤,就会:

1. 检查当前上下文。
2. 找出与正在进行的工作相关的内容。
3. 总结或删除已经不再需要的内容。
4. 记录还有哪些额外上下文可能有帮助。
5. 用整理后的版本替换旧上下文。

这相当于对上下文执行“垃圾回收”。如果没有这一步,智能体会不断积累陈旧信息,挤占新信息和相关信息的空间。

实现这一模式需要自定义编排,因为大多数框架都不能原生处理。具体做法是在不同步骤之间加入“记忆整合”阶段,用来调整上下文内容。

模式6:动态上下文窗口

智能体执行过程中的不同环节,所需的最佳上下文大小可能不同。

  • 决策步骤: 使用较小的上下文,聚焦当前需要作出的决定。
  • 综合步骤: 使用较大的上下文,纳入多个信息来源。
  • 生成步骤: 使用中等大小的上下文,并提供风格与格式参考。

一种可行模式是,让智能体工作流中的每个步骤使用不同的上下文结构,由编排层决定哪些内容进入哪个步骤。

这要求把智能体的工作拆分成明确步骤,而不是放进一个大循环。此处的框架选择很重要:LangGraph可以自然地处理这种模式,直接调用API则需要手动实现。

模式7:根据位置安排内容

既然模型会更多关注上下文的开头和结尾,就应把重要内容放在这些位置。

效果较差: 把关键指令埋在很长的系统提示词中间。

效果更好: 把关键指令放在最开头,并在接近末尾处再次强调。

在包含多份检索文档的RAG场景中,可以把最相关的文档放在开头,把相关性第二高的文档放在末尾,相关性较低的文档则放在中间。

这是一种战术性优化,但对输出的影响可以实际测量。

模式8:有选择地总结

总结方式并非全都一样。应根据下游任务的需要来设计摘要。

较差: 使用通用摘要,导致用户偏好被丢弃。

更好: 在摘要中明确保留与下游任务相关的用户偏好。

总结这份文档,重点关注:
- 已作出的技术决策。
- 提到的利益相关方。
- 尚未解决的问题或风险。

舍弃:
- 团队已经了解的一般背景。
- 重复的观点。

这段总结提示词是专门针对下游用途设计的。

模式9:结构化上下文

纯文本只是一种选择。结构化上下文(JSON、XML或特定标记)可以用更紧凑的形式承载信息。

冗长的叙述:

客户名叫John Smith,自2023年3月起成为客户。目前使用Pro套餐,按月付费,每月29美元。他启用了3项集成:Slack、Notion和Linear。过去30天的使用量为中等,共调用API 1,250次。

结构化表示:

{
  "customer": {
    "name": "John Smith",
    "since": "2023-03",
    "plan": "Pro",
    "billing": "monthly $29",
    "integrations": ["Slack", "Notion", "Linear"],
    "usage_30d": {"api_calls": 1250, "tier": "moderate"}
  }
}

结构化版本更短,而且通常更便于模型使用。模型可以迅速定位具体事实。

但要注意,并非所有模型都同样擅长处理结构化输入。应针对你的用例测试两种格式。

模式10:按优先级分层上下文

按照优先级划分上下文:高优先级内容始终纳入,中优先级内容在相关时纳入,低优先级内容按需检索。

始终纳入:

  • 系统提示词(身份、行为)。
  • 当前用户上下文(必要事实)。
  • 近期对话。

相关时纳入:

  • 与查询匹配的检索文档。
  • 最近步骤产生的工具输出。

按需获取:

  • 智能体通过工具调用请求的特定数据。
  • 超出近期窗口的历史上下文。

“按需获取”模式对系统扩展至关重要:智能体只在需要时检索所需内容,而不是预先加载一切。

模式11:淘汰策略

上下文接近上限时,应该淘汰什么?

  • 基于时间顺序: 最旧的内容最先淘汰。
  • 基于相关性: 与当前任务最不相关的内容最先淘汰。
  • 基于重要性: 标记为低重要性的内容最先淘汰。

一种实用做法是为上下文项标记优先级。需要淘汰时,按照优先级顺序删除。

context_items = [
    {"content": "...", "priority": "critical"},   # 永不淘汰
    {"content": "...", "priority": "high"},        # 最后淘汰
    {"content": "...", "priority": "medium"},     # 必要时淘汰
    {"content": "...", "priority": "low"},         # 最先淘汰
]

def evict_to_fit(items, budget):
    items_by_priority = sorted(items, key=lambda x: priority_value(x.priority))
    while total_tokens(items) > budget:
        items.remove(items_by_priority.pop(0))  # 删除优先级最低的项
    return items

模式12:缓存重复使用的上下文

许多调用会重复使用相同的上下文,例如相同的系统提示词、工具描述和用户资料。

目前大多数供应商都支持提示词缓存

  • Anthropic:在消息中显式添加 cache_control 标记。
  • OpenAI:自动缓存前缀匹配的请求。
  • Google:通过API显式创建缓存内容。

重复使用相同前缀时,缓存版本速度更快、价格更低,通常可便宜90%。

如果智能体会在一个会话中执行大量调用,应确保静态部分(系统提示词、工具、用户上下文)可以缓存。把动态内容(当前步骤、近期结果)放在可缓存前缀之后。

这是投资回报率最高的优化之一。假设会话中的50次调用都使用同一个10K token静态前缀:第一次按全价计费,之后每次都便宜90%,节省的成本相当可观。

模式13:上下文感知提示词

提示词可以引导模型更好地使用上下文:

请参考下方文档回答用户的问题。务必引用具体文档,并摘录相关段落。

如果在所提供的文档中找不到答案,请明确说明。不要编造信息。

如果多份文档中的信息都与问题有关,请综合这些信息,并指出其中不一致之处。

这种提示方式可以减少基于上下文回答任务中的幻觉,并提高引用质量。

何时应该使用更长的上下文

尽管存在上下文退化,但对于某些任务而言,更长的上下文确实更好:

单文档分析。 如果任务是“分析这份合同”,把整份合同放进上下文通常比分块检索更好。

比较多个项目。 并排比较10份合同时,把10份合同全部放进上下文会更有帮助。

在上下文中编辑代码。 要修改一个5K行代码文件中的函数,把整个文件放进上下文比只使用检索出的片段更容易。

总结完整对话。 要总结一段长对话,在一定范围内,使用完整上下文的效果更好。

一般规律是:如果任务本质上需要理解不同内容之间的关系,更长的上下文会有帮助;如果只需一小部分内容就能完成任务,则较小的上下文更好。

一个实用的经验法则是:50K token以内的上下文通常没有问题;50K–200K token仍可使用,但质量会有所下降;200K token以上的上下文往往不如更短的上下文。务必通过实际测试验证。

评估纪律

如何知道上下文工程是否有效?答案是评估。

具体可以开展以下评估:

召回测试。 在长上下文的不同位置埋入关键事实,测试模型能否使用这些事实,并衡量召回率随位置的变化。

干扰项测试。 对比同一查询在包含和不包含无关上下文时的表现,衡量性能下降幅度。

长上下文与RAG对比。 分别使用完整上下文和检索出的文本块回答相同查询,并比较质量。

token效率。 衡量每花一美元获得的质量。上下文越长,成本越高;质量是否也相应提升?

这些评估能够揭示你的上下文选择是否真的带来帮助。缺少评估,一切都只是猜测。

完整示例:研究助理

来看一个现实案例:为小型团队构建AI研究助理。

任务: 回答有关200份文档构成的语料库的问题,其中包括论文、内部文档和会议记录。

简单粗暴的做法: 把所有文档嵌入上下文,共300K token。质量尚可,但成本高、延迟大。

经过工程优化的做法:

上下文预算:25K token

- 系统提示词:1500 token(已缓存)
- 工具描述(search、fetch_doc等):800 token(已缓存)
- 对话记忆:1500 token(最近10轮)
- 针对当前查询检索的文本块:18000 token(通过RAG取得最相关的12个文本块)
- 用户当前问题:200 token
- 输出预算:约3000 token

智能体根据问题动态检索文本块。对话记忆保留近期上下文,静态元素则进行缓存。

结果:

  • 延迟:2–3秒,而使用300K上下文时为10–15秒。
  • 成本:约€0.01/次查询,而原来约为€0.10。
  • 质量:根据评估集测得的结果,质量有所提升,因为模型能够恰当地关注相关内容。

这就是严谨的上下文工程:它不是一次性决定,而是需要持续调优。

常见错误

以下是几种常见模式:

错误1:“上下文越多越好。” 一遇到质量问题,就试图用更长的上下文来解决。实际情况往往恰恰相反。

错误2:没有上下文预算。 各组成部分无限增长。用户资料部分膨胀到5K token,检索文本块部分膨胀到50K token,毫无约束。

错误3:忽略位置。 把关键指令埋在中间,指望模型自己找到。模型有时能找到,但往往找不到。

错误4:用冗长叙述表达事实。 明明结构化数据就足够,却使用长句,浪费token。

错误5:不总结对话。 对话不断增长,直至超出限制,随后要么质量逐渐下降,要么直接失败。

错误6:不使用缓存。 每次调用都为重复的静态前缀支付全价,白白错失轻松节省成本的机会。

错误7:不评估上下文选择。 想当然地认为“更好的上下文工程”正在奏效,实际却未必如此。

错误8:使用通用摘要。 总结时不考虑下游任务需要什么,导致重要信息丢失。

要点总结

长上下文窗口确实已经存在,但这不代表可以忽视上下文工程。远未达到技术上限时,质量就会开始下降,成本与延迟也同样不可忽视。

上下文工程需要遵循以下实践:

  • 把上下文视为一项预算。
  • 对记忆进行分层:近期内容原样保留,较早内容进行总结,最早内容提取为事实。
  • 即时检索,而不是预先加载。
  • 在不丢失信息的前提下进行压缩。
  • 把关键内容放在模型注意力较高的位置。
  • 按优先级对上下文进行分层。
  • 缓存静态前缀。
  • 持续评估。

与简单粗暴地“把一切都扔进上下文”相比,这些模式能让系统效果更好、速度更快、成本更低。

对于成熟的生产系统,上下文工程是杠杆效应最高的领域之一。底层技术并不复杂;能否严谨地运用这些技术,才是“演示可用”与“生产可靠”之间的分水岭。

持续投入这些模式,并建立严格的工程纪律。最终得到的AI系统,才能在面对更多数据、更长对话和更高复杂度时平稳扩展。

继续阅读

通过下一篇文章继续沿着相同的学习路径进行学习。