Post

HKUDS007: RAG-Anything 作为 Multimodal Document Ingestion 与 All-in-One RAG Layer

HKUDS007: RAG-Anything 作为 Multimodal Document Ingestion 与 All-in-One RAG Layer

这是 PENGYI_HKUDS_STUDYMAP 的第八篇。

1
HKUDS007 -> RAG-Anything

到目前为止,HKUDS 第一阶段我们已经看了:

1
2
3
4
5
6
7
HKUDS000 -> study map
HKUDS001 -> LightRAG
HKUDS002 -> Vibe-Trading
HKUDS003 -> nanobot
HKUDS004 -> CLI-Anything
HKUDS005 -> AI-Trader
HKUDS006 -> AgentSpace

现在来看 RAG-Anything。我对它的定位是:

1
RAG-Anything = Multimodal Document Ingestion + All-in-One RAG Layer

如果说:

1
2
3
4
5
6
LightRAG     = research memory / graph RAG memory
Vibe-Trading = quant research workflow
nanobot      = personal agent shell
CLI-Anything = software action layer
AI-Trader    = live trading platform layer
AgentSpace   = organizational agent workspace

那么:

1
RAG-Anything = 把复杂文档、图片、表格、公式、Office 文件、PDF 抽取成可进入 RAG 和知识图谱的多模态知识入口层

这对 Pengyi Research OS 很关键。真实研究资料不是干净的纯文本。金融研报、FICC 文档、公司年报、三张表、授信材料、合同、论文 PDF、PPT、图表、公式、截图,全部都是混合形态。如果没有一个文档入口层,后面的 research memory、quant workflow、agent planning 都会缺少稳定的数据地基。

Local Snapshot

这次阅读的是本地 HKUDS 工作区里的 RAG-Anything

ItemValue
repoRAG-Anything
remotehttps://github.com/HKUDS/RAG-Anything.git
branchmain
local head32eef6e
latest local commitdocs(README): add latest news entries
statusclean, synced with origin/main
licenseMIT
packageraganything
core dependencyLightRAG
parser optionsMinerU, Docling, PaddleOCR
Python requirementREADME recommends Python 3.10; pyproject.toml uses Python >= 3.10

本地规模:

MetricCount
total files57
main packageraganything/
docsdocs/
examplesexamples/
teststests/

核心目录:

1
2
3
4
5
6
7
8
9
10
11
raganything/
  raganything.py
  processor.py
  query.py
  batch.py
  parser.py
  modalprocessors.py
  config.py
  callbacks.py
  resilience.py
  utils.py

这说明它不是一个单页 demo,而是一个相对完整的文档处理框架:有 parser、有 processor、有 query、有 batch、有 callback、有 cache、有 failure-mode 文档,也有不同 parser 的测试。

1. 项目用途

RAG-Anything 要解决的问题很明确:

1
2
传统 RAG 假设输入是 text chunks。
真实文档通常是 text + image + table + equation + layout + page context。

所以它要做的是:

1
复杂文档 -> multimodal content_list -> text insertion + modal processing -> LightRAG storage / KG / retrieval -> text or multimodal query

它不是只做 OCR,也不是只做 PDF 解析。它是一个 all-in-one multimodal RAG framework,核心价值在于把复杂文档的内容拆开、理解、写入检索系统,并且在查询时允许文本查询、VLM 增强查询、多模态查询一起工作。

适用场景包括:

1
2
3
4
5
6
7
8
9
10
academic papers
technical reports
financial reports
enterprise documents
contracts
slides
tables
equations
images
mixed-format knowledge bases

对我们来说,它最重要的用途是:

1
把真实世界的 research material 变成 Research OS 可以调用的知识资产。

这一步在量化和 AI scientist 路线里都非常基础。没有 ingestion layer,后面所有 agent 都只能处理零散文本;有 ingestion layer,agent 才能读论文、读研报、读财报、读图表、读公式、读复杂材料。

2. 实现方式

RAG-Anything 的主类是:

1
RAGAnything(QueryMixin, ProcessorMixin, BatchMixin)

这个继承结构已经说明它的系统分工:

LayerResponsibility
RAGAnything总入口,管理 LightRAG、parser、config、modal processors
ProcessorMixin文档解析、cache、文本插入、多模态内容处理
QueryMixin纯文本查询、VLM 增强查询、多模态查询
BatchMixin文件夹级批处理、并发处理、失败统计

它的大流程可以概括成六步:

