AI 的 1M token 上下文工程:窗口越大,为什么 AI 越容易在中间失忆

0 阅读7分钟

过去两年,整个行业都在比拼一件事:谁的上下文窗口更大。正中间失忆

从 GPT-3 时代的 2048 个 token,到 Gemini 1.5 Pro 的 100 万个 token,再到今天各种 200K、1M 甚至 10M 窗口的商用模型,规格表上的数字一路狂奔。

可真正把这些巨无霸塞进业务的人,很快发现一个让人困惑的现象。

你把一整份厚达三百页的技术文档、一个中大型代码库、或者一年份的聊天记录全塞进去,模型确实读完了。

但当你追问中间某个具体结论,它不是答错,就是答得含糊,甚至直接说「这段内容没有出现在我的上下文里」。

窗口明明是够的,token 也不缺,为什么模型就是「看见了当没看见」?

先泼一盆冷水:窗口大不等于记得住

这个现象不是玄学,而是有论文和数据支撑的规律。

2024 年发表的一篇名为 Lost in the Middle 的论文,揭示了上下文窗口里一个被很多人忽略的秘密。

把 token 序列的位置当成横轴、把模型检索准确率当成纵轴,画出的曲线不是平坦的而是 U 形。

模型对开头和结尾的内容记忆得最好,这叫首因效应与近因效应。

而夹在正中间的信息检索准确率明显下滑,相关研究测出下滑幅度可超过 20 个百分点。

一句话总结:上下文越大,模型越容易在正中间词。

失忆不是玄学,而是注意力在「漏检」

要理解为什么会这样,得先看清大模型的注意力机制是怎么工作的。

模型在回答每一句话时,都会在窗口里所有 token 上计算注意力权重。

当你给它的上下文很短,比如只有几千 token,模型可以把头对头的注意力都尽量摊到每个关键信息上。

可一旦窗口涨到几十万、上百万 token,注意力就成了一块「饼」。

饼还是那么大的一块注意力预算,却要被切给越来越多的 token。

于是每个 token 分到的注意力就变薄了。那些夹在中间、又被海量噪音埋住的关键句,很难在模型眼里「亮」起来。

上下文工程:从「提示词工程」长出来的新学科

既然窗口再大也有「注意力死角」,聪明人的做法就不是继续堆 token,而是反过来管理它。

这就是上下文工程。

Anthropic 对它的定义很精炼:为 LLM 推理过程策划并维护一组最优 token 的策略集合。

换句话说,提示词工程解决的是「一句话怎么说」,RAG 解决的是「该检索什么」。

而上下文工程回答的是更根本的问题:这一次推理,模型到底应该看到哪些信息,又该坚决看不到哪些。

它把系统提示词、用户输入、检索文档、对话历史、工具定义、长期记忆全部当成一个整体来调度。

一句话:提示词工程是单点优化,上下文工程是全局编排。

中间信息为什么特别容易丢

除了注意力预算被摊薄,还有两个很现实的原因。

第一个是位置本身。

模型对上下文的开头和结尾敏感,这个 U 形曲线已经是被反复复现的实验结论。

第二个是干扰项。

真实业务场景里,塞进窗口的内容往往超过一半是无关噪音,比如日志、报错堆栈、重复的模板文本。

有评测显示,上下文里混入的无关内容越多,模型对目标信息的召回率掉得越快。

三个最管用的上下文工程手法

理论说完了,直接给可以落地的做法。

手法一:给关键信息「占好位置」

既然模型开头和结尾记得最牢,那重要结论就别埋在中间。

把最终答案、核心规则、最关键的事实放在提示词的最前面或最后面。

举个例子,如果你让模型总结一份合同,不要先说一堆背景再问条款。

把「请重点核对第三条违约责任」这种指令放在最开头,模型抓取到的概率会高很多。

手法二:噪音进不来,才叫管理

上下文工程的第一步不是加内容,而是砍内容。

工具输出的日志可以截断,过长的旧对话可以压缩成摘要,低于阈值的检索结果直接丢弃。

先砍到只剩高信号内容,再谈怎么排布。

手法三:让模型自己记笔记

这是 Anthropic 在长任务里反复验证的做法,叫结构化笔记。

模型每完成一个阶段,就把进展、结论、遗留问题写进窗口外的一个文件里。

下次推理需要时再读回来,而不是让全部历史都挤在窗口里。

一个真实的压缩模板

结构化笔记听起来抽象,落地其实就是一段很朴素的提示词。

下面是我常用的「事实累积型笔记」模板:

# 项目进度笔记
- 已完成
- 阶段一:接口联调通过
- 待办
- 阶段二:性能优化
- 关键决定
- 用户输入校验统一走服务端
- 当前上下文
- 正在处理:登录超时问题

模型每轮推理结束后,把这条笔记更新一遍,再带着新版本继续。

重要信息永远留在笔记里,对话历史可以放手删。

长上下文是不是就能干掉 RAG

一个很多人会问的问题:既然窗口都到 1M 了,还要 RAG 干嘛,直接全部塞进去不就行了。

答案没那么简单,两者其实是互补的,而不是替代。

维度长上下文直塞RAG 检索
适用语料能装进窗口的代码库/文档远超窗口的知识库
成本冷启动 0.07-3 美元每次单次检索便宜很多
首字延迟冷启动 5-30 秒通常 2 秒内
跨文档推理窗口内强仅限检索到的片段
语料更新每次重发整包独立更新索引

表里的关键信息是三行:成本、延迟、语料规模。

生产环境怎么选:一个判断框架

别凭感觉二选一,按三个问题来定。

第一问:语料总量能不能装进窗口。

能装进去,且更新不频繁,直接走长上下文,省一套检索基建。

第二问:查询量级多大。

每天几百次,成本差异无所谓;每天几万次,单次贵 10 倍也是天文数字,必须走 RAG。

第三问:对延迟的容忍度。

交互场景冷启动 30 秒不可接受,RAG 的 2 秒内首字响应才是正解。

大部分团队最终会走向混合路线:RAG 先把语料压缩到 5 万到 30 万 token,再把结果交给 1M 窗口模型做全局推理,配合前缀缓存摊薄成本。

踩过的坑,替你排掉三个

第一坑:把「能塞」当成「该塞」。

能放 1M 就把 1M 全放,结果又贵又慢又容易中间失忆,是最常见的错误。

第二坑:忽略缓存。

同样的前缀反复请求,不开启前缀缓存,成本按冷启动全额计费。

第三坑:不做位置编排。

关键指令埋在长篇背景中间,模型看不见,最后怪模型笨。

一句话收尾

上下文窗口是模型的能力边界,而上下文工程是把这个边界用好的手艺。

窗口越大,越考验你怎么切分、压缩、排布那些进入窗口的 token。

下次再遇到 AI 中间失忆,先别急着换更大窗口的模型。

把这句话拿出来问自己:该让模型看见的东西,我到底有没有放到它看得见的位置。