提示:如果不能访问 OpenAI,请点击 AiCode API 注册账号,通过代理访问。
在 Spring AI 1.0.0 中,Neo4jChatMemoryRepository 是用于将聊天记忆(对话历史)持久化到 Neo4j 图数据库的存储实现,它实现了 ChatMemoryRepository 接口,属于 Spring AI 聊天记忆模块的一部分。
Neo4jChatMemoryRepository 基于图数据库的特性,适合存储具有复杂关联关系的对话数据,尤其在需要对对话上下文进行多维度查询、分析或关联扩展时表现出色。
Neo4j 是一款开源的原生图数据库(Native Graph Database),专为存储、查询和处理具有复杂关联关系的数据而设计。它以 “图” 作为数据模型的核心,通过节点(Node)、关系(Relationship)和属性(Property)来表达数据及其之间的关联,相比传统的关系型数据库(如 MySQL)或文档数据库(如 MongoDB),在处理多对多关系、路径分析、关联挖掘等场景中具有显著优势。
Neo4j 数据库主要特性如下:
(1) 原生图存储:数据从底层设计就以图结构存储,而非通过关系表或文档间接模拟图关系,因此对关联数据的读写性能远超其他类型数据库。
(2)高效的图查询语言Cypher:提供声明式查询语言 Cypher,语法简洁直观,专为图操作设计,支持节点匹配、关系遍历、路径查找(如最短路径)、聚合分析等复杂操作。
(3)ACID 事务支持:完全支持事务的原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),确保数据操作的可靠性。
(4)高可用性与扩展性:支持集群部署(主从复制、因果集群),提供自动故障转移和读写分离,可通过水平扩展应对大规模数据和高并发场景。
(5)丰富的生态与集成:提供多种编程语言驱动(Java、Python、JavaScript 等)、REST API、与大数据工具(Spark、Flink)和 AI 框架(如 Spring AI)的集成能力。
Neo4j 数据库的数据模型核心由三部分组成:
(1) 节点(Node):表示实体(如“用户”、“商品”、“订单”),可被打上一个或多个标签(Label,类似关系型数据库的“表”),用于分类节点(如 :User :Product)。
(2)关系(Relationship):连接两个节点,具有方向和类型(如 :FOLLOWS :PURCHASED),表示实体间的关联(如“用户 A 购买了商品 B”)。关系必须有且仅有一个类型,且不可独立存在(必连接两个节点)。
(3)属性(Property):键值对(Key-Value),可附加在节点或关系上,存储具体数据(如节点 :User 可有 name: "Alice" age: 30,关系 :PURCHASED 可有 amount: 99.9 time: "2023-10-01")。
注意,Neo4j 是图数据库领域的标杆产品,其核心价值在于高效处理“关系密集型”数据。当业务场景中数据间的关联是核心(如社交、知识图谱、推荐),Neo4j 相比传统数据库能显著提升开发效率和查询性能。
下面将演示在 Windows11 下面通过 WSL2 安装的 Ubuntu 22.04.5 LTS (GNU/Linux 6.6.87.2-microsoft-standard-WSL2 x86_64) 系统中,通过 Docker 安装 Apache Cassandra 数据库,详细步骤如下:
(1)查看 Docker 版本信息,如果没有 Docker 请先安装 Docker。如下:
hxstrive@localhost:~$ sudo docker --version Docker version 28.3.2, build 578ccf6
安装 Docker 请参考 Docker 教程。
(2) 从 Docker Hub 拉取官方的 neo4j 镜像(默认会拉取最新稳定版),如下:
hxstrive@localhost:~$ sudo docker pull neo4j [sudo] password for hx: Using default tag: latest latest: Pulling from library/neo4j 4eb1dd59a738: Pull complete af4d3ed4f508: Pull complete aa20373901d9: Pull complete e259da529216: Pull complete 2aa9c2c55d90: Pull complete 4f4fb700ef54: Pull complete Digest: sha256:0c83938a8d825ade6e42ab81c4ab9a99a7e7ff05fb2fd248fd0636bbc6aa9aab Status: Downloaded newer image for neo4j:latest docker.io/library/neo4j:latest
(3)使用 docker run 命令启动 Neo4j 容器,需配置必要的端口映射、数据持久化和环境变量。如果仅用于临时测试,无需持久化数据,可直接运行:
docker run \ --name neo4j-test \ -d \ -p 7474:7474 \ # Web 管理界面端口 -p 7687:7687 \ # Bolt 协议端口(客户端连接用) -e NEO4J_AUTH=neo4j/password \ # 用户名/密码(默认用户为 neo4j) neo4j
参数说明:
--name neo4j-test:给容器命名(方便后续操作)。
-d:后台运行容器。
-p 7474:7474:将容器内的 7474 端口映射到主机的 7474 端口(Web 界面访问)。
-p 7687:7687:Bolt 协议端口,用于客户端(如 Java/Python 驱动)连接。
-e NEO4J_AUTH=neo4j/password:设置初始密码(首次登录需使用此密码,建议修改为复杂密码)。
hxstrive@localhost:~$ sudo docker run --name neo4j-test -d -p 7474:7474 -p 7687:7687 -e NEO4J_AUTH=neo4j/1234abcd neo4j 85f7a8d856029e726c27d6a44511fbbabfbddcdf4c22c2996e641e5c8b543471
(4)验证 Neo4j 运行状态,使用 docker ps | grep neo4j 查看容器是否启动成功。如果输出包含 neo4j 容器信息,说明启动成功,如下:
hxstrive@localhost:~$ sudo docker ps | grep neo4j 85f7a8d85602 neo4j "tini -g -- /startup…" 9 seconds ago Up 9 seconds 0.0.0.0:7474->7474/tcp, [::]:7474->7474/tcp, 7473/tcp, 0.0.0.0:7687->7687/tcp, [::]:7687->7687/tcp neo4j-test
还可以继续使用 docker logs 命令查看启动日志:
hxstrive@localhost:~$ sudo docker logs neo4j-test
Changed password for user 'neo4j'. IMPORTANT: this change will only take effect if performed before the database is started for the first time.
2025-10-17 07:02:24.589+0000 INFO Logging config in use: File '/var/lib/neo4j/conf/user-logs.xml'
2025-10-17 07:02:24.622+0000 INFO Starting...
2025-10-17 07:02:26.206+0000 INFO This instance is ServerId{36c81561} (36c81561-eaeb-498c-b567-b503262ab95a)
2025-10-17 07:02:29.192+0000 INFO ======== Neo4j 2025.09.0 ========
2025-10-17 07:02:32.296+0000 INFO Anonymous Usage Data is being sent to Neo4j, see https://neo4j.com/docs/usage-data/
2025-10-17 07:02:34.144+0000 INFO Bolt enabled on 0.0.0.0:7687.
2025-10-17 07:02:36.052+0000 INFO HTTP enabled on 0.0.0.0:7474.
2025-10-17 07:02:36.053+0000 INFO Remote interface available at http://localhost:7474/
2025-10-17 07:02:36.057+0000 INFO id: 9C1D6E955A82DA9A7218883E76600EA437B37510F82451FB9DF7F04A30D9CE27
2025-10-17 07:02:36.058+0000 INFO name: system
2025-10-17 07:02:36.058+0000 INFO creationDate: 2025-10-17T07:02:31.142Z
2025-10-17 07:02:36.059+0000 INFO Started.日志末尾出现了 Started. 表示服务已就绪。
(5)访问 Neo4j 管理界面
打开浏览器,访问 http://localhost:7474(如果是远程服务器,替换为服务器 IP)。首次登录时,输入用户名 neo4j 和设置的密码(如 1234abcd)。
注意,登录后会提示修改初始密码,建议设置一个新密码(后续客户端连接需使用新密码)。


