Appearance
3.1.3 为什么不能直接按整篇文档做检索和生成?
先给结论:整篇文档直接做检索和生成,最大的问题不是“技术上做不到”,而是“工程上通常不稳、成本高、相关性也不够细”。
这也是为什么大多数 RAG 系统最后都会回到 chunk。
先把问题说透
整篇文档直接进入链路,表面上看很省事:
- 不用切块
- 不用设计边界
- 不用考虑 overlap
但真正跑起来以后,问题通常会同时出现在检索阶段和生成阶段。
为什么整篇文档直接检索不稳
1. 文档整体相关,不代表答案局部突出
很多文档确实和问题相关,但真正有用的答案只占其中很小一部分。
如果按整篇文档去做匹配,系统更容易得到的是:
- “这篇文档好像相关”
而不是:
- “这段内容就是答案附近的证据”
这两者差别很大。前者适合人工再阅读,后者才更适合后续自动回答。
2. 一个文档里往往混着多个主题
真实文档经常不是只讲一件事。
比如一份制度文档里,可能同时包含:
- 适用范围
- 主流程
- 特殊情况
- 常见例外
- 历史备注
如果把整篇文档当成一个检索单位,系统很难知道用户真正问的是哪一段。
3. 文档越长,语义越容易被平均掉
从检索角度看,一份文档里混入的主题越多、无关内容越多,整体表示就越容易变得“什么都沾一点,但不够尖锐”。
结果就是:
- 文档可能能召回
- 但不一定能稳定排到最前
- 就算排到前面,也不一定是最容易回答的候选
为什么整篇文档直接生成也不稳
1. 会把太多无关内容一起送进上下文
即使一篇文档真的命中了问题,整篇送给模型时,也会把大量与当前问题无关的内容一起带进去。
这会直接带来几个问题:
- 模型更难聚焦
- 有效信息比例下降
- 上下文成本升高
- 多篇文档一起进来时更容易超长
2. 模型不一定每次都能自己抽对局部
很多人会默认相信:只要整篇文档给得够全,模型就会自己找到关键句。
这在有些简单问题上成立,但一旦遇到下面这些情况,就会明显变得不稳:
- 文档里有多个相似规则
- 新旧版本并存
- 特殊情况藏在后面
- 关键限制条件只是一小句
这时模型并不一定每次都抓到你最想让它抓到的那一段。
3. 多文档场景下几乎很快失控
如果用户问题需要参考的不止一篇文档,而是 3 篇、5 篇甚至更多,那整篇文档直塞上下文几乎很快就会变成:
- 放不下
- 放得下也读不稳
- 成本和延迟一起上升
所以整篇文档方案通常最大的幻觉是:
看起来省掉了切块这一步,实际上只是把复杂度推迟到后面的上下文爆炸里。
一个最小对比例子
python
full_document = """
退款规则总说明
普通商品签收后 7 天内支持无理由退货。
定制类商品不支持无理由退货。
质量问题售后申请时限为 15 天。
企业采购订单需走专门审批流程。
历史版本说明:2025 年之前规则另行处理。
"""
retrieval_chunks = [
"普通商品签收后 7 天内支持无理由退货。",
"定制类商品不支持无理由退货。",
"质量问题售后申请时限为 15 天。",
"企业采购订单需走专门审批流程。",
]如果用户问的是“定制类商品能不能无理由退货”,最理想的情况显然不是把整篇都喂给模型,而是优先把第二条相关 chunk 送进去。
这不是因为模型“看不懂整篇”,而是因为系统应该尽量先把真正相关的部分挑出来。
整篇文档方案最容易带来的三个后果
1. 召回粗
系统知道哪篇文档可能相关,但不知道哪一段更关键。
2. 上下文重
很多无关内容跟着一起进入 Prompt,稀释了答案证据。
3. 成本高
每次都喂整篇,token 成本和延迟通常会明显更高。
这三个问题叠在一起,就是整篇文档方案在真实工程里经常撑不住的原因。
那有没有例外
有,但通常范围比较窄。
比如:
- 文档本来就很短
- 一篇文档只讲一个非常聚焦的主题
- 数据量很小,只做本地化的小型工具
- 明确不追求高并发、低成本和复杂治理
这些场景里,整篇文档直接进链路有时可以暂时成立。
但只要系统开始出现下面这些特征,chunk 往往就会重新变成刚需:
- 文档变长
- 文档变多
- 问题更细
- 需要版本、权限、引用和治理
一个更工程化的理解方式
“为什么不能直接按整篇文档做检索和生成”这个问题,本质上不是在问:
- 模型能不能读长文档
而是在问:
- 文档是不是一个好的检索单位
- 文档是不是一个好的上下文单位
对大多数真实系统来说,这两个问题的答案都倾向于:不是。
所以后面才需要继续讨论:
- 怎么切
- 切多大
- 用什么边界切
- 检索用块和生成用块是否要分开
一句话总结
不能直接按整篇文档做检索和生成,不是因为整篇文档绝对不能用,而是因为它通常不是一个足够细、足够稳、足够经济的知识单位。对大多数 RAG 系统来说,先把整篇文档拆成更合理的 chunk,才是让后续检索和生成真正站稳的前提。