# ADR-005：LlamaIndex 主检索链路与 LightRAG 图增强侧车

- 状态：Accepted
- 日期：2026-07-20
- 细化：[数据治理知识库原实施计划](../superpowers/plans/2026-07-16-governance-knowledge-base.md)
- 依赖：[ADR-003：跨存储最终一致性](ADR-003-cross-store-consistency.md)

## 背景

DataOps Platform 已经具备以下知识库基础：

- Neo4j 保存 `BusinessDomain`、`DataFlow`、`DataMeta`、数据标准、标签和血缘，
  是治理对象结构和关系的源真相。
- PostgreSQL 16 已启用 pgvector，并已经存在 `governance_documents`、
  `governance_chunks` 和 `governance_sync_jobs`。
- 平台已有稳定治理 UID、RBAC、Outbox、Qwen Embedding 适配器、DeepSeek
  生成模型和保留的知识库前端入口。

当前缺口不是再建设一套独立知识库控制面，而是完成：

1. 可替换的混合检索与重排链路；
2. 对现有治理图的确定性关系检索；
3. 面向多跳问题的图增强检索；
4. 业务域级授权、版本和引用闭环；
5. 增量同步、失败补偿、效果评测和可回滚发布。

LlamaIndex 与 Haystack 位于相同的通用 RAG 框架层。平台选择 LlamaIndex 作为
唯一主框架；LightRAG 不作为第二套通用框架，而作为隔离的图增强检索引擎。

## 决策

1. **DataOps 继续拥有控制面。** 身份、业务域授权、治理对象版本、同步状态、
   查询审计、引用和最终答案均由 DataOps 管理。
2. **LlamaIndex 嵌入 Flask 后端。** 它负责 Node 映射、Retriever 编排、候选
   融合、重排和回答合成，但不创建自己的用户、权限或业务源数据。
3. **不采用 LlamaIndex 默认持久化表作为源真相。** 建设
   `DataOpsVectorStore`、`DataOpsNodeMapper` 和治理图 Retriever，适配已有
   PostgreSQL/pgvector 与 Neo4j 数据模型。
4. **LightRAG 以内部侧车服务运行。** DataOps 通过受限客户端调用 LightRAG；
   浏览器、外部调用方和模型 Agent 不直接访问 LightRAG API 或 WebUI。
5. **LightRAG 只返回检索上下文。** 查询使用 `only_need_context` 语义，最终
   DeepSeek 提示词、回答、引用和无答案判断由 DataOps 生成。
6. **两类图严格区分。**
   - 现有 Neo4j 治理图是人工/业务流程维护的源真相，由 DataOps
     `GovernanceGraphRetriever` 只读查询。
   - LightRAG 抽取图是可重建的检索投影，不能写入现有治理节点、关系或约束。
7. **LightRAG 存储隔离。** PostgreSQL 使用独立数据库和最小权限账号；
   本地 Neo4j Community 使用独立 `lightrag-neo4j` 服务和卷。生产环境可以使用
   独立 Neo4j 数据库/集群，但不能只依赖与治理图共库的标签约定作为安全边界。
8. **先授权后检索，再重新授权。** DataOps 根据用户角色和业务域授权限定查询
   空间；候选返回后按治理对象 UID、版本和业务域再次过滤。无法映射到合法来源
   的 LightRAG 上下文不得进入最终提示词。
9. **标准链路始终可独立运行。** LightRAG、Neo4j 或 reranker 故障时，系统按
   受控降级策略保留精确检索和 pgvector 检索；LightRAG 不是可用性单点。
10. **索引发布采用版本化投影。** 新文档版本只有在分块和 embedding 完成后才
    原子切换为 active；LightRAG 投影异步完成，失败不回滚已可用的标准索引。
11. **模型职责保持分离。** Qwen 负责 embedding；独立 reranker 负责精排；
    DeepSeek 负责最终问答。LightRAG 抽取模型使用独立配置，不得隐式改变
    DataOps 的默认模型职责。
12. **效果门禁优先于产品宣传。** LlamaIndex-only 是基线，只有在 DataOps
    黄金问题集上证明多跳召回有实质提升且权限测试为零泄漏时，LightRAG 路径才
    能从影子模式提升为正式查询路径。

