4. 使用SpringBoot快速集成LangChain4J, 实现AI的丝滑调用
1. 简介前几章简单测试了一下LangChain4J的特性, 本章使用SpringBoot快速集成LangChain4J, 实现丝滑调用大模型, 往期内容传送门
[*]LangChain4j 初识,想使用Java开发AI应用?
[*]LangChain4j-AIServices,原来调用AI这么简单?
[*]LangChain4j-RAG,实现简单的text-sql功能
LangChain4J官方提供了SpringBoot Starter, 本章就使用Starter进行快速集成.
2. 环境信息
使用SDK版本信息如下:
Java: 21
SpringBoot: 3.4.5
LangChain4j: 1.0.1
LLM: (使用在线的百炼(阿里)平台)
embedding模型: text-embedding-v3
chat模型: qwen-plus
PGVector(postgresql版本的向量数据库, 文章最后有相关的docker-compose): 0.8.0-pg17 3. Maven
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
spring-boot-starter-parent</artifactId>
<version>3.4.5</version>
<relativePath/>
</parent>
<groupId>com.ldx</groupId>
langchain-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>langchain-test</name>
<description>langchain-test</description>
<properties>
<java.version>21</java.version>
<guava.version>33.0.0-jre</guava.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>dev.langchain4j</groupId>
langchain4j-bom</artifactId>
<version>1.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
langchain4j-open-ai-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
langchain4j-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
langchain4j-open-ai</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
langchain4j-reactor</artifactId>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
langchain4j-pgvector</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>4. 配置信息
4.1 application.yml
通过在配置文件中声明模型信息 即可实现对应模型的自动注入
langchain4j:
open-ai:
# 普通聊天模型
chat-model:
api-key: ${LLM_API_KEY}
model-name: qwen-plus
base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
# 流式相应模型
streaming-chat-model:
api-key: ${LLM_API_KEY}
model-name: qwen-plus
base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
# 向量模型
embedding-model:
api-key: ${LLM_API_KEY}
model-name: text-embedding-v3
base-url: https://dashscope.aliyuncs.com/compatible-mode/v14.2 配置类
主要声明了
[*]聊天记忆提供类, 关联了记忆存储对象
[*]向量存储对象,这里使用的是pgvector
[*]内容检索器(RAG-检索实现)
package com.ldx.langchaintest.config;
import com.ldx.langchaintest.service.PersistentChatMemoryStore;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.pgvector.DefaultMetadataStorageConfig;
import dev.langchain4j.store.embedding.pgvector.PgVectorEmbeddingStore;
import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* config
*
* @author ludangxin
* @date 2025/5/15
*/
@Configuration
public class AiConfiguration {
/**
* 聊天记忆 提供者
*
* @param persistentChatMemoryStore 对话内容持久化对象
* @return 对话记忆 provider
*/
@Bean
public ChatMemoryProvider jdbcChatMemoryProvider(PersistentChatMemoryStore persistentChatMemoryStore) {
return memoryId -> MessageWindowChatMemory
.builder()
.id(memoryId)
// 这里使用了自定义的会话存储对象, 可以通过其实现对话过程内容的持久化
// 本地测试的话可以使用 InMemoryChatMemoryStore对象实现内存存储
.chatMemoryStore(persistentChatMemoryStore)
.maxMessages(5)
.build();
}
/**
* 向量存储对象
*
* @param embeddingModel 向量模型
* @return 向量存储对象
*/
public EmbeddingStore<TextSegment> embeddingStore(EmbeddingModel embeddingModel) {
return PgVectorEmbeddingStore
.builder()
.host("localhost") // 必需:PostgresSQL 实例的主机
.port(5431) // 必需:PostgresSQL 实例的端口
.database("postgres") // 必需:数据库名称
.user("root") // 必需:数据库用户
.password("123456") // 必需:数据库密码
.table("my_embeddings") // 必需:存储嵌入的表名
.dimension(embeddingModel.dimension()) // 必需:嵌入的维度
.metadataStorageConfig(DefaultMetadataStorageConfig.defaultConfig()) // 元数据存储配置
.build();
}
/**
* 内容检索器
*
* @param embeddingModel 向量模型
* @return 内容检索器
*/
@Bean
public ContentRetriever contentRetriever(EmbeddingModel embeddingModel) {
return EmbeddingStoreContentRetriever
.builder()
.embeddingStore(this.embeddingStore(embeddingModel))
.embeddingModel(embeddingModel)
.maxResults(10)
.minScore(0.65)
.build();
}
}4.3 聊天记忆持久化
实现了ChatMemoryStore接口, 这里测试使用的是map存储的, 生产环境中可以持久化到数据库中
chat过程中消息会通过ChatMemory调用ChatMemoryStore对聊天内容进行持久化/获取
package com.ldx.langchaintest.service;
import com.google.common.collect.ArrayListMultimap;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class PersistentChatMemoryStore implements ChatMemoryStore {
final ArrayListMultimap<Object, ChatMessage> messagesStore = ArrayListMultimap.create();
@Override
public List<ChatMessage> getMessages(Object memoryId) {
return messagesStore.get(memoryId);
}
@Override
public void updateMessages(Object memoryId, List<ChatMessage> messages) {
messagesStore.put(memoryId, messages.getLast());
}
@Override
public void deleteMessages(Object memoryId) {
messagesStore.removeAll(memoryId);
}
}4.4 tools
package com.ldx.langchaintest.tools;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* tools
*
* @author ludangxin
* @date 2025/5/15
*/
@Slf4j
@Component
public class SysTools {
@Tool("根据用户的名称获取对应的code")
public String getUserCodeByUsername(@P("用户名称") String username) {
log.info("get user code by username:{}", username);
if ("张铁牛".equals(username)) {
return "003";
}
return "000";
}
}5. 核心源码
5.1 Ai Services
@AiService 将实现AiService的自动注入
wiringMode = EXPLICIT: 用户自己指定相关的bean
缺省:wiringMode = AUTOMATIC: 项目启动时自动在环境中找对应的对象实现注入,如果有多个(比如:chatModel),启动报错
这里举了几种典型的场景 如
[*]普通聊天 chat()
[*]聊天记忆&流式输出 chatWithStream()
[*]提取指定内容并将结果结构化 extractPerson()
[*]提示词占位替换 mockUsername()
[*]rag text-sql chatWithSql()
package com.ldx.langchaintest.service;import com.ldx.langchaintest.domain.Person;import dev.langchain4j.service.MemoryId;import dev.langchain4j.service.SystemMessage;import dev.langchain4j.service.UserMessage;import dev.langchain4j.service.V;import dev.langchain4j.service.spring.AiService;import reactor.core.publisher.Flux;import java.util.List;import static dev.langchain4j.service.spring.AiServiceWiringMode.EXPLICIT;/** * ai svc * * @author ludangxin * @date 2025/5/16 */@AiService(wiringMode = EXPLICIT, chatModel = "openAiChatModel", streamingChatModel = "openAiStreamingChatModel", chatMemoryProvider = "chatMemoryProvider", contentRetriever = "contentRetriever", tools = {"sysTools"})public interface AiSqlAssistantService { String chat(String message); @SystemMessage("
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]