1
2
3
4
5
6
1. parse document
2. produce content_list
3. separate text and multimodal items
4. insert text into LightRAG
5. process image/table/equation/generic modal items
6. query through LightRAG, VLM, or multimodal query interface

2.1 Document Parsing

入口在 raganything/parser.py

它支持三类 parser:

1
2
3
MinerU
Docling
PaddleOCR

支持的文件类型包括:

1
2
3
4
5
PDF
Office: doc, docx, ppt, pptx, xls, xlsx
Images: png, jpeg, jpg, bmp, tiff, tif, gif, webp
Text: txt, md
HTML / other document formats depending on parser path

Office 文档需要额外注意:项目里有 LibreOffice 转 PDF 的路径。也就是说,真实部署时不能只 pip install,还要检查本机是否有 LibreOffice、MinerU、Docling、PaddleOCR 等外部依赖。

这里有一个很工程化的细节:在 Windows 上,MinerU 处理非 ASCII 路径可能有问题,所以测试里覆盖了“unsafe filename -> safe hashed path”的逻辑。这个细节对我们本地中文路径工作区非常重要。

2.2 content_list

解析后的中间表示是 content_list

它大概长这样:

1
2
3
4
5
6
[
    {"type": "text", "text": "...", "page_idx": 0},
    {"type": "image", "img_path": "...", "caption": "...", "page_idx": 1},
    {"type": "table", "table_body": "...", "caption": "...", "page_idx": 2},
    {"type": "equation", "latex": "...", "text": "...", "page_idx": 3},
]

这个中间层非常关键。它把复杂文档从“文件”变成“结构化内容单元”。

对 Research OS 来说,content_list 是一个可以复用的 schema:

1
2
3
4
5
PDF parser output
manual extraction output
paper parser output
finance report parser output
private document pipeline output

只要能转成 content_list,后续就可以绕过 parser,直接进入 RAG-Anything 的处理流程。项目也专门提供了 insert_content_list 示例,说明它并不强制绑定某一个 parser。

2.3 Text + Multimodal Split

raganything/utils.py 里的 separate_content 会把内容拆成两路:

1
2
text_content
multimodal_items

文本走 LightRAG 的普通插入逻辑。图片、表格、公式等内容会保留类型、页码、邻近文本、section path 等上下文,然后交给对应 modal processor。

这里有一个正确的设计判断:

1
不要把所有东西粗暴压平成文本。

图、表、公式本身有结构。直接压平成文本会丢失布局、表格关系、图文对应关系、公式语义。RAG-Anything 试图保留这些结构,然后再进入图谱和检索。

2.4 Modal Processors

多模态处理的核心在 raganything/modalprocessors.py

主要 processor 包括:

ProcessorPurpose
ImageModalProcessor分析图片、图表、截图、视觉内容
TableModalProcessor解释表格、结构化数据、趋势关系
EquationModalProcessor处理公式、LaTeX、数学表达
GenericModalProcessor处理其他非文本内容
ContextExtractor为多模态内容补上下文

modal processor 不只是生成 caption。它会把多模态内容变成 LightRAG 可以管理的 chunk、entity、relationship,并写入对应的 vector DB 和 knowledge graph。

这就是它和普通 OCR pipeline 的差异:

1
2
OCR pipeline: image -> text
RAG-Anything: multimodal item -> context-aware description + chunk + entity + relationship + KG insertion

2.5 LightRAG Integration

RAG-AnythingLightRAG 的关系不是替代,而是扩展。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
LightRAG:
  storage
  graph
  vector DB
  KV storage
  query modes
  entity / relationship retrieval

RAG-Anything:
  complex document parsing
  multimodal content routing
  modal processors
  content_list insertion
  VLM enhanced query
  batch processing

也就是说:

1
2
LightRAG = memory substrate
RAG-Anything = multimodal ingestion and query extension

这对我们的系统拼图很重要。不要把每个项目孤立看。RAG-Anything 是把真实世界资料送进 LightRAG 的入口层。

3. 关键组件

3.1 raganything.py

raganything.py 是总控制器。

它做几件事:

1
2
3
4
5
6
7
1. 初始化 config
2. 初始化 parser
3. 初始化 working directory
4. 初始化或接入 LightRAG
5. 初始化 parse cache 和 multimodal status cache
6. 初始化 image/table/equation/generic modal processors
7. 注册 close 清理逻辑

一个实用点:它允许传入已经存在的 LightRAG 实例。这样我们可以先有自己的 LightRAG memory,再把 RAG-Anything 接进来。

这对 Pengyi Research OS 很适合:

