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
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/v1
复制代码 4.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()
[code]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("
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |