跳到主要内容

RAG-Anything — 架构与原理

30 秒导读: 传统 RAG 只会读文字,碰到 PDF 里的图、表、公式就抓瞎。RAG-Anything 给每种「非文字」内容配一个专门的分析器(图给 VLM、表/公式给 LLM),让它们各自生成一段文字描述,然后把描述当成普通文本喂进 LightRAG 的知识图谱。于是「这张图说明了什么」「这个表的趋势是什么」也能被检索和问答。

1. 这是什么(零基础也能懂)

一句话定义: RAG-Anything 是一个多模态文档 RAG 框架——把一份混排了文字、图片、表格、公式的文档,整体喂进一个能被自然语言提问的知识库。

它解决谁的什么问题。 假设你有一篇学术论文 PDF,里面关键结论藏在「图 3 的曲线」和「表 2 的数字」里。普通 RAG 把 PDF 抽成纯文字时,图和表要么被丢掉、要么变成无意义的 [image] 占位。于是你问「实验结果如何」,系统答不上来,因为答案根本没进知识库。RAG-Anything 就是来补这一刀的。

核心直觉:把每种模态翻译成文字。 这是整个项目最重要的一个心智模型:

系统直接对图片做向量检索。它先让视觉模型(VLM)"看图说话",把图变成一段详细文字描述;表和公式同理交给 LLM 解读成文字。之后一切都是文本 RAG——图表公式都以它们的「文字代理」身份进入知识图谱。

这一步想通了,后面的架构就顺理成章:难点全在「怎么把模态翻译得准、怎么把代理文本接回文本图谱」。

它能做什么:

  • 解析 PDF / Office / 图片 / 文本(三种可换的解析器:MinerU、Docling、PaddleOCR)
  • 对图、表、公式分别用专门的处理器生成描述并抽取实体
  • 把所有内容(文字 + 模态代理文本)汇入一张多模态知识图谱
  • 三种查询:纯文本检索、带多模态内容的查询、VLM 增强查询(检索后把相关图片真的喂给 VLM 看)

用起来什么样: 一段最小真实调用(摘自 README):

# 示意,基于 README "End-to-End Document Processing"
rag = RAGAnything(
config=RAGAnythingConfig(working_dir="./rag_storage", parser="mineru"),
llm_model_func=llm_model_func, # 文本 / 表 / 公式分析
vision_model_func=vision_model_func, # 图片分析(VLM)
embedding_func=embedding_func,
)

# 解析 + 入库:一行搞定整篇 PDF
await rag.process_document_complete(file_path="paper.pdf", output_dir="./output")

# 问图问表,普通文本查询接口即可
answer = await rag.aquery("图表里展示的主要发现是什么?", mode="hybrid")

一句话类比: 把 RAG-Anything 想成一个**「随身翻译官 + 老资料员」**的组合:翻译官(模态处理器)先把图表公式翻成大白话,资料员(LightRAG)再把所有大白话归档进一张关系网。你问问题时,资料员去关系网里找,翻译官在必要时还能把原图调出来再看一眼(VLM 增强)。

2. 顶层全景(它大概怎么转)

RAG-Anything 本身不重新发明 RAG。它是一层薄薄的「多模态门面」,真正的图谱构建、向量检索、实体合并全都委托给底座 LightRAG。它自己只负责三件事:解析文档、把模态翻译成文字、把翻译结果接进 LightRAG 的内部存储

怎么读这张图

从左到右是数据流向。上半是**摄入(写)路径,下半是查询(读)**路径。中间那条竖线是边界:线左是 RAG-Anything 自己的代码,线右是它调用的 LightRAG 底座。

