一、引言
走到第8篇,回头看这条学习曲线,脉络开始变得清晰。
第3篇从分块策略的隐性代价切入,发现最基础的分块方式竟然藏着那么多坑;第4篇把检索优化的工程代价摊开,评估指标本身可能是虚假的安全感;第5篇梳理了RAG技术的演进,开始有了宏观视角;第6篇和第7篇则深入到推理层的KV Cache和Prefix Caching,那是另一条优化路径。
但读完这些,一个很现实的问题浮现出来:如果现在让我从零开始做一个RAG系统,我该从哪里下手?做出来后检索质量不行,又该从哪里优化?
这两件事,本质上是同一个问题的两面——RAG系统的架构设计与质量优化,不是先A后B的顺序关系,而是迭代闭环。做出来、发现问题、优化、再做、再发现问题……这个循环里最难的不是技术本身,而是知道在每个阶段该做什么,以及不该做什么。
本文不打算重复技术原理,也不写代码。只说两件事:RAG系统怎么做架构决策,以及检索质量怎么系统性地优化。
二、RAG系统的架构设计全景图
我从第3篇到第7篇拆开了RAG的各个组件,但读者需要一个完整的架构视图把这些组件串起来。
端到端数据流
从文档入库到用户得到答案,RAG系统涉及三条链路。
索引链路是离线的:文档加载→分块→Embedding→向量入库。这条链路做得对不对,直接决定系统能检索什么,也是后续优化中最难调整的部分。
检索链路是在线的:Query理解→检索→重排序→上下文构建→生成→后处理。这条链路做得快不快、准不准,直接决定用户体验。
缓存链路是跨请求的:KV Cache、Prefix Cache、查询缓存。这条链路决定了高负载下的系统表现,但通常是最晚被优化的。
三条链路的节奏不同,优化时机也不同。索引错了改起来成本最高,缓存优化需要量起来才有意义。
架构设计的三个关键决策时刻
回顾这两年所做过的RAG项目的架构决策过程,有三个时间节点值得单独拎出来。
系统设计阶段,要决定分块策略、Embedding选型、向量库选型。这些决策一旦做出,后面所有优化都建立在它们之上。当时我选了BGE-large-zh做Embedding、Milvus做向量库、三类文档差异化分块——这几个决策事后看都站得住,但并不是每个都能在选型时就有充分数据支撑。
上线前优化阶段,考虑混合检索、重排序、索引调优。这个阶段的决策相对安全,因为可以在测试集上量化验证。Hybrid Search和Reranker就是在这个阶段加上的,收益明确、风险可控。
生产运行阶段,关注缓存策略、监控告警、降级方案。这个阶段的决策取决于真实负载。缓存命中率低于预期怎么办?推理延迟突然飙升怎么办?没有监控数据,这些决策就是盲打。
三个阶段,决策的确定性和可验证性递减。系统设计阶段的决策影响最大但证据最少,生产运行阶段的决策影响最小但数据最多——这正是架构决策的困难所在。
索引阶段的决策要点
分块策略的决策树可以很直白:文档结构是否规整?如果是,按结构边界切;如果不是,按语义边界切;如果都不是,按固定大小切。我接触最多的是三类金融文档——财报、研报、公告——结构完全不同,用同一套分块参数处理,财报表格会被截断,研报章节会被打散,公告整篇反而被切成碎片。这个教训是第3篇的核心收获。
Embedding模型的选择是个实用主义问题。当时选BGE-large-zh不是因为它在Benchmark上分数最高,而是因为它在中文金融语料上表现稳定,且能本地部署。金融数据不能出境,这条约束直接排除了OpenAI。
向量数据库的选型围绕四件事:数据规模、QPS、延迟SLA、运维能力。Chroma在10万级数据上够用,但到了百万级就不行;Milvus能撑住,但运维成本高。我的决策逻辑是:选能撑住未来一年数据量的方案,而不是当前数据量的方案。
检索阶段的决策要点
召回策略有三层。纯向量检索在语义理解上有优势,但精确术语匹配是短板。Hybrid Search补上了BM25这块,RRF融合解决了权重调参的问题。重排序要不要加,取决于精度要求是否高于延迟预算——加了Reranker,Recall@5能提升10-20个百分点,但延迟会增加几百毫秒。
推理阶段的决策要点
推理层优化需要规模支撑。没有千万级日请求,Prefix Caching带来的收益可能还抵不上配置的成本。第6篇和第7篇详细拆了PagedAttention、MLA、Prefix Caching,但它们的适用条件差别很大:PagedAttention是基础,没有它vLLM都不成立;MLA是模型选型级别的决策,选了DeepSeek自然就有了;Prefix Caching和LMCache则需要根据实际负载评估收益。
三、基线建立:优化之前必须先做的事
做优化之前,有两件事要先确认——基线 和 测试集。没有这两样东西,优化就变成了无头苍蝇式调参。
为什么要先跑基线
理由很朴素:没有基线,怎么证明优化是有效的?
基线的作用有三层:第一,量化起点——你知道系统在当前配置下Recall@K是多少、MRR是多少、平均延迟是多少;第二,对照基准——每次优化后重新跑测试集,对比基线就知道收益多少;第三,决策依据——Reranker加了但Recall只提升了2%,值不值得为这点收益增加几百毫秒延迟?
有一个认知偏差在这里反复出现:我们总是高估某个优化的效果,又低估了测量基线的重要性。
建立基线的四步法
第一步很简单:用最基础的配置跑通全流程——固定分块、通用Embedding、仅向量检索。这个配置跑出来的结果就是起点,通常不会太好,但它给了你一个参照系。
第二步是构建测试集。从业务日志里抽20-50个典型问答对,覆盖三类文档、不同查询模式,人工标注期望答案和期望来源。这个测试集会反复使用,它的质量直接决定了优化方向对不对。
第三步记录基线指标:Recall@K、MRR、端到端延迟。指标不用多,关键是可复现。
第四步把基线固化下来——配置文件版本、模型版本、代码提交哈希,全部记录。三个月后如果需要回溯,知道当时跑的是什么版本。
测试集的维护
测试集不是一次性建完就扔在那里的。随着业务变化,新类型的查询出现,旧类型可能不再相关,测试集需要定期更新。每次优化跑完测试集后,如果发现某些case的标注本身有问题,及时修正。测试集的质量决定优化方向的质量——如果测试集本身有问题,优化工作就会变成无效劳动,在错误的方向上越走越远。
测试集质量决定优化方向
测试集质量不高,优化工作可能在错误的方向上浪费大量精力。以下三个案例说明了这种影响。
案例一:测试集覆盖不足导致优化方向偏差
假设RAG系统服务于三类用户:分析师查询财报数值、基金经理检索研报观点、合规人员追踪公告事件。如果测试集中只有财报数值查询的样本,即使Recall@K做到0.95,系统上线后面对研报观点查询时可能Recall@K不到0.3。用户感知到的不是“系统很准”,而是“系统只会在少数场景下准”。
正确的做法是:测试集按三类文档的实际调用比例抽样,确保覆盖所有场景的查询模式。如果某类查询在日志中占比10%,在测试集中也应占10%左右。测试集的结构应该反映业务真实分布,而不是开发者最熟悉的场景。
案例二:期望答案标注不准确导致评估结果失真
在标注数值类查询的期望答案时,标注者可能只写了数值本身,没有标注来源页码。评估时系统返回了正确数值但页码错误,本应判定为“部分正确”的Case被判定为“完全错误”,导致指标偏低,触发不必要的优化。
更隐蔽的情况是:标注者从文档A中找到了答案,但系统检索时返回了文档B中完全相同的数值。评估时如果只做文本匹配,可能判定“正确”,但来源追溯实际上是错误的。这在金融场景中是无法接受的。
应对方法是多人背对背标注同一批测试集,然后交叉验证。标注不一致的Case需要讨论达成共识,标注错误率过高的Case需要重新标注。标注成本的增加是值得的,因为测试集用一次就值回标注成本,而它会被反复使用无数次。
案例三:测试集数据过时导致过度优化
测试集是三个月前构建的,但业务新上线了一批去年最新的财报文档。旧测试集中没有涉及新数据的查询,系统在去年最新财报上的真实召回率可能远低于测试集显示的水平。优化者看到测试集指标很好,以为系统已经足够好,实际上在新数据上表现糟糕。
优化的目标是服务当前业务,而不是服务三个月前的测试集。测试集需要随业务变化持续更新。定期从生产日志中抽取新样本,替换掉过时或重复的旧样本,保持测试集的时效性和代表性。
测试集质量的核心维度
| 维度 | 要求 | 验证方式 |
|---|---|---|
| 覆盖度 | 覆盖所有文档类型和查询模式 | 分析业务日志中的查询分布 |
| 准确性 | 标注答案和来源必须准确 | 多人背对背标注+交叉验证 |
| 时效性 | 反映当前业务需求 | 定期更新,保留历史版本做对照 |
| 规模 | 足够统计显著,但不过量 | 20-50条/类,总数50-100条 |
在基线阶段就投入足够精力建设测试集。如果基线数据本身有问题,后续所有优化都会被打上问号。测试集的投入不是一次性成本,而是持续收益——每次优化跑一遍测试集,都是在复用这份前期投资。测试集的质量,决定了优化工作的天花板。
四、检索质量优化的系统性方法论
有了基线,就可以开始优化。优化有优先级,按收益从高到低排。
第一优先级:分块策略调整
如果只能优化一件事,优化分块策略。这是收益最高但也最容易被忽视的环节。
财报表格被截断,数值查询召回率直接归零;研报章节被打散,观点检索无法定位到完整上下文;公告按固定大小切分,反而把完整信息拆碎。这些问题在过去的项目里都遇到过。解决的思路很简单:不同类型文档用不同分块策略。
财报:表格独立块+文本段落分块。表格块不做二次切分,保持完整表格结构;文本块按段落切,chunk_size=512,overlap=20。
研报:按章节标题递归分块。识别章节标题作为切分边界,每个章节内部再按段落切,chunk_size=512,overlap=50。
公告:整篇作为一块。公告通常短,不需要再切。
调整分块策略的收益通常在10-30%的召回率提升,这是任何其他优化都达不到的幅度。
第二优先级:查询侧优化
查询侧优化的核心是让Query和文档在语义空间里更接近。
HyDE是典型手段——让LLM先根据Query生成一段假设文档,再用假设文档去检索。它的本质是把用户的口语化提问扩展成更接近文档风格的表述。
查询侧优化的收益通常在5-15%的召回率提升,但代价是多一次LLM调用。QPS超过50的场景慎用。
第三优先级:检索侧优化
Hybrid Search加RRF融合是性价比最高的检索侧优化。向量检索抓语义,BM25抓关键词,RRF把两路结果合并。不需要调权重,RRF的k值取60就行。
Reranker是更进一步。BGE-reranker这类交叉编码器精度高,但计算开销也高,所以只在Top-20上做精排,重排到Top-5。它的收益是10-20%的精度提升。
第四优先级:索引侧优化
Embedding模型升级和索引类型调整排在最末,因为收益有限、代价不小。
把BGE-small换成BGE-large,Recall能提升几个百分点,但向量维度从384涨到1024,存储和检索延迟都会增加。索引类型从FLAT换到IVF或HNSW,检索速度提升但召回率会略有下降。
这些优化不是不做,而是应该在前面几项优化做完之后,评估剩余差距再决定是否值得。
优化决策的工程原则
三个原则贯穿所有优化决策。
原则一:每次优化必须量化收益。加了Reranker,Recall从0.80提升到0.85——这个数据要记下来。没有量化就没有决策依据。
原则二:任何优化不能突破延迟SLA。P95延迟超过3秒,用户感知到的卡顿会抵消精度提升带来的收益。
原则三:金融场景的溯源要求高于精度。不能追溯来源的答案,再准确也不能用。来源标注是合规底线,优化不能以牺牲它为代价。
五、进阶知识与技巧
技巧一:分块大小与Embedding模型的匹配
低维Embedding模型(384维)语义表达能力有限,分块不宜太小,否则语义碎片化严重;高维模型(1024维)可以支持更细粒度的分块。实践中chunk_size通常不超过模型上下文窗口的1/3——例如模型支持4096 tokens,chunk_size取512或1024比较合适。
技巧二:分块策略的A/B测试
分块策略变更需要重建索引,成本高、风险大。上线前用不同策略分别入库到不同Collection,跑测试集对比效果,再决定是否切换。如果已经在生产环境,可以用双写策略——新旧策略同时入库,逐步切流。
技巧三:架构决策的记录与沉淀
每个决策应该记录四件事:候选方案、对比分析、选定方案、舍弃理由。三个月后回头看,技术选型文档和当时做的取舍记录能省下大量回溯时间。例如在项目的技术选型取舍文档里,记录下的排除的方案——Chroma被排除是因为不支持分区键,OpenAI被排除是因为数据出境问题,LangChain被排除是因为抽象层过多导致调试困难——这些记录后来在评审时帮了大忙。
六、工程检查清单
架构设计层面:
- □ 分块策略是否有明确的选型依据?
- □ Embedding模型是否针对领域数据评估过效果?
- □ 向量库是否匹配当前数据规模和未来1年的增长预期?
- □ 是否建立基线指标(Recall@K/MRR/准确率)?
- □ Hybrid Search和Reranker是否评估过增量收益?
优化执行层面:
- □ 各项优化的增量收益是否已量化记录?
- □ 分块策略变更的回滚方案是否就绪?
- □ 每个优化决策是否有数据支撑,而非靠直觉判断?
- □ 优化是否突破了延迟SLA?
测试集质量层面:
- □ 测试集是否覆盖所有文档类型和查询模式?
- □ 期望答案和来源标注是否经过交叉验证?
- □ 测试集是否定期更新以反映业务变化?
- □ 测试集标注不一致的Case是否已达成共识?
七、总结
RAG初级阶段的8篇文章,走到这里是时候做个小结。
关于设计:RAG系统不是“检索器+生成器”的简单组合,而是一条从文档到答案的完整决策链。架构师的职责是在分块、检索、推理三个层面做出恰当的取舍,而不是“用最好的组件”。每个组件都有它的适用边界,知道什么时候用、什么时候不用,比知道怎么用更重要。
关于优化:RAG系统优化的核心逻辑是“先建立基线,再按优先级逐节点迭代,每次优化必须量化收益”。分块策略收益最大且最容易被忽视,其次是混合检索与重排序,查询侧优化锦上添花,推理层优化则需要规模支撑才能体现价值。
关于测试集:测试集的质量决定了优化工作的上限。覆盖不足、标注不准、数据过时的测试集,会让所有优化决策都建立在错误的基础上。在基线阶段投入足够精力建设测试集,是优化工作中ROI最高的一笔投资。
好的RAG系统不是一次设计出来的,而是持续优化出来的。每一个优化决策都应该回答三个问题:为什么要优化它、优化后收益多少、是否值得为此付出工程成本。
至此RAG的内容已经收尾,这个系列将进入Agent阶段。RAG不再是独立的检索管道,而会变成Agent工具箱里的一个工具。分块策略、检索优化、缓存设计这些基础能力,并不会因为进入Agent阶段就失效——它们只是从“系统核心”变成了“工具能力”。掌握这些方法论,在Agent阶段依然会用得上,只是视角会从“如何设计一个检索系统”转变为“Agent如何在合适的时机调用检索能力”。