内部 RAG 落地实录:从 Dify 翻车到自建路由到知识图谱的心酸泪

<1> 背景 自动化测试代码维护这行干了挺久,以往基本是在和内部框架打交道,以往工作实属不难,只能说测试以及Debug比较耗时间精力 后来上面也想与时俱进一下,就想着结合AI搞点辅助我们工作的东西,想法是美好的 团队里有一套长期演进的内部工程体系,配置、脚本、规则和经验散在不同地方不同人。 新人要改...
内部 RAG 落地实录:从 Dify 翻车到自建路由到知识图谱的心酸泪
内部 RAG 落地实录:从 Dify 翻车到自建路由到知识图谱的心酸泪

<1> 背景

自动化测试代码维护这行干了挺久,以往基本是在和内部框架打交道,以往工作实属不难,只能说测试以及Debug比较耗时间精力

后来上面也想与时俱进一下,就想着结合AI搞点辅助我们工作的东西,想法是美好的

团队里有一套长期演进的内部工程体系,配置、脚本、规则和经验散在不同地方不同人。

新人要改一个东西,有时要问老同事;老同事也不一定每次都记得准,只能继续翻文件、搜历史、看代码。

于是很自然地想到:那就做一个 AI 知识库吧。

最初的预期很朴素:

  • 把文档、规范、经验整理进去
  • 用户用自然语言提问
  • 系统检索相关知识
  • 大模型组织答案

听起来没毛病,甚至很符合最初大家对 RAG 的想象。

但真正落地后才发现,内部业务知识和互联网公开文档完全不是一回事。

公开文档通常是"解释型"的:这个 API 怎么用、这个参数是什么意思、底层模块解释等。

我们的内部问题更多是"操作型"的:我要改一个现有流程、调整一个规则、关闭一个子项、增加一个步骤、定位一个历史遗留逻辑。

这两类问题看起来都叫问答,但需要的系统能力完全不同。

所以问题不是"能不能用 AI",而是"怎么让 AI按既定思路来理解"。

本地部署ai以及在vscode基础上做一个自己的业务汇总软件再基于cline改个有基础agent功能的插件,细节不赘述。

<2> 第一阶段:上了 Dify

当时的想法

Dify 嘛:

  • 文档丢进去
  • 切 chunk 做向量
  • 用户问问题,相似度召回
  • AI 回答

实际效果

  1. 各类实际术语听不懂
  2. AI拿到项目不知道从何开始,直接一顿召回一顿搜本地项目文件,实际各种答非所问完全靠大模型自己发挥

Dify 这套方案适合:文档类问答,知识相对固定,用户问法相对规范,需要一直自我调整

我们的问题是:业务实操类,问法千奇百怪,业务理解需要特定思路。
其实换个说法就是:把人对这项目各方面的理解思路等等抽成skills哈哈

但是细调用Dify软件就很不方便了,索性放弃Dify

<3> 第二阶段:自建路由

核心思路

先听懂意图,再谈检索

这一步其实不是先研究模型,而是先把自己平时遇到的需求拆开。

先把这些常见业务动作分出来,再针对每一类动作设计不同的处理路线。

然后再兼容用户真实问法。中文、英文、缩写、符号、口语表达都要算进去。如果不先统一到同一个意图,后面检索再准也没用。

最开始当然也有关键词规则,后来逐步加上 embedding 和语义分类。简单说,就是不只看用户用了哪个词,还要看这句话整体更像哪类需求。

为了提高稳定性,又加了一层小模型兜底。当前面的规则和语义分类都不够确定时,再让小模型辅助判断一次。它不是负责最终回答,而是负责把问题分到更合理的路线里。

再往后,就是把我们对项目的理解、业务维护经验、常见判断逻辑整理进 RAG。这个过程有点像把人的经验拆成一组组 skills:每类问题都有自己的判断方式、需要看的材料、不能踩的坑。

但它又不完全等同于传统 skills。传统 skills 分散在各处,后面维护起来容易散;RAG 这边有一个相对集中的知识入口,可以单独调路由,也可以单独调知识内容。对这种业务落地场景来说,反而更好维护。

<4> AI不走原定路线

路由做完后,又遇到一个很典型的问题:AI 有时不按你设计好的路线走。

很多需求其实只要进入对应路由,把输入拆好,再查对应知识,就能稳定完成。但模型有时会"觉得自己能行",上来就直接开始自己读文件、猜结构、自己组织答案。

还有一种情况是多轮对话。用户第二句明明是在补充上一句,打个比方比如"那把它改小一点",模型却把它当成一个全新的问题处理,完全不管历史上下文里的"它"是谁。

