跳转至

插件架构

Eagle-RAG 是 微内核 RAG 平台:领域无关的 Core,加上进程内行业插件以提升召回质量。插件与 Core 共享进程、模型与 MCP 端点;每个部署实例绑定单一行业命名空间。

英文正本:plugin-architecture.md

二开指南:编写行业 RAG 插件。模板:plugins/_template/


产品边界

Eagle-RAG 是面向 Agent 的 纯 RAG 数据层,不是业务 Agent 应用平台。

做(本系统职责) 不做(下游 Agent / 客户应用)
入库、分块、多编码器检索、RRF、溯源 业务工作流、多步规划 / 反思
REST / SSE / MCP 暴露 检索与入库 Text-to-SQL 执行、改库、发邮件、下单
行业插件提升 召回质量 行业 Agent UI、审批流、仪表盘
结构化上下文包 + sources 替 Agent 做决策或业务闭环
表面 范围
内置前端 仅 Core — knowhere(语义结构)+ pixelrag(视觉)混合检索
垂类插件(biomed、lakehouse-bi、…) 仅后端 + MCP — 本仓库不提供垂类 UI
下游 Agent / 客户自建 UI,经 MCP 或 API

ADR-008

flowchart TB
  subgraph fe [Built_in_Frontend]
    UI[Core_QA_Ingest_KB]
  end
  subgraph core [Core_RAG]
    KH[knowhere]
    PR[pixelrag]
    Mix[Hybrid_Retrieve]
  end
  subgraph domain [Domain_Plugins_Backend_MCP]
    BIO[biomed]
    LH[lakehouse_bi]
  end
  Agent[Downstream_Agent]

  UI --> Mix
  Mix --> KH
  Mix --> PR
  Agent --> Mix
  Agent --> BIO
  Agent --> LH

设计摘要

