Mindket

上下文腐化:为什么上下文越长,AI 的答案越差

黑色横幅,标题是“上下文工程”,下面是“AI 智能体每一步看到的内容”。

上下文腐化,是指模型的输入越长,准确率越低,而且在上下文窗口远没占满时就开始了。放在长输入中间的事实更容易被漏掉,比找出一句话更难的任务也会更早出错。对付它的办法是少发内容:少接工具,剪短工具结果,再用笔记开启新的会话。

本节内容

  • 在你实际发送的输入长度上测出准确率从哪里开始下滑,别只信宣传的窗口大小。
  • 把答案所依赖的那条事实放在提示词的开头或结尾附近。
  • 测试时用和问题措辞不同的事实。
  • 长时间运行的智能体,在跑偏之前就从笔记文件重新开始。
全部课程
本页目录
  1. 开始之前
  2. 用大海捞针测试量出上下文腐化
  3. 一次扫描改变了哪些变量
  4. 长输入的中间部分容易丢
  5. 为什么通过大海捞针测试还不够
  6. 长上下文里该把什么挡在外面
  7. Greg Kamradt 的大海捞针测试和 Niels Rogge 的 60% 习惯
  8. 常见错误
  9. 自己试一试
  10. 自测一下
  11. 常见问题
  12. 资料来源

开始之前

needlehaystack 包需要 Python 3.12 或更新版本,PyPI 上的版本是 2.0.0。第一个演示不需要 API 密钥。要测真实模型,就把 OPENAI_API_KEY 或 ANTHROPIC_API_KEY 写进 .env 文件。

本课程的第一课什么是上下文工程,列出了每次调用时上下文里装着什么。这一课讲的是,这堆内容越来越多时,准确率会怎样。

用大海捞针测试量出上下文腐化

先在你用的模型上把它量出来。大海捞针测试,是把一条事实(针)藏进一大段填充文字(大海)里,再让模型把它找出来。深度指这条事实在上下文中的位置,顶部是 0%,底部是 100%。

这个测试背后的开源工具叫 niah,它在一张长度和深度的网格上逐格测试,每一格写一行结果。下面的命令来自它的 README。

pip install needlehaystack
niah demo --fake          # no API key, ~1s, proves the install works
niah reconstruct results.jsonl --row 0

niah demo --provider anthropic            # needs ANTHROPIC_API_KEY

niah validate my-run.yaml         # parse + resolve, no model calls
niah run      my-run.yaml         # actually run the sweep, append to JSONL
  1. 用 pip install needlehaystack 安装。
  2. 运行 niah demo --fake。它用进程内的假模型,跑 2 种长度乘 3 种深度的网格,写出 results.jsonl,不用密钥就能检查整条流程。
  3. 用 niah reconstruct results.jsonl --row 0 还原模型看到的内容。每行结果只存一份配方,不存全文,这条命令会把它还原成一模一样的上下文。
  4. 把 ANTHROPIC_API_KEY 写进 .env,运行 niah demo --provider anthropic。工具会自己读取 .env。
  5. 把 README 里的模型配置复制到 configs/models/ 下,文件名要和运行配置里 model 那一行一致(示例就是 configs/models/anthropic-opus-4-medium.yaml),然后在包含 configs/ 的文件夹里,用 niah validate my-run.yaml 检查,再用 niah run my-run.yaml 运行。

一次扫描改变了哪些变量

README 里的示例运行配置,在 2,000 到 32,000 个 token 之间取 8 种上下文长度,在 0% 到 100% 之间取十一个深度点,每一格跑三个随机种子。

sigmoid 间隔会把更多深度点放在上下文的顶部和底部附近。model 这一行指向 configs/models/ 下的一个文件,里面是发给 SDK 的请求设置。

它的任务类型是 uuid_chain:把 A 指向 B、B 指向 C 这样的链接散布在上下文里,只问 A 对应的值,却不说出这条链。模型得自己找出每一跳,这比单纯查找考得更多。

另外几种内置任务是 single、multi 和 uuid。把 model 指向你实际上线的模型,把 context_lengths 设成你的应用会发送的长度,扫描结果才能回答你自己提示词的问题。

run_name: "uuid-chain-opus"
model: "anthropic-opus-4-medium"   # resolved against configs/models/

task:
  type: "uuid_chain"
  chain_length: 5

haystack:
  type: "files"
  path: "PaulGrahamEssays"

