我最早做 Agent 的时候,干过一件现在想起来很蠢的事:把一个 2000 行的日志文件整个塞进上下文。4 万 token,当时直接把窗口干满了。Agent 倒是没报错,它也 "读"完了——但后续每走一步都在梦游:工具调用顺序错乱,参数张冠李戴,就像一个刚塞下三斤自助餐的人被你逼着去跑马拉松。

那次之后我想明白一件事:上下文窗口不是一个 "能装多少"的容器,它是一笔预算。文件把预算花光了,后面的推理就开不了工。那怎么办?把文件变小再喂给模型。变小有两种做法:分块读取,或者摘要提取。哪个对?
很长一段时间,我都以为这是个二选一。直到我把两条路分别做了一遍,才发现它们根本不是同一个维度的选项。
窗口不是容器,是舞台
先讲底层机制。你在用任何大模型时会注意到一个现象:对话越长,它反应越慢,也越容易糊涂。这不是错觉。模型每生成一个 token,都要把窗口里所有既有 token 重新 "过一遍"——每个词跟其他所有词互相打个招呼,自己决定该注意谁。你输入 100 个词,它要做 1 万次打招呼;输入 1 万个词,就是 1 亿次。这就是自注意力,复杂度是 O(n²)。窗口翻一倍,计算量翻四倍。
这意味着窗口里的内容不是被 "存"进抽屉的,而是被 "摆"在舞台上的。台上角色太多,站在中间的基本没镜头。2023 年那篇 Lost in the Middle 论文实测过这一点:把一个事实放在长上下文的不同位置,看模型答对的概率差多少。结果有点残酷——
"In many scenarios, necessary information is located in the middle of long contexts, and we find that this leads to a significant performance drop." ——论文摘要原文
翻译成大白话:信息在开头或结尾,模型读得到;信息埋在中间,模型大概率没看见。所以当你把一个超大文件塞进窗口,你以为模型 "读"了全文,实际上它记住了开头和结尾,中间全靠猜。
分块读取:保留细节的代价是打碎全局
分块读取是最直觉的方案:装不下,就切小。工程上它有一套完整流程——先把文件按某种规则切成小块,每块小到能塞进窗口;然后把块做成索引(通常是向量库);用户提问时,用问题去检索索引,把命中的块拿出来送进上下文。这套东西有个名字,叫 RAG,检索增强生成。
它的成败完全取决于检索质量。检索漏掉一个关键块,模型不会告诉你 "我没查到"——它会一本正经地编一个答案,这就是幻觉。我朋友做过一个发票问答 Agent,分块时把 "应付总额:5000 元"切到了上一块末尾,检索时差一点点没命中。Agent 看着明细块,自信地报了个 4800 元。客户当场沉默。
块本身怎么切,也是玄学,几个原则供参考:
- 按语义边界切,别按固定 token 数硬切。代码按函数、文档按章节、聊天记录按轮次,硬切会把完整的句子和逻辑拦腰截断。
- 块大小从 512–1024 token 起步。块太小,语义被切碎,检索容易抓瞎;块太大,检索命中后整块塞进去又挤占窗口。
- 相邻块之间留 10%–20% 的重叠。关键信息正好落在边界上的概率不低,重叠是便宜且有效的保险。
分块方案的优点是精度:模型看到的是原文,引用的每一句都有据可查。代码库问答、合同条款核对、财务数字校验,这类要 "按原文说话"的任务,它很稳。缺点也很明显——它没有全局视角。让分块 Agent 写一份年度总结,它会给你东拼西凑,因为这家伙从头到尾只看过几个块,根本不知道全文在讲什么。
摘要提取:保住全局,细节开始说谎
摘要提取的思路刚好反过来:装不下,就先压缩。让模型读完全文,产出一份几百到几千字的摘要,塞进窗口。模型理解的对象从 "全文"变成了 "读书笔记"。
工程上有两种主流做法,在 LangChain 里直接对应两种链:map-reduce 把文件切成块,每块独立生成摘要,再把块摘要合并成总摘要,并行度好但块和块之间是割裂的;refine 逐块扫描,每读一块更新一次摘要,连贯性更好,但更慢更贵。
摘要的问题就出在 "压缩"这两个字上。压缩必然有损,而且损失是累积的。第一轮摘要丢掉 30% 的细节,对摘要再做摘要,又丢 30%。两三轮下来,具体数字、条款表述、代码里的函数名,都消失在传话游戏里了。
更要命的是,你事先不知道用户会问什么。用户问 "合同里违约金比例是多少?",可摘要里偏偏没有这个数字。这时候模型没有回到原文的能力——它只能猜。一个整体判断靠得住、具体细节全靠编的方案,在你做精确任务时会变成定时炸弹。
所以摘要适合的场景是另一头:写综述、给文件定性、判断相关性、生成 executive summary。要的是全局结构,不是局部精确。
一张表看清两个方案各自的死法
| 维度 | 分块读取 | 摘要提取 |
|---|---|---|
| 核心思路 | 切碎 + 按需检索 | 压缩 + 常驻上下文 |
| 保留的信息 | 原文细节 | 全局结构 |
| 丢失的信息 | 块与块之间的关系 | 被压掉的具体细节 |
| 失败模式 | 检索不到 → 幻觉补全 | 摘要失真 → 细节不可考 |
| 适合任务 | QA、代码、合同、数字 | 综述、分类、意图判断 |
| 成本特征 | 检索成本低 + 按需带块 | 全文多遍读 + 摘要费 token |
动手之前,三个问题先想清楚
块大小到底怎么定?
没有完美数字,只有适合你任务的数字。先从语义边界出发:代码按函数、文档按章节。语义结构不明显时,再从 512 token 起步做实验,观察检索命中率。重叠留 10%–20%。这个参数最终要跟你的 embedding 模型和任务类型一起调。
上下文窗口已经很大了,还需要分块或摘要吗?
需要。窗口大不解决注意力摊薄的问题,Lost in the Middle 已经证明了这一点。而且 Agent 的上下文预算不只属于文件——工具返回结果、中间推理、多轮对话历史都在抢。你把窗口全给文件,后面的步骤就没地方站了。
摘要之后能做问答吗?
能,但只能回答摘要里包含的信息。如果你预期用户会问细节,答案必须回到分块里去查——摘要负责 "理解全局",分块负责 "拿出证据"。两者本来就该配合。
地图 + 放大镜:不要二选一,要分层
看到这里你应该已经明白我的态度了。既然两种方案死法不同,正确的做法是把它们叠起来:全局靠摘要,细节靠分块,检索是连接两者的桥。
- 按语义边界把文件切成块,每块控制在 512–1024 token,能完整表达一个意思。
- 为每块生成一小段块级摘要,一两句话,提炼 "这块讲了什么"。
- 把块摘要聚合成一份全局摘要,这就是地图。全局摘要里要留 "指针",比如 "第三章讨论定价模型"——Agent 看到指针才知道该检索哪个方向。
- 全局摘要常驻上下文,Agent 在动手前先掌握大局。
- 用户提问时,用查询检索块,命中的块作为放大镜临时插入上下文。
这套设计在 LlamaIndex 里叫 Document Summary Index,Anthropic 2024 年发的 Contextual Retrieval 也是类似思路——在建立索引前为每个块补一段上下文描述,大幅提升检索命中率。为什么这条路走得通?因为人读书本来就是这样:先看目录和序言,确定这本书讲什么;需要某个数据时,再翻到具体那一页。Agent 应该是一样的。
一个更刁钻的场景:交叉引用密集的文档怎么处理?
法律文件和大型技术文档里到处都是 "上述协议"、"如前所述"这类引用,单独拎出一个块根本看不懂。两个补救方向:一是给每个块自动生成一段上下文描述再建索引(Contextual Retrieval 干的就是这事);二是把引用关系也放进索引,检索时顺带展开被引用的块。代价是构建阶段更慢、更贵,但检索质量会明显提升。
上下文窗口再大,也解决不了这三件事
你可能会说:上下文窗口都到 1M token 了,直接把 300 页文档塞进去不就行了吗?窗口大确实有用,但至少有三道坎过不去。
- 注意力摊薄。上下文越长,模型对中间内容的利用率越差。1M 窗口塞 100 页文档,真正被 "专注"的很可能只有前 10 页和后 10 页。
- 成本爆炸。输入 token 是计费的,而且 Agent 不是调用一次就完事,十几轮迭代下来,全文 token 反复烧。窗口再大也经不起这么造。
- 延迟飙升。自注意力是平方复杂度,窗口翻倍计算量翻四倍。模型花一分钟读完 1M token 再回答你 "第三页那个数字是多少"——你等得起吗?
Gemini 1.5 展示过在 1M token 上下文里做 "大海捞针"式检索,成绩确实亮眼(Gemini 1.5 技术报告)。但那是找一个孤立事实。真实任务往往是多跳的:要比较两个章节、要追踪一个概念在全文中的演变、要在矛盾数据里做权衡。这些对长上下文模型来说依然是硬骨头。
所以我的判断是:长上下文窗口解决的是 "读得下"的问题,而 Agent 面对的真正问题是 "看得见、记得住、想得清"。后者只能靠结构化的上下文管理来解决。往远处看,文件处理策略其实是 Agent 内存管理的一个子问题——对话历史、工具返回、中间推理都在争抢同一份预算。要彻底解决,需要的是 MemGPT 那种操作系统式的内存换页:重要的落盘,临时的进窗口,窗口满了把不用的换出去。
最后回到你最初的问题。一次性问答、需要精确引用,选分块;给文件定性、写综述,选摘要。但如果你在做一个真正的 Agent,别选边站——用摘要建地图,用分块做检索,把两者叠成记忆的层级。并且永远记住那个物理现实:模型看到的不等于记住的,记住的也不等于理解的。你的任务不是想方设法把更多内容塞进窗口,而是替模型决定,哪些内容值得被看见。
原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/806.html