关注点 机制
扩展模型 进程内加载 settings.plugins.enabled(仅同仓模块;无 pip entry_points
实例绑定 settings.plugins.default_namespace = Milvus Database + PG repository 过滤(ADR-002
KB 租户 同一领域 DB 内的 kb_name 标量过滤(多租户
热路径 hook PARSE / CHUNK / QUERY_ASSEMBLE,见 eagle_rag/plugins/hotpath_hooks.py
入库编排 IngestOrchestrator + CLASSIFY_* / EMBED_* / UPSERT_VECTORS
查询编排 QueryRouteClassifierRetrieverOrchestrator → 分路 rerank → RRF 合并
MCP {namespace}_{name};实例仅暴露 core_* + default_namespace 工具
配置旋钮 settings.plugins.options[<namespace>],经 plugin_options() 读取 — 非 Core 行业 typed settings

Core 本身也是插件(eagle_rag.plugins.core_defaults,namespace core),与垂类走同一 hook / MCP 扩展路径。


分层架构

flowchart TB
  subgraph entry [Entry]
    API[REST_SSE]
    MCP["/mcp FastMCP"]
  end
  subgraph kernel [Microkernel eagle_rag/plugins]
    PM[PluginManager]
    HB[HookBus]
    IO[IngestOrchestrator]
    RO[RetrieverOrchestrator]
    ER[EncoderRegistry]
    CR[CollectionStoreRegistry]
  end
  subgraph domain_pl [In_repo_plugins]
    CoreP[core_defaults]
    BioP[plugins.biomed]
    LhP[plugins.lakehouse_bi]
  end
  subgraph store [Storage]
    MV[(Milvus_DB_per_namespace)]
    PG[(PostgreSQL_plugin_namespace)]
    OBJ[(MinIO_keys_with_namespace)]
  end

  API --> PM
  MCP --> PM
  PM --> HB
  PM --> CoreP & BioP & LhP
  HB --> IO & RO
  IO --> ER & MV & PG
  RO --> ER & MV
  API --> PG & OBJ
模块 职责
eagle_rag/plugins/manager.py 发现、校验(G3)、加载、注册 MCP / Celery 模块
eagle_rag/plugins/hookbus.py invoke_first / invoke_all / invoke_transform,按 namespace 过滤
eagle_rag/plugins/contract.py PluginManifest + Plugin 协议
eagle_rag/plugins/hotpath_hooks.py 将 PARSE / CHUNK / QUERY_ASSEMBLE 接入 Knowhere 与 router
eagle_rag/plugins/ingest_orchestrator.py 分块:分类 → 编码 → 写入
eagle_rag/plugins/retriever_orchestrator.py 多 collection ANN + RRF
eagle_rag/plugins/mcp_registry.py @register_mcp_tool + RAG-only 命名守卫
eagle_rag/plugins/core_defaults.py 默认分类器、编码器、knowhere/pixelrag 管线
eagle_rag/db/namespace.py 解析 / 拒绝请求中的 plugin_namespace vs 实例默认值
eagle_rag/db/repositories/ 所有 PG 读写强制注入 plugin_namespace
eagle_rag/index/milvus_pool.py 池化 MilvusClient(uri, db_name=) — 禁止 per-request 切库

核心概念

plugin_namespacekb_name

术语 含义
plugin_namespace 部署时领域绑定(= Milvus Database)。由配置固定;不是运行时 UI 切换器。
kb_name 该 Database 内的知识库 id(标量过滤)。用户选 KB,不选领域。

API / UI 文案中勿将二者混称为 “namespace”。

单域部署

每个进程绑定一个 default_namespace。跨行业检索靠 多实例,Core 不做跨 Milvus Database fan-out。同一 DB 内,单次 query 可以跨多个 collection(如 eagle_text + eagle_text_biomed + eagle_visual)。

生产环境 repository 只信任 settings.plugins.default_namespace。请求显式传入且与实例不一致 → 403(除非 plugins.allow_namespace_override,仅测试)。见 ADR-002

基础 vs 专用 collection

每个领域 Database 恒有:

  • eagle_text — Knowhere 语义块(Qwen 文本嵌入,1536 维)
  • eagle_visual — PixelRAG tile / 图 / 表(Qwen3-VL,2048 维)

插件可增专用 collection(声明在 PluginManifest.provides_specialized_collections)。Core 默认路由 永不自动查专用 collection(ADR-004 G4);仅领域 QueryRouteClassifier 或 scope-aware catalog 并集可加入。

PixelRAG 视觉是 Core 一等公民,不是可裁剪插件。可插拔的是领域分块、分类器、编码器与专用 collection。


插件契约

插件模块导出模块级 plugin 对象,实现:

class Plugin(Protocol):
    manifest: PluginManifest
    def register_hooks(self, bus: HookBus) -> None: ...
    def on_load(self, ctx: PluginContext) -> None: ...
    def on_unload(self) -> None: ...
    def ensure_collections(self, ctx: PluginContext) -> None: ...
    # optional
    def register_mcp_tools(self) -> None: ...

PluginManifest 字段:

字段 用途
namespace 领域 id(corebiomedlakehouse-bi、…)
version 语义化版本
milvus_db_name 目标 Milvus Database(可选;经 milvus_ns 映射)
depends_on 依赖的其他 namespace;拓扑排序加载
provides_pipelines 加载时注册的入库管线名
provides_specialized_collections 额外 Milvus collection(reconstruct / stats 扇出)
provides_mcp_tools 声明的工具短名(文档 / health)
resource_hints 可选 GPU / 加载顺序提示

PluginManager.load_all()

  1. 始终确保启用 eagle_rag.plugins.core_defaults
  2. 导入各模块;拒绝重复 namespace。
  3. 校验 G3:非 core 的已启用插件必须等于 default_namespace
  4. 按依赖顺序调用 on_loadensure_collectionsregister_hooks
  5. CELERY_TASKS hook 收集 Celery 任务模块。
  6. 仅对 core + default_namespace 调用 register_mcp_tools()

Hook 系统

调用模式

模式 方法 语义
FIRST invoke_first 首个非 None 胜出(优先级降序)
TRANSFORM invoke_transform 管道:每个订阅者变换当前值
ALL invoke_all 收集全部结果;用于 QUERY_ASSEMBLE / CELERY_TASKS

namespace=None 的订阅者对所有上下文生效;其余仅当 HookContext.plugin_namespace 匹配时运行。Core 默认常用低优先级(-1000)作回落;垂类常用高优先级(100)。

异常策略(G13)

路径 策略
入库 / 分类 / 编码 / upsert / PARSE / CHUNK Fail-fastHookInvocationError
QUERY_ASSEMBLE 按订阅者 try/except;降级并记审计

Hook 一览

Hook 模式 典型用途
PARSE transform 丰富 Knowhere ParseResult
CHUNK transform 在 Knowhere 节点上做领域 metadata enrich(保留 path / 正文 / doc_nav;禁止从零重切)
INGEST_VISUAL_EXTRACT first 抽取视觉块 + 四锚点字段
CLASSIFY_CHUNK / CLASSIFY_VISUAL first 路由 chunk → collection + encoder
CLASSIFY_QUERY first 生成多 collection QueryRouteDecision
EMBED_TEXT / EMBED_VISUAL first EncoderRegistry 的领域编码器
UPSERT_VECTORS transform 持久化向量(默认写 Milvus)
INGEST_ROUTE_SELECTORS first 额外「格式 → 管线」选择器
QUERY_ASSEMBLE all ANN 前 query 扩写 / 实体 hint
QUERY_DENSE_EXPAND first ANN 前稠密/稀疏 query 扩写(biomed UMLS + 章节 cue)
RERANK first 分路 Tier-1 领域重排(如 PubMedBERT cosine)
RETRIEVE_SUPPLEMENT all ANN 后补充召回(如实体锚定药物文档 ANN)
RRF_POST_MERGE first RRF 后候选注入(如保证 supplement 命中进入重排池)
RERANK_MERGED first RRF 后合并重排(biomed:MedCPT CE + 章节/意图信号)
RETRIEVE_VISUAL_FILTER first 视觉过滤覆盖
CELERY_TASKS all 额外 Celery include 模块

热路径接线:

  • apply_parse_hook / apply_chunk_hook — Knowhere 入库路径
  • apply_query_assemble — router ANN 前(受 plugins.query_assemble_enabled 控制)

入库路径

固定顺序(G26):

PARSE → CHUNK → INGEST_VISUAL_EXTRACT → CLASSIFY_* → IngestOrchestrator (EMBED_* → UPSERT_VECTORS)
sequenceDiagram
  participant Celery
  participant Knowhere
  participant HotPath as hotpath_hooks
  participant Bus as HookBus
  participant Orch as IngestOrchestrator
  participant Milvus

  Celery->>Knowhere: parse document
  Knowhere->>HotPath: apply_parse_hook
  HotPath->>Bus: PARSE transform
  Knowhere->>HotPath: apply_chunk_hook
  HotPath->>Bus: CHUNK transform
  Knowhere->>Bus: INGEST_VISUAL_EXTRACT
  loop each text/visual chunk
    Orch->>Bus: CLASSIFY_CHUNK / CLASSIFY_VISUAL
    Orch->>Bus: EMBED_TEXT / EMBED_VISUAL
    Orch->>Bus: UPSERT_VECTORS
    Bus->>Milvus: write collection
  end
  Note over Orch: On full success update collections_used catalog

IngestOrchestrator.classifyCLASSIFY_*embed_and_upsertClassificationDecision.target_encoderEncoderRegistry / encoder_runtime 编码落库。批量入口见 ingest_helpers.pyingest_text_nodes / ingest_visual_record)。EncoderRegistry.validate_plan(collection, encoder_name) 在写入前拒绝维度不匹配。ClassificationDecision.exclusive_group 在同组内跳过 dual-write(防止专用 collection 与 base 重复写入)。

Collection catalog(入库 ↔ 查询契约)

仅在入库 终态成功documents.status=success、全 chunk 写入后)更新:

  • documents.extra["collections_used"] — 文档级
  • knowledge_bases.collections_used — KB 级并集

失败 / 部分成功不污染 catalog。查询 scope 用该 catalog 在文档/KB/tags 曾写入专用 collection 时强制加入对应 plans(ADR-006)。

格式路由(Knowhere vs PixelRAG)仍在 eagle_rag/ingest/router.py — 见 路由矩阵。插件可通过 INGEST_ROUTE_SELECTORS 补充。


查询路径

sequenceDiagram
  participant API
  participant HotPath as hotpath_hooks
  participant Bus as HookBus
  participant Class as CLASSIFY_QUERY
  participant Scope as scope_routing
  participant Orch as RetrieverOrchestrator
  participant RRF as merge_rrf

  API->>HotPath: apply_query_assemble
  HotPath->>Bus: QUERY_ASSEMBLE all
  API->>Class: route query
  Class->>Scope: union specialized collections from catalog
  Class-->>API: QueryRouteDecision plans
  API->>Orch: retrieve per plan
  loop each CollectionQueryPlan
    Orch->>Bus: QUERY_DENSE_EXPAND first
    Orch->>Orch: ANN (dense + optional sparse)
    Orch->>Bus: RERANK first (Tier-1)
  end
  Orch->>Bus: RETRIEVE_SUPPLEMENT all
  Orch->>RRF: merge + dedupe
  Orch->>Bus: RRF_POST_MERGE first(可选注入)
  Orch->>Bus: RERANK_MERGED first(domain)或 qwen3-rerank(core)
  RRF-->>API: NodeWithScore list

默认 vs 领域路由(G4 / G20)

  • Core CLASSIFY_QUERY:仅 eagle_text(hybrid / 有图时加 eagle_visual)。永不查专用 collection。
  • Biomed:规则 + UMLS 实体触发可加入 eagle_text_biomed / 化学 / 医学影像 collection;abstain 回落 Core。无实体命中的纯文本默认只查 eagle_textdefault_dual_text_search: false)。
  • Scope-aware 并集scope_filter 的 KB / document / tags catalog 含专用 collection 时,即使分类器 abstain 也强制加入对应 plans。