sweep:
  context_lengths: {min: 2000, max: 32000, num: 8,  scale: "linear"}
  depth_percents:  {min: 0,    max: 100,   num: 11, scale: "sigmoid"}
  seeds: [1, 2, 3]

runner:
  concurrency: 2
  retries: 2
  resume: true

store:
  type: "jsonl"
  path: "results/uuid-chain-opus.jsonl"

长输入的中间部分容易丢

位置和长度一样要紧。在 2023 年的一项研究里,Nelson Liu 和同事给模型 20 篇检索到的文档和一个问题,答案只在其中一篇里,然后把这篇文档从第一篇一路移到最后一篇。

答案在第一篇时,GPT-3.5-Turbo 的正确率是 75.8%,在最后一篇时是 63.2%。

放在第 10 篇时,它跌到 53.8%,比完全不给文档时的 56.1% 还低。Claude 1.3 的曲线平一些,在 55.9% 到 60.1% 之间。

论文把这种形状叫作 U 形:两头最好,中间最差。

落到你写的提示词上,就是把答案所依赖的那条事实放在开头或结尾附近,不要埋在一大段粘贴内容的中间。

GPT-3.5-Turbo 的正确率,按答案在 20 篇文档中的位置回答正确的问题比例,出自论文中 20 篇文档的表格。金色那一条是中间位置。
  • 答案在第 1 篇75.8%
  • 第 5 篇57.2%
  • 第 10 篇53.8%
  • 第 15 篇55.4%
  • 第 20 篇63.2%
  • 不给文档(闭卷)56.1%

来源:Hugging Face Papers: Lost in the Middle: How Language Models Use Long Contexts (2026年11月6日 查阅)

为什么通过大海捞针测试还不够

对大多数模型来说,找出一句话已经不难了,所以新的测试把难度加了上去。2025 年的基准测试 NoLiMa,让“针”和问题之间没有一个相同的词。模型要把两者联系起来,就得知道,比如说,森佩尔歌剧院在德累斯顿。

在这篇论文的最新版本里,13 个号称支持至少 128K token 的模型中,有 11 个在 32K 长度时跌到不足短上下文成绩的一半。GPT-4o 从 99.3% 降到 69.7%(见 NoLiMa)。

NVIDIA 的 RULER 在 2024 年也发现了同样的落差。按它的最新版本,测的 17 个模型在普通大海捞针测试上几乎都接近满分,可一旦任务需要多根针、追踪或汇总,只有一半在 32K 长度时还能保持令人满意的表现。

OpenAI 的 GPT-4.1 提示词指南说,这个模型在大海捞针测试上一直到 1M token 的上限都表现很好。指南同时提醒,要找出的条目越多,或者任务需要掌握整个上下文的状态,比如图搜索,表现就可能下降。

Chroma 在 2025 年 7 月的技术报告题为 Context Rot: How Increasing Input Tokens Impacts LLM Performance。它的复现代码包含三个实验:按意思而不是按字面匹配的针、来自 LongMemEval 的长聊天记录问答,以及照抄一串重复的词。README 这样概括结论:即使任务很简单,模型表现也会随输入长度变化。

原因在于 Transformer 读取内容的方式,Anthropic 的上下文工程指南做了解释。每个 token 都会关注其他所有 token,n 个 token 就有 n² 对关系,上下文越长,固定的注意力预算就摊得越薄。

模型在训练中见到的短序列也比长序列多。指南说,结果是一道缓坡,而不是一下子掉下悬崖。

长上下文里该把什么挡在外面

在智能体里,越堆越多的主要是工具输出和旧回合。

2026 年 6 月的一项研究,看了四个开源模型做长时间网页搜索的过程,发现累积的上下文越多,模型越常直接放弃,或者给出没把握的答案。把这些上下文删光,这两种情况几乎消失,但没跑完的任务变多了(见论文)。所以要有计划地删,而不是一次删光。

压缩和记忆工具有单独的一课,智能体记忆,按需载入工具和文件则是按需载入上下文的内容。

下表只给出简要做法,清除旧结果、记笔记和按需载入,这两课会讲得更深入。

