NO.19 · 人工智能
NeoInsight:LangChain + Neo4j 的知识图谱问答系统
前后端分离的 RAG 知识图谱问答演示项目——自然语言经 LLM 生成 Cypher、在 Neo4j 执行、再由 LLM 生成回答,全过程透明可调试,附带只读安全守卫、统一响应格式与 27 个 pytest 用例。
大模型能背下训练数据里的事实,但背不下你图数据库里的三元组。RAG 的常见做法是检索文本段落塞进上下文,而图谱路线更直接:让模型把问题翻译成 Cypher,在图上查完再把结果讲回人话。
NeoInsight 就是这个闭环的一个完整、可运行的演示。
一条链路,四步闭环
1 | 用户提问 |
全过程透明——响应里同时返回生成的 Cypher 和查询结果,出了问题能立刻分辨是「模型翻译错了」还是「图里没有这条数据」。这一点在调试 RAG 系统时比什么都重要。
技术栈
| 层 | 技术 |
|---|---|
| 前端 | Vue 2.6 · Element UI · Vuex · Vue Router · Axios(Vue CLI 5) |
| 后端 | Python · Flask 3 · neo4j 官方驱动 · LangChain-OpenAI · pandas / openpyxl |
| 存储 | Neo4j 5.x |
| 大模型 | DeepSeek / Kimi(OpenAI 兼容 API) |
模型可切换:内置 kimi 与 deepseek 两个 OpenAI 兼容供应商,在常量文件里加一项、环境变量里配一个 Key 就能扩展新模型。
四个值得留意的设计
只读安全守卫。LLM 生成的 Cypher 不可信,正则拦截 CREATE / MERGE / DELETE / SET 等写操作,保证图谱数据安全。把「模型输出当作不可信输入」是 AI 应用的基本功。
「宏定义」式常量中心。后端 app/constants.py、前端 src/constants.js 各一个文件,集中所有重要数据:端口、限制、错误码、数据导入结构、提示词模板,分 9 个分区管理。改配置不用翻代码,敏感项(Neo4j 密码、API Key)只放 .env。
统一响应格式与业务错误码。所有接口返回 {"code": 0, "message": "success", "data": ...}:
| code | 含义 |
|---|---|
| 40000 | 请求参数不合法(空问题 / 超长 / 不支持的模型) |
| 50200 | 模型服务调用失败 |
| 50300 | 关键依赖(如 Neo4j)不可用 |
| 50301 | 图查询失败 / 被只读守卫拦截 |
| 50302 | 所选模型未配置 API Key |
| 50000 | 服务内部错误 |
旧接口兼容。保留 GET /question 旧格式接口,教程的旧调用方不受影响。接口演进而不断旧调用,是维护成本最低的兼容策略。
数据与导入
scripts/import_data.py 把 Excel 事故记录导入图中,生成 Time / System / Incident / Account / Level / Reason / Loss 节点,并统一与 Incident 建立关联。默认导入会清空图库现有内容(--no-clear 可追加),脚本用 pandas/openpyxl 读表,适合「表格数据 → 知识图谱」的常见迁移场景。
接口一览
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/health |
健康检查(服务 / Neo4j / 已注册模型) |
| POST | /api/qa/ask |
标准问答入口,body: {"question": "...", "llm": "deepseek"} |
| GET | /api/qa/ask |
GET 形式:?question=...&llm=... |
| GET | /question |
旧版接口兼容,返回旧格式 {"result": "..."} |
1 | curl -X POST http://127.0.0.1:5002/api/qa/ask \ |
响应 data 中包含 answer(回答)与 cypher(实际执行的查询)。
一个值得记住的坑
如果回答与图谱无关、甚至在复读问题,通常不是程序错误——而是图库数据与提示词调校的场景不匹配,模型走了「通用知识回答」路径。提示词模板是针对事故数据场景调校的,换业务数据时必须同步调整提示词。RAG 系统的「检索质量」和「提示词场景」是一对必须一起换的齿轮。
测试方面,后端带 27 个 pytest 用例(API / 图服务 / 数据导入),前端通过 devServer 代理 /api 到 5002 端口,开发环境一般无需处理跨域。