ARTICLE DETAIL

资讯详情

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

RAG实战:用Ollama和LangChain4j打造不胡说的智能客服机器人

RAG实战:用Ollama和LangChain4j打造不胡说的智能客服机器人 客服这个领域我见过太多“看起来很聪明一开口就翻车”的机器人。同样的问题丢给 RAG 体系没搭好的机器人它能面不改色地答出一个正确率堪忧的答案——用户问一句“我上周买的手机为什么还没发货”它甚至能信誓旦旦地说“您的订单已送达感谢您耐心等待”。这不是技术不行是产品做错了方向你让一个什么都不记得的模型去回答一个需要查业务系统才能知道答案的问题它不编才奇怪。更早的时候流行做法是把 FAQ 直接塞进提示词。问题是一个中型电商的售后FAQ就有几百条prompt 根本塞不下塞下了效果也差模型会被无关条目干扰回答得前言不搭后语。后来大家开始做微调成本高不说昨天刚上架的新品说明它照样不知道。直到 RAG 出现这些问题才真正有一个工程上说得过去的解法。这篇文章我基于一个真实落地的客服机器人项目把 RAG 的底层原理、技术选型和完整工程实现拆开讲清楚内容覆盖文本拆解、向量检索、Ollama 本地部署、LangChain4j 集成、常见故障排查适合正准备做智能客服、知识库问答或者单纯想把 RAG 从“看得懂”变成“跑得通”的朋友。1. 为什么客服机器人总会“一本正经地胡说八道”1.1 幻觉不是 bug是模型的默认行为要理解 RAG 为什么能解决客服机器人的胡说八道问题得先搞清楚一个概念大模型为什么会捏造事实答案有点扫兴——它并没有主观意愿要骗你它只是在做一件极其机械的事情给定前面的文本预测下一个最有可能出现的词。你问“我们公司的退换货政策是什么”在模型眼里这不是一个需要去查数据库的问题而是一个“根据训练时见过的海量文本找出最通顺最常见回答模式”的任务。问题就在这你的公司、你的产品、你的售后政策模型在训练时大概率没见过。它没有这个事实就只能在“长得像”的文本里找一种听起来合理的回答方式。比如它见过无数电商的退换货政策都是“7天无理由退货”那它回答你的时候就会默认你的政策也是7天。如果你们的实际政策是“生鲜类不支持退换”它自然就错了。这种错误在 AI 领域有个专门的词叫“幻觉”更准确一点叫“忠实性幻觉”——模型不是乱说它是在用一个通用模式顶替你真实的数据。这里有一个关键认知幻觉不是 bug而是模型的默认行为。大模型天生就会泛化泛化在开放域闲聊里是优点在客服场景里是灾难。客服需要的是固定、准确、可控的信息它恰恰需要模型“别太灵活老实照抄”。这个需求跟模型天性是对着干的所以你没法靠“多骂它两句”来解决问题得从机制上给它一个事实来源。1.2 闭卷考试与开卷考试理解 RAG 的最佳类比我一般跟团队里新来的同学解释 RAG用的一个很土的类比大模型本身的问答相当于闭卷考试RAG 相当于开卷考试。闭卷考试里学生只凭脑子里的记忆答题。记忆里有你们公司的政策运气好答对了记忆里没有要么空着要么编一个看起来像模像样的答案。绝大多数模型的默认行为是后者——它倾向于编因为“编一个通顺的答案”比“承认我不知道”在概率上得分更高。RAG 做的事情就是提前告诉它“这次考试可以带资料”。开场先给它一摞资料退换货政策、订单查询指南、物流说明、常见问题。它答题的时候先把资料翻到对应那一页把那段文字摆在面前然后照着这段文字组织语言。它不会脱离资料瞎说因为你的指令是“只能根据提供的资料回答”一旦资料里没有它应该老实说不知道而不是继续编。这个类比看起来简单但准确覆盖了 RAG 的三个核心问题资料从哪来知识库建设怎么快速翻到对的那页检索怎么照着念还不跑偏生成后面所有工程细节本质上都是在优化三个环节中的某一个。1.3 RAG 的最小工作流程索引、检索、生成把 RAG 拆到最底层就是三个阶段。第一个阶段叫索引Indexing。把原始资料文档——不管格式Word、PDF、Markdown、Excel 都常见——先做格式化处理拆成一篇篇文章级别、段落级别的文本片段然后把每段文本转换成向量也就是一组几百维的数字最后把这些向量连同原始文本一起存进向量数据库。这一阶段做的事情相当于把资料库编成一本带目录、带页码的书。第二个阶段叫检索Retrieval。用户输入一个问题系统先对问题进行同样的向量化处理然后到向量数据库里找最相似的 Top-K 个文本片段把跟这个问题相关的资料片段捞出来。这里的关键指标是召回率该找的资料是否都找出来了有没有把最关键的那一段漏掉。第三个阶段叫增强生成Augmented Generation。把用户问题、检索到的资料片段、一条精心设计的系统提示词一起交给大模型让模型基于资料给出答案。这个阶段最关键的是提示词约束——你要明确告诉它“只能依据提供的资料回答资料中没有的内容必须明说不知道”。三个阶段各有各的坑索引阶段要处理文本切分检索阶段要调相似度阈值生成阶段要设计提示词约束。任何一个环节出问题最后用户感受到的都是“这个机器人又在胡说八道”。这也是为什么很多人照着教程搭完 RAG一测效果还是拉胯——不是原理有问题是细节没做透。2. 项目设计与技术选型什么样的客服机器人值得做2.1 需求拆解客服场景下要回答的问题分三类开始写代码之前我习惯先把需求盘清楚。一个典型的电商或企业客服机器人用户问题大致可以分成三类。第一类是固定知识类比如“你们发货用哪家快递”“售后电话多少”“发票怎么开”。这类问题在 FAQ 里有标准答案答案几乎不用变关键是要准确命中并完整输出。第二类是动态数据类比如“我的订单到哪里了”“这笔退款什么时候到账”。这类问题答案不在知识库而在业务系统里需要查接口拿数据RAG 管不着通常要单独接一个工具调用Function Calling或工作流。第三类是模糊兜底类比如“东西坏了怎么办”“能不能便宜点”。这类问题需要模型理解用户意图结合政策条款给出引导性的回答。RAG 主要解决第一类问题的精确命中在第三类问题里起到提供依据的作用。第二类问题需要跟业务系统打通那是另一套工程。我建议大家做项目时先把边界切开不要幻想一个 RAG 能搞定所有问题否则你会陷入一个尴尬境地知识库里的内容答得不错但用户真正高频问的订单状态反而答不了落地效果自然打折。2.2 技术栈选型为什么选 Ollama 和 LangChain4j这次客服机器人项目我选的技术栈是Ollama 管本地大模型Embedding 模型负责向量化向量数据库用 Chroma编排框架选了 LangChain4j。这套组合不是随手挑的主要考虑四个因素。第一是数据隐私。客服知识库里往往有产品价格、供应链条款、客户纠纷处理口径很多公司不希望这些内容发到云端大模型接口上。本地部署意味着数据不出内网这一点在企业里经常是一票否决项。第二是成本结构。调用云端模型按 token 收费客服机器人每天几千次调用加上知识库索引阶段反复重跑成本并不低。本地部署前期投入一台带 GPU 的服务器或者一台配置足够的开发机后面基本没有边际成本适合知识量中等、调用量稳定的场景。第三是可控性。本地部署能随意调整模型版本、提示词、采样参数甚至断网环境下也能跑。这对生产系统非常重要。第四是生态成熟度。LangChain4j 是 Java 生态里相对成熟的 RAG 框架如果团队开发语言偏 Java用它可以少写大量胶水代码。Python 生态当然有更好的选择但企业客服后端一般就是 Java 那一套统一技术栈会让部署运维更顺。组件选型上我用 Ollama 来做模型管理和推理没有直接用 transformers 写推理脚本因为它把模型下载、量化、显存管理、HTTP 服务全包了。日常开发调试一条命令就能起模型服务非常适合“先把功能跑通再逐步优化”的节奏。2.3 各组件职责与数据流这套系统里每个组件的职责边界很清晰用表格看会更直观。组件职责选型说明Ollama提供 LLM 推理服务和 Embedding 服务安装简单、模型管理方便适合本地部署Embedding 模型把文本映射为高维向量选支持中文的模型如 bge-m3向量数据库存储向量与原始文本提供相似度检索轻量方案可先选 Chroma生产考虑 MilvusLangChain4jRAG 流水线编排、提示词组装、对话记忆Java 生态与后端服务集成方便业务系统接口动态数据查询订单、物流等通过工具调用打通与 RAG 并行数据流大致是管理后台把 FAQ 文档上传系统清洗后拆成片段每段文本生成向量存入向量库。用户提问后端拿到问题先向量化到向量库检索 Top-K 片段再把问题、片段、系统提示词一起丢给本地大模型模型输出答案返回前端。若有动态数据类需求会额外触发业务接口查询结果同样作为上下文交给模型。链路不复杂但每个环节都有优化空间。3. 核心细节拆解决定 RAG 效果的几个关键节点3.1 文本拆解给知识库“切菜”的学问RAG 的第一步是文档切分很多人会忽略这个环节直接把一篇几万字的说明书扔进向量库结果检索时召回的全是大段落模型看着一堆语义相近的文本根本分不清哪句才是用户要的答案。文本切分做得好不好直接决定检索精度的上限。切分的核心是两个参数chunk size 和 chunk overlap。chunk size 是每个文本片段的长度一般按 token 计算中文场景大致可以粗估为 1 个汉字约等于 1~2 个 token。片段太长语义太杂检索命中后噪声多片段太短语义不完整模型上下文里缺少背景信息。以 FAQ 和产品说明这类知识库来说我常用的经验值是 500~800 token也就是一次回答能覆盖的信息量。overlap 是相邻片段的重叠长度通常设为 chunk size 的 10%~20%作用是避免在切点时把一个连续语义单元硬生生拆断——比如一句话被切一半后半句在下一个片段开头检索时可能只召回前半部分答案就缺了一条腿。切分策略还要看文档结构。纯文本可以按固定长度切但更聪明的做法是先按 Markdown 标题、PDF 章节、目录层级分段保持标题和正文属于同一个片段。我给知识库做切分时会先写一个基于正则的章节识别器把“3.1 退换货政策”这种小节标题识别出来以小节为单位再按长度切。这样检索到的片段自带标题上下文生成的答案准确很多。企业内部 wiki 类知识库尤其适合这种按结构切分的方式。至于本地文本拆解工具unstructured、LlamaIndex 的 loader、LangChain 的 splitter 都能用甚至自己写正则也完全可行没必要一上来就上重工具。3.2 Embedding 向量化语言变成数字之后发生了什么文本切完就要把每段文字变成向量。embedding 模型做的事情是把一段文本映射到一个几百上千维的稠密向量空间。在这个空间里语义接近的文本向量距离也近。“手机退货政策”和“智能手机退换规则”这两句话表面用词差别很大但向量距离会很近这就是向量检索能做语义匹配的原因跟关键词匹配完全是两回事。选 embedding 模型要注意三点中文效果、向量维度、本地能否跑。中文场景用纯英文训练模型效果会很差一般选 bge-m3 或类似的中文模型。向量维度影响存储和计算开销维度越高精度理论上越好但对本地部署不友好。Ollama 和 HuggingFace 生态都有预训练 embedding 模型Ollama 还提供统一接口调用拉下来就能用。这里提醒一个新手容易忽略的点embedding 必须保证“库里的文本”和“用户的问题”用同一个模型生成。如果构建知识库时用 A 模型检索时用 B 模型两个模型的向量空间完全不一致相似度计算就相当于拿尺子量两个不同坐标系里的距离结果毫无意义。这个坑我刚开始做 RAG 时踩过后来养成了习惯把所有模型版本记录到配置里换模型就全量重建索引。注意换 embedding 模型之后必须重建向量索引。不同模型产出的向量没有可比性这是 RAG 工程里最容易犯的低级错误。3.3 向量检索召回是 RAG 效果的天花板检索阶段的核心数学概念是向量相似度。最常用的是余弦相似度也就是两个向量夹角的余弦值范围从 -1 到 1越接近 1 表示方向越一致。查询向量和文本向量夹角小意味着问题和这段文本语义最接近。工程实现上向量数据库会提前为所有向量建索引结构例如 HNSW 这类近似最近邻索引。这样查询时不用暴力比对全库几千上万个向量能在几十毫秒内返回最相似的 Top-K 条结果。这里的 K 值很有讲究太小容易漏资料太大又让模型面对太多无关上下文。我做客服项目一般先设 K4再根据线上测试调整。召回率我想再强调一次理论上RAG 的上限由检索决定。如果检索阶段都没把正确答案对应的片段找出来那生成模型再强也不可能给出正确回答。所以排查问题时一定要先看检索结果而不是先怪模型。调试时我给系统加了一个“检索结果可视化”页面每条用户问题都能看到召回了哪几段文本这比黑盒猜心好一百倍。3.4 上下文组装与提示词设计让大模型“照着材料说话”检索完成之后要把用户问题、检索到的片段、系统提示词组装成一次完整的模型请求。提示词怎么写这里有一套可以直接用的模板思路。系统提示词的核心是划边界。举个例子“你是一个客服助手请严格依据下面提供的资料回答问题。资料中没有的内容请直接说明资料中未提及不要猜测不要编造。”这句话看着简单却是抑制幻觉的关键防线。我见过太多项目提示词写得松松散散只说“请帮助用户解决问题”模型自由发挥空间一大立刻开始编。你给的约束越明确模型跑偏的概率越低。用户消息的组装方式同样重要。很多人把所有片段堆在一起中间没有分隔模型经常抓不住重点。我习惯用明显的标签给每段资料分区比如用方括号标注来源类似“资料1退换货政策运营手册第3节”然后在提示词里要求模型回答时注明依据了哪份资料。这样不仅答案更准还能在售后排查时快速定位哪条知识出了问题。3.5 顺带说明RAG 知识库到底能不能存图片好多人问过“RAG 知识库能存图片吗”我明确回答纯文本 Pipeline 存不了图片的语义但工程上可以做变通。向量数据库本身存的是向量和文本没法直接对图片进行语义检索除非引入多模态 embedding 模型把图片也编码成向量那就相当于把 RAG 升级成多模态 RAG复杂度会上一个台阶。客服场景更务实的做法是存“引用关系”。图片文件放对象存储或本地目录知识库里只存图片的描述文本、文件名、路径字段。检索到对应描述文本时答案里带上图片路径前端就能展示给用户。比如一张“安装步骤图”知识库存一段“将螺丝拧入底部见说明书图3-2”检索命中后顺带返回图3-2的链接。这不算多模态但工程落地完全够用。4. 完整实操从零搭一个不会乱说的本地 RAG 客服机器人4.1 环境准备模型下载与本地服务启动动手前先把环境准备好。我以一台 16GB 内存的开发机为例这套配置跑小型模型足够。第一步安装 Ollama它支持 Windows、Linux、macOS。安装完成后终端里执行下面两条命令分别拉取对话模型和 embedding 模型。ollama pull qwen2.5:7b ollama pull bge-m3qwen2.5:7b 参数量 7B量化为 Q4 后在本地推理速度尚可中文能力在开源模型里属于第一梯队。bge-m3 是 embedding 模型中文效果稳定而且是多语言的后续如果知识库涉及英文也能用。模型下载完成后验证服务是否正常ollama list curl http://localhost:11434/api/tags看到模型列表返回说明服务就绪。这里要提醒一句Ollama 的模型文件较大拉取时间跟网络环境有关不同机器的下载体验差异不小耐心等待即可。默认监听 11434 端口不需要额外改配置。4.2 知识库构建从原始文档到向量库为了演示我准备了一个迷你客服知识库内容是模拟一家电商公司的退换货和物流 FAQ退换货政策7天无理由退货、生鲜不支持退换物流说明默认顺丰、偏远地区加时发票说明电子发票自动开具第一步用文本加载器读入所有文档。LangChain4j 里有现成的 Document 加载器支持文件系统路径和 URL。我习惯把所有知识文档放在一个统一目录加载时遍历目录即可。第二步做切分。策略是“标题优先再按长度兜底”。LangChain4j 支持按正则分割文档我自定义了一个规则遇到“第 N 条”或一级标题就断开没有标题的正文按每 600 token 切一段overlap 设为 80。第三步生成向量并入库。LangChain4j 里封装好 EmbeddingModel 后直接对每段文本调用 embed得到向量列表再写入向量存储。我用 Chroma因为它支持本地持久化重启不丢数据对演示项目刚好。核心代码用 Java 写出来大概是这样// 加载文档 ListDocument docs FileSystemDocumentLoader .loadDocumentsRecursively(Paths.get(/knowledge)); // 切分600 为块大小80 为重叠 DocumentSplitter splitter DocumentSplitters.recursive(600, 80); ListTextSegment segments splitter.splitAll(docs); // 向量化并入库 EmbeddingModel embeddingModel OllamaEmbeddingModel.builder() .baseUrl(http://localhost:11434) .modelName(bge-m3) .build(); EmbeddingStoreTextSegment store new ChromaEmbeddingStore(...); for (TextSegment segment : segments) { Embedding embedding embeddingModel.embed(segment.text()).content(); store.add(embedding, segment); }知识库这样就建好了。有个细节注意入库前把空白字符、多余换行清理一下不然向量化会产生噪音后面检索命中率受影响。我初始化之前都会先做一轮文本清洗成本很低收益却很实在。4.3 实现问答链路检索加增强生成知识库就绪之后核心问答链路就三行逻辑把用户问题向量化到向量库检索 Top-K把结果组装进提示词发到本地大模型。String question 生鲜食品能退货吗; Embedding queryEmbedding embeddingModel.embed(question).content(); ListEmbeddingMatchTextSegment matches store.findRelevant(queryEmbedding, 4); // 组装上下文 StringBuilder context new StringBuilder(); for (int i 0; i matches.size(); i) { context.append(资料).append(i 1).append() .append(matches.get(i).embedded().text()).append(\n); } // 调用 LLM ChatLanguageModel chatModel OllamaChatModel.builder() .baseUrl(http://localhost:11434) .modelName(qwen2.5:7b) .temperature(0.2) .build(); String prompt 你是一个客服助手。请严格按照下面提供的资料回答问题。 资料中没有的内容直接说明资料中未提及不要猜测不要编造。 资料 %s 用户问题%s .formatted(context, question); System.out.println(chatModel.generate(prompt));注意我把 temperature 设成 0.2不是 0。设成 0 确实更稳定但太快会导致相同问题来回复同一套措辞用户会觉得很机械0.2 在稳定性和自然度之间比较均衡实测下来对客服场景足够安全。这里还有一个片段去重的细节很多 FAQ 答案共用比如“质量问题请联系售后”这句会出现在多个片段里。不做去重模型会把同一句话当多条资料反复读浪费上下文窗口还容易引发前后矛盾。我的做法是按文本内容的哈希值去重代码里一行判断就能搞定。4.4 联调验证用边界问题测出真实水平代码写完不要急着部署先用测试用例把机器人反复轰一遍。我习惯准备三类测试问题标准问法、模糊问法、知识库范围外的问题。标准问法就是直接命中 FAQ 的问题比如“退货流程是什么”期望准确命中。模糊问法是用户口语化提问比如“东西不想要了能给退不”这个问题知识库里没有原句完全靠向量语义匹配主要检验 embedding 和切分策略。范围外问题是“你们公司什么时候上市”知识库里没这个信息模型应该明确回答“资料中未提及”而不是编一个时间。实测第一版时我的切分策略在模糊问法上翻过车“东西不想要了能给退不”召回到的片段全是价格和物流政策唯独没召回退货政策。排查后发现是检索 K 值太小而且退货政策片段太长语义被稀释了。后来把退换货政策按条款再拆细一级片段从 600 token 缩到 400 token召回率立马上来了。这个案例挺典型检索决定天花板切分决定地基。5. 常见问题与排查技巧实录5.1 检索不到相关内容先怀疑索引再怀疑参数最典型的故障是知识库里明明有答案模型却说找不到。排查顺序我建议这样先看检索结果里到底有几段。如果召回为空大概率是 embedding 模型不一致或者知识库根本没成功入库——查一下向量条数就能确认。如果召回有内容但答案还是不对那就是切分和 K 值的问题。切分上的问题主要是片段过碎或过整。片段过碎比如一句话拆到三个片段里任何一个单独片段都不含完整答案片段过整比如整节政策塞一个片段512 长度上下文可能放不下检索出来了模型也没法完整引用。调整经验FAQ 类知识平均片段 300~500 token长文档类知识可以到 600~800 tokenoverlap 始终维持 10%~20%。K 值方面我踩过的教训是K 太小漏召回K 太大噪声淹没有效信息。如果答案总在犹豫把 K 从 4 改成 6 或 8 再看如果答案啰嗦、跑题那可能是 K 太大。调参没有固定公式最好每次只改一个变量对照测试集看效果不要同时动三四个参数。5.2 回答接近但不够准确多数是上下文组装问题有一种情况很磨人模型确实用了检索到的资料但答案细节不对把“7天”说成“9天”。这种问题十有八九出在上下文组装上。原始文本里可能混有历史修订记录、不同版本的政策条款模型抓错了重点。解决思路是给资料打标注并让模型优先采用最新版本。我在知识库里为每份文档增加元数据字段比如“版本号”“生效日期”“适用范围”检索时把元数据一并带入上下文。提示词里明确“如果有多个版本优先采用生效日期最近的版本”。这条在企业知识库里特别重要因为业务文档经常更新旧版本不会删语义相近的新旧条款会同时被检索出来模型就容易混淆。另一个细节是长片段里答案藏在后半段模型的短上下文注意力有限。这种情况可以把提示词里的资料条数减少比如 K3同时要求模型先引用“资料片段中与问题直接匹配的原句”再展开解释能明显减少细节偏差。5.3 中文场景的专属问题边界、符号与模型能力中文 RAG 有一些专属的坑。第一是切分时最好按句号、问号、感叹号这种句子边界优先而不是硬按长度切否则很容易把一个完整句子从中间劈开语义残缺。第二是中文文档里的全角符号、换行符、特殊空格会干扰 embedding入库前要做一轮标准化。第三是模型中文能力差异很大。同一套 RAG 流水线换个中文语料好的模型效果天差地别。我在本地试过几个 7B 模型国产模型在中文客服场景明显更稳不仅理解准回答也更像真人。如果你的目标用户是中文用户不要迷信英文大模型优先考虑 Qwen、GLM 这些本土模型。另外中文里有一个“同义词现象”要留意。知识库写“退换货”用户问“换货”这两个词向量距离可能不算近因为语义上下文不同。为了缓解我在知识库里做了简单的别名扩充每条 FAQ 增加若干个口语化问法相当于提前把用户可能的不同表达写进资料库。这个工作量不大但对命中率的提升非常明显。5.4 资源与性能优化本地部署的容量规划本地部署最直接的瓶颈是显存和内存。Ollama 加载模型时会做量化7B 模型在默认 Q4 量化下内存占用约 4~5GBembedding 模型几百MB跑起来不算夸张。但如果有多个模型同时加载16GB 内存会很紧张建议按实际负载只常驻一个对话模型。推理速度方面纯 CPU 上跑 7B 模型一个回答可能要十几秒用户根本等不起。实际落地时要么用带 GPU 的机器要么换更小的量化版本比如 qwen2.5:3b。速度能提升不少而且在客服这种短答案场景准确率下降不明显。我的个人经验是客服答案普遍不超过几十个字3B 模型配合好的检索效果完全够用如果回答长文本再考虑 7B 以上。向量库规模也要管理。几千条文本的向量全文检索内存消耗不大但知识库到几十万条时检索延迟就会上升。那时需要加一层粗排比如先用关键词过滤再做向量精确匹配。这些属于“从能用变好用”的范畴是后面要聊的进阶话题。6. 从能用走向好用RAG 的瓶颈与进阶方向6.1 提升召回质量混合检索与重排序RAG 最常见的瓶颈就是召回。向量检索擅长语义匹配但对精确词和专有名词不够敏感。用户问“订单号 SO20240501 被拦截了”向量检索可能因为这条记录在知识库里只是旧例召回效果不好。这时候需要引入 BM25 这类关键词检索把向量检索和关键词检索的结果做加权融合这就是混合检索。混合检索的思路是把两路结果合成一路再交给下游。常见做法是把召回数量放大比如先召回到 Top-20关键词和向量各取一部分合并去重后用重排序模型Reranker基于用户问题对候选文本重新打分取前几名作为最终上下文。重排序模型对“问题-文档”做语义交叉编码精度比单独 embedding 高一个档次代价是需要额外算力。这套链路对客服项目非常有用。FAQ 类问题关键词价值高混合检索命中率提升明显复杂业务描述类问题重排序能纠正切分带来的碎片噪声。如果你前面已经把单路向量检索调到 80% 的准确率加上混合检索和重排序能朝 95% 走。这是 RAG 工程里性价比最高的一步进阶。6.2 从松散文档走向结构化知识Ontology RAG 与 GraphRAG再往深一层知识库如果只是大段 FAQ实体与实体之间的关系是隐含的。用户问“哪些商品不能退”可能需要跨多条政策拼答案普通向量检索很容易漏。这个场景适合把知识库结构化用图再存一份商品节点、政策节点、类目节点节点之间连边比如“生鲜”连到“不支持退”这就是 GraphRAG 的思路。基于本体的 RAGOntology RAG更进一步预先定义业务领域里的实体类型和关系类型商品、类目、政策、渠道、时限然后用抽取模型从文档里抽取三元组构成一张知识图谱。检索时先从向量库召回相关段落同时根据问题涉及的实体到图里取出关联关系两者合并作为上下文。真正的业务知识往往藏在关系里这一步能把 RAG 从“资料查询”提升到“知识推理”。Ontology RAG 的落地成本不低需要投入人工梳理本体结构和关系抽取。我的建议是先用普通 RAG 跑通业务等发现跨文档问题占比变高了再考虑引入图结构。不要在项目初期就上重武器。6.3 客服场景的工程化补充多轮对话、权限与考核RAG 本身解决的是单轮问答的准确问题但客服场景还有几个单靠 RAG 解决不了的工程问题。第一个是多轮对话。用户说“那怎么退呢”这个“那”指代的是上一轮的商品如果每轮都把对话历史塞给模型上下文窗口很快爆掉。工程上要做对话状态管理把用户意图、关键实体、已确认的信息抽出来作为检索和生成时的补充信息。从这个角度看一个带检索、带工具调用、带状态管理的 RAG 系统本质上就是一个简化版智能体。第二个是权限控制。不同角色的客服看到的资料层级不同比如普通客服看不到仅限主管的纠纷处理口径。简单做法是在检索阶段按用户角色过滤文档元数据把权限判断前置到检索而不是生成阶段这样模型根本接触不到无权查看的资料。第三个是效果考核。客服机器人上线后要有评价指标我常用的是“引用准确率”也就是答案里引用的知识片段是否与标准答案一致。这个指标需要人工抽检配合但比光看回答“像不像”可靠得多。每次知识库更新后都跑一遍回归测试集防止改一条政策时影响其他回答。6.4 认清边界RAG 不是银弹它和微调要配合使用最后聊一个常被问到的取舍问题RAG 好还是微调好我说句实在话这不是二选一九成场景下两者是搭配关系。RAG 负责“新闻化”知识天天更新、来源需要可追溯、答案要可控这些场景 RAG 是首选因为它不用重新训练模型就能改知识。微调负责“风格化”和“能力化”让回答语气更像品牌调性、让模型学会处理特定表单或指令格式这些靠微调更彻底。RAG 给模型提供事实微调给模型规定行为两者并不冲突。在客服机器人项目里我的习惯是主链路用 RAG 保证答案正确再用一个很小的 LoRA 微调模型统一回答风格、学习业务语气。这样既不会因为微调导致知识过期也不会因为纯 RAG 导致回答生硬。边界划清楚之后整个系统的可维护性会好很多。最后再分享一个小经验给机器人加一个“这个回答靠谱吗”的反馈按钮用户点“不靠谱”时回传问答对定期人工复核。这比任何离线评测都更有价值。我的第一个客服机器人就是靠这一批批真实反馈一点一点把“不会胡说八道”这五个字做扎实的。技术方案再漂亮不如把真实场景里的坑一个个排干净。
返回列表