你的RAG系统效果差,可能不是LLM的锅
过去一年我参与了5个RAG项目,从企业内部知识库到法律文书检索,从客服问答到学术论文搜索。每个项目上线前都信心满满,上线后都被现实打脸。最惨的一个项目,RAG的答案准确率只有34%——用户问的问题,系统返回的上下文完全不相关。
团队的第一反应是"换更好的LLM"、“换更好的Embedding模型”。但真相是:向量数据库用错了,前面的一切都是白费。 以下是我们在5个项目中踩过的7个致命错误。
错误一:Embedding模型和向量数据库的维度不匹配
这是最愚蠢但最常见的错误。某团队用BGE-M3(1024维)生成Embedding,但向量数据库的Collection建的是768维。写入时没有报错(因为Milvus自动做了截断),但查询时完全找不到相关文档——因为1024维被截断到768维后,语义信息丢失了30%。
解决方案:在数据Pipeline中加入维度校验。 在写入前检查Embedding维度和Collection定义是否一致。不一致就报错,不要静默截断。
金句:向量数据库不会告诉你Embedding维度错了,它只会告诉你"查不到"。
错误二:用了错误的相似度度量
向量数据库支持三种相似度度量:欧氏距离(L2)、内积(IP)、余弦相似度(Cosine)。不同Embedding模型训练时用的度量不同,你必须匹配。
- OpenAI的text-embedding-3使用余弦相似度(归一化后等价于内积)
- BGE-M3使用余弦相似度
- E5使用内积
- Sentence-BERT(经典版)使用余弦相似度
某团队用E5模型生成Embedding,但Milvus里配的是欧氏距离。结果是:本来最相关的文档排在第3位,而不是第1位。对于RAG系统来说,Top-3的召回率从98%降到了85%——有13%的查询完全找不到正确上下文。
金句:相似度度量选错了,相当于你的向量数据库在用一个错误的尺子做比较。
错误三:没有做文本分块策略优化
这是最容易被低估的坑。向量数据库的检索粒度取决于你的Chunking策略。如果每个chunk是500字,那么检索出来的就是500字的上下文。如果chunk是5000字,那检索出来的就是5000字。
某法律文档RAG项目,最初的chunk_size设成2000字。结果检索出来的上下文经常是"半截条款"——索赔条款的前半段在这个chunk,后半段在另一个chunk。LLM基于不完整的信息生成答案,准确率惨不忍睹。
优化后:chunk_size=800字,chunk_overlap=200字,按语义边界(段落、条款号)切分。准确率从34%提升到72%。
金句:Chunking是RAG系统中最不性感但最重要的环节。你的检索质量的上限,在Chunking阶段就已经决定了。
错误四:忽略了元数据过滤
某电商RAG项目,用户问"iPhone 16的电池容量",系统返回了iPhone 15、iPhone 14、甚至MacBook的电池信息。因为向量搜索只比较语义相似度,“iPhone”+“电池"在所有苹果产品中都很相似。
解决方案:在向量搜索中加入元数据过滤。为每个文档标注product_id、product_name、release_year等字段,查询时先过滤再搜索。
# 错误做法:纯向量搜索
results = collection.search(
data=[query_embedding],
anns_field="embedding",
limit=10
)
# 正确做法:带元数据过滤的向量搜索
results = collection.search(
data=[query_embedding],
anns_field="embedding",
param={"metric_type": "IP"},
limit=10,
expr="product_id == 'iphone16'"
)
优化后,准确率从72%提升到91%。
金句:纯向量搜索是RAG的天真版本。真正的生产系统必须结合元数据过滤。
错误五:检索结果没有重排序
向量搜索的Top-10结果中,第1名和第10名的相关度可能差很多,但原始排序有时候不准确——尤其是当查询和文档的语义相似度都很高时。
某学术论文RAG项目,用BGE-M3做检索,Top-5的召回率是92%,但首位准确率(Top-1的文档就是正确答案)只有58%。这意味着42%的查询中,LLM拿到的是一个"有点相关但不是最相关"的上下文,生成的答案自然也就不准确。
解决方案:引入Reranker模型(如BGE-Reranker-v2、Cohere Rerank),对检索结果做精排。首位准确率从58%提升到85%。
金句:检索是粗选,Rerank是精选。没有Rerank的RAG就像没有筛选的简历——你总是看到一堆"相关但不合适"的结果。
错误六:向量数据库的更新策略缺失
某客服知识库项目,FAQ文档每周更新一次。但团队没有设计增量更新机制,每次更新都是全量重建——先删除所有旧向量,再导入新向量。这导致每次更新期间,系统有15分钟的"空窗期”,查询返回空结果。
正确做法:设计增量更新管道。 新增文档→生成Embedding→insert到向量数据库;修改文档→更新对应记录的Embedding;删除文档→按ID删除。全量重建只在索引参数变更时进行。
金句:向量数据库的更新策略决定了你的RAG系统是"实时"还是"准实时"。
错误七:没有监控向量数据库的召回质量
最后一个错误是"上线后就不管了"。某项目上线3个月后,用户反馈答案质量下降。排查发现:随着新数据的加入,向量分布发生了偏移,原来的索引参数不再适用,召回率从96%降到了89%。
解决方案:建立持续的质量监控体系——
- 定期采样查询,人工标注答案正确性
- 监控召回率、首位准确率、平均延迟等指标
- 当召回率下降超过5%时,触发索引重建或参数调优
金句:RAG系统的质量不是上线时一次性保证的,是需要持续监控和改进的。
总结
这7个错误,有的是技术问题(维度匹配、相似度度量、索引参数),有的是工程问题(更新策略、质量监控),但核心都是一个:向量数据库不是"存进去就能查出来"的魔法盒子,它需要精心调校和持续维护。 如果你正在做RAG项目,对照这7条检查一下——你很可能踩了至少3个坑。