跳到主要内容

你的 RAG 懂文档,但它不懂你的工程师所知道的。

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的企业刚刚部署了一个 RAG 系统。你索引了每个 Confluence 页面、每份运行手册(runbook)、每篇架构文档。六个月后,一位高级工程师离职了——就是那个知道为什么支付服务会有那种不寻常的重试模式、为什么你们从不把缓存扩容超过 80%,以及周五绝对不要给哪家供应商打电话的人。这些知识从未被记录下来。你的 RAG 系统根本不知道它的存在。

这就是隐性知识(tacit knowledge)问题。这也是为什么大多数企业 AI 系统表现不佳的原因——不是因为检索质量或幻觉,而是因为它们所需的知识从一开始就没被捕获。60% 的员工表示,很难甚至几乎不可能从同事那里获取关键信息。90% 的组织表示,员工离职会导致严重的知识流失。你的 RAG 能索引的文档只是冰山一角。

显性知识并不是难点

知识管理理论中有一个非常有用的区分:显性知识(explicit knowledge)是任何已经写下来的东西——文档、运行手册、API 规范、复盘报告。而隐性知识(implicit knowledge)则存在于人们的脑海中——那是多年来在系统上工作所积累的直觉、思维模型和判断。

RAG 系统擅长第一类,但对第二类视而不见。它们可以检索到“缓存 TTL 设置为 300 秒”,但检索不到“我们在 2023 年尝试过 600 秒,结果在流量高峰期间导致了连锁数据库超时”。它们可以展示服务契约,但无法展示团队之间维持的非正式协议,因为正式的 API 更改需要六周的协调时间。

显性知识也会按可预测的时间表衰减。技术文档的半衰期大约为 18 个月。面向客户的信息在六个月内就会降级。市场敏感数据的有效期只有几周。但隐性知识不会以同样的方式衰减——它只是在携带它的人离开时随之而走。

工程上的问题不在于如何更聪明地检索知识,而在于如何在日常工作流程中,在隐性知识消失之前,持续地将其转化为显性知识。

为什么索引对话无法解决问题

显而易见的第一步是将沟通渠道(如 Slack、Teams、邮件线程)与文档一起丢进向量数据库。但这无一例外地会让检索效果变得更糟。

对话的结构与文档有着本质的不同。一个 Slack 线程可能包含五个不同的主题、三个跑题的笑话、一个立即被取代的链接,以及一个埋在中间的真正有用的架构见解。当你将其分块并嵌入(embed)到向量数据库中时,嵌入捕获的是所有这些内容的平均表征。在查询时,有用的见解在语义上被稀释成了噪音。

规模问题加剧了这种情况。向量数据库会随着增长而显著退化。在 10,000 份文档左右,嵌入聚类开始重叠。在 50,000 份文档时,检索精度可能会下降近 87%。添加数万个低信号的对话块会加速这种崩溃。你最终得到的是一个能以高置信度分数检索出对话片段,却无法提供有用上下文的系统。

分块大小的选择让情况变得更糟。小分块会丢失使交流变得有意义的周围上下文——如果没有前面五条消息,一条写着“我们应该改用另一种方法”的消息就毫无用处。大分块将多个想法混合到一个嵌入中,导致它在所包含的所有主题上的检索精度都很低。而对话恰恰处于这两种失败模式的交汇点。

真正奏效的方法:提取,而非索引

正确的架构应该将沟通渠道视为信号源,而不是文档库。与其索引原始内容,不如从中提取结构化知识。

主动标记,而非被动摄取。 与其索引整个对话历史,不如构建让工程师能够在交流发生时标记重要内容的系统。一个表情符号回应或一个简单的机器人指令(“!capture this”)就能触发针对该特定线程的结构化提取过程。这从根本上保持了高信噪比。在摄取阶段,人类依然是相关性的过滤器,而 AI 则负责提取和结构化。

结构化提取优于原始存储。 当捕获到一个有意义的交流时——比如确定了 Bug 根本原因的线程、关于安全约束的代码审查讨论、事件解决方案——不要存储原始文本。通过结构化提取运行它,提取出五个到七个维度:问题是什么、诊断是什么、解决方案是什么、这为以后建立了哪些约束、涉及哪些系统。存储结构化输出,并将原始文本仅用作上下文。Zalando 的事件分析系统正是这样做的:LLM 从复盘文档中提取五个核心维度,并严格限制猜测——当信息不明确时,模型必须明确指出,而不是填补空白。

用于批量提取的 Map-reduce。 对于处理历史存档——数年的事件报告、已合并的代码审查线程、已完成的问答工单——使用 map-reduce 方法。Map 阶段跨文档并行运行提取,为每个文档生成结构化输出。Reduce 阶段将这些输出聚合为更高级别的摘要或实体图。这实现了提取(可以并行化并单独验证)与综合(需要全局视图)的分离。

你可能错过的四种信号源

不同类型的渠道需要不同的提取策略。这里有四个隐性知识密度最高的来源。

事故复盘(Incident postmortems)。 大多数团队写完复盘后就再也不读了。累积的复盘存档实际上是关于系统行为最丰富的组织知识库——哪些组件会同时发生故障,哪些故障模式会反复出现,凌晨 3 点什么样的干预措施有效。Zalando 对两年多复盘数据的分析揭示了数据存储事故、配置问题和容量问题的重复模式,这些模式在任何单一报告中都是不可见的。这里的工程投入在于构建提取流水线并针对存档运行,同时在编写新复盘时保持数据的新鲜度。

