# 本项目 Graph RAG 思路与实现

## 1. 定位

本项目的 Graph RAG 负责从 Neo4j 中获取节点、关系和路径证据，适合回答：

- 某个任务包含哪些阶段；
- 实体之间是什么关系；
- 一个实体的上下游、依赖和关联对象是什么；
- 某条业务路径经过哪些节点。

当前实现属于 **Text-to-Cypher 型 Graph RAG**。它不使用 Neo4j 向量索引，也没有接入官方 `VectorRetriever`、`VectorCypherRetriever` 或 `HybridCypherRetriever`。

## 2. 当前实际运行方式

当前知识库绑定中配置了 `defaultCypher`，因此工作台实际使用的是**显式 Cypher**：

```cypher
MATCH p=(m:Mission {name:'东海海上目标救援任务'})
        -[:HAS_STAGE]->(s:Stage)
RETURN p
```

虽然前端传入了：

```json
{
  "allowTextToCypher": true
}
```

但后端的优先级是：

```text
显式 cypher/defaultCypher
>
自动 Text-to-Cypher
```

因此只要 `defaultCypher` 存在，就不会调用大模型生成 Cypher。

## 3. 总体流程

```mermaid
flowchart TD
    Q["用户问题"] --> K["KnowledgeBaseRagRetriever"]
    K --> G["GraphRagRetriever"]
    G --> E{"是否存在显式 Cypher"}
    E -->|是| X["使用 cypher/defaultCypher"]
    E -->|否| A{"是否允许自动生成"}
    A -->|否| W["返回 warning"]
    A -->|是| T["Text-to-Cypher"]
    T --> S["Schema + 示例 + 业务规则"]
    S --> B["RAG AI Bridge"]
    B --> L["LLM 生成 Cypher"]
    X --> C["CypherGuardService"]
    L --> C
    C --> N["Neo4j 执行"]
    N --> R["nodes + edges"]
    R --> EVIDENCE["GRAPH_RESULT 证据"]
    EVIDENCE --> ANSWER["多源证据融合回答"]
```

## 4. 查询请求

图检索使用统一的 `RagQuery`：

```json
{
  "query": "东海海上目标救援任务包括哪些阶段？",
  "sourceIds": ["1"],
  "topK": 5,
  "filters": {
    "allowTextToCypher": true,
    "maxDepth": 3
  }
}
```

主要字段：

| 字段 | 含义 |
|---|---|
| `query` | 用户自然语言问题 |
| `sourceIds` | Neo4j 图数据源 ID |
| `topK` | 结果规模控制 |
| `allowTextToCypher` | 是否允许自动生成 Cypher |
| `maxDepth` | 自动生成查询时允许的最大路径深度 |

## 5. 显式 Cypher 模式

显式 Cypher 可以来自：

```json
{
  "cypher": "MATCH ..."
}
```

或者知识库数据源绑定：

```json
{
  "defaultCypher": "MATCH ..."
}
```

执行过程：

```text
读取显式 Cypher
→ 跳过大模型
→ Java 安全校验
→ Neo4j 执行
→ 生成图证据
```

适合固定报表、固定演示、调试和确定性业务流程。缺点是无论用户如何变化问题，都可能执行同一条查询。

## 6. 自动 Text-to-Cypher 模式

删除 `defaultCypher` 后，如果满足以下任一条件：

```text
allowTextToCypher = true
retrievalMode = AUTO_GENERATE
```

系统会调用 `Neo4jGraphRagCypherGenerationService`。

### 6.1 构造生成上下文

Java 读取 Neo4j Labels，并组合：

- 用户问题；
- 节点标签；
- 节点属性说明；
- 关系类型和方向；
- 允许的 Label；
- 允许的 Relationship；
- 最大路径深度；
- Few-shot 问题/Cypher 示例；
- 业务语义规则。

当前关系 Schema 主要是手工配置：

```text
(:Mission {name: STRING})
-[:HAS_STAGE]->
(:Stage {name: STRING, sequence: INTEGER})
```

### 6.2 Few-shot 示例

```text
问题：东海海上目标救援任务包括哪些阶段？
Cypher：
MATCH p=(m:Mission {name:'东海海上目标救援任务'})
        -[:HAS_STAGE]->(s:Stage)
RETURN p
```