多编码器合并(G8 / G14 / G32)

  1. 可选 QUERY_DENSE_EXPAND(稠密 query 改写 + 稀疏词项 hint;意图经 retrieval_hints 传递)。
  2. CollectionQueryPlan 做 ANN(best-effort:失败路跳过并审计)。仅当 EncoderRegistry.CollectionProfile.hybrid_enabledsettings.router.hybrid_text_collections 包含该 collection 时做稠密+稀疏融合 — Core hybrid_fuse_dense_sparse 不含领域实体逻辑。
  3. 可选分路 RERANK hook(Tier-1 集合内 cosine 重排;领域打分在插件内,如 plugins/biomed/scoring.py)。
  4. 可选 RETRIEVE_SUPPLEMENT hook 追加实体锚定等补充命中。
  5. 用 RRF 合并(eagle_rag/router/rerank_fusion.py)— 禁止跨 embedding 空间 raw score。
  6. 可选 RRF_POST_MERGE hook(如 biomed 在 require_entity_match 时注入 supplement 候选)。
  7. RRF 后按 RerankPolicy 重排:Core general → DashScope qwen3-rerank;biomed domainRERANK_MERGED(MedCPT CE + metadata 信号)。none 跳过合并重排。
  8. source_chunk_id(非空)或 (document_id, path) 去重。