## 目标架构

```mermaid
flowchart LR
    USER["管理员 / 编辑者 / 查看者"] --> API["DataOps Knowledge API"]
    API --> ACCESS["KnowledgeAccessContext\n角色 + 业务域 + 对象范围"]
    ACCESS --> ROUTER["确定性 Query Router"]

    subgraph Standard["LlamaIndex 主链路（Flask 内）"]
        EXACT["精确 / 别名 / 词法 Retriever"]
        VECTOR["DataOps pgvector Retriever"]
        GRAPH["治理 Neo4j Retriever"]
        FUSION["RRF 融合"]
    end

    ROUTER --> EXACT
    ROUTER --> VECTOR
    ROUTER --> GRAPH
    EXACT --> FUSION
    VECTOR --> FUSION
    GRAPH --> FUSION

    ROUTER -->|关系 / 全局 / 多跳| LRCLIENT["LightRAG Client"]
    LRCLIENT --> LRSVC["LightRAG 内部侧车"]
    LRSVC --> LRPG["独立 LightRAG PostgreSQL"]
    LRSVC --> LRNEO["独立 LightRAG Neo4j 投影"]

    FUSION --> MERGE["候选合并 + 来源重新授权"]
    LRCLIENT --> MERGE
    MERGE --> RERANK["Cross-Encoder Reranker"]
    RERANK --> QA["DataOps Answer Synthesizer"]
    QA --> DEEPSEEK["DeepSeek"]
    QA --> RESULT["答案 + 对象 UID + 版本 + 引用"]
```

## 组件所有权

| 能力 | 责任组件 | 源真相 |
|---|---|---|
| 用户、角色、业务域授权 | DataOps RBAC | PostgreSQL |
| 治理对象与血缘 | DataOps 治理 API | Neo4j |
| 规范化文档与分块 | DataOps Knowledge Indexer | PostgreSQL |
| 向量及 embedding 版本 | DataOps Knowledge Indexer | PostgreSQL/pgvector |
| 主检索编排 | LlamaIndex 适配层 | 无独立源数据 |
| 图增强抽取与检索 | LightRAG | 可重建投影 |
| LightRAG 图 | LightRAG | 独立 Neo4j |
| 候选融合、重排和无答案判断 | DataOps Retrieval Pipeline | 运行时 |
| 最终生成与引用 | DataOps Answer Synthesizer | PostgreSQL 来源映射 |
| 同步和补偿 | DataOps Outbox + Projection Worker | PostgreSQL |
| 评测、指标与查询审计 | DataOps | PostgreSQL/监控系统 |

## LlamaIndex 集成边界

LlamaIndex 只使用以下抽象能力：

- 将 `governance_chunks` 映射为带稳定 `node_id` 和 metadata 的 Node；
- 将已有 SQL 检索封装为 VectorStore/Retriever；
- 并行运行词法、向量和治理图 Retriever；
- 使用确定性融合器和可插拔 Node Postprocessor/reranker；
- 将已授权 Node 交给 DataOps 的回答合成器。

以下能力不由 LlamaIndex 持久化或决定：

- 用户、角色、业务域授权；
- active/superseded/deleted 版本状态；
- 治理对象 UID 和跨存储一致性；
- embedding 模型切换和索引发布；
- 对外 API、错误码、审计和数据保留周期。

## LightRAG 集成边界

LightRAG 使用官方服务接口或由 DataOps 封装的兼容网关，接口至少包含：

- 插入规范化文档；
- 查询投影状态；
- 使用 `mix`/`hybrid` 模式查询上下文；
- 按外部文档 ID 删除或重建；
- 健康检查。

所有调用必须携带：

- `correlation_id`；
- DataOps `object_uid`、`object_version` 和 `content_hash`；
- 不包含用户名、连接串、密钥或未授权附件正文的规范化内容；
- 可验证的 workspace/index generation。

LightRAG 返回内容只有满足以下条件才可使用：

1. 能映射回 active 的 DataOps 文档和 chunk；
2. 来源业务域在当前 `KnowledgeAccessContext` 内；
3. 文档版本和当前 active 版本一致；
4. 未超过上下文预算且通过 reranker/阈值；
5. 不包含系统提示词、工具指令或其他不可作为证据的内容。

