你可能并不需要 RAG

1812 字
6 分钟
0

这篇文章的目的并非全盘否认 RAG(Retrieval-Augmented Generation,检索增强生成),而是尝试提供一种新的视角,帮助你重新思考“知识检索”这件事。

为什么我们需要 RAG?

回顾最初引入 RAG 的原因,主要有两点:

  1. 知识截止问题:LLM(Large Language Model,大型语言模型)的训练数据具有时间边界,无法覆盖最新信息。
  2. 企业数据隔离:企业内部的私有数据并未参与模型训练,模型天然“不可见”。

既然模型不知道,我们是否可以把所有数据直接通过提示词(Prompt)提供给它?

这种“把所有信息都塞进去”的思路,在实践中往往会遇到几个关键问题:

  • Token 消耗巨大:不仅成本高,还会显著拖慢响应速度。
  • 上下文窗口限制:即使部分模型支持百万级上下文,仍然存在物理上限。
  • 注意力分散(Lost in the middle):在长文本中,模型容易忽略中间信息,导致回答质量下降。

RAG 正是在这样的背景下诞生的:在调用模型之前,先检索出与问题最相关的内容,再将其作为上下文提供给模型,从而提升回答质量。

传统 RAG 面临的困境

为了更清楚地理解问题,我们先看一下传统 RAG 的基本流程:

graph TD subgraph 离线知识库处理 A[企业私有文档] --> B[文本切块 Chunking] B --> C[向量化 Embedding] C --> D[(向量数据库 Vector DB)] end subgraph 在线问答检索 E[用户 Query] --> F[向量化 Embedding] F -->|相似度检索| D D -->|召回 Top-K 碎片| G[拼接 Prompt] G --> H[LLM 生成回答] end style A fill:#f3e5f5,stroke:#9c27b0 style E fill:#e8f5e9,stroke:#4caf50 style H fill:#fff3e0,stroke:#ff9800

问题往往出现在复杂场景中。传统 RAG 依赖于基于文本片段(Chunk)的语义相似度检索。当答案分散在多个位置时,向量检索通常只能返回若干“相似”的片段,而这些片段之间缺乏完整的逻辑关联。

换句话说,它更擅长“找相关内容”,但不一定能“还原完整答案”。

基于这一问题,本文尝试提出一种不同思路:一种基于 Agent 的层级化检索方案,也可以理解为“弱化 RAG”的方式。

破局思路:基于目录树的检索方式

需要说明的是,这种方法并非通用解法,更适用于金融、法律等对准确性和逻辑完整性要求较高的场景。

核心思想:让模型“像人一样阅读”

当人类查阅一本专业书籍时,通常不会逐页阅读或随机翻找,而是遵循一个自然过程:

先看目录 → 浏览章节 → 定位段落 → 精读内容

这一过程可以在系统中被复现为一种“分层检索机制”。

在工程实践中,可以按如下步骤实现:

  1. 目录隔离管理
    原始文件统一存放在 raw 目录;经过处理后的结构化数据存放在 data 目录,实现数据分层管理。

  2. 放弃简单切块
    不再进行传统的 Chunk 切分,而是以文档结构为核心进行处理。

  3. 生成文档概览
    使用模型对文档整体进行总结,生成标题与摘要。

  4. 构建目录树
    提取章节结构(如一级、二级标题),并为每个节点生成简要描述,递归构建完整目录树。

  5. 结构化存储
    将目录结构与摘要整理为 JSON 文件,保存到 data 目录。

  6. 构建全局索引
    更新统一入口文件(如 index.md),用于管理所有文档的结构信息。

数据结构示例

一个典型的目录树结构如下:

json
{
  "document_id": "doc_1024",
  "title": "2024年度企业财务合规指南",
  "summary": "本文档详细规定了企业在2024年度的财务报销、税务申报及内控合规审计的相关标准与流程。",
  "source_file": "raw/finance_guide_2024.pdf",
  "toc": [
    {
      "level": 1,
      "title": "第一章:报销规范",
      "description": "涵盖差旅、餐饮及日常办公用品的报销标准及各级审批流程。",
      "content_path": "data/doc_1024/chapter_1.md",
      "sub_sections": [
        {
          "level": 2,
          "title": "1.1 差旅费报销",
          "description": "国内及国际出差的交通工具等级限制、酒店限额及发票合规要求。"
        }
      ]
    }
  ]
}

检索与问答流程

在完成上述结构构建后,问答流程将发生变化:

graph TD A[用户 Query] --> B[Agent 阅读全局 index.md] B --> C{Agent 决策路径} C -->|定位章节| D[读取 JSON 目录树] D --> E[加载对应内容] C -->|跨文档分析| F[多节点联合读取] E --> G[生成回答] F --> G

这种方式本质上将知识组织为类似 Wiki 的结构化网络。 在回答问题时,Agent 先进行路径选择,再进行局部阅读,必要时跨文档整合信息,从而生成更完整的答案。

进阶问题:大文件与复杂格式

在实际应用中,还需要处理复杂文档,例如体量较大的 PDF 文件或包含表格、图片的资料。

这类问题可以通过“多模态数据清洗”解决。例如借助类似 MarkItDown 的工具,将 PDF 转换为 Markdown,并保留结构信息。

如果转换后的内容仍然较大,可以基于 Markdown 的标题结构(如 ###)进行自然分段,再逐段生成描述,最终构建目录树。

结语

与其不断优化向量检索的召回效果,不如尝试从结构化组织的角度重新思考问题。让 Agent 具备类似人类的“阅读路径”,往往能带来更稳定、可解释的结果。

如果你有建议或者想法,欢迎进一步交流。

版权声明

本文采用 CC BY-NC-SA 4.0 协议进行许可。转载请保留原文链接及作者。