跳转至

RAG 学习路径

从 RAG 基础到生产环境运维 Eagle-RAG 的 curated 路径。每一级说明概念为何重要、映射到 Eagle-RAG 代码,并指向更深文档。

前置知识

开始前,你应熟悉:

  • Python 异步基础(FastAPI 处理器、Celery worker)
  • 向量数据库概念 — 嵌入、近似最近邻(ANN)搜索
  • LLM API — 对话补全、流式 token

本地文档站

运行 task docs:serve,在 http://localhost:8001 浏览。


Level 0 — 数学与系统背景

稠密检索一页纸

给定查询 \(q\) 与语料块 \(\{c_i\}\),稠密检索:

  1. 编码 \(q \rightarrow \mathbf{e}_q \in \mathbb{R}^d\),各 \(c_i \rightarrow \mathbf{e}_{c_i}\)
  2. 按相似度排序 — 通常在 L2 归一化向量上用余弦内积(IP)
  3. 返回 top-\(k\) 块用于构造提示

HNSW 通过多层邻近图导航,以亚线性时间近似第 2 步。Eagle-RAG 在 eagle_rag/index/milvus_visual_store.py 中对 L2 归一化的 2048 维视觉向量使用 IP — 数学上等价于余弦相似度。

优先阅读的论文

论文 年份 贡献 Eagle-RAG 映射
Lewis 等 2020 RAG = 检索 + 生成 EagleRouterQueryEngine.query()EagleMultimodalQueryEngine
Gao 综述 2023 完整 RAG 分类 分块(chunks_to_text_nodes)、重排(qwen3-rerank)、混合检索
MuRAG 2022 多模态证据检索 双 collection eagle_text + eagle_visual
HNSW 2016 图 ANN MILVUS_VISUAL_INDEX_TYPE=hnsw
DiskANN 2019 大规模磁盘 ANN MILVUS_VISUAL_INDEX_TYPE=diskann

Level 1 — RAG 基础

RAG 解决什么问题?

无检索时,LLM 可能幻觉事实或用过时训练数据作答。RAG 在生成前插入检索步骤

flowchart LR
    Q[User question] --> E[Embed query]
    E --> R[Retrieve top-k chunks]
    R --> P[Build prompt with context]
    P --> G[LLM generates answer]
    G --> A[Answer + citations]

经典流水线 — 分块 → 嵌入 → 索引 → 检索 → 生成 — 见 LlamaIndex RAG 概念

Eagle-RAG 映射

RAG 阶段 Eagle-RAG 组件 关键函数 / 模块 文档
解析与分块 Knowhere 类型化块 + PixelRAG 切片 parse_with_knowhere_sdk()pixelrag_build 摄入管线
嵌入 Qwen 文本 1536 维 + 视觉 2048 维 upsert_text_nodes()upsert_visual() 向量存储
检索 混合文本 + 视觉、标量过滤 EagleRouterQueryEngine.retrieve() 检索
重排 DashScope qwen3-rerank EagleMultimodalQueryEngine 生成
生成 Qwen-VL-Max 基于检索上下文 custom_query()stream_custom_query() 生成

动手:验证文本管线

task setup && task up
# 经前端或 POST /ingest 摄入 .md 文件
# 以 mode=text 查询
curl -s localhost:8000/query -H 'Content-Type: application/json' \
  -d '{"query":"What is in the document?","mode":"text","kb_name":"default"}' | jq .

Level 1 调参

概念 Eagle-RAG 旋钮 延伸阅读
ANN 召回 vs 延迟 HNSW ef、检索 top_k 向量存储
双编码器 → 交叉编码器鸿沟 top_k 后 gte-rerank top_n 生成
父文档噪声 section_summary + path 前缀下钻 检索
图扩展 token Knowhere 块中 connect_to 检索

外部参考


Level 2 — 多模态与路由

为何单一管线不够

纯文本 RAG 在答案位于图表、表格版式或示意图时失败。如 「见图 3」 无法召回像素。

flowchart TB
    Q[User query] --> R[Router Engine]
    R -->|text| T[KnowhereGraphRetriever]
    R -->|visual| V[PixelRAGVisualRetriever]
    R -->|hybrid| T
    R -->|hybrid| V
    T --> G[EagleMultimodalQueryEngine]
    V --> G
    G --> A[Answer + sources]

摄入路由 vs 查询路由

这是不同决策点:

时机 函数 决定
文档上传 eagle_rag/ingest/router.py route() Knowhere vs PixelRAG 管线
用户问题 eagle_rag/router/router_engine.py route_query() text / visual / hybrid 检索器

摄入路由用 PDF 形态探测(probe_pdf_form)、扩展名列表与文件名前缀。查询路由用 DeepSeek 分类或关键词启发式。

代码走读:route()(摄入)

# eagle_rag/ingest/router.py — 简化控制流
def route(...) -> list[str]:
    cfg = get_settings().ingest.routing
    ctx = _build_context(filename, content_type, source_uri, local_path, kb_name, ...)
    chain = _build_chain(cfg, probe=probe_pdf_form)
    return chain.select(ctx)  # ["knowhere"] | ["pixelrag"] | both

