数据截至 (上游 commit d8cdaa66c074)
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_list | raganything/parser.py |
separate_content | 把 content_list 拆成纯文本串 + 模态块列表 | raganything/utils.py |
模态处理器(*ModalProcessor) | 调 VLM/LLM 把单个图/表/公式翻译成描述 + 实体信息 | raganything/modalprocessors.py |
ProcessorMixin | 摄入主线:解析→分离→文本入库→模态批处理→接图谱 | raganything/processor.py |
QueryMixin | 三种查询;VLM 增强里把图片塞回检索 prompt | raganything/query.py |
BatchMixin | 整个文件夹/批量并发处理 | raganything/batch.py |
PROMPTS | 所有分析 prompt 与 chunk 模板 | raganything/prompt.py |
主线走一遍(高层)
一次 process_document_complete(processor.py:1648)的高层流程:
- 解析:解析器把文档变成
content_list(有序数组,每项是{type, ...}),见parse_document(processor.py:388)。 - 分离:
separate_content把type=="text"的拼成一大段文本,其余(image/table/equation/…)收进模态块列表。 - 文本入库:纯文本直接调 LightRAG 的
ainsert,走标准文本 RAG 流程。 - 模态处理:每个模态块各调对应处理器生成描述,再把描述当成 chunk 接进 LightRAG,并补一条
belongs_to关系把模态实体挂进图谱。
查询时,如果配了 VLM,aquery 默认走 VLM 增强:先让 LightRAG 检索出上下文 prompt,再把 prompt 里出现的图片路径换成真实图片喂给 VLM。
3. 阅读地图(各章建议顺序)
建议按顺序读,每章都先点题再下钻:
- 01-pipeline.md — 摄入主线:从一个 PDF 到知识图谱的 7 个阶段。先读这章建立全局。
- 02-modal-processors.md — 模态处理器:四个处理器如何「翻译」模态,鲁棒 JSON 解析,
belongs_to关系。这是项目工程含量最高的部分。 - 03-query.md — 三种查询:尤其是 VLM 增强查询「把图片塞回 prompt」的把戏与安全检查。
- 04-internals.md — 内部实现:解析器抽象、上下文抽取、doc_status 状态机、缓存,以及巧妙之处 / 边界 / 横向对比 / 代码地图。
4. 与底座 LightRAG 的关系(必读的一句)
RAG-Anything 和 LightRAG 是同一团队(HKUDS)的上下游:LightRAG 提供「文本 → 知识图谱 → 混合检索」的底座,RAG-Anything 在其上加多模态。代码里大量 from lightrag... 的 import 不是巧合——extract_entities、merge_nodes_and_edges、各种 *_vdb 存储都是直接复用 LightRAG 的。本库的所有「精华」都集中在怎么把模态优雅地嫁接到这套文本底座上,而不是重写 RAG。横向对比见 04-internals.md §横向对比。