RAG-Anything 自己 | LightRAG 底座
──────────────────────────────────────────────────┼──────────────────────────
文档(PDF/Office/图/文本) |
│ |
▼ |
① 解析器(MinerU/Docling/PaddleOCR) |
│ 产出 content_list:有序的内容块数组 |
▼ |
② separate_content:拆成「纯文本」+「模态块」 |
│ │ |
纯文本 │ 模态块 │ |
│ ▼ |
│ ③ 模态处理器(图/表/公式/通用)|
│ 调 VLM/LLM 生成描述+实体 |
│ │ |
▼ ▼ |
└──────────┬───────────────┘ |
▼ |
④ 接进 LightRAG 存储 ───────────────────┼──▶ text_chunks / chunks_vdb
(chunk + 实体 + belongs_to 关系) | entities_vdb / 知识图谱
| full_entities ...
──────────────────────────────────────────────────┼──────────────────────────
用户提问 |
│ |
▼ |
⑤ aquery ──(VLM 增强?)──────────────────────────┼──▶ LightRAG 检索出 prompt
│ | │
▼ | ▼
⑥ 把 prompt 里的图片路径换成 base64 ◀────────────┼── only_need_prompt 拿回
│ |
▼ |
⑦ 调 VLM 看图作答 ─────────────────────────────▶ 最终答案

部件一句话职责

部件干什么在哪个文件
RAGAnything总门面,组合三个 Mixin,管理 LightRAG 生命周期与处理器初始化raganything/raganything.py
RAGAnythingConfig全部配置(解析器、各模态开关、上下文窗口),支持环境变量raganything/config.py
解析器(Parser 子类)把任意格式文档转成统一的 content_listraganything/parser.py
separate_contentcontent_list 拆成纯文本串 + 模态块列表raganything/utils.py
模态处理器(*ModalProcessor)调 VLM/LLM 把单个图/表/公式翻译成描述 + 实体信息raganything/modalprocessors.py
ProcessorMixin摄入主线:解析→分离→文本入库→模态批处理→接图谱raganything/processor.py
QueryMixin三种查询;VLM 增强里把图片塞回检索 promptraganything/query.py
BatchMixin整个文件夹/批量并发处理raganything/batch.py
PROMPTS所有分析 prompt 与 chunk 模板raganything/prompt.py

主线走一遍(高层)

一次 process_document_complete(processor.py:1660)的高层流程:

  1. 解析:解析器把文档变成 content_list(有序数组,每项是 {type, ...}),见 parse_document(processor.py:388)。
  2. 分离:separate_contenttype=="text" 的拼成一大段文本,其余(image/table/equation/…)收进模态块列表。
  3. 文本入库:纯文本直接调 LightRAG 的 ainsert,走标准文本 RAG 流程。
  4. 模态处理:每个模态块各调对应处理器生成描述,再把描述当成 chunk 接进 LightRAG,并补一条 belongs_to 关系把模态实体挂进图谱。

查询时,如果配了 VLM,aquery 默认走 VLM 增强:先让 LightRAG 检索出上下文 prompt,再把 prompt 里出现的图片路径换成真实图片喂给 VLM。

3. 阅读地图(各章建议顺序)

建议按顺序读,每章都先点题再下钻:

  1. 01-pipeline.md — 摄入主线:从一个 PDF 到知识图谱的 7 个阶段。先读这章建立全局。
  2. 02-modal-processors.md — 模态处理器:四个处理器如何「翻译」模态,鲁棒 JSON 解析,belongs_to 关系。这是项目工程含量最高的部分。
  3. 03-query.md — 三种查询:尤其是 VLM 增强查询「把图片塞回 prompt」的把戏与安全检查。
  4. 04-internals.md — 内部实现:解析器抽象、上下文抽取、doc_status 状态机、缓存,以及巧妙之处 / 边界 / 横向对比 / 代码地图。

4. 与底座 LightRAG 的关系(必读的一句)

RAG-Anything 和 LightRAG 是同一团队(HKUDS)的上下游:LightRAG 提供「文本 → 知识图谱 → 混合检索」的底座,RAG-Anything 在其上加多模态。代码里大量 from lightrag... 的 import 不是巧合——extract_entitiesmerge_nodes_and_edges、各种 *_vdb 存储都是直接复用 LightRAG 的。本库的所有「精华」都集中在怎么把模态优雅地嫁接到这套文本底座上,而不是重写 RAG。横向对比见 04-internals.md §横向对比。