选择器优先级(首个非 None 胜出):

  1. PrefixSelectorknowhere: / pixelrag: 文件名前缀
  2. ForcedModeSelectorsettings.router.modeauto
  3. HttpUriSelector — URL → PixelRAG
  4. PdfFormSelector.pdfprobe_pdf_form()
  5. ExtensionSelector — 配置的扩展名列表
  6. ContentTypeSelector — MIME 回退
  7. 默认 — knowhere

完整走读:路由矩阵

融合锚定字段

Knowhere 解析含嵌入图/表的文档时,extract_visual_chunks() 按序遍历块,将最近文本块的 path 记为 parent_section。视觉向量写入 eagle_visual 并带四个锚定字段 — 见 多模态融合

清单

动手:对比管线

  • 摄入文本 PDF扫描 PDF;在 /tasks 对比任务日志
  • 对含图表文档运行 hybrid 查询
  • 打开 GET /documents/{id}/structure — 验证 doc_nav

外部参考


Level 3 — 生产 RAG

生产 RAG 意味着隔离降级可观测 — 不只是更大的 top_k

多租户(plugin_namespace + kb_name

Eagle-RAG 在单集群内使用两层隔离

标识符 机制
plugin_namespace Milvus Database + PostgreSQL 仓库过滤(部署时)
KB kb_name 该 Database 内标量过滤(请求时)

同一域 Database 内,多个 KB 共享基础集合(eagle_texteagle_visual)及可选专用集合。隔离靠 kb_name 标量过滤 — 非每 KB 独立 Milvus 集合。

kb_name == 'pharma' and document_id in ['doc_a', 'doc_b']

去重键 (sha256, kb_name, plugin_namespace) 允许同一文件存在于多 KB 与域(不同实例上)。详见 多租户

可靠性模式

模式 代码位置 效果
@with_retry + 死信 eagle_rag/tasks/dead_letter.py 指数退避;耗尽 → dead_letter 队列
检索器空列表 EagleRouterQueryEngine._fetch_nodes() 记录警告;继续其他模态
非阻塞视觉派发 dispatch_visual_chunks() 视觉队列失败时文本索引仍成功
任务状态机 eagle_rag/tasks/state.py 非法转移抛错 — 审计一致

范围过滤(高级检索)

QueryRequest.scope_filter = {kb_names, document_ids, tags}并集(OR)语义。标签经 document_keywordsresolve_tags_to_document_ids()。上限 router.max_scope_documents(默认 500)。

检索架构与引文质量

生产检索不止 "更大的 top_k",还关乎多空间融合、证据收敛与可核对的引文。四个概念正本:

概念 一句话 深入
多向量检索 单查询扇出多 (collection, encoder) 空间,空间内 hybrid、跨空间 RRF 秩序融合(不比分数) 多向量检索
证据聚合 RRF 后去重 / 候选注入 / 合并重排,收敛为连贯证据集 证据聚合
Citationware RAG 答案带 [n] 内联引文 + hovercard,sources 携带溯源坐标 Citationware RAG
Agent 可观测性 trace / metrics / IO / state 四层定位 agent 执行失败 Agent 可观测性

清单

动手:生产练习

  • scope_filter(KB + 标签)的混合查询
  • /mcp 调用 core_query
  • 模拟 Knowhere 宕机 — 验证 /health 降级且 API 不崩溃
  • 强制任务失败后经管理端检查死信队列
  • [ ](可选)EAGLE_RAG_PROFILE=biomed 后确认 MCP 出现 biomed_* 且无垂类前端依赖

外部参考


Level 4 — 贡献

架构变更时同步:README.mdREADME.zh.mdAGENTS.mddocs/*/architecture/plugin-architecture.mddocs/*/architecture/multimodal-fusion.mddocs/*/architecture/adr/008-*.mdeagle_rag/settings.yaml


配置速查

学习目标 可调设置
强制纯文本检索 ROUTER_MODE=text 或请求级 mode
PDF 扫描检测 pdf_probe.text_page_ratiopdf_probe.avg_chars_per_page
大规模视觉索引 MILVUS_VISUAL_INDEX_TYPE=diskann
范围过滤边界 router.max_scope_documents
Profile / 域绑定 EAGLE_RAG_PROFILEplugins.default_namespace;验证 /health/plugins
队列背压 celery.queues.pixelrag_queue.concurrency(保持为 1)

故障模式速查

症状 可能原因 文档
任务卡在 RENDERING Knowhere 轮询超时 可靠性
视觉来源为空 pixelrag_queue 积压或 OOM 运维排障
跨租户泄漏 缺少 kb_name 过滤或错误的 plugin_namespace / profile 多租户
重复上传被拒 去重命中 (sha256, kb_name, plugin_namespace) 入库 API

完整动手清单

  • task setup && task up — 启动全栈
  • 摄入文本 PDF 与扫描 PDF;在 /tasks 对比管线
  • scope_filter(KB + 标签)的混合查询
  • /mcp 调用 core_query
  • 在前端证据查看器中打开文档结构
  • POST /query/stream 流式查询 — 观察 SSE 事件顺序
  • 提交 PR 前运行 task be:test

参考文献