1
2
先有统一 research memory
再让 RAG-Anything 成为其中一个 ingestion adapter

3.2 processor.py

processor.py 是文档处理主干。

关键能力:

1
2
3
4
5
6
7
parse_document
process_document_complete
_process_multimodal_content
insert_content_list
parse cache
document status
multimodal status

它的 parse cache key 会考虑:

1
2
3
4
5
absolute file path
mtime
parser
parse_method
parser kwargs

这意味着同一个文件没有变化时可以复用解析结果。对大 PDF、Office 文件、研报来说,这个 cache 非常重要,因为解析通常是最慢、最容易失败、最昂贵的一层。

process_document_complete 是最主要的 end-to-end 入口:

1
2
3
4
5
6
file_path
  -> parse_document
  -> separate_content
  -> insert text into LightRAG
  -> process multimodal items
  -> mark status

insert_content_list 则是另一个重要入口:如果我们未来自己写 WorldQuant 因子文档整理器、研报 parser、论文 parser、合同 parser,只要输出 content_list,就可以直接进入这条路线。

3.3 query.py

查询层有三种关键模式。

第一种是纯文本查询:

1
await rag.aquery("What are the main findings?", mode="hybrid")

它会走 LightRAG 的 query mode,例如:

1
2
3
4
5
6
local
global
hybrid
naive
mix
bypass

第二种是 VLM-enhanced query。当系统有 vision_model_func 时,它可以在查询结果里识别相关图片路径,把图片编码后交给 vision model,让回答不只基于文本。

第三种是显式多模态查询:

1
2
3
4
5
6
7
await rag.aquery_with_multimodal(
    "Explain this equation in the context of the document.",
    multimodal_content=[
        {"type": "equation", "latex": "..."}
    ],
    mode="hybrid",
)

这类接口很适合研究场景:

1
2
3
4
拿一张图问论文结论
拿一个表问财务趋势
拿一个公式问模型假设
拿一段截图问它在整篇文档里的意义

3.4 batch.py

batch.py 负责批处理。

主要能力:

1
2
3
4
5
process_folder_complete
process_documents_batch
process_documents_batch_async
process_documents_with_rag_batch
filter_supported_files

它支持:

1
2
3
4
5
6
folder scan
recursive scan
supported extensions filtering
concurrency via asyncio.Semaphore
success / failure statistics
dry run

这对研究资产库非常重要。真实场景不是“传一个 PDF”,而是:

1
2
3
4
100 篇论文
500 份研报
一批公司公告
一个文件夹的 PPT / PDF / Excel

RAG-Anything 已经把批处理作为一等能力放进系统里,而不是后面临时写脚本。

3.5 callbacks.py

callbacks.py 提供 lightweight callback system。

它覆盖的事件包括:

1
2
3
4
5
6
parse start / complete / error
text insert start / complete
multimodal start / item complete / complete
query start / complete / error
document complete / error
batch start / complete

还有 MetricsCallback

这个设计适合接入我们的 Research OS:

1
2
3
4
5
每次 ingest 的耗时
每个文档失败在哪一步
多模态 item 有多少
每次 query 的延迟和错误
批处理的成功率

未来如果做 dashboard,这些 callback 就是天然的观测点。

3.6 resilience.py

resilience.py 提供 retry 和 circuit breaker。

它主要面向:

1
2
3
4
network error
timeout
API transient failure
upstream temporary failure

这对多模态 RAG 很现实。文档解析可能调用外部工具,LLM/VLM 调用可能超时,embedding 可能失败。如果没有 retry 和熔断,批量 ingest 很容易被一个临时错误打断。

3.7 config.py

配置项覆盖了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
working_dir
parser
parse_method
output_dir
image/table/equation processing switches
max concurrent files
supported file extensions
recursive folder processing
context window
context mode
max context tokens
headers / captions inclusion
content format
use full path

也就是说,它不仅能跑 demo,也在考虑真实工程部署时的可调参数。

4. Context-Aware Processing

docs/context_aware_processing.md 是一个很关键的文档。

多模态内容不能脱离上下文理解。比如:

1
2
3
4
一张图在不同章节里含义不同
一个表格需要标题和前后段落解释
一个公式需要知道符号定义
一个截图需要知道来源页面

所以 RAG-Anything 提供 ContextExtractor,支持:

1
2
3
4
5
6
7
page-based context
chunk-based context
context_window
max_context_tokens
include_headers
include_captions
filter_content_types

对金融和科研文档,这一点非常重要。