深入:多 collection / 多编码器 / hybrid / RRF 跨空间扇出的系统化设计见 多向量检索;RRF 合并后的证据收敛(去重 / 候选注入 / 合并重排)见 证据聚合;生成期 [n] 引文链路见 Citationware RAG

Core 与插件边界(检索)

职责 Core 领域插件
编排 RetrieverOrchestrator — hook 分发、RRF、去重 注册 QUERY_DENSE_EXPANDRERANKRETRIEVE_SUPPLEMENTRRF_POST_MERGERERANK_MERGED
意图识别 QueryRetrievalIntent 数据结构 plugins/biomed/query_intent.py,经 QUERY_DENSE_EXPAND 产出
Hybrid 稀疏 在稠密 ANN 命中上做词项重叠 经 hook + EncoderRegistry 提供 sparse_terms / collection 列表
Milvus upsert 元数据 按 schema 透传(milvus_text_store CHUNK hook 写入领域字段(primary_drugsbiomed_section 等)
实体加权 / 过滤 插件 rerank hook(RERANKRERANK_MERGED

Core 在 query 热路径上 不得 import plugins.<domain>。Biomed 评测与运维见 eval/biomed/RETRIEVAL.md

父文档检索(settings.router.parent_doc_retrieval,默认 true)仍是 Core 在 eagle_text 上的两阶段 Milvus 路径(先 section_summary,再 path 下钻)。Eagle 不调用 Knowhere 的 RetrievalAgent / WorkflowOrchestratorADR-005)。


隔离模型

Milvus(ADR-001

  • 每个 plugin_namespace 对应一个独立 Milvus Databasecoredefaultlakehouse-bilakehouse_bi,…)。
  • 向量上不设 plugin_namespace 标量字段;隔离靠物理 DB。
  • MilvusClientPool 在构造时绑定 db_name。禁止 per-request using_database,禁止对池内 client close()

PostgreSQL

领域表一律经 repository 注入 plugin_namespace。不同 namespace 下同名 kb_name 不串线。覆盖 documents、keywords/tags、sessions、images 元数据、task audit、notifications、MCP call log。

对象存储 / 缓存

图片 object key、原始文档 key、MCP cache key 均贯穿 plugin_namespace,多实例共享 MinIO/Redis 时仍隔离。


MCP 表面

单一 FastMCP 应用挂载于 /mcp(默认 HTTP)。

规则 细节
命名 {namespace}_{name},下划线分隔(core_ingestbiomed_query_entities
注册 显式 plugin.register_mcp_tools();装饰器 @register_mcp_tool
实例过滤(G3) core_* + default_namespace 插件工具
RAG-only assert_rag_only_tool_name 拒绝副作用片段(execute_sqlsend_email、…)
Breaking change 插件化前的裸名(ingest不提供 alias

Core 工具:core_ingestcore_querycore_retrieve_textcore_retrieve_visual

垂类示例:

  • Biomed:biomed_query_entitiesbiomed_retrieve_compounds
  • Lakehouse:lakehouse_bi_query_semantic_contextlakehouse_bi_retrieve_historical_analysis

ADR-003MCP 工具


部署 profile

通过 EAGLE_RAG_PROFILE(或 YAML active_profile)启用。Profile 对顶层 settings 做 deep-merge。

# eagle_rag/settings.yaml(节选)
plugins:
  enabled:
    - eagle_rag.plugins.core_defaults
  default_namespace: ${PLUGIN_NAMESPACE:-core}
  allow_namespace_override: false
  query_assemble_enabled: true
  options:
    biomed:
      default_dual_text_search: false
      exploratory_search_collections: []
      encoder_mode: auto   # auto | require_native | deterministic

profiles:
  core:
    plugins:
      enabled: [eagle_rag.plugins.core_defaults]
      default_namespace: core
    milvus:
      db_name: default
  biomed:
    plugins:
      enabled: [eagle_rag.plugins.core_defaults, plugins.biomed]
      default_namespace: biomed
    milvus:
      db_name: biomed
  lakehouse-bi:
    plugins:
      enabled: [eagle_rag.plugins.core_defaults, plugins.lakehouse_bi]
      default_namespace: lakehouse-bi
    milvus:
      db_name: lakehouse_bi

默认 compose profile 为 core(生产安全)。启用 biomed(实验性)/ lakehouse-bi(开发中)需对应 profile 并重启 — 二者均非生产默认,启用即接受成熟度风险。Docker 镜像打包 plugins/;compose override 挂载 ./plugins 便于本地迭代。


已交付垂类插件

插件 成熟度
plugins/biomed 实验性 — API/collection 可能变更;非生产稳定
plugins/lakehouse_bi 开发中 — 参考骨架;尚不适合生产
plugins/_template 新行业插件脚手架

plugins/biomed(实验性)

专用 collection(eagle_text_biomed / eagle_text_medcpt / eagle_chemical / eagle_medical_radiology / eagle_medical_pathology),7 个领域编码器(pubmedbert / molformer / medcpt-* / medimageinsight [BiomedCLIP + open_clip] / uni2),IMRaD CHUNK 富化,分层文档路由器(TDR),实体锚定补召回,以及 MedCPT + 信号融合 Tier-2 重排。评测基线(aligned 46 题):Hit@5 / MRR 0.85-0.87

完整深入Biomed 插件(collection、编码器、入库、UMLS、MCP、配置)+ Biomed 检索(意图、路由、Tier-1/Tier-2 重排融合、补召回、RRF)。运维侧失败诊断:eval/biomed/RETRIEVAL.md

plugins/lakehouse_bi(开发中)

能力 细节
Collection 仅基础 eagle_text / eagle_visual
Hooks PARSE / CHUNK 语义层 typed metadata;QUERY_ASSEMBLE hint
MCP 只读语义上下文 + 历史分析检索
边界 仅检索 — 不执行 SQL;connector 导出元数据文件供入库

plugins/_template

新行业插件最小骨架:manifest、hooks、MCP 注册、README。


模型

角色 归属 模型
路由 / 生成 LLM Core DeepSeek
VLM Core Qwen-VL-Max
文本嵌入 Core 默认 Qwen text-embedding-v4(1536)
视觉嵌入 Core 默认 get_visual_encoder()pixelrag 本地 HF Qwen3-VL-Embedding-2B 或 dashscope 百炼 qwen3-vl-embedding(2048)
重排 Core Qwen qwen3-rerankrerank_policy: general 时)
领域重排 Biomed 插件 MedCPT cross-encoder(medcpt-rerankrerank_policy: domain 时)
领域编码器 插件 Label pubmedbert / molformer / medimageinsight(BiomedCLIP/open_clip)/ uni2

垂类可注册额外编码器;Core 仍用 DeepSeek/Qwen 做全局路由与生成。Core 视觉留在 Qwen 空间;医学影像永不回落其上。


可观测性

PluginManager.health_payload()(经 admin health 暴露)报告:

  • default_namespace、已启用模块、manifests
  • 专用 collection、声明的 MCP 工具、Celery 模块

KB stats / collection 列表会扇出绑定 namespace 的 provides_specialized_collections

PluginAuditeagle_rag/plugins/audit.py,经 PluginContext.audit.log_decision(...)):

Sink 细节
AI JSONL event=plugin_audit_decisionget_ai_logger,持久)
Redis LIST eagle:plugin_audit:{namespace}:recentLPUSH+LTRIM
内存 ring 上限 telemetry.plugin_audit_ring_cap(Redis 不可用时回退)
Prometheus plugin_audit_decisions_totalplugin_audit_rrf_dedupe_total