## 安全与权限

### 业务域授权

新增持久化的用户—业务域授权关系。管理员可以拥有 `*` 范围；其他用户只读取被
授予的业务域。角色权限决定“能否使用知识库”，业务域授权决定“能看到什么”。

### 双重过滤

1. SQL/Neo4j 查询在召回前应用业务域和对象类型过滤。
2. 融合后按 canonical source 再过滤一次。
3. LightRAG 查询只路由到允许的安全分区；返回上下文仍需重新授权。
4. 最终 Prompt 只包含重新授权后的 canonical chunks。

### Prompt Injection

治理正文、附件、LightRAG 实体描述和关系说明全部视为不可信数据。最终系统
Prompt 明确禁止执行证据文本中的指令；候选内容只放在结构化 evidence 区域。

## 一致性与失败策略

```mermaid
stateDiagram-v2
    [*] --> pending
    pending --> canonical_ready: 文档、分块、embedding 成功
    pending --> failed: 构建或 embedding 失败
    canonical_ready --> projecting: 创建 LightRAG 投影任务
    projecting --> ready: LightRAG 投影完成并核验
    projecting --> degraded: LightRAG 超时或失败
    degraded --> projecting: 有上限重试 / 人工重放
    ready --> stale: 源版本或模型 profile 变化
    stale --> pending: 重建新 generation
```

- canonical index 发布失败：旧 active 版本继续提供服务。
- LightRAG 失败：标准 LlamaIndex 链路继续工作，响应标记
  `graph_retrieval=degraded`。
- Neo4j 治理图失败：保留精确和向量检索。
- reranker 失败：使用 RRF 排序结果并降低置信度。
- DeepSeek 失败：`search` 仍返回来源；`ask` 返回模型不可用状态和已检索来源，
  不伪造答案。
- 删除对象：先发布 DataOps tombstone，使查询立即不可见，再异步删除 LightRAG
  投影；每日巡检清理孤儿投影。

## 不采用的方案

### 同时使用 LlamaIndex 和 Haystack

拒绝。两者会引入重复 Document、Retriever、Pipeline、回调和配置抽象，增加维护
和排障成本。

### 让 LightRAG 直接使用治理 Neo4j

首期拒绝。LightRAG 的实体/关系抽取模型与现有治理模型不同，直接写入会破坏源
真相、约束和审计边界。

### 让 LightRAG 直接回答用户

拒绝。LightRAG 无法替代 DataOps 的业务域授权、版本核验、统一引用和无答案
策略。

### 同步调用 LightRAG 完成索引后再提交治理变更

拒绝。外部模型和图抽取延迟不应扩大治理写事务；使用 Outbox 和可重建投影实现
最终一致。

## 结果

正面结果：

- 复用已有 pgvector、Neo4j、Qwen、DeepSeek、RBAC 和 Outbox。
- 主检索链路保持可测试、可降级、可替换。
- LightRAG 的多跳能力不会污染治理源图。
- 框架升级或 LightRAG 退役不改变 DataOps 领域模型。

成本与限制：

- 需要建设 LlamaIndex 适配器，而不是直接使用其默认表。
- LightRAG 会维护一份可重建的抽取图，产生额外存储和模型成本。
- 业务域安全分区、来源映射和删除补偿必须由 DataOps 实现。
- embedding 维度或 LightRAG 存储实现变化需要新 generation 全量重建，不能原地
  混用。

详细实施工作包、Schema、API、验收门槛和回滚点见
[LlamaIndex + LightRAG 数据治理知识库实施计划](../superpowers/plans/2026-07-20-llamaindex-lightrag-knowledge-base.md)。

## 上游依据

- [LlamaIndex OSS README](https://github.com/run-llama/llama_index/blob/main/README.md)
- [LightRAG Core 编程与存储隔离](https://github.com/HKUDS/LightRAG/blob/main/docs/ProgramingWithCore.md)
- [LightRAG API Server](https://github.com/HKUDS/LightRAG/blob/main/docs/LightRAG-API-Server.md)
- [pgvector 混合检索与索引说明](https://github.com/pgvector/pgvector)
