ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RAG落地六道分水岭:从流水线到可上线的关键细节

RAG落地六道分水岭:从流水线到可上线的关键细节 “RAG烂大街”这话我认一半。打开任何一个技术社区搜索RAG十篇有九篇是同一套流水线加载文档、文本切分、embedding、写进向量库、检索、丢给大模型。这套东西用Dify拖拽也能做用LangChain写几十行也能做甚至Ollama加个开源embedding模型纯本地也能跑起来。但我见过太多人把这条流水线跑通之后兴冲冲拿去测真实业务结果效果一塌糊涂问什么都答非所问引用来源驴头不对马嘴甚至知识库里明明有的内容它也答不出来。问题不在流水线本身而在流水线之外的六处细节。这六处才是真正区分一个RAG项目是“能演示”还是“能落地”的分水岭。1. 先认清人人都能搭的RAG流水线问题到底出在哪1.1 五步流水线为什么“烂大街”标准RAG流程简单得不像一个AI应用文档加载、文本切分、向量化、相似度检索、拼接上下文后交给大模型生成。框架层面早就帮你封装好了langchain4j easy rag这类项目更是把“Easy”写到了名字里跑通一个demo可能只需要半小时。这也带来一个副作用大量教程都停留在“怎么跑通”的层面把流水线本身当成了RAG的全部。于是文档加载用PDF就完事切分用固定长度就完事检索只看向量相似度就完事生成全靠大模型自由发挥。如果用户问的是“谁负责哪个部门”这种简单事实问题这套流水线勉强能看一旦涉及多条件筛选、时间先后、多文档交叉印证立刻现出原形。我把这种现象叫“流水线幻觉”你以为自己做了RAG其实只是搭了个玩具管道。真正的工程问题从来不在管道通不通而在管道里的每一站有没有做对。1.2 真正的瓶颈藏在流水线外从我的经验看一个RAG项目从“能演示”走到“能上线”差距基本集中在这六个地方文本切分方式、检索召回策略、多模态文档处理、知识冲突处理、生成阶段约束、评测反馈闭环。这六个环节彼此独立又互相影响。切分不好检索就召不回完整信息检索不准生成阶段再约束也会无米下锅冲突不处理模型只能随机挑一个来源回答评测不建整个链路永远在“感觉还行”和“惨不忍睹”之间反复横跳。所以后面我会按顺序把这六处逐一拆开每一处都会给出可落地的方案和参数不是讲概念。2. 分水岭一chunk切分决定知识库的上限2.1 固定大小切分的三个隐藏问题很多人一上来就用RecursiveCharacterTextSplitter按固定token数切块加上一点overlap就完事。这个方案跑demo没问题但到真实知识库就会暴露三个问题。第一语义被拦腰截断。比如一段技术文档里前半句是“该接口不支持直接修改”后半句是“如需更新请先删除后重建”固定切分很可能把这两句话分到两个chunk。用户问“接口怎么更新”时只检索到后半句模型就会一本正经地回答“先删除后重建”完全不知道前提是“不支持直接修改”。第二段落级别信息丢失。简历、合同、FAQ这类文档一个完整条目被拆成多个chunk后向量化时每个chunk都只有半个意思检索打分被稀释。实际效果就是多条件查询永远差一口气。第三结构性标记被忽略。Markdown标题、表格行、XML标签本身是有层级含义的。固定切分不会管这些结果就是“条款2.3”和“条款2.4”的内容混在一起模型回答时根本无法定位具体条目。我的建议很简单能用结构解析就用结构解析按文档本身的标题、段落、表格行来切。只有纯文本且毫无结构时才退回到固定长度并且chunk_size控制在256到512 token之间overlap在20到50 token之间。chunk不是越小越好太小上下文不完整太大检索噪声高。2.2 本地文本拆解工具怎么选很多人问“有没有本地的RAG文本拆解工具”答案是不仅有而且质量已经很好。我常用的三套unstructured支持PDF、Word、PPT、HTML能把标题和段落结构识别出来适合办公文档。marker/MinerU面向PDF的深度解析能处理双栏、表格、公式大模型训练语料很多就是这种工具洗出来的。LangChain里自带的各种Splitter适合已经切成纯文本之后做二次切分但不要指望它理解结构。选型时不要一上来追求最重的工具。我见过有人为了切几十个PDF引入一整套GPU服务做OCR结果大部分文档是文字版PDF完全没必要。正确做法是先抽样10份文档肉眼看一下版式复杂度纯文字单栏用unstructured就够了扫描版多栏加表格再上marker或OCR公式多还得考虑Mathpix。另外提一句切分结果一定要可视化检查。我会把切分后的chunk连同来源页码一起导出成JSON随机抽几个看内容是否完整尤其是表格和代码块。很多“检索不到”的问题根源不是embedding不行而是chunk里已经没有完整答案了。3. 分水岭二检索质量比embedding模型更值得投入3.1 向量检索不是万能药混合检索才是底线embedding模型把文本映射成向量然后算余弦相似度这是RAG最经典的检索方式。但它的短板也很明显语义表达层面相似不等于实际答案相同。比如“怎么申请年假”和“休假审批流程是什么”embedding可能觉得很像但答案出处完全不同反过来“这个月报销截止日”和“报销制度”字面差很远向量也可能错过。所以现在做RAG检索我基本不会只靠向量。混合检索是底线向量召回语义相近的文本BM25或TF-IDF这类稀疏检索保证关键词能精确命中。两边各有top-k结果后用RRFReciprocal Rank Fusion合并排序公式很简单score sum(1 / (k rank))k一般取60。这个方案几乎不增加成本但对“专有名词、编号、人名”这类精确匹配的提升非常明显。举个实际场景用户问“KB-2024-011号合同违约金是多少”如果只做向量检索embedding很可能把“KB-2024-011”当成噪声召回的是一堆“合同违约金”通用条款。加上BM25精确匹配”KB-2024-011“这个编号会单独贡献权重正确合同文本就能被捞回来。3.2 重排、查询改写和知识图谱把检索精度抠到极致混合检索之后如果top-5里仍然混着不相关内容就需要rerank。向量检索阶段用的是Bi-Encoder把问题和文档分别编码后再算相似度速度快但精度有限。rerank阶段换成Cross-Encoder把问题和文档拼在一起输入模型打分精度高一个量级代价是慢。所以常用做法是第一阶段召回50到100个候选第二阶段rerank保留top-5到top-10再喂给大模型。查询改写也值得做。用户口语化问题“上次说那个新政策还能用吗”直接拿原句去检索效果很差。可以先让大模型把问题改写成适合检索的形式“XX政策当前是否有效请提供最新版本发布日期”。多查询扩展也行一个用户问题扩展成三四个不同角度的检索词合并结果后去重。如果知识库是强关系的业务文档比如公司制度、产品FAQ、学术论文Ontology RAG的思路值得借鉴。它不是用向量库替代知识图谱而是把实体关系抽出来比如“张三 - 任职于 - A部门”遇到“张三在哪部门”这类问题先用图谱定位实体和关系再去文档里找细节。这能解决向量检索不擅长多跳查询的痛点代价是构建和维护图谱的成本不低。我的建议是先用混合检索加rerank跑一段时间如果大量badcase都是关系型问题再考虑引入图谱。4. 分水岭三图片和表格怎么进知识库才能被检索到4.1 先搞清楚“知识库能不能存图片”这个问题我经常被问“RAG知识库能存储图片吗”答案是能但要分清楚“存图片”和“让图片里的信息被检索到”是两回事。向量数据库本身可以存图片向量用CLIP之类的多模态模型把图片编码成向量然后拿文本向量去匹配图片向量。这条路在“以图搜图”或“图文问答”里成立但大多数RAG知识库的检索入口是文本用户的query是自然语言文档里的图片如果只存了视觉向量文本检索阶段根本碰不到它。日常项目里更务实的做法是把图片内容转成文本后入索引。常见的实现有三种一是对图片生成描述文本比如“产品维修步骤图打开底部盖板可以看到三个螺丝”二是对扫描件做OCR直接提取文字三是表格识别并转成Markdown保留行列结构。图片文件本身放在对象存储或本地路径回答时通过元数据把原图引用给用户这样既保证信息可检索又不破坏问答的文本链路。4.2 扫描件、公式、表格多模态落地的日常方案扫描版PDF和带图片的手册是RAG项目最容易翻车的地方。文字是图片的一部分不OCR就完全检索不到。我的处理顺序是表格优先段落其次复杂版式最后。表格用unstructured或专门的表格识别模型转成Markdown因为表格按行切块后每个chunk包含“表头该行内容”比如“项目 | 金额 | 负责人”非常适合事实类查询。扫描文字用PaddleOCR或Tesseract中文场景PaddleOCR效果明显更好但不建议直接拿OCR全文当chunk先做版面分析还原段落结构。公式和复杂排版要单独说。论文PDF里的数学公式普通OCR会转成一堆乱码。要么用Mathpix这类工具把公式转成LaTeX要么干脆在切分时把公式按图片处理检索到上下文后引用原图。不要把公式和正文硬塞进同一个chunk两者混在一起只会互相拖累向量质量。多模态嵌入模型比如CLIP不是不能用而是成本高需要额外维护一套图片向量索引对小规模知识库性价比很低。先做“图片转文字”这条路的ROI最高80%的图片类badcase都能解决。5. 分水岭四多份资料“打架”时知识库该听谁的5.1 知识冲突的三个典型来源一个真实的知识库很少只有一份文档。公司有旧版制度和新版制度官网产品介绍和销售培训PPT说法不一致网上抓取的内容和内部资料数据对不上——这些冲突如果不处理RAG就会随机抽风。第一类冲突是版本冲突最常见。制度文件永远有v1.0、v2.0甚至同一份PDF里前面写着“2025年起执行”后面附录还留着去年表格。第二类是口径冲突比如两份文档对同一指标的统计范围定义不同。第三类是模型固有知识与知识库冲突大模型预训练阶段记住的东西可能和你的私有资料矛盾这时候必须让知识库“压制”模型记忆否则模型会混合两份来源。5.2 冲突处理流程从元数据过滤到显式检测处理冲突的第一道防线是元数据过滤。每个文档入库时必须带版本号、发布日期、生效日期、来源类型。检索时强制要求version2.0或effective_date今天很多冲突根本到不了LLM那一步就被过滤掉了。第二道防线是给检索结果打来源标签。返回的每个chunk都附带文档ID、标题和更新时间Prompt里明确要求大模型优先引用标注为“最新生效”的文档并给出引用出处。这里有个细节检索阶段做rerank时可以把“是否来自同一文档”作为一个分组条件不要把五个chunk全部取自同一份过时文档。第三道防线才是显式冲突检测。当不同文档对同一问题的描述矛盾时可以离线定时跑一批冲突扫描把常见问题分别检索每个文档用LLM判断答案是否矛盾然后生成一个“冲突清单”人工确认。线上问答如果同时召回到矛盾内容最稳妥的做法不是让模型强行选边而是把两边的说法都呈现给用户并明确标注“资料A来自2023年版资料B来自2025年版当前以B为准”。这套流程不用一次性做完。先做元数据过滤和来源标注已经能消除大部分可见冲突显式检测等知识库规模大了再补。6. 分水岭五生成阶段不设防再好的检索也白搭6.1 约束生成让模型只在检索结果内说话检索做得再好生成阶段不做约束大模型照样会“自由发挥”。因为LLM天生倾向把问题回答得完整流畅知识库没有的信息它会用训练记忆补齐而这个补齐过程正是幻觉源头。我的Prompt里会固定三句话你只能依据上下文中的信息回答用户问题。如果上下文中没有足够信息请直接回答“知识库中未找到相关内容”不要编造。引用信息时标注来源编号如[1][2]来源编号来自上下文元数据。这层约束看起来简单但能明显降低幻觉率。同时把temperature调到0.1到0.3之间减少随机采样带来的跑偏。如果业务要求结构化输出再叠加JSON Mode或Function Calling让模型输出固定字段。有人担心“上下文不足就拒答”会降低体验这个担心是多余的。RAG的价值不是让模型什么都懂而是让模型在它该懂的地方精确、在不懂的地方诚实。我见过很多尬聊式回答用户问一个知识库里根本没有的问题模型绕了一大圈给出看似合理实则错误的答案最后用户彻底失去信任。6.2 拒答与引用RAG智能体最容易被忽略的底线当RAG升级成Agent能调用外部工具、能多轮推理时生成约束反而更容易失控。因为智能体可以把“找答案”的责任推给工具但工具返回结果不理想时它依然会尝试用自己的话补齐这就是RAG智能体最常见的翻车点。我的原则是工具结果不完整就不要继续往下编。比如智能体搜索到3条结果但只有1条跟问题相关正确的做法是只引用这1条或者明确告诉用户“只找到部分相关信息其余未在知识库中验证”而不是把3条模糊结果揉成一个看似完整的答案。引用溯源也要做成强制机制。每个回答后面跟着引用文档号和原文片段用户能点击跳转到源文档。这样即使答案错了用户也能确定错误发生在哪一环而不是对整个知识库失去信心。对内部知识库系统来说这种可信度比一次性答对更重要。7. 分水岭六没有评测体系的RAG只是demo7.1 从Dify、LangChain4j到Ollama工具选型要看最终目的工具层面现在很成熟关键是选对场景。Dify的知识库流水线适合快速验证可视化编排、自带检索调试界面业务人员也能看懂。LangChain4j easy rag适合Java技术栈的团队集成Spring Boot很顺。Ollama加开源embedding模型适合本地部署和隐私敏感场景比如ollama pull bge-m3做中文向量ollama pull qwen2.5做生成再配一个Chroma或Milvus就是一个能跑的简易本地RAG知识库零基础教程也确实可以直接复现。但工具选型不是分水岭评测才是。我为什么这么说因为Dify和Ollama都只是把流水线拼起来真正决定RAG效果的是你往里面放了什么数据、用什么标准判断好坏。很多项目挂在“模型换了好几个都一样差”其实是评测体系缺失导致问题被归因到错误环节。7.2 用RAGAS和人工评测集把质量变成可量化指标我的建议是每一个RAG项目从第一天起就建一个评测集。数量不用多50到100条真实问题就够了每条问题配上标准答案或判断标准。然后每次调整切分、检索、Prompt都跑一遍评测集对比指标变化。业界常用的RAGAS评估框架有三个核心指标忠实性答案是否完全基于检索上下文、答案相关性是否回答了用户问题、上下文相关性检索到的chunk是否包含答案。前两个是生成阶段第三个是检索阶段。这三个指标能快速暴露瓶颈在哪一层上下文相关性低说明检索没召回忠实性低说明生成没约束答案相关性低说明整体就问歪了。这套体系看起来像“额外工作”但它能救你于水火。我踩过最深的坑是花了两周调embedding和chunk自我感觉良好直到做了评测才发现失败案例90%集中在“多条件查询”上跟embedding无关是切分把条件拆散了。没有评测集这半个月的力气全白费。工程上还要加一个坏case追踪机制。线上问答日志里把“用户问题、检索到的chunk、生成答案、用户是否点踩”记下来每周挑几个典型badcase回归到评测集让评测集越养越贴近真实场景。很多团队只做上线前的评测上线后就放任自流这是不对的知识库数据更新后评测集也应该跟着更新。8. 最后一处心得把RAG当产品做而不是当脚本跑如果只能给你一条建议我希望是从一个文档加十个问题的最小闭环开始。不要一上来就接几十个知识库数据源、选好几个向量库、部署三套模型。先把一份真实业务文档切成像样的chunk用混合检索召回用Prompt约束生成再用十个真实问题验证效果。看看这十问里有多少能精确引用来源回答、有多少因为知识库没内容而诚实拒答。这个最小闭环跑通了再把切分规则扩展到更多文档类型把检索从单路扩展成混合检索加rerank把评估集从十条扩展到上百条。RAG从来不是一步到位的魔法它是一条需要反复调节的链路。那六处真正的分水岭不是在流水线上多写几行代码而是你愿不愿意在每个环节都停下来问一句这里到底有没有做对。我自己在这条路上栽过的跟头几乎都出在“觉得已经跑通”的那一刻。所以别急着炫耀那条闪闪发光的流水线先去跑一遍评测集把那些答错的case一条一条打开看你会很快找到自己的分水岭。
返回列表