一个表格本身只是数字;它前面的段落可能说“单位为百万元”,后面的段落可能解释“同比增长来自一次性收入”。如果只抽表,不抽上下文,后面的 agent 很容易误读。

5. Failure Modes

docs/multimodal_rag_failure_modes.md 非常值得我们保留为 checklist。

多模态 RAG 常见失败包括:

Failure ModeMeaning
OCR/layout silently corrupts textOCR 看似成功,但内容顺序、列、标题错了
table structure lost表格被压成普通文本,行列关系消失
image-caption misalignment图片和 caption / nearby text 对错
retrieval biased toward text检索只命中文本,忽略图片和表格
slow vs stuck不知道系统是在慢跑还是卡死
local image path issueUI 或远程环境无法访问本地图片路径

这份 checklist 对 Pengyi Research OS 很有价值。我们未来不是只要“能跑”,而是要能诊断:

1
2
3
4
5
6
7
是哪一步坏了?
parser 坏了?
OCR 坏了?
table schema 坏了?
image path 坏了?
retrieval ranking 坏了?
VLM 没有真正看到图?

这个诊断能力是 R&D Agent 的关键。

6. Tests Reveal Engineering Boundary

测试文件说明了一些工程边界。

testparser_wiring.py 覆盖:

1
2
3
BatchParser 可以选择 PaddleOCR parser
RAGAnything 初始化时可以选择 parser
ProcessorMixin parse_document 使用选中的 parser

testparser_kwargs.py 覆盖:

1
2
3
4
5
6
MinerU env propagation
Docling Python API path
unknown kwargs behavior
invalid env type
Windows unsafe filename safe path
Docling converter cache

testpaddleocr_parser.py 覆盖:

1
2
3
4
5
6
7
SUPPORTED_PARSERS includes paddleocr
get_parser returns PaddleOCRParser
unknown parser rejection
import parser module does not eagerly import paddleocr
missing dependency behavior
parse image content_list schema
parse PDF page index

这说明这个项目在处理真实用户环境时已经踩过一些坑:

1
2
3
4
5
不同 parser 的依赖很重
Windows 路径会出问题
Docling CLI / Python API 会迁移
PaddleOCR 不应该被 eager import
parser kwargs 要有边界

这些都是我们以后提 PR 或自己做 Research OS 时需要特别关注的地方。

7. 和 LightRAG / Vibe-Trading / AI-Trader / AgentSpace 的关系

现在 HKUDS 这组项目的拼图越来越清楚。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
RAG-Anything
  -> ingest PDFs, Office docs, images, tables, equations

LightRAG
  -> store and retrieve structured research memory

Vibe-Trading
  -> turn research intent into quant workflow, code, backtest, evidence

AI-Trader
  -> move from research workflow toward live trading platform and agent competition

AgentSpace
  -> organize human + agents as teams with ownership, permissions, runtime, audit

所以:

1
2
3
4
5
RAG-Anything 是资料入口。
LightRAG 是知识记忆。
Vibe-Trading 是研究动作。
AI-Trader 是交易平台。
AgentSpace 是组织工作空间。

这就非常接近一个真实的 AI research organization stack。

8. 对 Pengyi Quant Research OS 的启发

8.1 数据源问题可以拆成两层

我们之前一直在想 quant research 的数据源问题。RAG-Anything 给了一个提示:数据源不只是行情数据。

可以拆成两层:

1
2
market data / factor data
research document data

前者是价格、成交量、财务指标、订单簿、另类数据。后者是研报、论文、公告、财报、会议纪要、策略文档、投研笔记。

RAG-Anything 主要解决第二层:

1
research document data -> structured multimodal knowledge

这会直接增强 R&D Agent 的假设生成能力。

8.2 R&D Agent 需要 ingestion layer

我们想做的 R&D Agent 是:

1
2
3
4
5
6
自动提出因子假设
自动实现
自动回测
自动诊断偏差
自动生成下一轮研究计划
人类 PM 审核

但它提出假设不能只靠模型自己的参数记忆。它需要读材料:

1
2
3
4
5
6
7
8
paper
news
blog
PDF
research report
financial statement
factor docs
strategy memo

RAG-Anything 就是“读材料”的工程入口。

8.3 真实文档要注意合规和脱敏

如果我们用公司材料、银行材料、授信材料、WorldQuant 因子库、内部合同、客户资料,就必须区分:

1
2
private research workspace
public website / public GitHub

公开版本只能使用:

1
2
3
4
5
6
公开论文
公开研报
公开数据
自造样例
脱敏样例
获得授权的材料