出自 Anthropic 的上下文工程指南、工具编写文章和高级工具使用文章,以及 Niels Rogge 的文章,阅读于 2026-11-06。
越堆越多的内容怎么处理出处
智能体已经用完的工具调用结果清掉。Anthropic 把清理旧工具结果称为最轻量的压缩方式之一。Anthropic:Effective context engineering for AI agents
很长的工具输出分页、过滤或截断。Claude Code 默认把一次工具响应限制在 25,000 个 token。Anthropic:Writing effective tools for agents
当前任务从不调用的工具少接几个服务器,或者等某一步需要时再载入工具。Anthropic:Effective context engineering for AI agents 和 Introducing advanced tool use
连着做了好几个任务的会话把进度写进文件,再开一个读取这个文件的新会话。Niels Rogge 发在 Hugging Face 博客上的文章

Greg Kamradt 的大海捞针测试和 Niels Rogge 的 60% 习惯

大多数长上下文报告引用的大海捞针测试,最早是 X 上的一条帖子。2023-11-08,如今担任 ARC Prize 主席的 Greg Kamradt 发布了他对 GPT-4-128K 的测试结果。

他把一句关于旧金山的话藏进 Paul Graham 的文章里,测了 15 种深度和 15 种长度,最长到 128K token。超过 73K token 后,回忆能力开始下降,放在 7% 到 50% 深度之间的事实最常被漏掉。放在最开头的事实,在每种长度下都能找到。

他当时的建议今天依然适用:上下文越少,准确率越高,而且没有哪条事实一定能被找出来。他的代码库后来成了第一节里的 niah 工具。

Niels Rogge 为 Hugging Face 的 Transformers 库贡献了大约 50 个模型架构。他在 2026 年 3 月的一篇文章里,讲了自己怎样用 OpenAI 的 Codex 应用移植一个视频模型,当时用的是 GPT-5.3 Codex。

智能体读取并更新一个 progress.md 文件,他前后让它继续了大约十次。Codex 的压缩让他一直待在同一个对话里;换成别的工具,他就会重新开始,就像下面引用的那样。写出上下文腐化报告的 Chroma,也在自己的 YouTube 频道上用视频讲解了这项研究。

通常,编码智能体一用到上下文窗口的 60%,我就得重开一个对话,因为过了这个点模型就是会变笨,这个问题叫作上下文腐化。

Niels Rogge, 为 Hugging Face Transformers 贡献了约 50 个模型,引文为译文 · Hugging Face (2026年11月6日 查阅)
Greg Kamradt(@GregKamradt)2023 年 11 月 8 日在 X 上发帖:对 GPT-4-128K 的长上下文回忆做压力测试。128K token 的上下文很棒,但表现到底怎样?我想弄清楚,于是做了一次“大海捞针”分析。
Greg Kamradt 在 X 上,2023 年 11 月 8 日
Chroma 的 YouTube 频道上的视频。

X 官方嵌入卡片的截图,拍摄于 2026-11-06,时间为 UTC。X 用“显示更多”截断了原帖。点击截图可到 X 上打开原帖。

常见错误

  • 把模型宣传的窗口大小,当成它能好好工作的长度。
  • 用和问题有相同词语的针做测试,再指望换一种说法的事实也能拿到同样的分数。
  • 把答案所依赖的那条事实,埋在一大段粘贴内容的中间。
  • 一个智能体会话一直开着,跨越好几个不相干的任务。
  • 一次把历史删得干干净净,智能体连自己做到哪一步都忘了。

自己试一试

  • 运行 niah demo --fake,再运行 niah reconstruct results.jsonl --row 0,在还原出来的上下文里找到那根针。
  • 复制运行配置,把 model 指向你用的模型,把 context_lengths 设成你的应用会发送的长度。
  • 同样的长度,先用 single 跑一次,再用 multi 跑一次,比较两次的分数。
  • 记下你的智能体答案开始下滑时的输入长度,并计划在那之前从笔记重新开始。

自测一下

  1. 在 Lost in the Middle 研究里,20 篇文档中,GPT-3.5-Turbo 在哪种情况下表现最差?

    查看答案

    B. 答案在中间附近 答案在第 10 篇时,正确率跌到 53.8%,比完全不给文档时的 56.1% 还低。

  2. 为什么一个模型在经典的大海捞针测试上拿高分,却仍会漏掉你文档里的事实?

    查看答案

    A. 针常常和问题有相同的词,靠字面匹配就能找到 NoLiMa 去掉了这种字面重合,13 个模型里有 11 个在 32K 时跌到不足短上下文成绩的一半。

  3. 哪条 niah 命令不需要 API 密钥就能跑完整的演示扫描?

    查看答案

    C. niah demo --fake README 的快速上手部分,用 niah demo --fake 对进程内的假模型运行扫描。

  4. 一个智能体在同一个会话里做完了三个任务,答案开始变差。下一步更好的做法是什么?

    查看答案

    D. 把进度存进笔记文件,再开一个读取它的新会话 新会话丢掉了过时的 token,笔记文件把下一步需要的内容带过去。