这类问题光靠提示词里说"请优先走 RAG"是不够的。因为模型一旦进入自由发挥状态,就很难保证每次都守规矩。

后来做法变成:先检测当前项目是否属于我们已知的业务项目。如果是,就在底层强制加规则,让它优先走固定 RAG 路线,而不是随便读文件和自由发挥。

这样做以后,系统不一定一下子变得非常聪明,但至少变得可诊断了。答错的时候可以看出来:是项目识别错了,是路由错了,是知识没召回,还是模型最后总结跑偏了。

<5> 人工汇总知识不够用易过期

走到这一步后,AI 已经能处理一些简单、固定流程的业务需求了。但新的问题也很明显:知识库不能只靠人工写。

人工总结的知识短期有用,但长期会遇到三个问题。

第一,维护成本越来越高。后续可能项目在变,文档也要跟着变,靠人手动同步迟早会漏,其实推广到别的项目也容易变。

第二,答案会逐渐不可信。知识写进去的时候是对的,不代表几个月后还对。内部项目最怕的不是"不知道",而是系统拿着过期知识自信地指导用户。

第三,模型有时会为了补上下文读太多内容。看似更努力,实际会增加 token 消耗和服务压力,而且读得越多,越容易把不相关内容混进来。

所以后面思路又变了:不能只把项目当成一堆文档,而要把它看成一张结构网。

一个业务对象可能关联配置、规则、动作入口、脚本、命令、上下游顺序。靠纯文本相似度去猜这些关系,不稳定,也浪费。

于是开始尝试走LangChain + neo4j路线把项目内条目切离结构抽取,再把这些关系放进图谱。
图谱不是为了替代 RAG,而是给路由结果提供更精准的背景补充:这个对象在哪里、它关联哪些东西、下一步该查哪类材料。

这样原本"靠模型自己理解项目"的问题,就变成了"先由系统把结构上下文准备好,再让模型基于这些上下文回答"。

(小小的吐槽一下:其实到图谱前这个就已经基本实现功能了,最核心最主要是上面觉得要图谱才放心,因为别人好像什么王道路线就是那么走的,没办法胳膊肘拧不过大腿不是吗手动滑稽

<6> 展示层也要自己做

结构抽取图谱建出来以后,本以为可以直接用数据库工具展示。实际又踩了一个坑。

neo4j数据库浏览器适合工程调试,不适合业务展示。比较好的图谱浏览能力都在企业版里,

普通版本虽然能证明"数据确实在里面",但对普通用户来说,看到的常常只是一堆点和线。

我最开始就只是部署到容器里测试,怎么看怎么别扭以为得下个软件,结果实际还是得付费了属于是

用户不关心数据库里有多少节点,他关心的是:这个对象为什么会关联到这些东西,我要改它应该看哪里。

所以展示层也得自己做。

这个浏览器不追求通用图数据库能力,只服务当前业务:

  • 打开后默认展示一个对象的局部关系
  • 节点按业务类型着色
  • 边显示关系含义
  • 支持搜索、点击查看详情、逐步展开
  • 隐藏原始大段内容,只展示对维护有用的信息

它的目标不是替代数据库,而是把图谱翻译成业务人员能看懂的界面。

后续如果用户能自己搜索对象、展开关系、点节点看详情,再结合 RAG 给出的解释和修改建议,就比较不戳了"。

<7> 过程中最大的几个教训

1. 不要把 RAG 理解成"文档问答"

文档问答只是 RAG 的一种最简单形态。

内部业务场景里,用户往往不是来问"这段文档什么意思",而是要完成一个动作。动作需要结构、规则、上下文和边界。

如果只做文档问答,很容易一开始看起来能用,深入使用就暴露问题。

2. 意图识别比召回更早出问题

很多人调 RAG 时第一反应是调 chunk、调 embedding、调相似度阈值。

这些当然重要,但在操作型场景里,更早的问题是:系统有没有判断对用户要做什么。

意图错了,召回越准越危险,因为它会在错误方向上给出很完整的答案。

3. 结构化知识比堆文档更重要

文档越堆越多,不等于系统越懂业务。

有些知识应该写成说明,有些知识应该从项目里自动抽取,有些知识应该建成关系,有的知识需要把人的理解抽出来

把所有东西都塞进向量库,只会让问题变得更难诊断。

4. 展示工具会影响认可度

这是后来才意识到的。

同样一套图谱数据,如果只在数据库浏览器里展示,普通用户会觉得乱不知道干啥的;如果用业务视角重新组织,用户才会觉得"这个东西能用"。

所以展示层不是锦上添花,它会影响别人对系统成熟度的判断,也方便用户检查

9 个帖子 - 6 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文