这一点必须写进 Research OS 的规则里。RAG-Anything 能处理复杂文档,但这不代表我们可以把任何文档公开化。

9. 可以怎么用起来

一个最小 Pengyi workflow 可以是:

1
2
3
4
5
6
7
8
1. 建立 private research corpus
2. 放入公开论文、公开财报、公开研报、自己写的研究笔记
3. 用 RAG-Anything batch ingest
4. 进入 LightRAG memory
5. 用 Vibe-Trading / 自己的 Quant R&D Agent 查询知识
6. 生成 factor hypothesis
7. 人类 PM 审核
8. 进入 backtest / evidence ledger

如果公开展示,可以做一个 sanitized demo:

1
2
3
4
5
sample paper PDF
sample annual report
sample table
sample equation
sample chart image

然后展示:

1
2
3
4
RAG-Anything ingest
LightRAG retrieve
agent produces research note
human PM checklist

这个 demo 很适合我们的网站和 GitHub portfolio。

10. 可以提 PR 的方向

不是为了提 PR 而提 PR。要从真实使用中找改进点。

可能的 PR 方向:

DirectionWhy Useful
Windows + LibreOffice setup guide我们本地中文路径、Windows 环境很容易遇到坑
finance report ingestion example对 HKUDS 和我们的 quant 路线都自然
content_list schema doc帮助外部 parser 接入 RAG-Anything
parser failure checklist把 failure modes 转成更可执行的 debug guide
VLM media path docs本地图片路径、public URL 映射是真实部署痛点
callback metrics example展示 ingest dashboard 如何接入
offline setup Windows guidetiktoken/cache/网络限制在国内环境常见
LightRAG interop guide说明如何接入已有 LightRAG instance

最适合我们的方式是:

1
2
3
先自己跑通一个公开样例
记录真实卡点
把卡点整理成 issue 或 PR

这样贡献才是自然的、可信的。

11. 和 QuantMind / X2Strategy 的关系

我们之前比较过 QuantMind 和 X2Strategy。

现在可以再加一层:

1
2
3
4
RAG-Anything -> 把复杂资料转成可检索知识
QuantMind    -> 把金融知识组织成结构化 knowledge
X2Strategy   -> 把 paper / idea 继续推向 strategy generation / backtest
Vibe-Trading -> 把自然语言研究意图变成 agentic quant workflow

所以它们不是互斥关系,而是上下游关系:

1
documents -> multimodal knowledge -> structured finance knowledge -> strategy idea -> implementation -> backtest -> diagnosis

对我们的 R&D Agent 来说,这条链路非常清楚:

1
2
3
4
RAG-Anything / LightRAG = read and remember
QuantMind = structure finance knowledge
Vibe-Trading / X2Strategy = act on strategy research
Human PM = review and decide

12. Pengyi Version

如果把它放进 Pengyi Research OS,我会这样命名:

1
2
3
4
5
6
7
8
9
10
11
12
13
Pengyi Research OS
  ingestion/
    rag_anything_adapter/
  memory/
    lightrag/
  knowledge/
    quantmind_schema/
  workflow/
    vibe_trading_orchestrator/
  trading/
    ai_trader_reference/
  organization/
    agentspace_reference/

RAG-Anything 对应的不是最终交易系统,而是最前面的资料入口:

1
raw documents -> structured multimodal knowledge

这一步做扎实,后面的 AI scientist、quant researcher、R&D agent 才有真实的知识燃料。

13. Study Map Position

现在 HKUDS map 可以更新成:

IDProjectPengyi Interpretation
HKUDS000Study Map第一阶段项目地图
HKUDS001LightRAGsource-grounded research memory
HKUDS002Vibe-Tradingagentic quant research workflow
HKUDS003nanobotpersonal always-on agent shell
HKUDS004CLI-Anythingagent-native software action layer
HKUDS005AI-Traderagent-native live trading platform layer
HKUDS006AgentSpaceorganizational agent workspace
HKUDS007RAG-Anythingmultimodal document ingestion and all-in-one RAG layer

HKUDS007 的一句话总结:

1
RAG-Anything 是把真实世界复杂文档送进 Research OS 的多模态入口层。

对我们来说,这不是边缘项目,而是非常核心的 infrastructure。因为我们要成为 AI scientist,不是只写代码,也不是只聊天,而是要让系统能持续吸收材料、形成记忆、提出假设、执行实验、复盘结果。

RAG-Anything 正好站在这个链路的第一步。

This post is licensed under CC BY 4.0 by the author.