#上下文太多为什么会让大模型变笨:长上下文退化、Context Engineering 与科研机会综述
一句话结论:“上下文太多让模型变笨”不是错觉。问题不在于信息多本身有害,而在于当前大模型虽然能把更多 token 放进窗口,却没有同等强大的信息选择、抗干扰、状态维护、证据绑定、记忆压缩和长程信用分配能力。真正值得研究的不是单纯把窗口从 128K 拉到 1M,而是研究 effective context use:模型怎样知道该看什么、忽略什么、记住什么、压缩什么、什么时候回查原文,以及如何在长轨迹中保持目标不漂移。
这篇文章面向两类读者:
- 初学者:你可能刚接触长上下文、RAG、KV cache、Agent memory,不确定这些词之间是什么关系。
- 想做研究的人:尤其是关心 LLM Agent、代码智能、长轨迹 RL、context compressor、latent-space reasoning 的读者。
我会尽量避免把文章写成论文列表。每个晦涩概念第一次出现时,先用人话解释,再给技术名词;每类方法都说明它解决什么、不解决什么;最后给出更适合开题的研究切入点。
#0. 阅读路线:先抓住主线,再看细节
这篇文章比较长,因为它覆盖的是一个完整研究方向。你可以按目标选择路线:
| 你的目标 | 建议重点阅读 | 读完应得到什么 |
|---|---|---|
| 快速理解问题 | 第 1、2、3、17 节 | 知道为什么“长窗口”不等于“会用长上下文” |
| 梳理论文脉络 | 第 3、4、5、6、7、8、9、16 节 | 知道 benchmark、机制、方案分别回答什么 |
| 做 LLM Agent | 第 2、4、10、12、13 节 | 知道 agent 为什么会目标漂移、重复探索、记忆污染 |
| 做代码智能 | 第 2.3、3.10、10.6、12.4、13.3 节 | 知道 repo 级任务为什么不是“多塞代码”能解决 |
| 做 context compressor | 第 4.6、8、10.5、13.2 节 | 知道为什么摘要不等于决策状态 |
| 做长轨迹 RL | 第 4.8、10.7、12、13.4、13.6 节 | 知道上下文管理如何变成可学习策略 |
| 做 latent-space reasoning | 第 8.4、8.5、13.5 节 | 知道 latent memory 为什么可能比自然语言历史更适合长期任务 |
先记住七句话:
- 能装下很多 token,不等于能可靠用上这些 token。
- 长上下文退化不是一个 bug,而是一组失败模式:找不到、用错、被带偏、忘约束、压缩丢细节、长轨迹归因失败。
- 长窗口、RAG、压缩、KV cache、memory 不是互相替代关系,而是一条信息流里的不同环节。
- RAG 的核心不是召回更多,而是让正确证据以低噪声、可追溯的形式进入模型。
- 压缩的核心不是写短摘要,而是保留未来决策需要的信息。
- 对 agent 和代码任务来说,长上下文问题最终会变成决策问题:何时读、何时记、何时删、何时验证。
- 未来强 agent 的关键能力不是吞下无限上下文,而是管理上下文。
全文的因果链可以压成一行:
上下文变长 → 关键信息被噪声、位置和历史状态淹没 → 模型出现检索、推理、证据绑定和目标维护失败 → 系统需要检索、排序、压缩、记忆、验证和上下文策略 → 科研机会来自这些环节之间的断点。
面向 wenjun 研究兴趣,可以先看这张导航表:
| 兴趣方向 | 在本文中的核心问题 | 最值得抓的研究问题 |
|---|---|---|
| LLM Agent | agent 跑久后如何不忘目标、不重复探索、不把错误假设写进记忆 | Agent Lost-in-the-Middle、memory pinning、context policy |
| 代码智能 | repo 级任务里如何找对文件、调用链、测试证据,而不是被相似代码带偏 | Lost-in-Repository、provenance-aware code context、test-feedback memory |
| 长轨迹 RL | 最终成功或失败发生在很多步后,如何知道哪一步上下文管理动作有责任 | memory credit assignment、context actions、process reward |
| Context compressor | 如何把长历史压短,但仍保留未来任务成功所需信息 | decision-sufficient compression、counterfactual memory evaluation |
| Latent-space reasoning | 是否可以不把所有状态写成自然语言,而用更紧凑的内部状态表示任务 | latent task state、memory tokens、state slots |
#1. 先定义问题:Long Context 不等于 Effective Context
长上下文问题可以从一句话展开:
模型能装下更多上下文,不等于它能可靠使用更多上下文。
这里有四个容易混淆的概念:
| 概念 | 人话解释 | 技术说法 | 常见误解 |
|---|---|---|---|
| 能装下 | prompt 里最多可以放多少 token | nominal context length / context window | “支持 1M token,所以就能理解 1M token” |
| 能找到 | 关键信息在里面,模型能不能定位 | in-context retrieval | “答案在 prompt 里,模型自然会看到” |
| 能用对 | 找到信息后,能不能组合、推理、绑定来源 | reasoning and evidence binding | “模型说出正确词,就说明它用对了证据” |
| 能管理 | 长任务中,能不能决定什么该记、该删、该回查 | context management / context engineering | “保留完整历史就等于有记忆” |
标称上下文长度,英文常叫 nominal context length 或 context window,意思是“接口最多允许输入多少 token”。
有效上下文能力,英文常叫 effective context length 或 effective context capacity,意思是“模型在真实任务里到底能稳定利用多少上下文”。
可以用一个普通比喻理解:一个书包能装十本书,不代表你考试时能在十本书里快速找到正确公式、判断哪页是关键、把几页内容组合起来解题。长窗口是书包容量;有效上下文能力是查找、理解和组织信息的能力。
直觉上,我们会觉得:给大模型更多上下文,它应该更聪明。比如:
- 给它更多论文,它应该综述更全面;
- 给它更多代码文件,它应该修 bug 更准;
- 给它更完整的聊天历史,它应该更理解用户;
- 给 agent 全部工具调用轨迹,它应该少重复犯错;
- 给 RAG 系统召回更多文档,它应该更不容易漏信息。
但真实情况常常相反。上下文越塞越多后,模型可能出现这些失败:
| 失败现象 | 一个具体例子 | 这说明什么 |
|---|---|---|
| 找不到关键事实 | 答案明明在 prompt 中间,模型却说不知道 | 长窗口不是均匀搜索器 |
| 被无关材料带偏 | RAG 多召回几篇相似旧文档,答案反而错 | 噪声不是无害的 |
| 忘记中间约束 | 用户早期说“不要改 A 文件”,后面模型仍然改了 | 长轨迹状态维护弱 |
| 目标漂移 | agent 跑了几十步后,开始优化次要问题 | 当前动作和原始目标脱节 |
| 重复探索 | 之前已经查过某个文件,后面又反复读 | 历史没有变成可用记忆 |
| 摘要丢细节 | 压缩历史后,文件路径、错误栈、边界条件没了 | 摘要不等于决策状态 |
| 长输出不一致 | 写长报告时前后矛盾、遗漏约束 | 长输入理解和长输出规划不同 |
| 证据来源错配 | 答案看起来合理,但引用了另一篇相似文档 | 模型没有把结论和来源绑牢 |
所以,这里的“变笨”不是说模型参数突然退化,而是说:
在长上下文条件下,模型把有限计算和表示能力分散到了太多候选信息上,导致真正对当前任务有用的信息没有被稳定提取、保持和使用。
小结:长上下文研究不是只问“窗口多长”,而是问“信息进入模型以后,模型能不能找到、用对、记住、验证和压缩”。
#2. 为什么这个问题现在特别重要?
#2.1 长窗口让人产生了一个危险错觉
过去几年,模型厂商不断把 context window 拉长:从 4K、8K,到 32K、128K,再到百万 token。长窗口很诱人,因为它看起来可以绕过很多复杂系统问题:
- 不想做检索?那就把所有文档塞进去。
- 不想做 memory?那就把完整历史保留。
- 不想做代码索引?那就把整个 repo 塞进去。
- 不想设计 agent 状态?那就把完整工具调用轨迹放进 prompt。
- 不想做压缩?那就多买一点上下文预算。
但这只是把“系统设计问题”转嫁给模型内部。模型看到所有内容,不代表它能做出正确的信息筛选。
更准确的说法是:
长窗口降低了信息进入模型的门槛,但没有自动解决信息管理问题。
#2.2 Agent 会把长上下文问题从“读长文”放大成“跑长任务”
在普通问答里,长上下文可能只是多几篇文档;但在 LLM Agent 里,上下文会自然膨胀成一条长轨迹:
- 用户目标;
- system/developer 指令;
- agent 自己的计划;
- 工具调用结果;
- 文件读取内容;
- 测试日志;
- 错误尝试;
- 中间总结;
- 代码 diff;
- 新一轮修复计划。
这类上下文有两个特点。
第一,信息密度极不均匀。几万 token 里可能只有十几行关键证据,其他都是辅助日志、重复解释、过时假设。
第二,时间顺序和因果关系重要。早期一个错误判断可能导致后面一串失败;中间一次测试输出可能推翻此前假设;后期一次摘要可能把真正关键的约束删掉。
所以,对 agent 来说,长上下文问题不只是“长文档 QA”,而是长轨迹决策:模型要在多步行动中持续维护目标、证据、约束和不确定性。
#2.3 代码智能是长上下文退化的高压场景
代码任务比普通长文档更难,因为代码里的关键信息常常不在自然语言段落里,而在结构关系里:
- import 说明模块依赖;
- 类型定义说明数据形状;
- 函数签名说明调用约束;
- 调用图说明影响范围;
- 配置文件说明运行环境;
- 测试 fixture 说明隐含输入;
- 历史实现说明兼容逻辑;
- 错误日志说明失败位置;
- 命名约定说明项目风格。
把整个 repo 塞进 prompt 并不等于理解 repo。一个代码 agent 需要的是结构化检索、符号索引、证据来源追踪,以及能用测试结果修正判断的循环。
一个简单例子:
用户说“修复登录失败”。报错栈在
auth/session.py,但真正根因可能在config/defaults.yaml里的过期字段;另一个相似函数legacy_login很像,但不是当前调用路径。如果模型只靠长上下文里的表面相似性,就很可能改错文件。
#2.4 长轨迹 RL 和 latent-space reasoning 也绕不开它
如果把 agent 看成一个会行动的系统,那么“上下文管理”本身就是一组动作:
- 读什么;
- 检索什么;
- 记住什么;
- 压缩什么;
- 丢弃什么;
- pin 住什么;
- 什么时候验证;
- 什么时候回查原文。
这些动作会影响最终任务成败,但失败常常在很多步之后才出现。这就变成了长程信用分配问题。人话说,就是“最后失败了,到底该怪哪一步?”英文叫 long-horizon credit assignment。
这也是长轨迹 RL 关心的问题。放到长上下文研究里,就是让 agent 学会一套 context management policy,也就是“上下文管理策略”。
Latent-space reasoning 可以先理解为“不把所有中间状态都写成自然语言,而是在模型内部或外部维护更紧凑的状态表示”。比如用 latent memory tokens 表示目标、约束、证据和不确定性。这可能比不断追加自然语言历史更接近长期智能体的形态。
小结:长上下文退化之所以重要,是因为它已经从“长文档理解”扩展成 agent、代码、RL 和长期记忆里的基础问题。
#3. 现象层:怎么证明“长上下文不等于会用上下文”?
这一节先看现象。先不用急着解释为什么,只需要确认:模型在长上下文下确实会系统性失败,而且失败方式不止一种。
可以把 benchmark 看成一组“显微镜”:每个 benchmark 放大一种失败。如果只看单个榜单,很容易得出“某模型长上下文强/弱”这种粗结论;如果合起来看,就能得到一张失败地图。
| 现象问题 | 对应 benchmark | 它放大的失败 | 后面会对应的机制 |
|---|---|---|---|
| 答案位置变化会不会影响模型 | Lost in the Middle、NIAH | 中间信息更容易被忽略 | 位置偏置、注意力稀释 |
| 字面匹配去掉后还会不会找证据 | NoLiMa | 语义检索弱于表面匹配 | 检索噪声、任务理解不足 |
| 多条事实能不能组合 | BABILong、RULER aggregation | 找到局部事实但推不出结论 | 证据绑定失败、推理负担增加 |
| 很长输入后能不能稳定生成长输出 | LongGenBench | 前后矛盾、结构漂移 | 全局规划弱、状态维护弱 |
| 长上下文示例能不能归纳任务规则 | LongICLBench | 示例多了反而悟不出规则 | 任务归纳失败 |
| 代码仓库里能不能找对结构证据 | RepoBench、SWE 类任务 | 相似文件和调用关系造成误导 | 结构噪声、验证不足 |
#3.1 位置会影响答案:Lost in the Middle
代表工作: Lost in the Middle: How Language Models Use Long Contexts,Liu et al., 2023,arXiv:2307.03172。
这篇工作问了一个很朴素的问题:如果答案就在上下文里,只是放的位置不同,模型表现会一样吗?
实验方式大概是:把多个文档拼成一个长上下文,其中只有一个文档包含答案。然后控制包含答案的文档位于开头、中间、结尾。结果发现,很多模型对开头和结尾的信息利用更好,对中间的信息明显更差。这就是 Lost in the Middle。
用人话说:模型不是像搜索框那样均匀检索整篇上下文,它更像一个有阅读习惯和注意力偏好的读者。开头、结尾、最近出现的内容更容易被它使用,中间内容更容易被淹没。
#3.2 找一根针不等于理解草堆:Needle-in-a-Haystack
代表项目: Greg Kamradt 的 Needle-in-a-Haystack 测试。
Needle-in-a-Haystack,简称 NIAH,意思是“草堆里找针”。做法很简单:在一大段 haystack 文本里插入一句 needle,比如“这座城市最喜欢的颜色是紫色”,然后问模型这句事实是什么。通过改变上下文长度和 needle 位置,可以画出模型在不同长度、不同深度下的召回热力图。
它的优点是直观、可视化、容易跑,因此在业界很流行。很多模型发布长上下文能力时都会展示类似图。
但它的问题也很大:它多数时候只测字面匹配。字面匹配,英文叫 literal matching,意思是“题目怎么问,原文里差不多就怎么写”。如果问题和 needle 用词高度重叠,模型不需要真正理解长上下文,只要像内部搜索一样找到匹配片段就行。
所以,NIAH 是起点,不是终点。一个模型能通过 NIAH,不代表它能在真实 RAG、代码仓库或 agent 轨迹里稳定使用证据。
#3.3 综合长文本理解:LongBench 和 L-Eval
LongBench:LongBench: A Bilingual, Multitask Benchmark for Long Context Understanding,Bai et al., 2023,arXiv:2308.14508。
L-Eval:L-Eval: Instituting Standardized Evaluation for Long Context Language Models,An et al., 2023,arXiv:2307.11088。
这两类 benchmark 的作用是把长上下文评测从“找一根针”扩展到更接近真实使用的任务,包括:
- 单文档问答;
- 多文档问答;
- 摘要;
- few-shot / in-context learning;
- 合成检索;
- 代码理解;
- 长对话理解。
这里的 in-context learning 也需要先解释一下。人话说,它就是“把几个例子放进 prompt,让模型临时学会这次任务怎么做”。比如给模型 5 个情感分类样例,它就按同样格式分类第 6 个。长上下文里的 in-context learning 更难,因为示例和规则本身也会变成长文本。
LongBench 还有一个重要点:它是双语 benchmark,包含中文任务。对中文模型和中文应用来说,它比纯英文 benchmark 更贴近实际生态。
#3.4 标称窗口不等于真实可用窗口:RULER
代表工作: RULER: What’s the Real Context Size of Your Long-Context Language Models?,Hsieh et al., 2024,arXiv:2404.06654。
RULER 的核心问题是:模型标称 128K,并不代表它真的能在 128K 内稳定工作。它设计了一系列可控任务来测“真实有效上下文长度”,包括单 needle、多 needle、variable tracking、common word extraction、aggregation 和 QA。
这里的 variable tracking 可以先用人话理解:模型要在长文本里追踪某个变量或状态被多次赋值、修改后的最终结果。比如一段长记录里不断写“钥匙在抽屉里”“钥匙被拿到书包里”“书包被放到车里”,最后问钥匙在哪里。它比找一句固定事实更难,因为模型要维护状态。
RULER 比普通 NIAH 更接近压力测试,因为它不只问模型能不能找一条事实,还会增加 needle 数量、干扰项和推理复杂度。它的重要贡献是把宣传语里的“context window”拆成了实验中的“effective context size”。
#3.5 去掉字面匹配捷径:NoLiMa
代表工作: NoLiMa: Long-Context Evaluation Beyond Literal Matching,2025,arXiv:2502.05167。
NoLiMa 直接针对 NIAH 的缺陷:如果问题和上下文中的答案有大量词面重叠,模型可以靠 literal matching 过关。NoLiMa 尽量减少问题和证据之间的字面重叠,要求模型通过语义关联找到信息。
比如不是直接问“紫色城市是什么”,而是用一个间接表达让模型理解“那个关于城市偏好的事实”对应哪条上下文。这更接近真实 RAG:用户的问题常常不会和文档原文一模一样。
NoLiMa 的意义是提醒我们:长上下文检索能力要分成字面检索和语义检索。前者高分不代表后者强。
#3.6 找到事实还不够:BABILong
代表工作: BABILong: Testing the Limits of LLMs with Long Context Reasoning-in-a-Haystack,2024,arXiv:2406.10149。
BABILong 把 bAbI 风格推理任务放进长上下文 haystack 中。模型不只是找一句事实,还要做 fact chaining、deduction、induction、counting、集合操作等。
这些词可以先这样理解:
- fact chaining:把多条事实串起来,比如 A 在 B,B 在 C,所以 A 和 C 有关系。
- deduction:根据规则推出必然结论。
- induction:从多个例子中归纳模式。
- counting:在长上下文中数满足条件的对象。
BABILong 对“模型变笨”的理解很重要:很多时候模型不是完全找不到证据,而是找到局部证据后,不能稳定组合多个证据。
也就是说,长上下文退化至少包括两层:
- retrieval failure:找不到该用的信息。
- reasoning failure:找到了信息,但组合和推理失败。
#3.7 超长上下文时代的评测:InfiniteBench
代表工作: ∞Bench / InfiniteBench: Extending Long Context Evaluation Beyond 100K Tokens,2024,arXiv:2402.13718。
InfiniteBench 面向 100K token 以上的超长上下文,包含真实任务和合成任务,比如超长书籍/文档问答、长上下文检索、摘要、代码、多文档理解等。
它的价值在于:当模型窗口进入 100K+ 后,10K 级 benchmark 已经不够区分能力。超长上下文会引入更严重的计算成本、位置偏置、噪声干扰和评测难题。
#3.8 长上下文中的任务归纳也会崩:LongICLBench
代表工作: Long-context LLMs Struggle with Long In-context Learning,2024,arXiv:2404.02060。
LongICLBench 问的是:如果 prompt 里放大量示例、类别和标签说明,模型能不能像短 in-context learning 那样临时学会任务?
结果表明,长上下文模型不一定擅长长 ICL。示例多、类别多、label space 大时,模型需要从长上下文中压缩出任务规则和类别边界,这比单点检索更难。
这对科研的启发是:长上下文问题不仅是 retrieval,也是 task induction。任务归纳,英文叫 task induction,人话说就是“模型要从一堆例子、格式、约束里悟出这次到底应该怎么做”。
#3.9 长输入后的长输出更难:LongGenBench
代表工作: 两个近似同名工作:arXiv:2410.04199 和 arXiv:2409.02076,均围绕 LongGenBench / long-form generation。
很多评测只看模型能不能从长输入中抽取答案,但真实应用常常要求模型生成长输出,比如写报告、写技术方案、生成长代码、写复杂 PRD。
长生成会暴露另一类退化:
- 前后矛盾;
- 遗漏约束;
- 重复;
- 结构漂移;
- 局部段落正确但全局组织差;
- 引用前文时错配。
这说明“长上下文理解”和“长上下文生成”是两种不同能力。前者像读书找证据,后者像基于整本书写一篇结构稳定的文章。
#3.10 代码领域的长上下文不是普通长文本:RepoBench 与 SWE 类任务
代表工作: RepoBench: Benchmarking Repository-Level Code Auto-Completion Systems,Liu et al., 2023,arXiv:2306.03091。
RepoBench 面向 repository-level code completion,包括检索相关代码、跨文件代码补全、端到端 pipeline。它说明代码长上下文有特殊性:代码不是普通自然语言,关键信息常藏在结构关系里。
如果进一步看 SWE-bench 这类真实 issue 修复任务,问题会更接近 agent:模型不仅要读代码,还要决定读哪些文件、运行哪些测试、如何解释报错、如何修改并验证。RepoBench 更偏补全;SWE 类任务更偏长轨迹代码修复。二者放在一起看,可以更完整地理解代码智能里的长上下文退化。
#3.11 Benchmark 小结
| Benchmark | 主要测什么 | 它说明什么 | 局限 |
|---|---|---|---|
| Lost in the Middle | 相关信息位置变化 | 模型有位置偏置,中间信息利用差 | 任务较简单 |
| Needle-in-a-Haystack | 长上下文单点检索 | 快速可视化不同位置/长度召回 | 容易被字面匹配刷高 |
| LongBench / L-Eval | 多任务长文本理解 | 长上下文能力需要多任务评估 | 极长上下文覆盖有限 |
| RULER | 真实有效上下文长度 | 标称窗口不等于有效窗口 | 合成任务较多 |
| NoLiMa | 非字面匹配长上下文检索 | 去掉 lexical shortcut 后模型会掉分 | 仍偏检索 |
| BABILong | 长上下文推理 | 找到事实后还要能组合推理 | 合成风格较强 |
| InfiniteBench | 100K+ 超长上下文 | 超长场景下能力继续退化 | 评测成本高 |
| LongICLBench | 长上下文 ICL | 长 prompt 中归纳任务规则很难 | 偏分类 ICL |
| LongGenBench | 长输入条件下长生成 | 检索强不代表长生成稳定 | 自动评测难 |
| RepoBench / SWE 类任务 | 仓库级代码理解、编辑、验证 | 代码长上下文需要结构理解和工具闭环 | 很难隔离单一机制 |
小结:长上下文退化不是一个单一现象。不同 benchmark 分别测位置、语义检索、多证据推理、长生成、任务归纳和代码结构理解。
#4. 机制层:为什么上下文越长越容易失败?
Benchmark 告诉我们“失败了”,机制研究要回答“为什么失败”。下面这些机制不一定互斥,很多真实失败是多种机制叠加。
更具体地说,现象层给了我们四个问题:
- 为什么位置一变,答案就变差?
- 为什么多给文档会让 RAG 更容易错?
- 为什么找到证据后仍然会推错或引用错?
- 为什么 agent 跑久后会忘记目标、约束和失败经验?
机制层就是对这四个问题的拆解。理解这些机制之后,后面的 RAG、压缩、KV cache、memory 才不会像一堆互不相干的技术名词。
#4.1 注意力稀释:资料太多,重点被淹没
注意力稀释,英文可以叫 attention dilution。人话解释是:当上下文变长,候选 token 变多,模型每一步生成时都要在更多 token 中选择相关证据。虽然 transformer attention 不是简单平均,但无关 token 数量变多后,会产生竞争:一些表面相似但无关的 token 会抢占模型的注意力和表示容量。
类比一下:桌上只有三份资料时,你很容易找到重点;桌上堆了一百份资料,其中九十份都和主题有点像但其实没用,就容易看晕。
这解释了为什么 RAG top-k 不是越大越好,也解释了为什么长代码上下文里模型会被相似函数名、旧实现、错误日志带偏。
#4.2 位置偏置:模型更容易相信开头、结尾和最近内容
位置偏置,英文是 positional bias。它指模型对不同位置的信息使用不均匀。模型更偏好开头、结尾、最近上下文、system/user 指令附近的信息。中间信息容易被忽略。
原因可能来自:
- 预训练数据里重要信息常在标题、开头、结尾;
- 自回归生成天然有近因偏置;
- RoPE、ALiBi 等位置机制在外推时不稳定;
- 指令跟随训练强化了对末尾 query 的关注。
这对应 Lost in the Middle。对 agent 来说,中间轨迹常常包含重要工具结果和失败教训。如果这些信息被忽略,agent 就会重复犯错。
#4.3 干扰项不是无害的:相似错误信息会污染答案
很多人以为“无关上下文最多没用,不会有害”。这是错的。无关上下文只要和问题表面相似,就可能成为错误证据。
比如问一个函数 bug,prompt 里有三个相似函数。模型可能看到了最长、最近、名字最像的那个,却不是实际调用的那个。对 RAG 来说,top-k 文档里混入过期文档、相似但错误文档,模型可能会把它们编进答案。
这类问题可以叫 retrieval noise 或 context noise。它是“上下文多了变笨”的核心机制之一。
| 噪声类型 | 人话解释 | 例子 |
|---|---|---|
| 主题相似噪声 | 讲的是同一主题,但不是当前问题的证据 | 检索到同名 API 的旧版本文档 |
| 结构相似噪声 | 格式像证据,但内容不相关 | 相似函数、相似测试、相似日志 |
| 时间过期噪声 | 曾经正确,现在过期 | 旧迁移文档、旧配置说明 |
| 指令噪声 | 文档里出现看似命令的文本 | 网页 prompt injection、README 示例命令 |
| 自我生成噪声 | agent 之前写下的错误计划 | 早期错误假设被后续当成事实 |
#4.4 指令冲突:长上下文里到处都是“伪指令”
长上下文不只是事实,还可能包含各种指令:
- system 指令;
- developer 指令;
- 当前用户请求;
- 历史用户请求;
- 网页里的 prompt injection;
- 文档里的示例命令;
- agent 自己之前写下的计划。
模型需要区分“这段文本是在描述一个指令”还是“这是现在必须执行的指令”。这并不总可靠。长上下文越多,冲突指令越多,目标越容易漂移。
这对安全和 agent 都很关键:RAG 文档中的恶意文本可能抢夺目标;agent 自己早期的错误计划也可能在后续被当成真约束。
#4.5 证据绑定失败:知道答案但不知道答案来自哪里
证据绑定,英文可以叫 evidence binding。人话解释是:模型不仅要说出一个结论,还要把结论和正确来源绑定起来。
比如:
- “这个函数需要改”,要知道是哪个文件、哪一行、哪个调用链支持这个判断;
- “论文 A 证明了 X”,要知道是不是论文 A,而不是同主题论文 B;
- “用户不希望改测试”,要知道这来自当前用户请求,而不是历史对话里的另一个任务。
长上下文中,模型常常能生成一个看似合理的答案,但证据来源错配。对代码 agent 来说,这尤其危险,因为它可能改错文件、修错 bug,甚至用错误日志解释正确失败。
#4.6 摘要不是免费的:自然语言压缩会丢掉未来需要的细节
为了节省上下文,系统经常把历史总结成摘要。但自然语言摘要是有损压缩,而且通常优化“人读起来像总结”,不是优化“未来决策充分”。
它会丢:
- 文件路径;
- 行号;
- 失败尝试;
- 不确定性;
- 证据来源;
- 用户早期约束;
- 边界条件;
- 时间顺序;
- 反事实信息,也就是“为什么不是另一个解释”。
所以真正的问题不是“怎么总结得更短”,而是“怎么保留未来任务会需要的信息”。我会把这个叫 decision-sufficient compression,也就是决策充分压缩。
普通摘要问:“这段历史发生了什么?”
决策充分压缩问:“为了未来任务成功,哪些信息必须保留?”
#4.7 长上下文中的任务归纳更难
很多长上下文任务不只是找信息,而是要从上下文中归纳“当前任务规则”。这就是 task induction。人话说,就是模型要从一堆示例、格式、约束和标签里临时悟出“这次到底应该怎么做”。
长 ICL 崩溃就属于这个问题。示例越多、类别越多、规则越复杂,模型越需要从长上下文中形成一个紧凑任务表示。它不仅要记住事实,还要抽象出规则。
这和 agent 也有关。一个 agent 在长任务中不仅要记住“读过什么文件”,还要逐渐形成“这个 repo 的测试方式是什么”“这个项目的架构约定是什么”“当前 bug 的真实根因更可能在哪里”。
#4.8 长程信用分配:最终失败了,不知道是哪一步上下文管理错了
在 agent 任务中,最终失败可能由很早之前一个小错误导致:
- 读错文件;
- 漏掉约束;
- 错误总结;
- 检索到错误文档;
- 测试失败后错误归因;
- 把不确定假设写成确定 memory。
但 reward 往往只在最后出现。模型很难知道到底哪一步上下文管理动作错了。这就是长程信用分配,英文是 long-horizon credit assignment。
这把“长上下文”从推理问题推进到了 RL 问题:agent 不只要回答,还要学习何时读、何时记、何时删、何时检索、何时验证。
#4.9 机制总表:从“读长文”到“管理信息”
| 失败症状 | 可能机制 | 对应改进方向 |
|---|---|---|
| 答案在中间但没用上 | 位置偏置、注意力稀释 | memory pinning、位置鲁棒训练 |
| RAG 多召回反而更差 | 检索噪声、证据绑定失败 | rerank、query-aware compression、provenance |
| agent 重复探索 | 摘要损失、状态维护失败 | task state、失败 memory、过程记录 |
| 代码 agent 改错文件 | 结构噪声、证据绑定失败 | repo 索引、调用图、测试验证 |
| 长报告前后矛盾 | 长生成规划失败、全局状态弱 | outline planning、分段校验、引用约束 |
| 压缩后忘约束 | 决策信息被删 | decision-sufficient compression |
再把机制和方案的对应关系写得更直接:
| 机制问题 | 为什么会发生 | 直接方案 | 更深的科研问题 |
|---|---|---|---|
| 位置偏置 | 模型对开头、结尾、最近内容更敏感 | 长上下文训练、位置编码扩展、memory pinning | 怎样训练 agent 对旧轨迹中的关键状态保持鲁棒 |
| 注意力稀释 | 相关 token 被大量无关 token 竞争 | RAG、rerank、query-aware compression | 怎样定义“当前任务真正需要的信息” |
| 检索噪声 | 相似但错误的文档进入上下文 | reranker、answer verification、GraphRAG | 怎样让检索优化最终推理成功,而不是只优化相似度 |
| 指令冲突 | 长上下文里混有历史指令、网页指令、示例命令 | instruction hierarchy、context sanitization、source labeling | agent 如何区分“文本里说的命令”和“当前要执行的命令” |
| 证据绑定失败 | 结论和来源没有被稳定绑定 | provenance、citation check、evidence-aware decoding | 模型如何在长上下文中维护结论-证据配对 |
| 压缩损失 | 摘要删掉未来才需要的细节 | 结构化 state、decision-sufficient compression | 压缩目标如何从“像摘要”变成“能完成任务” |
| 长程信用分配 | 最终失败和早期 context action 之间距离太远 | context action log、process reward、counterfactual memory test | 怎样用 RL 学会读、记、删、查、验证 |
小结:长上下文退化的核心不是“模型太笨”,而是“信息生命周期没有被管理”:进入、排序、压缩、记忆、验证、遗忘,每一步都可能出错。
#5. 解决方案总图:不要只问“窗口多长”,要问“信息怎么流动”
可以把现有解决方案分成七层:
| 层次 | 代表方向 | 它解决什么 | 它解决不了什么 |
|---|---|---|---|
| 模型架构/位置编码 | RoPE scaling、ALiBi、PI、YaRN、LongRoPE | 让模型能表示更长位置 | 不保证会用上下文 |
| 长上下文训练与系统 | 长上下文继续训练、FlashAttention、RingAttention、PagedAttention | 降低长序列训练/推理成本 | 不直接解决噪声和目标漂移 |
| 稀疏/流式注意力 | StreamingLLM、LM-Infinite、滑动窗口、局部全局 attention | 控制计算和旧上下文保留 | 可能牺牲旧信息精确召回 |
| 检索增强 | RAG、RETRO、Atlas、Self-RAG、GraphRAG、RAPTOR | 不把所有信息塞进 prompt,先筛选 | 检索错或召回噪声会污染生成 |
| 上下文压缩 | LLMLingua、LongLLMLingua、Selective Context、AutoCompressor | 把 prompt 压短,保留重要信息 | 压缩可能丢关键细节 |
| KV/注意力压缩 | H2O、SnapKV、PyramidKV、Cross-layer KV | 降低长上下文推理显存和延迟 | 更多是系统优化,不等于理解更好 |
| Agent memory / context engineering | memory store、pinned memory、provenance、state tracking | 管理长轨迹状态 | 缺少统一训练目标和 benchmark |
读这些方案时,最好把它们想成一条信息流,而不是一堆独立技术:
外部世界的信息很多 → 检索筛一遍 → rerank 排序 → 压缩整理 → 放进模型窗口 → 模型用 KV cache 推理 → agent 把关键结果写回 memory → 下一步继续循环。
这个信息流里,每个环节都可能出错:
- 检索漏了关键证据;
- rerank 把错误文档排前;
- 压缩删掉了边界条件;
- 长窗口让关键片段落在中间;
- KV 压缩丢掉了旧约束;
- memory 写入了错误假设;
- agent 没有验证就继续行动。
从因果链角度看,这七层可以分成三类:
- 让信息进得来:长窗口、位置编码、长上下文训练、系统优化。它们解决容量和成本问题。
- 让信息进得准:RAG、rerank、GraphRAG、压缩。它们解决筛选和组织问题。
- 让信息留得住、用得对:agent memory、pinned state、provenance、verification、context policy。它们解决长期状态和证据绑定问题。
这三类缺一不可。只做第一类,模型会被噪声淹没;只做第二类,agent 仍可能跑久后忘记目标;只做第三类,如果底层窗口和系统成本不支持,也很难处理真实长文档和代码库。
#6. 方向一:把窗口变长,但别把它当成最终答案
这一方向主要解决“模型能不能装下更长上下文”和“长上下文能不能算得动”。它是底座,但不是完整解决方案。
#6.1 RoPE、ALiBi 与位置外推
位置编码用人话说,就是让模型知道每个 token 在序列里的位置。如果没有位置信息,“我喜欢你”和“你喜欢我”在词袋层面差不多,但含义完全不同。
RoPE 来自 RoFormer: Enhanced Transformer with Rotary Position Embedding,Su et al., 2021,arXiv:2104.09864。它通过旋转变换把位置信息融入 Q/K,使 attention 具备相对位置感。LLaMA、Qwen、Mistral 等很多模型都使用 RoPE 或变体。
这里的 Q/K 可以简单理解成 attention 里的“查询”和“索引”。模型生成下一个 token 时,会用当前状态去查询上下文里哪些位置相关。RoPE 改变的就是这种查询和索引如何带上位置信息。
ALiBi 来自 Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation,Press et al., 2021,arXiv:2108.12409。它给 attention score 加一个随距离线性衰减的 bias,让模型训练短上下文、测试长上下文时仍有一定外推能力。
这些方法解决的是“模型如何表示更远的位置”。但它们不解决“哪个远处信息重要”。所以它们是长上下文能力的底座,不是完整答案。
#6.2 Position Interpolation、YaRN、LongRoPE
Position Interpolation:Extending Context Window of Large Language Models via Positional Interpolation,Chen et al., 2023,arXiv:2306.15595。核心思想是不要直接把位置外推到模型没见过的区域,而是把长序列位置压缩映射回训练过的位置范围,再少量继续训练。
可以把它想成地图缩放:原来模型只熟悉 0 到 4K 的坐标,现在要看 0 到 32K,不是直接把坐标扔给它,而是按比例压回熟悉区域。
YaRN:YaRN: Efficient Context Window Extension of Large Language Models,Peng et al., 2023,arXiv:2309.00071。它改进 RoPE scaling,对不同频率维度做更合理的缩放,用较少训练 token 扩展上下文。
LongRoPE:LongRoPE: Extending LLM Context Window Beyond 2 Million Tokens,Ding et al., 2024,arXiv:2402.13753。它通过非均匀 RoPE 缩放和 progressive extension,把窗口扩到百万 token 级别。
这条线的演化逻辑是:
- 先解决“直接外推会崩”;
- 再解决“压缩位置会损失局部分辨率”;
- 再解决“极长上下文需要不同频率/位置段不同处理”。
但核心限制一直没变:能放进去不代表会用。
#6.3 流式上下文:StreamingLLM / LM-Infinite
流式上下文用人话说,就是模型面对不断到来的长输入时,不可能永远保存全部历史,只能保留一部分关键旧信息和最近信息。
StreamingLLM:Efficient Streaming Language Models with Attention Sinks,Xiao et al., 2023,arXiv:2309.17453。它发现模型会持续关注开头几个 token,即 attention sinks。attention sink 可以理解为“模型总爱看的一些锚点 token”。于是 StreamingLLM 保留开头 sink tokens 和最近窗口,丢弃中间旧 KV,实现流式生成。
LM-Infinite:LM-Infinite: Zero-Shot Extreme Length Generalization for Large Language Models,Han et al., 2023,arXiv:2308.16137。它通过特殊 attention mask 和距离感知机制,让模型零训练或少训练地处理极长输入。
这类方法很适合长期对话、日志流、持续运行 agent。但它们通常会牺牲旧历史的精确可回忆能力。因此,它们必须和外部 memory/RAG 配合。
#6.4 稀疏注意力、滑动窗口和线性化方向
稀疏注意力可以先用人话理解:不要让每个 token 都看所有 token,而是让它只看局部窗口、少数全局 token 或被路由到的块。早期的 Longformer、BigBird 等工作就沿着这个方向探索。很多现代长上下文模型也会使用 sliding window、global attention、block sparse attention 等工程变体。
这类方法的好处是成本可控。缺点是:如果关键证据恰好不在可见范围内,模型就会漏掉。也就是说,稀疏注意力把“信息选择”提前到了注意力模式里。如果选择规则太粗,就会形成新的 blind spot。
还有一些方向尝试把序列建模做得更接近线性成本,比如状态空间模型、线性 attention、混合架构。这里不展开论文名,因为本文的重点不是架构综述。对长上下文研究来说,关键问题仍然是:这些架构是否真的提升了 effective context use,还是只是让更长输入更便宜。
#6.5 FlashAttention / RingAttention / PagedAttention:让长上下文算得动
FlashAttention:Dao et al., 2022,arXiv:2205.14135。
FlashAttention-2:Dao, 2023,arXiv:2307.08691。
RingAttention:Ring Attention with Blockwise Transformers for Near-Infinite Context,Liu et al., 2023,arXiv:2310.01889。
PagedAttention 常和 vLLM 系统一起讨论,它把 KV cache 管理得更像分页内存,减少碎片并提升吞吐。
这些方法主要解决计算问题。
普通 attention 在长序列上很贵,因为每个 token 都可能和每个 token 交互,长度翻倍,计算和显存压力会迅速上升。FlashAttention 通过 IO-aware tiling 避免显式 materialize 巨大的 attention matrix;RingAttention 把长序列 block 分到多设备,用 ring 通信计算 blockwise attention;PagedAttention 更关注推理服务时 KV cache 的内存管理。
这里的 IO-aware 可以简单理解为“少在显存和高速缓存之间搬运数据”。长序列里,数据搬运本身会成为瓶颈。
它们非常重要,因为没有系统优化就训练不了、服务不了长上下文模型。但它们主要解决“算不算得动”,不是“会不会被噪声带偏”。
小结:长窗口解决“放得下”和“算得动”,但不解决“选得准”和“用得对”。这也是为什么下一层必须是 RAG 和检索增强。
#7. 方向二:RAG 与检索增强,不要把所有东西都塞进上下文
如果长窗口的问题是“给太多”,RAG 的基本思想就是“先筛选再给”。
#7.1 经典 RAG:先检索,再生成
RAG 是 Retrieval-Augmented Generation 的缩写,中文常说“检索增强生成”。人话解释是:模型回答前,先从外部资料库找几段相关材料,再让模型基于这些材料回答。
代表工作包括:
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks,Lewis et al., 2020,arXiv:2005.11401;
- REALM: Retrieval-Augmented Language Model Pre-Training,Guu et al., 2020,arXiv:2002.08909;
- Atlas: Few-shot Learning with Retrieval Augmented Language Models,Izacard et al., 2022,arXiv:2208.03299;
- RETRO: Improving language models by retrieving from trillions of tokens,Borgeaud et al., 2021,arXiv:2112.04426。
RAG 的基本流程是:
- 把外部文档切成 chunk;
- 给 chunk 建索引;
- 用户提问时召回 top-k 片段;
- 把这些片段放进 prompt;
- 让模型基于证据回答。
这里的 chunk 就是文档切片,top-k 就是检索器返回最相关的前 k 个片段。
RAG 解决了上下文窗口有限的问题,也让知识可更新。但它引入新问题:
- chunk 切错会断掉上下文;
- top-k 太小会漏证据;
- top-k 太大会引入噪声;
- retriever 和 generator 目标不一致;
- 多跳问题需要多轮检索;
- 检索片段缺少 provenance 或排序错误。
所以 RAG 不是把长上下文问题消灭了,而是把它拆成“检索 + 排序 + 压缩 + 生成 + 证据核验”的系统问题。
#7.2 RAG 的关键不是召回更多,而是控制噪声
很多 RAG 系统的第一反应是调大 top-k。但如果问题需要 2 条证据,而你召回 20 条,其中 18 条是相似噪声,模型可能更容易错。
因此 RAG 需要几个配套能力:
- rerank:召回后重新排序,把真正相关的证据放前面。
- query rewriting:把用户问题改写成更适合检索的查询。
- multi-hop retrieval:第一轮证据不够时,再基于中间线索检索下一轮。
- provenance tracking:每条答案都能追到来源。
- answer verification:生成后检查答案是否被证据支持。
这些能力本质上都是 context engineering:决定哪些信息进入模型、以什么顺序进入、以什么粒度进入。
#7.3 Dense retriever、reranker 和 ColBERT:检索不是一个黑箱
向量检索用人话说,就是把文本变成向量,问题和文档向量越接近,越可能相关。它速度快、能做语义匹配,但也容易召回“主题像、答案不对”的片段。
reranker 是第二道排序器。第一阶段先粗召回很多候选,第二阶段用更贵但更细的模型重排。它像先用关键词在图书馆找一堆书,再逐本看目录判断哪本真的相关。
ColBERT 这类 late-interaction 检索方法介于粗向量和重 rerank 之间。它不是把整段文本压成一个向量,而是保留 token 级交互,能更细地判断匹配关系。
这些检索细节之所以重要,是因为长上下文退化经常不是 generator 单独造成的。很多错误在进入模型前就已经发生了:正确证据没有被召回,或者排在噪声后面。
#7.4 Self-RAG:让模型自己决定是否检索
代表工作: Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection,Asai et al., 2023,arXiv:2310.11511。
Self-RAG 的思想是:模型不应该每次都机械检索,而应该学会判断什么时候需要检索、检索内容是否有帮助、生成答案是否被证据支持。
这比普通 RAG 更接近 agent,因为它把检索变成一个决策动作。对长上下文研究来说,这非常关键:上下文管理本质上也是一种 action policy。
#7.5 RAPTOR / GraphRAG:为全局问题建立层次化或图结构上下文
普通 chunk RAG 对局部问答还行,但对全局综合不够。比如用户问“这家公司过去一年战略变化是什么”,答案可能分散在很多文档里,不能靠召回几个局部片段解决。
RAPTOR:Recursive Abstractive Processing for Tree-Organized Retrieval,Sarthi et al., 2024,arXiv:2401.18059。它对文档递归聚类和摘要,形成树状索引。查询时既可以取底层细节,也可以取高层摘要。
GraphRAG:From Local to Global: A Graph RAG Approach to Query-Focused Summarization,Edge et al., 2024,arXiv:2404.16130。它构建实体关系图和社区摘要,适合回答“全局性问题”,比如一个组织、文档库或知识库的主题结构。
图结构可以先理解成“节点和边”。节点可以是人、公司、函数、文件、概念;边表示它们之间的关系。GraphRAG 的直觉是:很多全局问题不是靠一段文本回答,而是靠关系网络回答。
这类方法承认一个事实:长上下文真正难的是多粒度信息组织。系统既要保留原文细节,又要有高层结构。
#7.6 RAG 与长窗口的关系:不是谁替代谁
长窗口和 RAG 经常被拿来对比,但它们更像互补关系:
| 场景 | 长窗口适合 | RAG 适合 | 最好组合 |
|---|---|---|---|
| 单篇长文档 | 保留全文顺序和上下文 | 快速定位相关段落 | 先检索相关段,再按原文邻域展开 |
| 多文档知识库 | 直接全塞成本高且噪声大 | 按问题召回证据 | RAG + rerank + provenance |
| 代码仓库 | 可容纳更多文件片段 | 按符号、调用图、测试召回 | repo index + targeted context |
| Agent 长轨迹 | 保留最近动作和工具结果 | 回查旧证据和 memory | recent window + external memory |
| 全局总结 | 有助于看整体 | chunk RAG 容易碎片化 | 层次摘要 + 图结构 + 长窗口合成 |
如果只靠长窗口,系统容易被噪声淹没。
如果只靠 RAG,系统容易漏掉跨段关系和全局结构。
更稳的路线是把 RAG 当成上下文入口,把长窗口当成推理工作台,把 memory 当成长期状态。
小结:RAG 的价值不是“省 token”这么简单,而是把信息选择从模型内部黑箱搬到可设计、可评测、可验证的系统环节。
#8. 方向三:上下文压缩,不是所有 token 都同等重要
RAG 只回答了“哪些原始材料可能相关”。它还没有回答两个后续问题:
- 召回材料太长时,哪些细节应该保留、哪些可以删?
- agent 跑多步以后,哪些中间结果应该变成长期状态,而不是每次重新检索?
这就引出上下文压缩。压缩不是为了把文字变短而变短,而是为了在有限预算里保留对当前和未来决策最有用的信息。
#8.1 三种压缩:抽取式、生成式、潜空间式
为了避免把压缩混成一团,可以先分三类:
| 压缩类型 | 人话解释 | 优点 | 风险 |
|---|---|---|---|
| 抽取式压缩 | 从原文里挑关键句/关键 token | 保留原文证据,容易追溯 | 可能不够短,也可能漏掉跨句关系 |
| 生成式压缩 | 让模型写摘要或结构化状态 | 可读、灵活、能合并信息 | 容易幻觉、丢来源、写得过于确定 |
| 潜空间压缩 | 压成 hidden vectors / latent tokens | 可能更省 token、更适合模型内部使用 | 不可解释,难审计,训练目标难 |
这三类不是互斥的。真实 agent 可能需要:抽取原始证据、生成结构化 state、再用 latent memory 保存部分长期状态。
#8.2 LLMLingua / LongLLMLingua:用小模型压缩 prompt
LLMLingua:Compressing Prompts for Accelerated Inference of Large Language Models,Jiang et al., 2023,arXiv:2310.05736。
LongLLMLingua:Accelerating and Enhancing LLMs in Long Context Scenarios via Prompt Compression,Jiang et al., 2023,arXiv:2310.06839。
LLMLingua 用小模型估计 prompt 中 token 的重要性,删掉低信息量 token,从而减少成本。LongLLMLingua 更强调 query-aware compression,也就是“根据当前问题来压缩”。如果用户问的是实验结果,就保留实验表格;如果问方法细节,就保留方法段落。
它们的价值在于:压缩不只是省钱,也可能提升准确率,因为它减少了噪声和 lost-in-middle。
但它们也有风险:压缩器可能删掉未来才重要的信息。尤其是 agent 场景,当前 query 不是最后一个 query;一次压缩可能影响后续很多步。
#8.3 Selective Context:删除低信息量内容
代表工作: Unlocking Context Constraints of LLMs: Enhancing Context Efficiency of LLMs with Self-Information-Based Content Filtering,Li, 2023,arXiv:2304.12102。
Selective Context 的直觉是:prompt 里很多 token 信息量很低,可以通过自信息等指标过滤掉。自信息可以先理解为“一个 token 有多意外”。越常见、越容易预测的词,信息量越低。
优点是简单,缺点是“信息量低”不等于“任务不重要”。比如代码里的一个括号、一个变量名、一个否定词,语言模型概率上可能不起眼,但对任务至关重要。
这说明上下文压缩不能只看语言概率,还要看任务后果。
#8.4 AutoCompressor / ICAE / latent compression:把长上下文压成 latent memory
AutoCompressor:AutoCompressors: Language Models that Can Compress Their Own Context,Chevalier et al., 2023,arXiv:2305.14788。它让模型把长上下文压缩成 summary vectors,后续继续使用这些向量。
ICAE / ICAE-like latent compression 一类工作尝试把长上下文压成少量 memory / latent tokens。这里更重要的是方向本身:把上下文压缩成少量 latent tokens / memory tokens,而不只是自然语言摘要。
latent token 可以先用人话理解成“模型内部的压缩记忆格子”。它不一定是人类可读的文字,但可能保存比文字摘要更高效的状态。
这条线和 latent-space reasoning 很接近。自然语言摘要有两个缺点:
- 它占 token;
- 它把不确定、多源、细粒度证据压成了表面确定的一段话。
latent memory 的想法是:让模型在隐藏空间里保留任务状态,也许能比文字摘要更高效。但难点也很明显:
- 可解释性弱;
- 训练目标不好定义;
- 跨模型迁移困难;
- 很难保证关键证据没有被压坏;
- 对安全和可审计性不友好。
#8.5 决策充分压缩:比摘要更适合 agent 的目标
如果压缩是给人看的,那摘要质量很重要。
如果压缩是给 agent 后续决策用的,那最终任务成功率更重要。
一个更适合 agent 的压缩目标可以是:
- 输入长上下文或 agent trajectory;
- compressor 输出短文本、结构化 memory 或 latent state;
- downstream agent 继续完成任务;
- 用最终任务成功率训练或评估 compressor;
- 加入 provenance,让压缩信息能回查原文;
- 做 counterfactual:删掉某条压缩 memory,看任务是否失败。
这里的 counterfactual 可以理解成“反事实测试”:如果我把某条记忆删掉,任务就失败,说明它可能真的有价值;如果删掉后完全不影响结果,说明它可能只是噪声。
这比“做一个摘要器”更像科研,因为它定义了新的压缩目标:不是复述历史,而是保留未来成功所需状态。
#8.6 压缩器应该输出什么?
对 agent 和代码任务,压缩结果不一定只是一段摘要。更合理的输出可能是一个小型状态表:
| 字段 | 例子 | 作用 |
|---|---|---|
| goal | 修复登录失败,不能改 public API | 保持目标 |
| constraints | 不要改测试;保持向后兼容 | 防止越界 |
| evidence | auth/session.py:88 报错,config/defaults.yaml 字段缺失 | 支撑判断 |
| hypotheses | 根因可能是默认配置迁移遗漏 | 保留不确定性 |
| failed_attempts | 改 legacy_login 无效,因为当前路径未调用 | 避免重复 |
| next_checks | 跑 pytest tests/test_session.py | 指导下一步 |
| provenance | 每条状态对应原始文件/日志/工具调用 | 可回查 |
这个表比自然语言摘要更笨拙,但更适合长期任务。它把“读起来顺”换成了“后续可用”。
小结:真正有研究价值的 context compressor 不应该只优化压缩率或摘要可读性,而应该优化下游任务成功率、约束保留、证据可回查和不确定性保存。
#9. 方向四:KV cache 压缩与稀疏注意力,让长上下文推理更便宜
压缩解决的是语义层 token 预算:哪些信息要以文本、表格或 latent state 的形式保留下来。但长上下文还有一个更底层的预算问题:模型生成时,前面所有 token 的中间表示也要占显存和带宽。也就是说,即使语义上你知道要保留什么,系统上也要能付得起推理成本。
这就是 KV cache 压缩要处理的问题。
KV cache 用人话说,就是模型生成时会缓存前面 token 的中间表示,避免每生成一个新 token 都从头算一遍。上下文越长,缓存越大,显存和延迟越高。
可以把它想成做题时桌上的草稿纸。你已经算过的一些中间结果不想重算,就写在草稿纸上。但题目越长,草稿纸越多,最后桌子也会被占满。
#9.1 H2O:保留 Heavy Hitters
代表工作: H2O: Heavy-Hitter Oracle for Efficient Generative Inference of Large Language Models,Zhang et al., 2023,arXiv:2306.07174。
H2O 观察到少数 token 在生成中贡献了大量 attention,于是保留这些 heavy hitter token 和近期 token,丢弃不重要 KV。
heavy hitter 可以理解成“模型经常回头看的关键 token”。H2O 像一种内部记忆淘汰策略:保留重要旧信息 + 最近信息。
#9.2 StreamingLLM / SnapKV / PyramidKV / Cross-layer KV
SnapKV:SnapKV: LLM Knows What You are Looking for Before Generation,Li et al., 2024,arXiv:2404.14469。它利用 prompt 阶段的 attention pattern 选择重要 KV,在生成前压缩 cache。
PyramidKV 这类方法通常利用不同层、不同位置的重要性差异,像金字塔一样保留不同粒度的 KV。可以把它理解成:越底层越关注局部细节,越高层越关注抽象语义,不同层不一定需要保存同样多的历史。
Cross-layer / layer-sharing KV cache compression 一类方法尝试跨层共享、复用或裁剪 KV 表示,从而减少长上下文推理时的缓存占用。
这类方法更多是系统层优化:它们让长上下文推理更省显存、更快。但需要注意:
KV 压缩选择了保留哪些历史 token,因此它实际上也在做信息选择。
这使它和 context management 有潜在连接。
#9.3 KV quantization、paging 和服务系统
除了“丢哪些 KV”,还有一类方法问:“能不能把 KV 存得更便宜?”这包括 KV quantization、paged KV management、prefix caching 等系统技术。
量化可以先理解为“用更少位数保存数字”。它会节省显存,但可能损失精度。prefix caching 则是把多个请求共享的 prompt 前缀缓存起来,避免重复计算。对长上下文应用来说,这些技术会直接影响成本和延迟。
它们不一定提升模型的有效上下文能力,但会改变可行的系统设计。比如如果 prefix caching 很便宜,系统就可以把稳定的工具说明、repo 索引摘要、用户偏好长期放在前缀;如果 KV 很贵,系统就必须更积极地压缩和检索。
#9.4 KV 压缩和语义 memory 的关系
KV 压缩偏底层,memory 偏语义层。二者可以结合:
- KV 压缩负责让最近上下文高效运行;
- 外部 memory 负责保存长期任务状态;
- RAG 负责回查原文证据;
- compressor 负责把长轨迹转成短状态;
- provenance 负责保证状态可追溯。
如果要做科研,一个有意思的问题是:底层 attention/KV 的重要性信号,能不能帮助上层 memory 选择?反过来,上层任务状态能不能指导 KV 保留哪些 token?
比如代码 agent 已经知道当前 root cause 在 config/defaults.yaml,那么底层 KV 保留策略是否应该偏向保留和该文件、该配置、该调用链相关的 token?这就是从系统优化走向任务感知上下文管理。
小结:KV cache 压缩首先是成本问题,但它隐含地选择了保留哪些历史表示。未来更有意思的方向是任务感知 KV 与语义 memory 协同。
#10. 方向五:Agent memory 与 Context Engineering
到这里,方案链条已经覆盖了“放得下、找得到、压得短、算得动”。但对 agent 来说,还差最后一环:任务不会在一次问答里结束。模型需要把多轮行动中的目标、约束、证据、失败和验证结果组织成可持续更新的状态。
这就是 agent memory 与 context engineering。
Context Engineering 用人话说,就是设计信息怎样进入模型:哪些信息放 prompt,哪些放 memory,哪些被固定在高优先级位置,哪些只保留来源,哪些可以删除,什么时候回查原文。
它不是 prompt engineering 的简单扩大版。Prompt engineering 常常是写好一个输入;context engineering 面对的是一个持续变化的信息系统。
#10.1 Memory 不只是聊天记录摘要
一个真正有用的 agent memory 至少应该分层:
| Memory 类型 | 保存什么 | 为什么重要 |
|---|---|---|
| 长期用户偏好 | 用户是谁、偏好什么、稳定目标是什么 | 避免每次重新询问 |
| 当前任务状态 | 现在要做什么、已经完成什么、还缺什么 | 防止目标漂移 |
| 证据 memory | 关键文件、论文、网页、工具输出 | 支撑可验证结论 |
| 失败 memory | 哪些方案试过、为什么失败 | 避免重复探索 |
| 约束 memory | 不要做什么、必须遵守什么 | 防止破坏用户要求 |
| 程序性 memory | 常用工作流、测试命令、项目习惯 | 提升长期效率 |
| provenance | 每条记忆来自哪里,能不能回查原文 | 防止摘要幻觉 |
很多当前 agent 的问题是,它们把这些都混在一段自然语言 summary 里。结果是:可读,但不可靠。
#10.2 现有 memory/agent 思路能提供什么启发?
这里不需要堆很多系统名,但几个方向值得理解:
- Reflexion 类方法:让 agent 在失败后写反思,下次避免同样错误。它强调失败经验,但反思如果没有证据来源,也可能变成自我生成噪声。
- Voyager 类方法:让 agent 把成功技能存成可复用代码或策略。它提醒我们 memory 不只保存事实,也保存可执行技能。
- MemGPT 类方法:把有限上下文和外部记忆结合,像操作系统管理内存一样把信息换入换出。它直接把“上下文不够用”变成 memory management 问题。
- MemoryBank / LongMem 类方向:尝试维护长期对话或长期任务记忆。它们说明长期 memory 需要更新、遗忘和检索机制。
这些系统共同指向一个问题:memory 不应该只是“越多越好”的日志,而应该是被管理、可验证、可过期、可回查的任务状态。
#10.3 Pinned memory:把关键状态从普通上下文里提升出来
对 long-horizon agent,一个很实用也很值得研究的思想是 memory pinning:把关键目标、约束、已验证事实固定在高优先级区域,而不是让它们混在长历史中间。
pin 可以理解成“把便签贴在显示器边缘”。普通历史会随着上下文增长被淹没,但被 pin 的内容会持续出现在模型容易看到的位置。
代码 agent 中可以 pin:
- issue 的真实目标;
- 不允许修改的文件;
- 当前确定的 root cause;
- 已经验证失败的假设;
- 关键测试命令;
- 用户偏好;
- 当前分支和工作区状态;
- 已经改过的文件和原因。
科研问题是:
- 哪些信息应该被 pin?
- pin 多了会不会也造成噪声?
- pin 的位置和格式是否影响模型使用?
- 能不能学习一个 pinning policy?
- pin 住的信息是否需要定期验证和过期?
#10.4 Provenance-aware memory:每条记忆都要能回查来源
长上下文压缩最危险的是把来源丢掉。比如摘要写“测试失败是因为 X”,但原始日志其实只是“可能因为 X”。后续 agent 会把这个不确定判断当成事实。
所以 memory 应该带 provenance。provenance 的人话解释是“这条信息从哪里来”。它可以包括:
- 来源文件;
- 行号;
- 工具调用 ID;
- 时间戳;
- confidence;
- 原始 span;
- 当前是否仍然有效。
这对代码 agent 特别重要,因为最后修改代码时需要知道证据来自哪里。
#10.5 Agent context loop:一个更可靠的上下文循环
一个实用的 agent context loop 可以长这样:
| 步骤 | 做什么 | 防止什么失败 |
|---|---|---|
| Plan | 明确当前目标和缺口 | 目标漂移、无目的检索 |
| Retrieve / Read | 只读取和当前缺口相关的信息 | 关键证据缺失 |
| Select Evidence | 把证据和噪声分开 | 注意力稀释、检索噪声 |
| Update State | 更新任务状态、约束、失败记录 | 早期约束遗忘 |
| Act | 执行编辑、调用工具或回答 | 行动和证据脱节 |
| Verify | 用测试、检查器、引用核验结果 | 错误假设继续传播 |
| Compress | 把轨迹压成决策充分 memory | 长轨迹无限增长 |
| Pin / Drop | 固定关键状态,删除低价值历史 | 关键状态被埋、噪声累积 |
这样看,context engineering 不是一个附加模块,而是 agent 的主循环。它决定 agent 每一步看到什么,也决定错误会不会被及时纠正。
#10.6 代码智能里的 context engineering
代码 agent 是研究长上下文的好试验场,因为它有可验证反馈:测试能不能过、类型检查能不能过、lint 能不能过。
在代码场景里,context engineering 至少包括:
- 文件选择:哪些文件应该读,哪些不该读。
- 符号选择:哪些函数、类、类型、变量是关键。
- 调用关系:当前函数被谁调用,又调用谁。
- 测试证据:失败测试的堆栈和断言是什么。
- 编辑历史:改过什么,为什么改。
- 约束保留:用户说不要改什么、不要跑什么。
- 验证记录:哪些命令跑过,结果如何。
这比普通文档 QA 更适合研究“长轨迹 RL + context management”,因为每一步上下文选择都会影响最终测试结果。
可以用一个简化例子把这条因果链串起来:
用户要求修复登录失败。agent 先看到
auth/session.py的报错,于是把整个auth目录塞进上下文;其中legacy_login和当前路径很像,模型被它带偏,改了旧函数。测试仍失败。后续摘要只写“修改登录逻辑无效”,却没有保留“旧函数不在当前调用路径上”这个原因。下一轮 agent 又回到相同方向,重复探索。
这个例子里,每一步都对应前文机制:
| 失败点 | 对应机制 | 更好的 context action |
|---|---|---|
| 只按报错文件读上下文 | 检索证据不完整 | 沿调用图读入口、配置、测试 fixture |
被 legacy_login 带偏 | 结构相似噪声 | rerank 时结合调用路径和测试覆盖 |
| 摘要没写失败原因 | 压缩损失 | failed_attempts 字段记录“为什么失败” |
| 下一轮重复探索 | memory 不可用 | pin 已验证失败假设,后续检索降权 |
| 没有及时跑针对性测试 | 验证不足 | 把 test result 写回 provenance memory |
#10.7 Context engineering 的概念地图
| 问题 | 系统动作 | 需要的表示 | 可评测指标 |
|---|---|---|---|
| 我缺什么信息? | retrieve / read | query、计划、未知项 | 关键证据召回率 |
| 哪些信息可信? | verify / cite | provenance、confidence | 引用准确率、证据支持率 |
| 哪些信息要长期保留? | write memory / pin | goal、constraint、fact、failure | 约束保留率、重复探索率 |
| 哪些信息可以删? | drop / compress | value score、过期时间 | 成本下降、不降成功率 |
| 失败该怪哪一步? | credit assignment | action log、counterfactual | 删除/替换 memory 后成功率变化 |
小结:对 agent 来说,上下文不是静态输入,而是一个不断更新的工作记忆系统。研究重点应从“给模型什么 prompt”转向“让 agent 学会管理信息生命周期”。
#11. 从方案到研究:一条适合初学者的概念地图
前面内容很多。这里专门整理一张“看到某个问题时该想到什么”的地图。
| 你观察到的问题 | 先不要急着说 | 应该拆成什么问题 | 可能用什么方法 |
|---|---|---|---|
| 模型长上下文答错 | “模型不行” | 答案是否进入上下文?是否在中间?是否有噪声?是否需要多跳? | evidence recall、position sweep、noise sweep |
| RAG 加文档后更差 | “召回还不够” | top-k 是否引入相似错误证据?排序是否错?证据来源是否混淆? | rerank、provenance、answer verification |
| 摘要后 agent 忘事 | “摘要质量不够好” | 摘要是否保留目标、约束、失败原因、来源和不确定性? | decision-sufficient state、structured memory |
| 代码 agent 改错文件 | “代码模型弱” | 是否理解调用路径?是否被相似文件带偏?是否跑了正确测试? | repo index、call graph、test feedback |
| agent 跑久后重复探索 | “历史太长” | 失败尝试有没有写入可检索 memory?是否 pin?是否过期? | failed_attempt memory、pin/drop policy |
| 长任务最终失败 | “最后一步错了” | 哪个早期 context action 造成后续失败? | credit assignment、counterfactual memory test |
如果把这张表浓缩成一句话,就是:
长上下文研究的核心能力,是把“模型答错了”拆成“信息在哪里、怎么进来、怎么被压缩、怎么被记住、怎么被验证、怎么影响后续动作”。
#12. 怎么评测这个方向?不要只做更大的 leaderboard
如果想做科研,我建议不要只做一个新的“大杂烩 benchmark”。更有价值的是设计能隔离机制的 benchmark。
评测设计要顺着同一条因果链走:
先控制输入里有什么、在哪里、噪声是什么 → 再观察模型是否找到、是否用对、是否引用对 → 最后看 agent 是否把结果变成后续可用状态。
如果只看最终成功率,失败原因会混在一起;如果只看单步检索准确率,又看不到长期任务里的目标漂移和压缩损失。因此好的评测应该同时覆盖输入变量、过程指标和最终结果。
#12.1 评测应该拆开哪些变量?
可以系统控制这些变量:
- 位置:关键证据放在开头、中间、结尾、最近历史。
- 长度:总 token 数从短到长变化。
- 噪声比例:相关证据和无关干扰项的比例。
- 干扰相似度:干扰项只是无关,还是高度相似但错误。
- 证据数量:答案需要一条证据还是多条证据。
- 推理深度:找到事实即可,还是需要多跳组合。
- 输出长度:短答案还是长报告、长代码。
- 压缩方式:原文、人工摘要、模型摘要、query-aware compression、latent memory。
- 上下文策略:full context、sliding window、RAG、pinned memory、learned memory。
- provenance:模型是否能引用正确来源。
- 成本:token、延迟、显存、工具调用次数。
这些变量的价值在于,它们能把“模型不行”拆成更具体的问题:是位置问题、噪声问题、推理问题、压缩问题,还是记忆管理问题。
#12.2 不只看 accuracy:还要看证据和过程
长上下文任务的指标不能只有最终答案准确率。至少还应该看:
| 指标 | 人话解释 | 为什么重要 |
|---|---|---|
| Answer accuracy | 答案对不对 | 最终效果 |
| Evidence recall | 关键证据有没有进入上下文 | 区分检索失败和推理失败 |
| Citation precision | 引用来源是否正确 | 发现证据绑定失败 |
| Constraint retention | 早期约束是否被遵守 | 测 agent 目标维护 |
| Noise robustness | 干扰项增加后性能掉多少 | 测抗干扰 |
| Compression faithfulness | 压缩后是否保留关键事实和不确定性 | 测压缩损失 |
| Repeated exploration rate | agent 是否重复查无关信息 | 测 memory 是否可用 |
| Cost / latency | 需要多少 token、时间和显存 | 测系统可用性 |
如果只看最终答案,很多问题会被混在一起。比如答案错了,可能是检索没召回,也可能是召回了但模型没用,也可能是用了但推理错,还可能是摘要已经把证据删了。
#12.3 Agent 轨迹评测应该看什么?
对 agent,不要只看最终答案。还应该看过程指标:
- 是否重复读取同一无关文件;
- 是否忽略早期约束;
- 是否把错误假设写入 memory;
- 是否能回查原始证据;
- 是否在测试失败后正确归因;
- 是否能避免已经验证失败的方案;
- 是否保持目标一致;
- 是否在长轨迹后仍能说明当前状态。
最终成功率当然重要,但过程指标能帮助定位机制。
#12.4 代码 benchmark 的一个基本设计
一个面向 code agent 的长上下文 benchmark 可以这样构造:
- 给一个 repo 级 bug;
- 关键信息藏在某个文件、测试或日志中;
- 插入相似但错误的 distractor 文件;
- 控制关键信息出现在上下文前、中、后;
- 让模型或 agent 修复;
- 评估是否定位正确文件、是否引用正确证据、测试是否通过。
这类评测能同时覆盖 long-context retrieval、noise robustness、provenance、code editing、agent memory 和 verification。
#12.5 一个更实验化的评测矩阵
如果要把论文实验做扎实,可以用下面这个矩阵组织:
| 维度 | 可选设置 | 想回答的问题 |
|---|---|---|
| Context strategy | full、RAG、sliding、summary、pinned、learned selector | 是“给更多”好,还是“选得更准”好 |
| Evidence position | early、middle、late、recent | 是否存在 agent lost-in-middle |
| Distractor type | none、topic-similar、structure-similar、outdated、instruction-like | 哪种噪声最伤 |
| Compression | none、generic summary、query-aware、decision-sufficient、latent | 哪种压缩保留未来决策信息 |
| Memory intervention | keep、delete、shuffle、corrupt、expire | 哪些 memory 真的有因果价值 |
| Verification | no test、unit test、type check、citation check | 验证是否能纠正上下文错误 |
这样的矩阵比“又做一个大榜”更能产出机制结论。
小结:好评测要能回答“为什么错”,而不只是给一个总分。长上下文研究尤其需要过程指标、证据指标和反事实干预。
#13. 我认为最值得关注的科研机会
如果从“现象 → 机制 → 方案”的链条倒推,最好的科研机会通常不在“再做一个更长窗口模型”,而在那些已有方案彼此衔接不好的地方:
| 断点 | 为什么有研究价值 | 可落地题目 |
|---|---|---|
| benchmark 能测静态 QA,但测不好 agent 轨迹 | agent 的失败来自多步状态维护,不只是一次检索 | Agent Lost-in-the-Middle |
| 摘要能压短历史,但不保证保留未来决策信息 | 当前压缩目标和下游成功率错位 | Decision-Sufficient Context Compression |
| 代码 RAG 能找相似文件,但不一定找对调用路径 | 代码证据是结构化的,不只是语义相似 | Lost-in-Repository |
| memory 能写入经验,但不知道哪条真的有因果价值 | 长轨迹 RL 需要 credit assignment | Memory Credit Assignment |
| 自然语言历史可读但冗长、噪声多 | 长期 agent 需要更紧凑任务状态 | Latent Task State |
| 系统会检索、压缩、验证,但策略多是启发式 | context action 可以学习 | Context Management Policy |
#13.1 Agent Lost-in-the-Middle:把经典现象从静态 QA 推到长轨迹 agent
现有 Lost in the Middle 多是文档 QA。真正有意思的是:agent 轨迹中是否也存在 lost-in-the-middle?
可以构造多步任务:
- 早期给用户目标;
- 中间工具结果里出现关键约束或 root cause;
- 后期需要使用这个信息完成任务;
- 控制该信息在轨迹中的位置和格式;
- 比较 full context、sliding window、summary、pinned memory、learned memory selector。
贡献可以是:提出 agent trajectory 版本的 lost-in-middle benchmark,并证明普通长窗口无法解决,memory pinning / learned context selection 可以缓解。
为什么值得做:它和 LLM Agent、长轨迹、context compressor 都直接相关,而且实验可以从 API 模型开始,不必先训练大模型。
#13.2 Decision-Sufficient Context Compression:决策充分压缩
普通摘要问:“这段历史发生了什么?”
决策充分压缩问:“为了未来任务成功,哪些信息必须保留?”
可做方法:
- 输入长上下文或 agent trajectory;
- compressor 输出短文本、结构化状态或 latent state;
- downstream agent 继续完成任务;
- 用最终任务成功率训练或评估 compressor;
- 加入 provenance,让压缩信息能回查原文;
- 做 counterfactual:删掉某条压缩 memory,看任务是否失败。
论文贡献可以不是“又一个摘要模型”,而是一个更适合 agent 的压缩目标和评测框架。
#13.3 Lost-in-Repository:代码 agent 的长上下文失败 benchmark
代码是非常好的试验场,因为它有自动验证信号。可以设计一个 benchmark:
- 给一个 repo 级 bug;
- 关键信息藏在某个文件、测试或日志中;
- 插入相似但错误的 distractor 文件;
- 控制关键信息出现在上下文前、中、后;
- 让模型或 agent 修复;
- 评估是否定位正确文件、是否引用正确证据、测试是否通过。
这个方向能连接:
- RepoBench / SWE-bench;
- RAG for code;
- agent memory;
- provenance;
- long-horizon RL;
- code editing。
论文题目可以叫 Lost-in-Repository: Measuring and Mitigating Long-Context Failures in Code Agents。
#13.4 Memory Credit Assignment:哪些记忆真的有用?
现在 agent memory 很多是启发式:模型觉得重要就写下来。但一个 memory item 是否真的帮助未来成功,很少被因果评估。
可以做:
- 记录 agent 的 memory;
- 对 memory item 做删除、替换、打乱;
- 看任务成功率变化;
- 学一个 memory value model;
- 把 memory write/delete/retrieve 当作 action,用最终成功率或过程奖励训练。
这和 long trajectory RL 非常接近,因为它把上下文管理变成了可学习策略。
#13.5 Latent Task State:用潜空间状态替代冗长自然语言历史
如果自然语言上下文太长、太噪、太容易丢信息,一个根本性方向是维护 latent task state。
latent task state 可以先理解为“模型内部或外部维护的一组不可读或半可读状态槽”,它们不直接等同于自然语言摘要,而是服务于后续决策。
可以想象几个 latent slots:
- 目标 slot;
- 约束 slot;
- 已验证事实 slot;
- 待解决问题 slot;
- 代码修改状态 slot;
- 不确定性 slot;
- 失败尝试 slot。
模型每一步不是把全部历史塞回 prompt,而是更新这些 latent slots,再基于它们决策。
难点是训练和解释,但它很有潜力成为“从上下文工程走向模型机制”的方向。
#13.6 Context Management Policy:把读、记、删、查变成可学习策略
更进一步,可以把 context management 明确建模成一个策略:
| Action | 含义 | 可能奖励 |
|---|---|---|
| read | 读取文件、文档、日志 | 是否读到关键证据 |
| retrieve | 从外部 memory / index 检索 | 召回是否相关且低噪 |
| pin | 固定关键目标或约束 | 后续是否减少遗忘 |
| compress | 压缩长历史 | 是否保留决策必要信息 |
| drop | 删除低价值上下文 | 是否降低噪声且不丢关键证据 |
| verify | 测试或核验证据 | 是否纠正错误假设 |
这条线自然连接 RL。困难在于 reward 设计:最终任务成功太稀疏,过程奖励又容易被 hack。因此需要可解释的过程指标和反事实评估。
#13.7 Long-context RL for code agents:把测试反馈变成上下文管理奖励
代码任务有一个优势:它有比较硬的反馈。测试通过、类型检查通过、lint 通过,都可以作为最终或中间信号。
可以设计一种训练或评估框架:
- agent 在 repo 中执行 read / search / edit / test;
- 系统记录每一步 context action;
- 最终用测试结果给 reward;
- 用过程指标辅助 credit assignment,比如是否读到 root cause 文件、是否保留用户约束、是否避免错误 distractor;
- 训练 memory selector、context compressor 或 retrieval policy。
这比直接训练“会修 bug 的模型”更窄,也更可控。它研究的是:在已有模型能力上,怎样通过上下文管理提升长轨迹成功率。
小结:面向 wenjun 的研究兴趣,最值得抓的不是“更长窗口”,而是 agent/code 场景中可评测、可干预、可学习的上下文管理机制。
#14. 一个可能的论文路线图
如果要从这里开题,我建议不要一开始就做“通用长上下文综述型 benchmark”,而是沿着下面路线。
#阶段 1:现象复现与机制隔离
目标:证明在 agent/code 场景中,长上下文失败确实存在,并且能区分原因。
实验:
- position sweep:关键约束放在不同位置;
- noise sweep:逐渐增加相似 distractor;
- compression sweep:比较原文、摘要、query-aware 压缩;
- memory intervention:删除/替换某条 memory;
- provenance check:模型答案是否引用正确来源。
产出:一个小而硬的 benchmark + taxonomy。
#阶段 2:提出一个简单有效的 mitigation
不要一开始就做复杂 RL。可以先做一个强 baseline:
- memory pinning;
- provenance-aware context compressor;
- learned reranker;
- decision-sufficient summary;
- context budget allocator。
核心是证明:不是窗口越长越好,而是选择机制更重要。
#阶段 3:走向学习式 context management
当 benchmark 和 baseline 站住后,再把它升级成学习问题:
- context action:read / retrieve / pin / compress / drop / verify;
- process reward:正确保留约束、正确引用证据、忽略噪声;
- final reward:任务成功;
- credit assignment:识别哪个上下文动作影响结果。
这时就能自然连接 long-horizon RL。
#阶段 4:latent memory / latent reasoning
最后再尝试更基础的模型机制:从文本 memory 过渡到 latent memory,让模型学习一个紧凑状态,而不是无限增长的自然语言历史。
这条线风险更高,但也更接近范式变化。
小结:好的开题路线不是一上来做全能系统,而是先用可控评测证明失败机制,再做简单可解释的缓解方法,最后再引入学习式策略和 latent state。
#15. 常见误解
#误解一:上下文窗口越长,RAG 就不需要了
不对。长窗口减少了检索的必要性,但没有消除信息选择问题。全塞进去会带来噪声、位置偏置、成本和证据错配。更合理的方向是:长窗口 + RAG + rerank + compression + provenance。
#误解二:上下文压缩就是摘要
不对。摘要是给人看的,context compression 是给下游任务服务的。对 agent 来说,压缩质量应该由后续任务成功率、约束保留率、证据可回查性来评估。
#误解三:Needle-in-a-Haystack 高分就说明模型会用长上下文
不对。NIAH 主要测单点检索,且容易被字面匹配解决。真实任务还需要语义检索、多证据推理、抗噪、长生成一致性和状态维护。
#误解四:KV cache 压缩只是系统优化,和智能无关
不完全对。KV 压缩确实首先是系统优化,但它决定保留哪些历史 token,因此也在隐式做信息选择。如果能把底层保留策略和上层任务状态结合,可能产生更强的长上下文机制。
#误解五:agent memory 写得越多越好
不对。memory 写太多会变成新的噪声源。更重要的是 memory 的结构、来源、置信度、过期机制和后续可用性。
#误解六:长上下文失败只是模型不够大
不完全对。更大的模型通常更强,但长上下文失败包含系统性问题:位置、噪声、来源绑定、压缩、状态维护、验证循环。只增大参数或窗口,未必能解决这些信息管理问题。
#误解七:只要做了 GraphRAG 或 memory,长上下文问题就解决了
不对。GraphRAG 和 memory 都是在重组信息,但重组本身也会出错:图抽取会漏关系,社区摘要会丢细节,memory 会过期,检索会带来噪声。它们需要 provenance、验证和过期机制配合。
#误解八:长上下文评测只要看最终 accuracy
不够。最终 accuracy 很重要,但不能告诉你错在哪里。长上下文研究还要看证据召回、引用准确、约束保留、重复探索、压缩保真、成本和延迟。
#16. 代表工作清单
这不是完整 bibliography,而是帮助建立路线图的代表工作。读论文时建议先按问题读:它测什么失败、解决什么环节、有没有处理噪声和证据来源。
#长上下文退化与 benchmark
- Liu et al., Lost in the Middle: How Language Models Use Long Contexts, 2023, arXiv:2307.03172.
- Greg Kamradt, LLMTest Needle In A Haystack, GitHub project.
- Bai et al., LongBench: A Bilingual, Multitask Benchmark for Long Context Understanding, 2023, arXiv:2308.14508.
- An et al., L-Eval: Instituting Standardized Evaluation for Long Context Language Models, 2023, arXiv:2307.11088.
- Hsieh et al., RULER: What’s the Real Context Size of Your Long-Context Language Models?, 2024, arXiv:2404.06654.
- NoLiMa: Long-Context Evaluation Beyond Literal Matching, 2025, arXiv:2502.05167.
- BABILong: Testing the Limits of LLMs with Long Context Reasoning-in-a-Haystack, 2024, arXiv:2406.10149.
- Zhang et al., ∞Bench: Extending Long Context Evaluation Beyond 100K Tokens, 2024, arXiv:2402.13718.
- Long-context LLMs Struggle with Long In-context Learning, 2024, arXiv:2404.02060.
- LongGenBench: Long-context Generation Benchmark, 2024, arXiv:2410.04199.
- LongGenBench: Benchmarking Long-Form Generation in Long Context LLMs, 2024, arXiv:2409.02076.
- Liu et al., RepoBench: Benchmarking Repository-Level Code Auto-Completion Systems, 2023, arXiv:2306.03091.
#位置编码、长上下文扩展与系统
- Su et al., RoFormer: Enhanced Transformer with Rotary Position Embedding, 2021, arXiv:2104.09864.
- Press et al., Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation, 2021, arXiv:2108.12409.
- Chen et al., Extending Context Window of Large Language Models via Positional Interpolation, 2023, arXiv:2306.15595.
- Peng et al., YaRN: Efficient Context Window Extension of Large Language Models, 2023, arXiv:2309.00071.
- Ding et al., LongRoPE: Extending LLM Context Window Beyond 2 Million Tokens, 2024, arXiv:2402.13753.
- Xiao et al., Efficient Streaming Language Models with Attention Sinks, 2023, arXiv:2309.17453.
- Han et al., LM-Infinite: Zero-Shot Extreme Length Generalization for Large Language Models, 2023, arXiv:2308.16137.
- Dao et al., FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness, 2022, arXiv:2205.14135.
- Dao, FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning, 2023, arXiv:2307.08691.
- Liu et al., Ring Attention with Blockwise Transformers for Near-Infinite Context, 2023, arXiv:2310.01889.
#RAG、层次检索与知识组织
- Lewis et al., Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks, 2020, arXiv:2005.11401.
- Guu et al., REALM: Retrieval-Augmented Language Model Pre-Training, 2020, arXiv:2002.08909.
- Borgeaud et al., RETRO: Improving language models by retrieving from trillions of tokens, 2021, arXiv:2112.04426.
- Izacard et al., Atlas: Few-shot Learning with Retrieval Augmented Language Models, 2022, arXiv:2208.03299.
- Khattab and Zaharia, ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction over BERT, 2020, arXiv:2004.12832.
- Gao et al., HyDE: Precise Zero-Shot Dense Retrieval without Relevance Labels, 2022, arXiv:2212.10496.
- Asai et al., Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection, 2023, arXiv:2310.11511.
- Sarthi et al., RAPTOR: Recursive Abstractive Processing for Tree-Organized Retrieval, 2024, arXiv:2401.18059.
- Edge et al., From Local to Global: A Graph RAG Approach to Query-Focused Summarization, 2024, arXiv:2404.16130.
#上下文压缩、KV 压缩与记忆
- Li, Unlocking Context Constraints of LLMs: Enhancing Context Efficiency of LLMs with Self-Information-Based Content Filtering, 2023, arXiv:2304.12102.
- Chevalier et al., AutoCompressors: Language Models that Can Compress Their Own Context, 2023, arXiv:2305.14788.
- Jiang et al., LLMLingua: Compressing Prompts for Accelerated Inference of Large Language Models, 2023, arXiv:2310.05736.
- Jiang et al., LongLLMLingua: Accelerating and Enhancing LLMs in Long Context Scenarios via Prompt Compression, 2023, arXiv:2310.06839.
- Zhang et al., H2O: Heavy-Hitter Oracle for Efficient Generative Inference of Large Language Models, 2023, arXiv:2306.07174.
- Li et al., SnapKV: LLM Knows What You are Looking for Before Generation, 2024, arXiv:2404.14469.
- Cross-layer / layer-sharing KV cache compression works, 2024 onward.
#Agent memory 与长轨迹相关方向
- Reflexion-style agents:用反思记录失败经验,适合理解失败 memory。
- Voyager-style agents:把成功技能沉淀为可复用程序或策略,适合理解 procedural memory。
- MemGPT-style memory management:把上下文窗口和外部 memory 看成可换入换出的记忆系统。
- Long-term memory works such as MemoryBank / LongMem:适合理解长期对话、长期用户状态和记忆检索。
- SWE-bench-style code agent tasks:适合理解真实代码修复中的长上下文、检索、编辑和验证闭环。
#17. 最后的判断
如果只是做工程,最直接的路线是:
RAG + rerank + query-aware compression + memory pinning + provenance + verification。
它能较快改善真实系统效果。
如果要做科研,我最看好四条线:
- Agent trajectory 里的 long-context degradation:把 lost-in-middle / distraction / instruction conflict 从静态文档 QA 推到动态 agent。
- Decision-sufficient context compression:把摘要从“复述历史”变成“保留未来决策所需状态”。
- Code agent context failure benchmark:利用代码任务可验证的特点,研究长上下文、检索噪声、memory、RL credit assignment 的交叉问题。
- Latent task state and context management policy:把自然语言历史压成可学习的任务状态,并学习何时读、记、删、查、验证。
这几条线共同指向一个更大的命题:
未来的强 agent 不会靠无限上下文窗口取胜,而会靠更好的信息管理机制取胜。
也就是说,真正的研究对象不是“长上下文模型”,而是“会管理上下文的模型”。从 Long Context 到 Effective Context,关键转变是:让 LLM 学会管理信息,而不是吞下信息。
用本文开头的因果链收束一下:
- 现象上,长上下文模型会出现位置敏感、噪声干扰、长生成漂移、代码结构误判、agent 目标遗忘。
- 机制上,这些失败来自注意力稀释、位置偏置、证据绑定失败、压缩损失、指令冲突和长程信用分配。
- 方案上,长窗口只是入口,RAG 负责筛选,压缩负责降噪和保留状态,KV 优化负责成本,agent memory 和 verification 负责长期闭环。
- 科研上,最有价值的问题是把这些环节串起来:让模型不仅能读长上下文,还能知道什么该读、什么该信、什么该记、什么该删,以及什么时候必须回到原始证据。
如果未来的 LLM Agent 真能长期可靠地写代码、读论文、操作工具和完成复杂任务,它依赖的不会是一个无限大的 prompt,而是一套可学习、可验证、可压缩、可回查的上下文管理系统。