T
traeai
登录
返回首页
Towards Data Science

RAG 不是机器学习,且 ML 工具包解决的是错误问题

8.7Score
RAG 不是机器学习,且 ML 工具包解决的是错误问题

TL;DR · AI 摘要

RAG 不是机器学习,使用 ML 工具包解决的是错误问题。文章指出,尽管 RAG 看似类似 ML,但其核心是构建搜索系统而非训练模型,因此超参数调优、嵌入模型微调等 ML 方法无法解决 RAG 的真实故障,反而导致资源浪费和信任下降。

核心要点

  • RAG 解决的是确定性答案查找问题,而非预测未知结果,因此不能用 ML 方法优化。
  • RAG 的失败是具体可追溯的结构性缺陷,如解析错误或检索偏差,而非统计噪声。
  • 在 RAG 中,改进系统依赖工程手段(如更好的解析、更精确的检索),而非模型训练或数据增强。

结构提纲

按章节快速跳转。

  1. RAG 被误认为是机器学习,导致团队投入大量时间在错误的优化方向上。

  2. ·RAG 与 ML 的本质区别

    ML 预测未知结果,而 RAG 查找已存在的文档答案,两者问题性质不同。

  3. ML 表现以整体准确率衡量,RAG 则需逐个分析错误原因。

  4. RAG 错误源于结构缺陷,如解析错误或检索偏差,而非模型泛化能力不足。

  5. 提升 RAG 效果需改进解析、检索和提示设计,而非微调模型。

  6. 将 RAG 视为 ML 会导致工具错配,应采用工程思维而非 ML 思维解决问题。

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • RAG Is Not Machine Learning
    • 核心观点
      • RAG 不是 ML
      • ML 工具包不适用
    • 问题本质
      • ML:预测未知
      • RAG:查找已知
    • 失败模式
      • 结构性缺陷
      • 可追溯性
    • 解决方案
      • 工程优化
      • 非模型训练

金句 / Highlights

值得收藏与分享的关键句。

#RAG#机器学习#企业AI#信息检索#大语言模型
打开原文

六个月来,他们一直在微调自己的 RAG 管道。

  • 他们进行了五次 Optuna 超参数搜索。
  • 他们添加了一个自定义重排序器。
  • 他们在自己的数据上微调了嵌入模型。

生产环境的准确率始终没有提升。试点用户持续抱怨同样的错误答案。六个月后,问题出在解析器上。

团队并非陷入困境,而是迷失了方向。RAG 不是机器学习,而 ML 工具包解决的是错误的问题。 这是当前企业 RAG 中最昂贵的误解。它耗费数月精心工作,让错误的人从事错误的任务,并悄然侵蚀系统信任。

RAG 看起来足够像机器学习,以至于 ML 工具包似乎成了顺理成章的下一步。这些直觉(超参数优化、评估数据集、可解释性框架)本身并不错误。它们是从错误的领域引入的。适用于训练模型的方法,不适用于构建搜索系统。

重点不是 ML 本身不好。驱动向量搜索的嵌入模型本身就是一个深度学习模型,但你不需要训练它,只需要使用它。重点是,你围绕它构建的系统不是一个模型,将其视为模型会浪费时间、选择错误的指标、雇佣错误的人,并掩盖真正的故障模式。

“RAG 不是 ML”这一观点是 _企业文档智能_第1卷 的一部分,该系列文章从最小到大规模逐步构建企业级 RAG。四个砖块(解析、问题解析、检索、生成)正是本文所指向的工程工具包。

