# 本项目 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 负责: - 清除 `` 内容; - 提取 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 和结果转换。