返回博客
·AI技术

RAG 落地踩坑记:我花了三个月才搞明白的事情

RAG 系统落地过程中的十大坑:文档切块策略、embedding 选型、混合检索、查询改写、防幻觉等实战经验总结。

#RAG#LLM#向量数据库#AI工程化

# RAG 落地踩坑记:我花了三个月才搞明白的事情

去年我开始做公司的 RAG 系统,目的是给客服团队做一个能回答产品问题的 AI 助手。

听起来很简单对吧?检索增强生成,不就是把文档切块、embedding、检索、喂给 LLM 嘛。

我花了三个月,踩了十个以上的坑,才跑出一个能用的系统。今天把这些坑整理出来,希望其他人能少走弯路。

坑一:文档切块不是越细越好

刚开始我把文档切成 500 字的块,觉得越细检索越准。结果呢?检索出来的内容碎片化严重,LLM 拼不起来完整的上下文。

后来改成 1000-1500 字,配合重叠 200 字的方式,效果明显好了。关键是要让每个块有**完整的语义**,而不是一段被截断的文字。

经验:**切块策略取决于你的文档类型**。技术文档可以切细一点,产品手册这类需要连贯上下文的,切大块更好。

坑二:embedding 模型选错了,后面全白搭

我一开始用了 OpenAI 的 text-embedding-ada-002,效果还行但贵。后来换成 BGE-M3,免费且支持多语言,效果居然更好——因为我们中文文档多,ada-002 对中文的理解一般。

如果你主要处理中文,**不要迷信 OpenAI 的模型**。BGE、Moka-Embedding 这些国产模型在中文场景下表现更好,而且便宜得多。

坑三:向量数据库选型纠结了很久

最后选了 Qdrant,原因是它支持 sparse-dense hybrid search(稀疏+稠密混合检索),这对我们的场景特别重要。

纯向量检索有个问题:**同义词问题**。比如用户搜"退款",但文档里写的是"退货退款流程",纯向量相似度可能匹配不到。

Qdrant 的 hybrid search 结合了 BM25 和向量检索,"退款"能匹配到包含"退货退款"的文档,准确率提升了至少 30%。

坑四:没有做查询改写

这是我最后悔没早点做的事。

用户的问题往往很简短,比如"怎么退货"。如果直接拿这个问题去检索,很难找到高质量的答案。

加了查询改写后,效果明显改善。我把用户的问题先喂给 LLM,让它生成 3-5 个相关查询,然后用这些查询去检索,最后去重合并结果。

代码大概是这样:

rewrite_prompt = """

将用户问题扩展为多个相关检索 query,用于知识库检索。

用户问题:{question}

要求:生成3-5个不同角度但相关的查询,每个查询不超过20字。

只输出query列表,每行一个。

"""

这一步几乎零成本,但效果提升很明显。

坑五:prompt 里没告诉 LLM "不知道就说不知道"

一开始我的 system prompt 是:"你是一个客服助手,请根据检索到的文档回答用户问题。"

结果 LLM 会在检索结果不相关时,**强行编一个答案**。客服同事反馈说有次用户问"能不能开发票",文档里完全没有相关内容,但 LLM 回答"可以开增值税普通发票"——实际上是错的。

改成:"请仅根据检索到的文档回答。如果文档中没有相关信息,明确告诉用户'我无法从现有资料中找到答案',不要编造信息。"

问题彻底解决了。**这一行改动,比调优整个检索 pipeline 都重要。**

坑六:没有做答案的来源溯源

用户问完问题后,最关心的是"你这个答案从哪来的"。一开始我没做溯源,直接返回 LLM 的回答。用户不信任,客服同事也经常被怼。

后来在返回答案时,附带了来源文档的标题和片段引用。用户可以看到答案的依据,信任度明显提升。

技术上,只需要在检索结果里保留 doc_idchunk_text,在生成答案时把引用信息拼进 output 就行。

总结

RAG 看起来简单,落地的时候全是细节。我的经验是:

  • 切块策略要按文档类型调整,不要一刀切
  • 2. embedding 模型选对的,不要选贵的

    3. 混合检索比纯向量检索效果好得多

    4. 查询改写几乎是必选项

    5. prompt 里一定要限制 LLM 不要编造

    6. 来源溯源是建立信任的关键

    如果只能做一件事,我推荐做第 5 条——**限制 LLM 不要编造**。这个问题不解决,其他优化都是锦上添花。


    *作者是一个被 RAG 毒打过的后端工程师,目前正在努力成为一个"懂点 AI 的传统程序员"。*