配置:telemetry.plugin_audit_enabled / plugin_audit_redis_enabled / plugin_audit_health_limit。各 sink 均为 best-effort,不拖垮热路径。示例 category:classify_chunkroute_queryscope_routing_errorhook_failureGET /health/plugins 暴露 recent_decisions / audit_stats

深入:trace / metrics / input-output / state 四层观测模型与失败定位 playbook 见 Agent 可观测性;运维实操端点见 可观测性(运维)


源码布局

eagle_rag/plugins/          # 微内核
  manager.py
  hookbus.py / hooks.py / hotpath_hooks.py
  contract.py / context.py / audit.py
  ingest_orchestrator.py / retriever_orchestrator.py
  ingest_helpers.py
  classifier.py / routing.py / scope_routing.py
  encoder_registry.py / encoder_runtime.py
  mcp_registry.py / milvus_ns.py
  core_defaults.py
  ingest_catalog.py / ingest_tracker.py / …
eagle_rag/ingest/
  visual_encoder.py         # Core get_visual_encoder()(pixelrag | dashscope)
plugins/                    # 同仓垂类插件
  _template/
  biomed/
  lakehouse_bi/
tests/plugins/              # 契约、隔离、hook、垂类测试

相关文档

文档 主题
Biomed 插件 Biomed collection、编码器、入库、UMLS、MCP、配置
Biomed 检索 Biomed 检索算法(意图、路由、Tier-1/Tier-2 重排、补召回、RRF)
编写行业 RAG 插件 如何新增垂类
插件术语表 术语速查
多模态融合 Knowhere + PixelRAG 锚点
路由矩阵 格式 → 管线
ADR-001 Milvus DB = 领域
ADR-002 单域实例
ADR-003 MCP 命名 / G3
ADR-004 RRF / G4
ADR-005 Knowhere 职责边界
ADR-006 Catalog + scope-aware plans
ADR-007 Profile / 编码器 / UMLS 说明
ADR-008 RAG-only + 前端范围