项目概述
本教程将介绍如何使用LangChain4j和Milvus向量数据库构建一个具备流式输出、会话管理、会话隔离和基于文档RAG检索能力的AI机器人。我们将使用阿里百炼模型作为LLM后端,并通过Docker部署Milvus向量数据库。
项目地址:https://gitee.com/LRTesthhh/langchain4j-chat-demo.git
技术栈
- 框架:Spring Boot 3.5.4
- AI工具链:LangChain4j 1.0.0-beta3
- 向量数据库:Milvus 2.6.0
- 模型:阿里百炼 qwen-plus
- 响应式编程:Reactor
- 容器化:Docker
步骤1:安装与部署Milvus向量数据库(此次使用win演示)(更多部署方式查看Run Milvus in Docker (Linux) | Milvus Documentation)
在windows环境下使用Docker Desktop安装Milvus
- 首先确保已安装Docker Desktop并启动
- 打开终端,执行以下命令拉取Milvus镜像:
# 拉取Milvus standalone镜像
docker pull milvusdb/milvus:v2.3.4-standalone
- 创建Milvus数据和配置目录:
mkdir -p d:\milvus\data\
mkdir -p d:\milvus\config\
- 启动Milvus容器:
docker run -d --name milvus-standalone -p 19530:19530 -p 9091:9091 -v d:\milvus\data:/var/lib/milvus/data -v d:\milvus\config:/var/lib/milvus/config milvusdb/milvus:v2.3.4-standalone
- 验证Milvus是否启动成功:
docker logs milvus-standalone
如果看到"Milvus successfully started"的日志,说明Milvus已成功启动。
步骤2:创建Spring Boot项目并配置依赖
创建项目
使用Spring Initializer创建一个新的Spring Boot项目,选择以下依赖:
- Spring Boot Starter Web
- Spring Boot Starter Webflux
- Spring Boot Starter Actuator
- Spring Boot Starter Test
添加LangChain4j和Milvus依赖
在pom.xml中添加以下依赖:
<!-- Spring Boot Actuator 用于监控和管理应用,提供健康检查、指标收集等功能 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Spring Boot Web 起步依赖,用于构建 Web 应用,支持 RESTful 服务和 MVC 架构 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Test 起步依赖,用于编写和运行单元测试及集成测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 日志框架 Logback 的经典实现,用于记录应用程序运行时的日志信息 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<!-- LangChain4j 的 OpenAI Spring Boot 起步依赖,简化与 OpenAI 模型的集成 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>1.0.0-beta3</version>
</dependency>
<!-- LangChain4j 核心 Spring Boot 起步依赖,提供 AI 服务的基础支持 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>1.0.0-beta3</version>
</dependency>
<!-- Spring Boot WebFlux 起步依赖,用于构建响应式 Web 应用,支持流式数据处理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- LangChain4j Reactor 模块,用于在响应式编程中集成 AI 功能 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-reactor</artifactId>
<version>1.2.0-beta8</version>
</dependency>
<!-- LangChain4j Easy RAG 模块,简化检索增强生成(RAG)流程的实现 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-easy-rag</artifactId>
<version>1.0.0-beta3</version>
</dependency>
<!-- LangChain4j 对 Milvus 向量数据库的支持模块 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-milvus</artifactId>
<version>1.0.0-beta3</version>
</dependency>
<!-- Milvus Java SDK,用于与 Milvus 向量数据库进行交互 -->
<dependency>
<groupId>io.milvus</groupId>
<artifactId>milvus-sdk-java</artifactId>
<version>2.6.0</version>
</dependency>
<!-- LangChain4j 提供的嵌入模型实现,基于 all-MiniLM-L6-v2 模型 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-embeddings-all-minilm-l6-v2</artifactId>
<version>1.2.0-beta8</version>
</dependency>
<!-- Testcontainers 的 Milvus 模块,用于在测试环境中启动 Milvus 容器 -->
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>milvus</artifactId>
<version>1.19.6</version>
</dependency>
<!-- LangChain4j 嵌入功能核心模块,提供嵌入模型的通用接口和实现 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-embeddings</artifactId>
<version>1.2.0-beta8</version>
</dependency>
<!-- LangChain4j Milvus Spring Boot 起步依赖,简化 Milvus 在 Spring Boot 中的集成 -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-milvus-spring-boot-starter</artifactId>
<version>1.0.0-beta3</version>
</dependency>
步骤3:配置阿里百炼模型
在AiConfig.java中配置OpenAiChatModel(兼容阿里百炼接口):
不同供应商集成了不同依赖,这里使用openai的可以兼容阿里百炼,你也可以使用其它兼容的模型,兼容模型列表参考:所有支持的语言模型比较表 | LangChain4j 中文文档
@Configuration
public class AiConfig {
@Bean
OpenAiChatModel openAiChatModel() {
return OpenAiChatModel.builder()
.apiKey("你的阿里云API密钥")
.modelName("qwen-plus") //模型名称
.logRequests(true) //请求日志打印(debug级)
.logResponses(true) // 返回日志打印
.maxRetries(3) // 最大重试次数
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1") //url
.build();
}
// 其他配置...
}
注意:在生产环境中,建议将API密钥存储在配置文件或环境变量中,不要硬编码。
步骤4:配置Milvus向量存储
在AiConfig.java中添加Milvus配置:
在第一次嵌入向量时,如果数据库不存在会自动根据你的数据库名创建一个,而此数据库的向量维度为你定义的维度。
数据经嵌入模型向量化后的维度应与数据库维度相等,否则报错。嵌入模型向量维度可配置修改。
我使用langchain4j内置嵌入模型,默认为384.因此我定义store时写入384
@Bean
MilvusEmbeddingStore embeddingStore() {
return MilvusEmbeddingStore.builder()
.host("localhost") // 主机
.port(19530) //端口
.collectionName("my_database_0") //数据库名
.dimension(384) // 向量维度
.indexType(IndexType.FLAT)
.metricType(MetricType.COSINE)
.consistencyLevel(ConsistencyLevelEnum.EVENTUALLY)
.autoFlushOnInsert(true)
.build();
}
步骤5:实现RAG检索功能
配置内容检索器,实现基于文档的RAG检索:
首先我们需要加载我们想要读取的文件或文件夹,
然后需要创建分词器和嵌入模型,我使用框架内部的分词器和模型,你也可以自己定义配置。
ContentRetriever 是一个接口,具体实现取决于你自己使用什么检索器,我这里使用miluvs。
构造时选填许多参数,我这里填了重要的minScore,意思是向量余弦相似度达到多少分以上匹配。以及返回最大ji
@Bean
ContentRetriever contentRetriever(MilvusEmbeddingStore embeddingStore) {
// 创建嵌入模型
EmbeddingModel embeddingModel = new AllMiniLmL6V2EmbeddingModel();
// 创建文档分割器
DocumentSplitter documentSplitter = new DocumentByParagraphSplitter(1000, 0);
// 创建嵌入存储注入器
EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
.documentSplitter(documentSplitter)
.embeddingModel(embeddingModel)
.embeddingStore(embeddingStore)
.build();
// 加载文档
List<Document> documents = FileSystemDocumentLoader.loadDocuments("src/main/resources/templates");
ingestor.ingest(documents);
// 创建内容检索器
return EmbeddingStoreContentRetriever.builder()
.embeddingStore(embeddingStore)
.embeddingModel(embeddingModel)
.minScore(0.7)
.maxResults(5)
.build();
}
步骤6:实现会话管理
配置聊天记忆提供者,实现会话隔离:
为了实现多会话隔离,我们需要为不同用户或请求分配独立的对话上下文。LangChain4j 提供了 ChatMemoryProvider
接口,我们可以自定义实现它,并通过 memoryId
区分用户。这个id呢一般我们使用SessionId。
这里我们采用 MessageWindowChatMemory
作为记忆机制,该方式维护一个固定长度的消息窗口(如最近 10 条消息),适合大多数对话式任务。
@Bean
ChatMemoryProvider chatMemoryProvider() {
return new ChatMemoryProvider() {
@Override
public ChatMemory get(Object memoryId) {
return MessageWindowChatMemory.builder()
.maxMessages(10) //最大消息数
.id(memoryId) // id
.build();
}
};
}
步骤7:定义AI服务接口
创建Assistant接口,定义聊天服务:
写一个接口,打上@AiService注解并做一些配置就行了,框架内部为我们的接口做了代理,不需要我们关心底层实现,更高级的自定义自由化编码参考官方文档:LangChain4j 中文文档 | LangChain4j 中文文档
wiringMode :这个属性一般两种,一种是自动装配,我们这里选择手动配置
chatModel :这是大语言模型的bean名,可以在config配置,或者导入依赖自动装配
chatMemoryProvider :会话记忆提供者,类似工厂,如果是存在的会话记忆直接拿来用,如果新的会话直接创建,根据id识别。我们在config类以及对其做了配置
contentRetriever :检索器bean,用于文本检索
@AiService(
wiringMode = AiServiceWiringMode.EXPLICIT, //配置模式:手动(自动)
chatModel = "openAiChatModel", // 大语言模型
chatMemoryProvider = "chatMemoryProvider", // 上下文对话
contentRetriever = "contentRetriever" // 检索器
)
public interface Assistant {
@SystemMessage("你是一个文档分析助手小红")
Flux<String> chat(@MemoryId String memoryId, @UserMessage String userMessage);
}
步骤8:实现控制器
创建AiController,提供RESTful API:(为了方便我就没连数据库持久化)
@RestController
public class AiController {
@Resource
private Assistant assistant;
private final Map<String, List<String>> sessionHistory = new ConcurrentHashMap<>();
@GetMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> chat(@RequestParam String userMessage, @RequestParam(required = false) String sessionId) {
// 将会话消息添加到历史记录
sessionHistory.computeIfAbsent(sessionId, k -> new ArrayList<>()).add("You: " + userMessage);
// 如果sessionId为空,使用默认值
if (sessionId == null || sessionId.isBlank())
sessionId = "default";
return assistant.chat(sessionId, userMessage);
}
}
步骤9:运行和测试
- 确保Milvus容器正在运行
- 在项目的resources/templates目录下添加一些文档
- 启动Spring Boot应用
- 使用curl或浏览器测试API:
- 我让ai写了一个简单的index页面,支持各种文档格式检索,我上传了一个小项目设计书和我的简历,项目书里有我的姓名,我问ai我的项目相关的东西,不仅给我总结的很到位,甚至根据我的基础信息匹配了我的简历。还是挺好玩的哈哈哈哈
curl "http://localhost:8080/chat?userMessage=你好&sessionId=test1"
拓展与官方链接
总结
本教程介绍了如何使用LangChain4j和Milvus构建一个具备会话管理和RAG检索能力的AI机器人。我们实现了:
- Milvus向量数据库的Docker部署
- 阿里百炼模型的连接配置
- 会话管理和隔离
- 基于文档的RAG检索
- 响应式API接口
希望本教程对你有所帮助!有任何问题请在评论区留言指正!!!!