首先,在项目中添加以下依赖:
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-model-chat-memory-repository-neo4j</artifactId> </dependency>
注意:spring-ai-model-chat-memory-repository-neo4j 是专门用于将 聊天记忆(对话历史)持久化到 Neo4j 图数据库 的模块,提供了基于图结构的对话记忆管理能力。
到这里,准备工作就做完了,下面开始编写代码。
首先,创建一个名为 AiConfig.java 的配置类,用来配置 ChatMemory 和 Neo4jChatMemoryRepository,代码如下:
package com.hxstrive.springai.springai_openai.chatMemoryRepository.chatMemoryRepository4;
import org.neo4j.driver.Driver;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.memory.repository.neo4j.Neo4jChatMemoryRepository;
import org.springframework.ai.chat.memory.repository.neo4j.Neo4jChatMemoryRepositoryConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AiConfig {
/**
* 定义聊天记忆(ChatMemory)Bean
* 采用窗口模式(MessageWindowChatMemory),限制最多保存的消息数量
*
* @param chatMemoryRepository 聊天记忆存储仓库(Neo4j实现)
* @return 配置好的聊天记忆对象
*/
@Bean
public ChatMemory chatMemory(Neo4jChatMemoryRepository chatMemoryRepository) {
return MessageWindowChatMemory.builder()
.chatMemoryRepository(chatMemoryRepository) // 注入Neo4j存储仓库,指定消息持久化方式
.maxMessages(20) // 设置窗口大小,最多保存20条消息(超过则自动丢弃最早的消息)
.build();
}
@Bean
public Neo4jChatMemoryRepository cassandraChatMemoryRepository(Driver driver) {
Neo4jChatMemoryRepositoryConfig config = Neo4jChatMemoryRepositoryConfig.builder()
.withDriver(driver)
.build();
return new Neo4jChatMemoryRepository(config);
}
}然后,将 ChatMemory 注入到客户端代码中,如下:
package com.hxstrive.springai.springai_openai.chatMemoryRepository.chatMemoryRepository4;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class SpringAiDemoApplication implements CommandLineRunner {
@Autowired
private ChatModel chatModel;
@Autowired
private ChatMemory chatMemory;
public static void main(String[] args) {
SpringApplication.run(SpringAiDemoApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
StringBuilder builder = new StringBuilder();
// 唯一会话ID,同一个会话上下文中保持一致
String sessionId = "USER-251017100313";
String question = "四川大学是985吗?";
String ai = chat(sessionId, question);
builder.append(String.format("用户问题:%s\n", question));
builder.append(String.format("机器回复:%s\n", ai));
question = "是211吗?";
ai = chat(sessionId, question);
builder.append(String.format("用户问题:%s\n", question));
builder.append(String.format("机器回复:%s\n", ai));
System.out.println(builder.toString());
}
private String chat(String sessionId, String question) {
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultSystem("你是AI助手小粒,所有回复均使用中文。")
.defaultAdvisors(
new SimpleLoggerAdvisor() // 输出聊天日志
).build();
// 1. 将用户输入添加到记忆
UserMessage userMessage = new UserMessage(question);
chatMemory.add(sessionId, userMessage);
// 2. 获取记忆中的所有消息(上下文),传递给 AI 模型
ChatClient.CallResponseSpec responseSpec = chatClient.prompt().messages(chatMemory.get(sessionId)).call();
// 3. 将 AI 回复添加到记忆,更新上下文
AssistantMessage assistantMessage = responseSpec.chatResponse().getResult().getOutput();
chatMemory.add(sessionId, assistantMessage);
// 4. 返回 AI 回复内容
return assistantMessage.getText();
}
}运行代码,输出如下:

执行成功后,登录到 Neo4j 的 Web 页面,查看刚刚存入的数据。如下图:


下面是 Spring AI 中,关于 neo4j 的配置项:
属性 | 说明 | 默认值 |
spring.ai.chat.memory.repository.neo4j.sessionLabel | 存储对话会话的节点的标签 | Session |
spring.ai.chat.memory.repository.neo4j.messageLabel | 存储信息的节点的标签 | Message |
spring.ai.chat.memory.repository.neo4j.toolCallLabel | 存储工具调用的节点(如 Assistant 信息中)的标签 | ToolCall |
spring.ai.chat.memory.repository.neo4j.metadataLabel | 存储消息元数据的节点的标签 | Metadata |
spring.ai.chat.memory.repository.neo4j.toolResponseLabel | 存储工具响应的节点的标签 | ToolResponse |
spring.ai.chat.memory.repository.neo4j.mediaLabel | 存储消息相关的媒体的节点标签 | Media |
注意:Neo4j 存储库将自动创建会话 ID 和消息索引的优化索引。若使用自定义标签,系统同样会为这些标签建立索引。虽无需初始化 Schema,但需确保应用可访问 Neo4j 实例。
更多信息请访问官方文档 https://docs.spring.io/spring-ai/reference/api/vectordbs/neo4j.html。
提示:如果不能访问 OpenAI,请点击 AiCode API 注册账号,通过代理访问。