返回博客
·AI Technology

RAG 规模化实践:那些文档不会告诉你的向量索引坑

从 1000 条到 100 万条数据,RAG 系统踩过的那些坑和实战调优经验

#RAG#向量数据库#LLM#检索增强生成

# RAG 规模化实践:那些文档不会告诉你的向量索引坑

搞 RAG(Retrieval-Augmented Generation)一年半了,从最初的几十条文档测试,到现在支撑百万级向量数据库检索,踩过的坑足够写本书。网上教程千篇一律:切分文档 -> 嵌入向量 -> 存入向量库 -> 检索 -> 生成。但实际生产环境中,这些步骤里暗藏了多少坑,只有亲自趟过才知道。

今天就来聊聊我在 RAG 规模化过程中遇到的几个致命问题,以及我是怎么解决的。

问题一:切分粒度太小,上下文碎片化

刚开始做 RAG 时,我照搬教程,把文档按固定长度切分(比如每 500 个 token 一段)。结果检索出来的结果惨不忍睹——一篇讲金融合规的文档,被切成几十段,每段只有零散的关键词。检索时,系统可能只返回合规这个词所在的一段,完全丢失了上下文。

解决方案:按语义切分,而不是按长度切分

我开始尝试用 NLP 方法按语义边界切分文档。比如用句子之间的停顿、段落结构、标题层级作为切分点。具体做法是:

  • 先用自然语言处理库识别文档的段落和句子
  • 2. 用句子嵌入计算句子之间的相似度

    3. 在相似度下降的谷底处切分,保证每个片段有完整的语义

    虽然实现起来麻烦了点,但检索质量提升不是一倍两倍。以前搜贷款审批流程,返回的是东拼西凑的关键词片段;现在能返回完整的申请 -> 审核 -> 放贷全流程描述。

    问题二:向量索引过时,检索效果越来越差

    文档更新后,我没有及时更新向量索引。结果就是:新文档里的信息检索不到,旧文档的错误信息却还排在前面。RAG 系统越用越臃肿,检索质量直线下降。

    解决方案:增量索引 + 定期重组

    我设计了一个增量更新机制:

  • 新文档/修改文档直接计算向量并追加到索引中
  • 每天凌晨低峰期做一次索引重组,清理过期向量
  • 为每个文档添加时间戳,检索时根据时效性加权
  • 但这里有个坑:向量数据库的索引重组是个重操作,百万级数据量时可能占用大量内存。我在生产环境试过,重组期间查询延迟飙升。解决方案是:双索引机制——旧索引保留一段时间,新索引构建完成后再切换。期间可能有个短暂的不一致期,但胜在安全。

    问题三:相似度检索不等于语义相关

    用 cosine similarity 做向量检索,看似合理,实际效果并不总是理想。有些向量距离很近,但语义完全无关;有些语义相关的,向量距离却较远。

    解决方案:混合检索策略

    我现在用向量检索 + 关键词检索的混合策略:

  • 先用向量检索找候选结果(top 20)
  • 2. 再用 BM25 等关键词算法对这些结果重新排序

    3. 最后把综合得分最高的结果送入 LLM

    这个组合拳效果显著。比如搜索怎么关闭会员订阅,向量检索可能找到很多包含会员、关闭字样的文档,但 BM25 排序能把最匹配的具体操作说明排到前面。

    问题四:检索片段太长,LLM 上下文浪费

    以前我把检索到的整个 chunk 全部丢给 LLM,结果 token 消耗巨大,而且 LLM 经常被淹没在无关信息里。一个 500 token 的 chunk,可能只有最后 50 token 是真正有用的。

    解决方案:检索摘要 + 分段处理

    现在我的流程是:

  • 检索到 top 3 个 chunk(共约 1500 token)
  • 2. 先用一个小模型快速提取每个 chunk 的核心摘要(约 100 token)

    3. 把摘要给 LLM 判断哪个最相关,再只把最相关的完整 chunk 送入生成模型

    这样既节省了 token,又提高了生成的准确性。虽然多了一步摘要处理,但整体成本反而降低了。

    问题五:没有评估机制,效果差到哪都不知道

    刚开始做 RAG 时,我觉得能检索到就行,没想过效果评估。结果上线后,用户反馈检索结果一堆不相关。这时候才知道,没有评估指标,你就不知道哪里出了问题。

    解决方案:构建评估数据集和自动化评估流水线

    我现在的做法是:

  • 收集真实用户的查询和期望答案,构建测试集
  • 2. 每次更新 RAG 管道后,用测试集跑回归测试

    3. 评估指标包括:检索命中率、答案准确率、token 效率等

    工具上推荐用 LangChain 的评估模块,或者专门的 RAG 评估框架。没有评估的 RAG 开发,就像闭着眼睛开车——你知道车在开,但不知道有没有跑偏。

    额外经验:分库分表策略

    当向量数据量超过百万级,单库性能开始吃撑。我试过把向量数据按 topic 分表——金融类放一个表,医疗类放一个表。检索时先判断 topic,再针对性检索。

    这个策略在特定场景下有效,但也增加了复杂度。如果 topic 判断不准,检索结果就会缺失。更稳妥的做法是:先优化单库性能(选择合适的向量索引算法、配置合理的内存),实在撑不住再考虑分库。

    总结

    RAG 不是嵌入向量+检索那么简单,背后有很多坑需要填。从语义切分到混合检索,从增量评估到架构分库,每一步都需要根据实际业务场景做权衡。

    最重要的是:别指望一次搞定。RAG 是迭代出来的,边用边调,持续优化,才能做出真正好用的系统。

    > 经验之谈:RAG 系统的成功与否,不在于用了多复杂的模型,而在于数据准备和检索质量。先把基础做稳,再考虑锦上添花的优化。