
摘要本文面向正在做企业知识库、客服问答、文档问答和内部资料助手的开发者复盘 RAG 项目从 Demo 到上线时最容易出错的环节文档清洗、切片策略、向量召回、关键词兜底、重排、引用展示、离线评测和线上日志。开篇RAG 的难点不是接入向量库而是让答案可信很多 RAG Demo 看起来很顺上传 PDF切片写入向量库用户提问后召回几段文本再让大模型组织答案。这个流程跑通并不难难的是上线后持续答得准、答得稳、答得可解释。我见过不少知识库项目演示时效果很好一接真实文档就开始翻车召回内容看似相关但答非所问答案说得很顺却找不到出处同一个问题换个问法结果差很多文档更新后旧内容还在被引用。所以这篇文章不讨论“哪家模型更强”而是从工程角度整理一套 RAG 知识库避坑清单。目标很明确让知识库不只是能搜到资料而是能稳定生成有依据的答案。一、先处理文档质量再谈向量检索RAG 的第一步不是 embedding而是文档清洗。很多知识库效果差不是模型不行而是喂进去的材料本身很脏。常见问题包括PDF 页眉页脚重复进入正文、表格被拆碎、目录和正文混在一起、扫描件 OCR 错字、同一份制度多个版本同时存在、附件里的编号和正文引用对不上。我的建议是给文档入库前加一个最小清洗流程提取正文、去掉页眉页脚、保留标题层级、记录来源文件、记录页码或章节、给每个片段生成稳定 ID。没有这些元数据后面即使召回成功也很难给用户可靠引用。二、切片不要只按字数要保留语义边界最粗暴的切片方式是每 500 字切一段重叠 50 字。这个方法能跑但经常破坏语义。比如一个制度条款被切成两半或者标题和正文分离召回时只拿到正文却不知道它属于哪个章节。更合理的策略是按文档结构切片标题、段落、列表、表格优先保留完整语义。如果文档格式比较规范可以先按标题层级切再对过长段落做二次切分。切片的核心不是长度而是“召回后能不能单独解释问题”。一个片段最好包含足够上下文同时不要混入太多无关内容。三、只靠向量召回不够关键词召回要保留向量检索擅长语义相似但不擅长精确匹配。很多企业知识库里有型号、合同编号、客户简称、内部系统名、产品编码这些信息向量化以后未必好找。所以我更倾向于混合召回向量召回负责语义关键词召回负责精确命中。两路结果合并后再去重、排序。例如用户问“DR-2026 试用额度怎么开”向量检索可能理解成“试用政策”关键词检索能直接命中 DR-2026。两者结合召回质量通常比单一路线稳得多。四、重排不是锦上添花是真实项目的分水岭很多 RAG 项目会一次召回 top 10然后直接塞给大模型。问题是 top 10 里经常有半相关内容模型会被噪音带偏。重排的作用是在初召回后重新判断“哪个片段最能回答这个问题”。哪怕不用复杂模型先做一些规则也有帮助问题关键词覆盖率、标题匹配、时间版本、文档优先级、片段长度、是否包含明确答案。真正上线时我通常会把召回拆成两层第一层尽量召全第二层尽量排准。宁可多花一点重排成本也不要把明显无关的内容丢给生成模型。五、答案必须带出处否则用户无法信任企业知识库和普通聊天最大的区别是用户不只要一个流畅答案还要知道依据来自哪里。建议每条答案都带引用来源文件、章节标题、页码或片段 ID。如果答案里涉及制度条款、价格、合同、交付范围引用更重要。这里还有一个细节不要让模型自己编引用。引用应该由系统根据召回片段生成模型只负责组织语言。否则很容易出现“看起来像引用实际上查不到”的问题。六、给模型明确边界找不到就说找不到RAG 最怕的不是回答少而是凭空补全。我会在系统提示词里明确要求只基于给定资料回答资料不足时说明缺少信息不要猜测制度、价格、合同条款必要时列出需要补充的文件。这类提示词看似保守但对企业场景更安全。用户宁愿看到“当前知识库没有找到依据”也不希望系统自信地给出错误答案。七、没有评测集就不知道优化有没有用RAG 优化不能只靠人工感觉。建议从真实问题里整理一组评测集常见问题、边界问题、容易混淆的问题、需要精确引用的问题。每次改切片、召回、重排或 Prompt 后用同一组问题跑一遍看命中率、引用准确率、拒答是否合理、答案是否过长。评测集不用一开始很大先做 30 到 50 条高频问题就很有价值。它能避免团队陷入“我感觉这版更好”的争论。一个最小可落地的检索流程下面这段伪代码展示的是流程不绑定具体向量库。重点是把清洗、混合召回、重排、引用和日志拆开而不是把所有逻辑塞进一个函数。def answer_question(question: str):cleaned_query normalize_query(question)vector_hits vector_search(cleaned_query, top_k30)keyword_hits keyword_search(cleaned_query, top_k20)candidates merge_and_deduplicate(vector_hits, keyword_hits)ranked rerank(question, candidates, top_k6)if not ranked or ranked[0].score 0.62:return {answer: 当前知识库没有找到足够依据建议补充相关文档。,references: [],}answer generate_answer(questionquestion,contexts[item.content for item in ranked],instruction只基于给定资料回答并保留出处。)return {answer: answer,references: [item.source for item in ranked],}我的实践记录我在整理 AI 调用和知识库工程化问题时会把一些实践记录放在 www.dreamrouter.top。这里不把它写成推荐只作为一个观察入口做知识库系统时可以顺手关注调用日志、模型消耗、失败率和召回链路是否可追踪。无论你用自研方案还是第三方工具真正要关注的是答案是否有依据问题是否能复盘优化是否有数据支持。结尾欢迎补充你的 RAG 踩坑经历RAG 项目上线以后最有价值的不是“接入了多少模型”而是能不能把企业资料变成可信、可追踪、可维护的问答能力。如果你也做过知识库评论区可以聊聊你遇到最多的是切片问题、召回问题、引用问题还是文档质量问题觉得这份检查表有帮助可以点赞、收藏后面我继续整理 RAG 评测和线上日志设计。