```text
问题：如果东海发生人员落水事故，应按照什么流程开展救援？
Cypher：
MATCH p=(m:Mission)-[:HAS_STAGE]->(s:Stage)
WHERE m.name CONTAINS '东海'
RETURN p
ORDER BY s.sequence
```

### 6.3 调用生成服务

Java 向 RAG AI Bridge 发送：

```text
POST http://127.0.0.1:18733/text2cypher
```

Bridge 要求模型只返回一条只读 Cypher，不输出解释、Markdown 或中间过程。

## 7. 两层安全控制

### 7.1 Python Bridge

Python 负责：

- 清除 `<think>` 内容；
- 提取 Markdown 代码块中的 Cypher；
- 去掉末尾分号；
- 检查只读开头；
- 禁止写操作和危险过程调用。

### 7.2 Java Guard

`CypherGuardService` 再次检查：

- 禁止分号和多语句；
- 禁止注释；
- 禁止 `CREATE`、`MERGE`、`DELETE`、`SET`、`DROP` 等；
- 禁止权限、索引、约束和批量事务操作。

最终还应使用 Neo4j 只读账号形成数据库级安全边界。

## 8. Neo4j 执行和结果转换

校验通过后，Java 根据 `graphSourceId`：

1. 读取并解密 Neo4j 连接配置；
2. 创建或复用 Driver；
3. 在指定 database 中执行 Cypher；
4. 限制查询时间、节点数和关系数；
5. 将 Neo4j Path、Node、Relationship 转成 `nodes` 和 `edges`。

示例结果：

```json
{
  "nodes": [
    {"labels": ["Mission"], "properties": {"name": "东海海上目标救援任务"}},
    {"labels": ["Stage"], "properties": {"name": "任务接收", "sequence": 0}}
  ],
  "edges": [
    {"source": "mission-id", "target": "stage-id", "type": "HAS_STAGE"}
  ]
}
```

## 9. Graph RAG 证据

查询结果封装为：

```json
{
  "sourceType": "GRAPH",
  "evidenceType": "GRAPH_RESULT",
  "content": "图查询返回7个节点、6条关系",
  "score": 1.0,
  "payload": {
    "nodes": [],
    "edges": [],
    "paths": []
  },
  "metadata": {
    "cypher": "MATCH ...",
    "explicitCypher": "MATCH ...",
    "nodeCount": 7,
    "edgeCount": 6,
    "durationMs": 74
  }
}
```

判断查询来源：

- `explicitCypher`：使用了固定 Cypher；
- `generatedCypher`：使用了自动 Text-to-Cypher。

`score=1.0` 不是向量相似度，只表示这是数据库实际执行得到的结构化证据。

## 10. 当前未实现的能力

当前图节点和关系没有向量化，也没有：

- Neo4j Vector Index；
- Neo4j Full-text Index；
- `VectorRetriever`；
- `VectorCypherRetriever`；
- `HybridRetriever`；
- `HybridCypherRetriever`；
- 文档自动抽取实体和关系的 `SimpleKGPipeline`。

因此当前 Graph RAG 的准确定位是：

> 显式 Cypher 优先、支持自动 Text-to-Cypher、经过双层只读校验、将 Neo4j 节点和关系作为多源 RAG 证据。

## 11. 后续演进方向

1. 动态读取完整图 Schema，包括属性、关系方向、约束和索引；
2. 去除救援演示专用的硬编码关系与示例；
3. 使用 `EXPLAIN` 预检生成的 Cypher；
4. 对 Schema 错误最多自动修复一次；
5. 统一 Python 与 Java 的安全规则；
6. 对有长文本描述的节点增加 BGE-M3 embedding；
7. 增加“向量/全文找种子节点 + 固定 Cypher 扩展”的混合 Graph RAG。

## 12. 关键代码

- `KnowledgeBaseRagRetriever`：多源知识库调度；
- `GraphRagRetriever`：图检索主入口；
- `ExplicitCypherGenerationService`：显式 Cypher；
- `Neo4jGraphRagCypherGenerationService`：自动生成 Cypher；
- `RagAiBridgeClient`：调用 `/text2cypher`；
- `CypherGuardService`：Java 只读安全校验；
- `GraphSourceServiceImpl`：执行图查询；
- `Neo4jExecutorService`：Neo4j Driver 和结果转换。