1. 两个不同的问题[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#two-different-problems)

机器学习解决的是真实答案未知且需要预测的问题。这个客户会流失吗?这笔交易欺诈的概率是多少?这张图片是一只猫吗?你事先不知道答案。这就是为什么你要训练一个模型。模型从带标签的示例中学习,泛化到新输入,并产生预测。性能是在数千个测试用例上整体衡量的,因为单个预测可能错误,但模型整体仍然有用。

RAG 解决的是不同的问题。“这份合同的有效日期是什么?”这个问题的答案存在于文件第一页,或者根本不存在。没有什么需要预测。系统要么在文档中找到答案并忠实报告,要么失败并应说明这一点。性能在问题级别是二元的(找到了或没找到),即使你在多个问题上测量总体比率也是如此。

这些差异是具体的:

  • 在 ML 中,“模型在 8% 的情况下出错”是系统的特征。你会建立冗余、下游检查、对边缘情况的人工审查。在 RAG 中,“系统 8% 的时间给出错误答案”是一个缺陷。这 8% 中的每一个都有特定原因:检索到了错误的段落,检索到了正确的段落但模型改写得不好,答案不在语料库中而系统编造了一个。它们不是可以平均优化的统计噪声。它们是可单独修复的故障。
  • 在 ML 中,你通常无法判断模型为何在某个案例中出错。这就是为什么可解释性是一个研究领域。在 RAG 中,你可以总是知道。检索日志记录了返回的段落。生成器看到了那些确切的段落。如果答案错误,你沿着链条向后追溯就能找到断裂的环节。没有任何隐藏之处。
  • 在 ML 中,模型通过在更多数据上训练来改进。在 RAG 中,系统通过更好地索引、更仔细地解析、更精确地检索、更清晰地提示来改进。这些都不是训练。它们是工程。

这种差异改变了当出现问题时你选择的工具。

文章 2 中记录的情况完全符合此描述:否定、精确标识符、内部缩写、长上下文中的信号稀释、主题接近度超过实际答案。当你更换嵌入模型或调整块大小时,这些都不会改变。这些不是模型能通过学习摆脱的缺陷,因为没有带标签的信号告诉模型“这是正确的一行”以便其进行训练。修复方法是结构性的(问题解析、专家关键词、了解文档结构的检索),接下来的部分将介绍三个 ML 反射,它们选择了错误的工具。

2. 三个不适用的论点[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#three-arguments-that-dont-apply)

三种 ML 方法默认被引入 RAG 项目:超参数优化、带有训练/测试分割的评估数据集,以及特征归因可解释性。每一种在 ML 内部都是合理的。每一种在这里都会失效。

2.1 超参数论点[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#the-hyperparameter-argument)

最常见的表述大致如下:块大小、重叠、top-k、相似度阈值。这些都是超参数,你应该像优化 ML 模型一样对其进行优化,使用 Optuna 或 Ray Tune 等工具。运行一次扫描,绘制曲线,选择最佳配置。

在这种设置中,top_k 是检索器保留的段落数,similarity_threshold 是段落必须达到的最小余弦得分才能合格。下面的代码声明了所有四个作为要优化的数字:

团队通常会做什么(以及为什么这是错误的活动)

python
import optuna
def objective(trial):
    chunk_size    = trial.suggest_int("chunk_size", 100, 2000)
    chunk_overlap = trial.suggest_int("chunk_overlap", 0, 200)
    top_k         = trial.suggest_int("top_k", 1, 20)
    threshold     = trial.suggest_float("threshold", 0.5, 0.95)
    accuracy = run_rag_pipeline_and_score(
        chunk_size, chunk_overlap, top_k, threshold
    )
    return accuracy
study = optuna.create_study(direction="maximize")
study.optimize(objective, n_trials=200)  # 两周的计算后...

这里确实有一点道理。这些变量确实会影响检索质量,而且值得进行调优。问题始于“超参数”这个词,它带入了一个隐含假设的比喻。

在机器学习中,超参数控制模型的学习方式:学习率、正则化强度、层数。模型本身在训练过程中发生变化;而超参数则塑造了这种变化。在 RAG 中,并没有学习过程。块大小并不控制任何东西的学习方式。它控制的是一个函数如何分割文本,每次都是同样的方式,无论你之前输入了什么。

看起来像超参数的东西其实是一种配置选择,就像你在配置搜索引擎时所做的那样。调优所需的专业知识不是统计优化,而是理解你的文档结构和问题的形式。512 个标记的块大小可能在密集的学术论文上表现得非常出色,但在保险合同上却可能灾难性地失败,因为单个条款可能跨越 800 个标记,将其分成两半会丢失赋予该条款意义的条件。任何网格搜索都无法告诉你这一点。你需要阅读你的文档。

这就是为什么那些对块大小进行网格搜索的团队经常发现一个“最佳”值,在测试集上表现略好,而在生产数据上表现完全相同。测试集上的最优值是测试集的产物,而不是底层系统的真正改进。他们优化了一个数字,而不是解决问题。

常见陷阱:一个团队运行 Optuna 对块大小、top_k 和相似度阈值进行了两周的搜索,最终得到块大小为 487,但不知道为什么。对于“为什么是 487?”这个问题,诚实的答案是“因为 Optuna 说的”。这个答案在真实的生产故障中无法存活,当文档分布发生变化时也无法泛化。一个因为大约是这个语料库中段落大小而选择 500 的块大小,比因为扫描结果落在那里而选择 487 更有说服力。

正确的活动不是调整数字。而是决定结构性如何分块。按部分?按段落?按目录条目?按问题类型,短查找与长条款使用不同的分块器?通过查看文档和问题来回答,而不是通过优化曲线。

块大小抗拒优化还有一个更深层次的原因:从构造上讲,没有单一的块大小可以满足所有问题。考虑同一份保险合同上的两个问题:

  • _“生效日期是什么?”_ 答案是一行,位于第一页的某个地方。它需要一个足够小的块,以精确地定位到单一行。
  • _“保单的除外责任是什么?”_ 答案可能是一页,也可能是三页,取决于保险公司是如何写的。它需要一个足够大的块,以捕获整个部分。

没有一个数字能满足两者。200 个标记的块大小会将除外责任部分切成不连贯的碎片。2000 个标记的块大小会把生效日期淹没在周围的噪声中。

因此,试图找到“最佳块大小”并不是一个调优问题。框架本身是错误的:没有一个单一的数字可以服务于答案长度不同的问题分布。

原则上,你可以让块大小根据问题做出反应,通过训练一个小模型,从问题的特征中预测出正确的分块器:分类意图,回归预期答案长度,输出一个策略。这将是机器学习在真正适用的问题上的合法应用,其中某些东西正在被学习。

但你不需要这样做。你可以写下规则。看一个问题,你就能判断它是在询问日期、章节还是比较。领域专家也能做到。十行 Python 代码加上手写的关键词条件也可以做到。RAG 不是机器学习的更深层次原因是,对于系统内部的大多数决策,你已经知道答案,或者你团队中的某个人知道。机器学习是用于没有人预先知道答案的问题的工具。

正确的方法是停止寻找一个块大小,转而根据不同的问题类型路由到不同的检索策略:

python
# 应该做的:按问题类型路由
def chunk_for_question(question: str, line_df, toc_df):
    intent = classify_intent(question)
    if intent == "point_lookup":          # "what is the effective date?"
        return chunk_by_line(line_df)
    elif intent == "section_retrieval":   # "what are the exclusions?"
        return chunk_by_toc_section(line_df, toc_df)
    elif intent == "comparison":          # "compare clauses A and B"
        return chunk_by_full_section(line_df, toc_df)

上面的两个代码块就是本节的全部论点。第一个在四个数字上运行 Optuna 两周,产生了一个没人能辩护的值。第二个为每种问题类型做出一个结构性决策,并产生了一个任何人都能解释其行为的系统。

后续文章将阐述如何分类意图(第 6 章,关于问题理解)以及不同检索方法和粒度的实现方式(第 7 章,关于检索)。这里的重点只是,活动不是调优,而是路由。

2.2 评估数据集论点[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#the-evaluation-dataset-argument)

下一个机器学习(ML)导入是评估方法。其推理如下:RAG 与任何 ML 系统一样,需要一个合适的评估数据集:包含问题和预期答案的配对数据,划分为训练集和测试集,并使用精确率(precision)和召回率(recall)进行评分。像 RAGAS 这样的框架甚至让这变得更加诱人,提供了忠实度(faithfulness)、答案相关性(answer relevancy)和上下文召回率(context recall)等指标,看起来非常“ML 化”。

评估是有用的。问题不在于是否要进行评估,而在于这些指标意味着什么。在机器学习中,评估告诉你模型是否从训练数据泛化到了未见过的示例上。划分训练/测试集的原因是你希望检测过拟合:即模型记住了训练集,而不是学习到可迁移的模式。

在 RAG 中,没有需要泛化的部分。过拟合(当模型记忆了训练样本而非学习到能迁移到新数据上的模式)在这里不会发生:系统在每次查询之间不会发生变化。检索器每次都计算相同的余弦距离。生成器遵循相同的提示模板。没有模型会根据数据进行调整。

RAG 的评估衡量的是三件事,它们都是关于覆盖范围和质量的问题,而不是统计泛化:

  • 我的语料库中是否包含答案? 如果不包含,系统就无法找到它。这是一个内容问题,而不是模型问题。
  • 我的检索器能否找到正确的段落? 如果答案存在于语料库中,但检索器遗漏了它,系统就会失败。这是一个搜索问题。
  • 我的生成器是否忠实地遵循了检索到的内容? 如果正确段落已被检索,但模型错误地改写或虚构了额外信息,系统就会失败。这是一个生成纪律问题。

每一项都指向一个具体的修复方案。将它们混杂在一个综合的“准确率”分数下会丢失信息。75% 的准确率来自“语料库缺少 25% 的已记录主题”和来自“检索器 25% 的时间错过正确段落”需要采取不同的行动。前者需要摄入更多文档,后者则需要修复检索器。一个将两者同等对待的综合指标掩盖了诊断信息。

这也解释了为什么使用 RAGAS 风格框架的团队有时会在保留的测试集上报告极佳的指标,然后却看到系统在生产环境中失败。测试集涵盖了语料库中有答案且检索器恰好找到了它们的主题。生产环境中的问题是,答案根本不在语料库中,系统要么幻觉生成,要么无法说出“未找到”。测试集上的指标之所以高,是因为测试集很友好。系统并没有坏掉,而是评估出了问题。

你需要按问题类型分解评估的内容,大约只需十行代码:

python
# 每个问题、每种意图的检索召回率
def evaluate_retrieval(reference_set, retrieve_fn):
    rows = []
    for ref in reference_set:
        retrieved_lines = retrieve_fn(ref.question)
        recall = len(set(retrieved_lines) & set(ref.expected_lines)) / len(ref.expected_lines)
        rows.append({
            "question": ref.question,
            "intent":   ref.intent,
            "recall":   recall,
            "hit":      recall > 0,
        })
    return pd.DataFrame(rows)
# 始终按问题类型拆分,不要只看汇总结果
df.groupby("intent")["hit"].mean()
# point_lookup        0.92
# section_retrieval   0.41   <-- 这才是真正的问题
# comparison          0.55

单一的综合准确率为 63% 会隐藏 section_retrieval 上的灾难性失败。按意图分组的分析立即揭示了这一点。这里的召回率指的是:在答案存在于语料库中的问题中,检索器是否找到了正确的段落?按意图(point_lookup、section_retrieval 等)分组显示了哪类问题失败了,因此也就明确了管道的哪一部分需要修复。

RAG 有两个评估表面,形状完全不同。

检索表面是一个搜索问题:正确的段落在模型面前出现了吗?测量这一指标意味着检查一组参考问题,看相关行或页面是否被检索到了。该指标是在你关心的级别上的召回率(按行召回、按页召回、按节召回),并且针对你的语料库是特定的。其他人无法为你运行此评估。你的语料库是独一无二的。这是评估工作的主要部分。

生成表面则不同。一旦正确段落被检索到,问题就变成了:模型是否以正确的格式、带有适当的引用并清晰地返回了一个“未找到”的响应,从而产生了一个忠实的答案?其中一些你可以自己评估,但大部分已经由 LLM 供应商评估过了。OpenAI、Anthropic 和 Mistral 投入大量资源来测试他们的模型是否遵循 JSON 模式、拒绝虚构以及遵守提示指令。这些是他们改进模型的维度。作为 RAG 构建者,你不是在训练生成器,而是在消费它。如果模型在返回结构化 JSON 方面表现糟糕,或者对其输入不忠实,你在集成后一小时内就会注意到。这不是一个需要建立的指标;而是一个显而易见或正常的 sanity check。

这在实践中意味着:你的大部分评估时间应投入到检索(这是与语料库相关的,只有你能完成)上,而不是生成(这主要是供应商的问题,且明显失败很快就能发现)上。那些花数周时间构建复杂的生成评估套件的团队,通常是在推迟更困难的检索工作,而这本可以改善结果。

进一步阅读:《评估你的系统》(系列后续文章)将详细介绍如何为你的特定语料库构建参考集、四个关键指标,以及为什么按问题类型指标至关重要,而汇总指标则是误导性的。

2.3 可解释性论点[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#the-explainability-argument)

机器学习拥有自己的可解释性工具包。SHAP 值用于将预测归因于特征,LIME 用于复杂模型的局部近似,注意力可视化则用于 Transformer 模型。当人们开始要求 RAG 的可解释性时(“为什么系统给出了这个答案?”),他们自然会转向这些工具。他们希望评估检索的相关性,衡量文档的贡献,可视化哪些标记影响了输出。

讽刺的是,RAG 从设计上就比大多数机器学习模型更具可解释性。不需要 SHAP,也没有需要破解的模糊性。系统从特定来源中检索了这些特定段落,并在此基础上构建了答案。这就是解释本身。它是基于文档的,而不是统计性的。

这指向了机器学习与 RAG 之间更深层次的不对称性。在机器学习中,人类有直觉但无法量化。问谁在泰坦尼克号上幸存下来,人们会说 _财富_、_年龄_、_阶级_:这些都不错,但都不精确。而模型没有这种疑虑:拟合一棵决策树后,根节点的分割是 _性别_,下一个切割是一个没人能猜到的确切年龄阈值,然后是阶级。每一个分割都是一个直觉无法产生的数字。模型的存在就是为了把这些数字写下来。

图 1

_一个真实的 sklearn 决策树在泰坦尼克号数据上的表现。每个阈值都是直觉无法产生的数字——作者图片_

对于文本数据,方向发生了逆转。用户可以直接阅读源文件。律师在审查合同时可以看到条件、例外和日期。合规官员阅读政策时知道某种行为是否违反了它。文本不会隐藏其含义,专家已经是熟练的读者。

也有例外:讽刺和反语是经典例子,现代大语言模型有时能捕捉到字面阅读者所忽略的内容。但在企业环境中,用户是领域专家。

模型不是为了解释文本而存在的。它的存在是为了在语料库规模上进行阅读,而引用足以让专家在几秒钟内验证任何答案。

当用户问“为什么是这个答案?”时,正确的回答不是注意力权重的热力图或特征归因分数。而是:“我查看了这份合同的第 12、47 和 89 页。这是我使用的原文。答案由此文本得出。” 如果用户不同意答案,他们可以自己阅读源文件并做出判断。他们不需要可解释性框架。他们需要引用。

第 1 章中的五十行管道已经展示了这一点。提示要求模型在结构化 JSON 中返回答案的同时,附上起始和结束行号(以及它们所在的页码);标注员随后在 PDF 上高亮显示这些确切的行。不需要 SHAP,不需要 LIME,不需要注意力可视化,也不需要专门的可观测性平台。"解释" 是提示编写方式的副产品。引用是答案的一部分,而不是附加的分析层。

跟踪记录就是解释。阅读它不需要解释,只需要阅读。

将机器学习可解释性引入 RAG 是在解决一个不存在的问题。对检索得分使用 SHAP 就像是用手术刀打开邮箱。检索得分是你在可读输入上计算出的一个数字。你不需要归因于那些你已经看到的东西。

机器学习可解释性框架的更深层次失败在于,它让你关注错误的事情。你开始试图解释 _为什么_ 某个段落在向量空间中的得分高于另一个,这是一个几乎不可能回答且无关紧要的问题。重要的是是否检索到了正确的段落,以及答案是否忠实地反映了它。这些问题可以通过阅读日志和源文件来回答。不需要任何工具。

3. 当你正确看待 RAG 时会发生什么[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#what-changes-when-you-see-rag-correctly)

一旦你停止将 RAG 视为机器学习,两件事会发生变化。日常工具、指标和人员围绕搜索而非训练重新组织。并且一个更深层次的问题(_智能位于何处_)从模型转移到团队。两者都源于相同的框架。

3.1 工具、指标、人员[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#tools-metrics-people)

有三件具体的事情会发生变化。

工具发生变化:你不需要 PyTorch,也不需要训练集群,或者超参数优化框架来运行系统本身。你需要一个好的解析器、一个灵活的检索器、精心设计的提示工程,以及对所有发生事件的结构化日志记录。那些确实是机器学习的组件(嵌入模型、大语言模型)作为服务被消费。它们是商品输入,而不是你需要构建或训练的东西。

指标发生变化:整体准确率被逐故障模式的指标所取代:检索召回率(我们是否找到了正确的段落?)、答案忠实度(模型是否忠实地遵循了它?)、提取准确性(在提取结构化数据时,数值是否匹配?)、未找到率(当答案不在语料库中时,我们是否清楚地说明了这一点?)。每项指标测量一个具体方面,每一项都对应于你可以修复的流水线中的特定部分。

人员的变化: 一个纯粹的机器学习团队试图交付一个RAG系统时,常常会忽略使其成功和失败的关键因素。最重要的技能是软件工程(系统有许多需要良好组合的组件)、领域专业知识(必须有人知道某个领域问题的好答案应该是什么样子),以及信息检索直觉(必须有人能像搜索引擎设计师一样思考,而不是像模型训练师)。机器学习专业知识是有用的,但并不是主导技能。一个由机器学习研究人员组成、没有领域专家的团队,可能会产出一个精心调优的系统,但却偏离了核心目标。而一个由一名具备机器学习意识的工程师、两名软件工程师和一名领域专家组成的团队,通常会表现得更好。

3.2 智能存在于何处[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#where-the-intelligence-sits)

人员的变化指向了一个更深层次的问题:系统的智能存在于哪里?

在机器学习系统中,智能存在于模型中。模型保存着模式。团队向其提供训练数据并调整损失函数。而在RAG系统中,智能存在于团队中。律师知道首先应查看哪些条款。承保人知道“免赔额”是什么意思,以及通常在哪一页出现。合规官知道哪种法规适用于哪种产品。这些知识都不在嵌入模型中,也不是通过超参数搜索得出的。它们早已存在于那些阅读这些文件多年的人的大脑中。

观察一位承保人打开一份新保单。她不会线性地阅读它。她首先跳到除外责任部分,因为她已经看过五百份这样的文件,知道陷阱通常出现在那里。她检查受益计划中的免赔额和上限。她检查地域条款。三分钟后,她对合同的理解比任何嵌入模型在一千份此类合同上生成的都要清晰。这种习惯正是系统需要放大的地方。

3.3 逐块放大专家能力[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#amplifying-the-expert-brick-by-brick)

企业级RAG系统的工作是放大这种专业知识的规模,而不是取代它。这具体取决于每个“砖块”。

解析是第一步。如果解析器将合同的PDF转换为混乱的文本,那么下游的任何聪明方法都无法恢复它。如果文档有有效的目录,解析器必须干净地提取它,因为目录是专家用来导航的工具。当文档根本没有目录时(如扫描的传真、导出为PDF的幻灯片、旧式打字机打印的保单),重建目录本身就成了一个独立的任务,通常比任何检索调整都更有用。

问题理解将团队的词汇表跨越用户提问方式与文档回答方式之间的鸿沟。试点用户输入 _kettle_,合同中写的是 _small electrical appliance_。合规官输入 _data breach_,保单中写的是 _unauthorized disclosure of personal information_。专家知道这种映射关系。问题解析器将这种映射转化为查找表:跨语言翻译、拼写变体、复数形式、内部缩写。这些都不是从数据中学来的,而是由专家决定并记录下来的。

检索通过放大专家已经手动完成的工作来增强其能力。专家搜索关键词;这一部分已经很容易。专家无法大规模完成的是在数千页上运行正则表达式模式、检查两个术语是否在同一段落内共现,或在整个语料库中组合布尔条件。检索器快速完成这些工作,然后将候选结果返回给专家进行验证。

生成执行专家原本会手动完成的两件事:引用支持答案的确切段落,并将原始值格式化为可用的形式。页面上的字符串 3455434 变成答案中的 €3,455,43420260516 变成 May 16, 2026。_thirty days from the date of the loss_ 保持原样,并附上回溯到条款的引用,以便专家可以一键验证。

第5、6、7和8章依次开发每个“砖块”:提取目录结构的解析器、映射词汇的专家词典、了解目录的检索器、生成类型化答案的生成器。每次都是同样的原则:拿起人类专业知识的一部分,并将重复的部分交给机器。

这也是为什么本系列在自主代理方面非常谨慎。它默认优先使用关键词检索而非嵌入相似性。它将重排序器调优视为最后手段。这些默认设置假设没有专家可供咨询。在企业环境中,专家总是存在的。系统应该倾听他们的意见。

如果你所处的环境没有专家、问题无边界、文档差异很大,那么本系列可能不是你最好的指南。通用检索和自主代理在这些情况下更为合适。

4. 两个部分,两种故障模式[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#two-parts-two-failure-modes)

理解RAG的一种有用方式是将其视为一个搜索引擎,加上一个撰写答案的大语言模型。两个部分,各自有明确的任务,各自有不同的失效方式。

搜索引擎从文档中检索段落。给定一个问题,返回最有可能包含答案的行、段落或章节。这是一个纯粹的搜索问题:选择性、召回率、排序。几十年的信息检索理论都适用。其中一部分使用神经嵌入的事实并不会改变其本质;嵌入相似性只是多个排名信号之一。

大语言模型(LLM) 接收一段文本和一个问题,并生成带有引用的自然语言答案。LLM 并不会“找到”答案——搜索引擎已经完成了这项工作。LLM 是从它面前的一段文本中“写出”答案的。它更像一个翻译或抄写员,而不是一个预言家。

回到第一篇文章中的四个组成部分:解析、问题理解与检索共同构成了搜索引擎;生成则是由 LLM 完成的。四块砖的视角是操作性的(每一块对应一盒代码);而两部分的视角是你在出现问题时脑海中持有的思维模型。

这两部分以不同的方式失败,诊断始于它们之间的交界处。提取一个失败查询的追踪信息:被检索到的段落是否出现在模型前面?它们是否包含答案?

如果答案不在检索到的段落中,那么罪魁祸首是搜索引擎,修复必须在上游进行。正确的页面是否因解析器的问题而损坏(OCR 错误、多词术语跨行拆分、双栏交错)?问题解析器是否遗漏了专家词汇表应扩展的同义词?检索机制是否将正确页面排出了 top_k 范围,或者在需要正则表达式的标点符号上出错?或者相关文档根本不在语料库中?这四种情况完全不同,全部位于上游。在定位具体问题之前,“调整检索器”毫无意义。同样,这些在工作时放大专家能力的四个组件(第 3.3 节),在这里也会以各自的方式失效,每个都有一篇深入分析的文章(文章 5、6、7)。

如果答案在检索到的段落中,但响应是错误的,那么罪魁祸首是 LLM,修复必须在下游进行。常见模式包括:模型改写时丢失了条件,因为模式留出了自由格式的答案而返回了原始的 3455434,引用了错误的行号,捏造了段落中不存在的数值,或在应该说“未找到”时生成了一个答案。五种生成错误,五种不同的修复方法,全部涉及提示、模式或后验证层(文章 8)。它们都不会通过调整检索器来改善。

这就是实际诊断的样子。用户问:“基础 Transformer 使用多少个头?”(答案:8,来自论文 _Attention Is All You Need_ 的第 5 页,Vaswani 等人,2017;arXiv 非独占分发许可,在 arXiv 摘要页面 上声明)。系统报告为“16”。提取追踪信息。

检索返回了第 4、7、8 页。其中没有一页包含基础模型配置:第 8 页描述了“大”模型(确实使用 16 个头),第 4 和第 7 页描述了编码器结构。生成器读取了错误的页面并返回了那里找到的数字。错误在于检索,而非生成。

为什么检索漏掉了第 5 页?关键词是 ['heads', 'base', 'model']。第 7 页出现了“heads”六次;第 5 页只出现两次。关键词检索器根据原始词频排序,没有检查“base”、“model”和“heads”是否在同一行共现。在关键词检索器中只需修改五行 Python 代码即可解决此问题。

没有发生的情况是:没有人进行微调。没有人运行扫描。没有人添加重排序器。诊断耗时五分钟;修复耗时一个下午。

这种分离使得 RAG 在实践中可行。每个故障都有特定的部分可以修复。没有让检索和生成纠缠在一起的训练循环。它们是独立的组件,组合清晰,每个都可以单独替换。生产系统从这一特性中获益良多:你可以更换嵌入模型、更换 LLM、更换解析器,而无需重新训练任何东西。

整个管道是配置,而不是模型。

当出现问题时,你只需更改配置:检索方法、提示、模式、验证规则。你不需要重新训练。你更改一个 Python 文件,发布,测量受影响类别的每个问题类型的指标,并确认修复有效。迭代周期:几小时,而不是几周。

一旦你将 RAG 视为组装的配置,而非学习的行为,系列文章中的其余选择就会自然而然地出现。

5. 六个月在错误的问题上[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#six-months-on-the-wrong-problem)

一家中型企业的团队被分配了六个月的时间,为数千份内部文档交付一个 RAG 系统。他们首先构建了一个包含 500 个问题的评估数据集,将其分为 70/30 的训练集和测试集。他们设置了 Optuna 来扫描块大小、重叠、top-k 和相似性阈值。第一次扫描花费了一周的计算资源,返回了一个“最佳”配置,团队将其部署用于内部测试。

试点用户立即抱怨。系统回答流畅,但在评估者明确知道的问题上,一半时间都是错误的:关于特定条款、特定日期、特定数值限制的问题。团队的回应是扩大评估数据集,再运行一次扫描,对嵌入模型进行合成问题-文档对的微调,并添加一个重排序器。又过去了三个月。生产准确率没有提升。

哪里错了:解析器将带有退化 OCR 层的扫描页面视为原生文本。大约 30% 的语料库实际上无法阅读,但团队的评估集恰好是从可读的 70% 中抽取的。无论块大小优化、嵌入微调还是重排序器集成,都无法解决这个问题:三分之一的文档产生了垃圾信息。仅需两天投资来检查每一页(即文章 5 中的解析工作),就能在第一天发现这个问题。

团队花了六个月时间处于机器学习模式(扫描超参数、扩大评估集、微调模型),而修复其实只需要更改解析器。

Image 2

_在 TEAM 路线上进行了几个月的机器学习活动;而在 CORPUS 路线上,语料库中的错误却一直未被处理 —— 作者供图_

这个故事是综合性的,但其中每个元素都曾在真实的项目中发生过。这种模式是一致的:机器学习的直觉驱使团队走向看似富有成效的优化活动,而结构性问题则被搁置在解析器、语料库或未找到逻辑中。当一个 RAG 系统陷入困境时,第一反应不应该是“让我们进行调优”。而应该是“让我们端到端地追踪一个失败查询发生了什么,并找出断裂的环节。”

6. 结论[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#conclusion)

RAG 看起来像机器学习。这种相似性是表面的。答案存在于文档中,或者不存在。没有统计泛化,没有学习曲线,也没有映射到真实故障的训练/测试分割。正确的框架是搜索引擎组装:一个搜索引擎加上一个大语言模型,两个部分可以独立修复,用每种故障模式的度量指标取代整体准确率。

坚持机器学习框架的成本不是智力上的。而是六个月精心工作在错误的问题上。第 4 篇文章将正确的框架转化为一个可工作的诊断工具:RAG 问题位于文档复杂性与问题控制的网格上,每个单元格都需要不同的技术栈。

第 4 篇文章是进入 _企业文档智能_第 1 卷的一个入口,该系列从解析、问题解析、检索和生成等方面逐步构建企业级 RAG:每个模块都使用工程工具包,而不是机器学习工具包来处理。

图片 3

7. 来源与进一步阅读[](file:///C:/Users/shike/Documents/Github/rag/book/03_rag_is_not_ml.html#sources-and-further-reading)

这篇文章将 RAG 放在了 50 年的信息检索传统(Manning, Raghavan, Schütze, 信息检索导论, 2008) 中,而不是机器学习传统中。BM25 经常在分布外优于密集检索器这一经验性主张来自 Thakur 等人(BEIR,NeurIPS 2021)。每种故障模式的框架与 Barnett 等人(七种故障点,2024) 的方向相同。诚实的承认是,重排序器是一个微弱的学习层,机器学习方法在这里适用。本文用于可解释性的框架是 引用作为解释:RAG 回答携带其来源行,因此 ML 项目预算中的可解释性工具变得不必要。

与本文方向相同:

  • Manning, Raghavan, Schütze, _信息检索导论_ (剑桥,2008)。本文将 RAG 放入的 50 年信息检索传统。
  • Thakur 等人,_BEIR_ 基准,NeurIPS 2021 (arXiv:2104.08663)。在 MS MARCO 上调优的密集检索器经常在分布外输给 BM25。对 _信息检索,而非机器学习_ 框架的经验支持。
  • Barnett 等人,_工程 RAG 系统时的七种故障点_,2024 (arXiv:2401.05856)。RAG 故障的从业者分类。与每种故障模式的框架方向相同。
  • Kamradt,_ haystack 中的针_ (2023)。经典的长上下文检索基准。仅限研究:测试长上下文中单个逐字事实,而不是企业用户提出的问题聚合。在第 1 篇文章中讨论,并在第 7 篇文章中开发。

不同角度,不同背景:

  • Es 等人,_RAGAS:检索增强生成的自动化评估_,EACL 2024 (arXiv:2309.15217)。使用汇总的机器学习指标(忠实度、答案相关性、上下文精确度/召回率)在基准数据集上评估 RAG。背景是研究基准;本文的框架是在固定的企业语料库上的每种故障模式率。
  • Saad-Falcon 等人,_ARES:检索增强生成系统自动化评估框架_,NAACL 2024 (arXiv:2311.09476)。带有合成训练/开发/测试分割的机器学习风格 RAG 评估框架。与 RAGAS 相同的背景;本文认为训练/测试分割范式不适合企业 RAG,因为答案要么存在于文档中,要么不存在。
  • Lewis 等人,_知识密集型 NLP 任务的检索增强生成_,NeurIPS 2020 (arXiv:2005.11401)。命名 RAG 的论文,也是联合训练检索器和生成器的论文。一个有用的边界参考:最初的 RAG 论文是一篇机器学习论文,尽管继承了名称的工程模式并非如此。

AI 可能会生成不准确的信息,请核实重要内容