一个知识问答 Demo,带我搞懂了 Milvus、Neo4j 在 RAG 里到底各干什么

0 阅读6分钟

最近学习 RAG,我做了一个很小的知识问答 Demo。

页面只有两部分:

  • 左边上传知识文件
  • 右边输入问题,查看回答

但当我把 Milvus、Neo4j、Docker 真正串起来以后,才发现:

RAG 远不只是“上传文档,再让 AI 回答问题”。

Milvus、Neo4j 和 Docker 各自负责的事情完全不同。


1. 先说结论:它们不是替代关系

我最开始有一个问题:

已经有了 Milvus,为什么还要 Neo4j?

后来才明白,二者解决的根本不是同一种问题。

Milvus 解决的是语义相似度问题。

比如知识库里写的是:

社保查询可通过“某某人社”提供服务入口。

用户问的是:

社保查询使用哪个系统?

虽然两个句子用词不完全一样,但表达的意思很接近。Milvus 可以通过向量检索,把相关内容找出来。

Neo4j 解决的是实体关系问题。

比如:

某某市人力资源和社会保障局
  ↓ 负责
社保查询
  ↓ 由系统支撑
某某人社

这类“谁负责谁、谁支撑谁、谁依赖谁”的关系,用图数据库表达会非常清晰。

所以我现在的理解是:

Milvus:找语义相近的内容
Neo4j:找业务实体之间的关系
大模型:整理上下文并生成答案
Docker:把整个环境快速跑起来

2. Milvus:解决“用户说法和文档写法不一样”

传统关键词搜索有一个明显问题:

用户说的是 A,文档写的是 B,但两者其实表达同一个意思。

例如:

用户提问:社保查询使用哪个系统?
文档描述:社保查询由某某人社提供服务入口。

如果只做关键词匹配,可能根本搜不到。

Milvus 的思路不一样。

它会把文本转换成向量,再计算问题和文档之间的语义距离。

也就是说,它更关心:

这两个句子的意思是不是相近?

一个最小的 RAG 流程可以理解成:

上传文档
↓
文本切分
↓
向量化
↓
写入 Milvus
↓
用户提问
↓
问题向量化
↓
Milvus 检索相关文本
↓
把相关文本交给大模型
↓
生成答案

Milvus 的作用,就是从大量文档里快速找出和问题最相关的内容。


3. Neo4j:让 RAG 不只会“搜”,还知道“关联”

只靠 Milvus,其实也能做一个基础 RAG。

但实际业务里,很多问题不是找到一段相似文本就结束了。

例如用户问:

社保查询使用哪个系统?

系统除了要找到“某某人社”这段文本,还可能需要继续确认:

  • 这个事项由哪个部门负责?
  • 使用的系统是什么?
  • 有哪些政策依据?
  • 还关联哪些办理事项?

在 Neo4j 中,这些内容可以建成节点和关系:

(部门)-[:RESPONSIBLE_FOR]->(事项)

(系统)-[:SUPPORTS]->(事项)

(政策)-[:COVERS]->(事项)

当系统查到“社保查询”后,就可以沿着关系继续查询。

这也是图数据库的优势:

Milvus 告诉你“什么内容可能相关”,Neo4j 告诉你“这些内容之间到底是什么关系”。


4. 哪些场景适合 Milvus + Neo4j?

如果只是公司制度、产品说明书、技术文档这类简单知识库,单独使用 Milvus 做 RAG 通常已经够用。

但如果知识之间有大量关联关系,Neo4j 就会更有价值。

例如:

  • 政务服务:事项、部门、政策、系统之间存在关联
  • 企业知识库:制度、岗位、流程、权限、系统之间存在关联
  • 运维知识库:服务、接口、中间件、负责人、故障之间存在依赖
  • 教育平台:课程、章节、知识点、习题之间存在学习路径

可以这样理解:

Milvus:从知识库里找相关内容

Neo4j:从关系网里找准确路径

两者组合后,RAG 的回答会更有依据。


5. Docker:学习阶段最容易忽略,但最值得掌握

第一次搭 Milvus 和 Neo4j 时,我最大的感受不是 AI 有多难。

而是环境真的很多。

Milvus 需要相关依赖服务,Neo4j 需要单独配置账号、密码和端口,Spring Boot 项目也需要连接这些服务。

如果全部手动安装,学习成本会很高。

所以 Docker 的意义很直接:

不先折腾环境,先把服务跑起来。

一个本地学习环境大概可以这样组织:

Docker Compose
├── Milvus
├── Milvus 相关依赖
├── Neo4j
└── Spring Boot 应用

学习 Docker 时,我觉得先理解下面三个概念就够了。

镜像

镜像可以理解为应用的运行模板。

例如 Neo4j 官方镜像中,已经准备好了运行 Neo4j 所需的环境。

容器

容器是镜像运行起来后的实例。

可以简单理解为:

镜像是菜谱

容器是做出来的菜

数据卷

数据库容器如果没有挂载数据卷,删除容器后数据可能就没有了。

所以要养成一个意识:

服务可以重建,数据不能随便丢。


6. 我现在理解的 RAG 架构

以前我理解 RAG 是:

文档
↓
向量库
↓
检索
↓
大模型回答

现在我会把它理解得更完整:

上传知识文件
↓
文本切分与清洗
↓
Milvus 做语义检索
↓
Neo4j 查询实体关系
↓
大模型整合上下文
↓
生成最终答案

在这条链路中:

  • Milvus 提供相关文本
  • Neo4j 提供业务关系
  • 大模型负责理解并回答
  • Docker 保证整个本地环境可以复现

7. 这次学习最大的收获

做完这个 Demo 后,我越来越觉得:

大模型负责表达,知识库负责提供事实,工程设计决定答案是否可靠。

真正难的不是接入一个大模型接口,而是:

  • 文档怎样切分更合理?
  • 检索结果是否真的相关?
  • 实体和关系怎样建模?
  • 怎样避免大模型脱离资料自由发挥?
  • 怎样让回答有来源、有依据、可追溯?

Milvus、Neo4j、Docker 看起来是三个独立技术。

但放在 RAG 场景里,它们刚好组成一个完整链路:

Docker 让环境稳定运行

Milvus 让知识可以被语义搜索

Neo4j 让知识之间产生关系

大模型让知识被整理成可读答案

这就是我目前理解的 RAG。

不是让 AI 变得无所不知。

而是给它一个可靠、可检索、可关联的外部大脑。


你在学习 RAG 时,最先卡住的是文档切分、Milvus 检索,还是 Neo4j 图谱建模?

#RAG #Milvus #Neo4j #Docker #SpringBoot #AI应用开发