常见问题

大模型的上下文腐化是什么?

就是输入变长时准确率的下滑,即使所有内容都装得进窗口也会发生。因为下滑是渐进的,没有哪个 token 数能标出它从哪里开始,所以要在你自己的模型、你自己的长度上量一量。

1M token 的上下文窗口能解决上下文腐化吗?

不能,不过新模型撑得更久。Anthropic 在 2026 年 2 月报告,Claude Opus 4.6 在 MRCR v2 测试的 8 根针、1M token 版本上得分 76%,而 Sonnet 4.5 只有 18.5%。两个分数都不是满分。

长提示词里,指令该放在哪里?

OpenAI 的 GPT-4.1 指南建议在所给上下文的开头和结尾各放一次;如果只放一次,放在上下文上方比放在下方效果好。Anthropic 2023 年的长上下文提示词文章则强调把指令放在末尾,所以两种顺序都用你自己的扫描测一测。

上下文腐化和幻觉是一回事吗?

不是,不过一个可能引出另一个。幻觉是自信地给出错误答案。上下文腐化则是正确的事实就在提示词里,模型却漏掉或用错了它。AI 幻觉那一课讲的是前者。

资料来源

  1. Hugging Face Papers: Lost in the Middle: How Language Models Use Long Contexts (2026年11月6日 查阅)https://huggingface.co/papers/2307.03172
  2. Hugging Face Papers: NoLiMa: Long-Context Evaluation Beyond Literal Matching (2026年11月6日 查阅)https://huggingface.co/papers/2502.05167
  3. Hugging Face Papers: RULER, What's the Real Context Size of Your Long-Context Language Models? (2026年11月6日 查阅)https://huggingface.co/papers/2404.06654
  4. Hugging Face Papers: Diagnosing and Mitigating Context Rot in Long-horizon Search (2026年11月6日 查阅)https://huggingface.co/papers/2606.29718
  5. GitHub: chroma-core/context-rot (2026年11月6日 查阅)https://github.com/chroma-core/context-rot
  6. GitHub: Needle In A Haystack (niah) README (2026年11月6日 查阅)https://github.com/gkamradt/needle-in-a-haystack
  7. PyPI: needlehaystack (2026年11月6日 查阅)https://pypi.org/project/needlehaystack/
  8. Anthropic Engineering: Effective context engineering for AI agents (2026年11月6日 查阅)https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
  9. Anthropic Engineering: Writing effective tools for agents (2026年11月6日 查阅)https://www.anthropic.com/engineering/writing-tools-for-agents
  10. Anthropic Engineering: Introducing advanced tool use on the Claude Developer Platform (2026年11月6日 查阅)https://www.anthropic.com/engineering/advanced-tool-use
  11. Anthropic: Introducing Claude Opus 4.6 (2026年11月6日 查阅)https://www.anthropic.com/news/claude-opus-4-6
  12. Anthropic: Prompt engineering for Claude's long context window (2026年11月6日 查阅)https://www.anthropic.com/news/prompting-long-context
  13. OpenAI Cookbook: GPT-4.1 prompting guide (2026年11月6日 查阅)https://developers.openai.com/cookbook/examples/gpt4-1_prompting_guide
  14. X: Greg Kamradt, pressure testing GPT-4-128K with long context recall (2026年11月6日 查阅)https://x.com/GregKamradt/status/1722386725635580292
  15. Hugging Face blog: Niels Rogge, How I contributed a new model to the Transformers library using Codex (2026年11月6日 查阅)https://huggingface.co/blog/nielsr/contributing-to-transformers-with-codex
  16. YouTube (Chroma): Context Rot: How Increasing Input Tokens Impacts LLM Performance (2026年11月6日 查阅)https://www.youtube.com/watch?v=TUjQuC4ugak

分享本节课

按需取用上下文,而不是全部粘贴

浏览 Mindket 上的 MCP 服务器。每一个都让智能体只取某一步需要的文件或记录,其余的留在上下文之外。

浏览 MCP 服务器

本节课的 Markdown 版本 · 上下文工程:在每一步给 AI 智能体合适的上下文 · 全部课程