代码审查线程(Code review threads)。 代码审查以一种极少在别处记录的方式,将架构推理过程外显化。诸如“由于会话亲和性要求,我们不应在此使用连接池”或“当上游发生变化时,这种模式在 2022 年曾导致系统崩溃”之类的评论,包含了合并后的代码中不可见的约束。一旦 PR 关闭,审查线程通常就被丢弃了。代码审查提取流水线会监控已合并的 PR,识别包含非琐碎决策依据(区别于风格纠错)的审查线程,并将决策及其约束提取到可查询的知识图谱中。采用跨任务蒸馏的 CodeBERT 架构在代码和注释特征的结构化提取上达到了约 81% 的 F1 分数——这已经足够好到可以派上用场,但还不足以在没有人工验证的情况下运行。

问答和求助频道线程。 内部开发者论坛、运维频道和帮助台包含了自然结构化的问题-解决方案对。有人提问,问题得到了回答。这种交流捕捉到了一个真实的问题和一个经过验证的解决方案。这些信号比大多数文档都要强,因为提问代表了某人遇到的实际理解缺口,而答案则代表了成功传递的知识。与预防性编写的文档不同,问答线程代表了真正被需要的知识。

离职和交接访谈。 与直觉相反,获取隐性知识最高效的时刻之一是某人离开时。一场结构化的技术离职访谈——不是人力资源部的陈词滥调,而是针对工程领域的知识转移会议——可以在两个小时内提取出多年的内含知识。那些该工程师依赖但没有其他人完全理解的系统。他们做出的未记录的设计决策。他们学会留意的反复出现的故障模式。这无法推广到所有人,但对于资深工程师和长期员工来说,结构化技术离职访谈的 ROI 非常高。

针对此用例,图模型优于扁平向量集合

以文档为中心的 RAG 配合扁平向量检索在处理单一来源类型时效果尚可。但当你试图合成跨多个来源和时间段的知识时——这正是隐性知识检索所要求的——它就会失效。

诸如“为什么支付服务有异常的重试行为”之类的查询,可能需要连接 2023 年关于供应商 SLA 的 Slack 讨论、添加重试逻辑时的代码审查评论,以及默认设置导致级联故障时的事故复盘。这些文档中没有任何一个能单独回答这个问题。它们之间的关系才能。

基于图的检索直接对此建模。实体(服务、工程师、事故、配置、决策)是节点。提取的关系(导致、解决、约束、影响)是边。查询遍历图以发现扁平向量相似性无法找到的多跳关系。微软的 GraphRAG 现已广泛应用于企业知识系统,证明了在需要跨文档连接信息的问题上,感知图的检索明显优于纯向量方法。

实际意义在于,你从提取的复盘、代码审查和对话中构建的知识库不应输入到扁平向量库中。它应该输入到一个实体相互关联且关系明确的知识图谱中。检索层随后使用语义相似性增强的图遍历,而不仅仅是相似性。

时间衰减是特性,而非缺陷

构建结构化提取流水线的一个优势是,你可以获得知识产生时间及其上下文的明确时间戳。这使得时间衰减(temporal decay)成为可能——当查询具有上下文敏感性时,赋予新知识比旧知识更高的权重。

半衰期为 18 个月的技术文档与上周的复盘,其相关性评分权重应该不同。两年前在现已重写的系统上建立的代码审查约束可能会产生严重的误导。在你的相关性评分中融入一个时间衰减因子(可根据知识类型调整)。关于已弃用子系统的事故处理方案在返回时应带有明确的新鲜度元数据,而不是被默认等同于当前信息。

这不同于简单的近因偏见。目标不是忽略旧知识,而是显现其时效,以便检索使用者做出明智的判断。检索到的知识若带有明确的新鲜度元数据,比隐藏了年龄的时间加权更有价值。

组织行为难题

如果提取流程需要工程师在知识生成阶段投入大量精力,那么这一切都无法奏效。如果隐性知识的捕获减慢了产生这些知识的工作流,那么其价值就是负向的。

有效的系统旨在现有工作流中拦截知识,而不是增加新的流程。代码审查提取在 PR 合并时自动运行。事故提取在复盘文档完成时自动运行。Slack 提取通过明确的信号(反应、命令)触发,这只需要一个动作,而不是一个独立的流程。工程师的主要工作流保持不变,知识捕获只是一个副作用。

标注负担必须基本为零。那些要求工程师填写知识捕获表单、撰写结构化摘要或为独立数据库标记知识的系统,将因无人采用而失败。自愿贡献知识的摩擦力上限非常低。

你实际在构建的是什么

隐性知识捕获是一个披着 AI 外衣的数据工程问题。AI 部分 —— 提取模型、嵌入、图谱构建 —— 已经非常成熟。更难的问题在于:

  • 为每个信号源定义提取模式(复盘文档、代码审查、问答线程的结构各不相同)
  • 构建在正确的生命周期阶段拦截每个源的数据摄取流水线
  • 设计验证层,在提取错误损坏知识图谱之前将其捕获
  • 建立所有权和维护流程,确保知识图谱不会发生偏移

大部分工程工作都是基础设施。最终的回报是一个检索系统,它可以回答“为什么这个系统会这样表现”,而不是“文档里关于这个系统是怎么说的” —— 这通常是两个截然不同的问题,而且只有前者能在工程师流失后幸存下来。

References:Let's stay in touch and Follow me for more thoughts and updates