找回密码
 立即注册
首页 业界区 安全 4. 使用SpringBoot快速集成LangChain4J, 实现AI的丝滑调 ...

4. 使用SpringBoot快速集成LangChain4J, 实现AI的丝滑调用

铜坠匍 2025-6-20 07:47:47
1. 简介

前几章简单测试了一下LangChain4J的特性, 本章使用SpringBoot快速集成LangChain4J, 实现丝滑调用大模型, 往期内容传送门

  • LangChain4j 初识,想使用Java开发AI应用?
  • LangChain4j-AIServices,原来调用AI这么简单?
  • LangChain4j-RAG,实现简单的text-sql功能
LangChain4J官方提供了SpringBoot Starter, 本章就使用Starter进行快速集成.
2. 环境信息

使用SDK版本信息如下:
  1. Java: 21
  2. SpringBoot: 3.4.5
  3. LangChain4j: 1.0.1
  4. LLM: (使用在线的百炼(阿里)平台)
  5.         embedding模型: text-embedding-v3  
  6.         chat模型: qwen-plus
  7. PGVector(postgresql版本的向量数据库, 文章最后有相关的docker-compose): 0.8.0-pg17
复制代码
3. Maven
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4.     <modelVersion>4.0.0</modelVersion>
  5.     <parent>
  6.         <groupId>org.springframework.boot</groupId>
  7.         spring-boot-starter-parent</artifactId>
  8.         <version>3.4.5</version>
  9.         <relativePath/>
  10.     </parent>
  11.     <groupId>com.ldx</groupId>
  12.     langchain-test</artifactId>
  13.     <version>0.0.1-SNAPSHOT</version>
  14.     <name>langchain-test</name>
  15.     <description>langchain-test</description>
  16.     <properties>
  17.         <java.version>21</java.version>
  18.         <guava.version>33.0.0-jre</guava.version>
  19.     </properties>
  20.     <dependencyManagement>
  21.         <dependencies>
  22.             <dependency>
  23.                 <groupId>dev.langchain4j</groupId>
  24.                 langchain4j-bom</artifactId>
  25.                 <version>1.0.1</version>
  26.                 <type>pom</type>
  27.                 <scope>import</scope>
  28.             </dependency>
  29.         </dependencies>
  30.     </dependencyManagement>
  31.     <dependencies>
  32.         <dependency>
  33.             <groupId>org.springframework.boot</groupId>
  34.             spring-boot-starter-web</artifactId>
  35.         </dependency>
  36.                           
  37.         <dependency>
  38.             <groupId>dev.langchain4j</groupId>
  39.             langchain4j-open-ai-spring-boot-starter</artifactId>
  40.         </dependency>
  41.                           
  42.         <dependency>
  43.             <groupId>dev.langchain4j</groupId>
  44.             langchain4j-spring-boot-starter</artifactId>
  45.         </dependency>
  46.         <dependency>
  47.             <groupId>dev.langchain4j</groupId>
  48.             langchain4j-open-ai</artifactId>
  49.         </dependency>
  50.         <dependency>
  51.             <groupId>com.google.guava</groupId>
  52.             guava</artifactId>
  53.             <version>${guava.version}</version>
  54.         </dependency>
  55.         <dependency>
  56.             <groupId>dev.langchain4j</groupId>
  57.             langchain4j-reactor</artifactId>
  58.         </dependency>
  59.         <dependency>
  60.             <groupId>dev.langchain4j</groupId>
  61.             langchain4j-pgvector</artifactId>
  62.         </dependency>
  63.         <dependency>
  64.             <groupId>org.projectlombok</groupId>
  65.             lombok</artifactId>
  66.             <optional>true</optional>
  67.         </dependency>
  68.         <dependency>
  69.             <groupId>org.springframework.boot</groupId>
  70.             spring-boot-starter-test</artifactId>
  71.             <scope>test</scope>
  72.         </dependency>
  73.     </dependencies>
  74.     <build>
  75.         <plugins>
  76.             <plugin>
  77.                 <groupId>org.apache.maven.plugins</groupId>
  78.                 maven-compiler-plugin</artifactId>
  79.             </plugin>
  80.             <plugin>
  81.                 <groupId>org.springframework.boot</groupId>
  82.                 spring-boot-maven-plugin</artifactId>
  83.                 <configuration>
  84.                     <excludes>
  85.                         <exclude>
  86.                             <groupId>org.projectlombok</groupId>
  87.                             lombok</artifactId>
  88.                         </exclude>
  89.                     </excludes>
  90.                 </configuration>
  91.             </plugin>
  92.         </plugins>
  93.     </build>
  94. </project>
复制代码
4. 配置信息

4.1 application.yml

通过在配置文件中声明模型信息 即可实现对应模型的自动注入
  1. langchain4j:
  2.   open-ai:
  3.     # 普通聊天模型
  4.     chat-model:
  5.       api-key: ${LLM_API_KEY}
  6.       model-name: qwen-plus
  7.       base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
  8.     # 流式相应模型  
  9.     streaming-chat-model:
  10.       api-key: ${LLM_API_KEY}
  11.       model-name: qwen-plus
  12.       base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
  13.     # 向量模型  
  14.     embedding-model:
  15.       api-key: ${LLM_API_KEY}
  16.       model-name: text-embedding-v3
  17.       base-url: https://dashscope.aliyuncs.com/compatible-mode/v1
复制代码
4.2 配置类

主要声明了

  • 聊天记忆提供类, 关联了记忆存储对象
  • 向量存储对象,这里使用的是pgvector
  • 内容检索器(RAG-检索实现)
  1. package com.ldx.langchaintest.config;
  2. import com.ldx.langchaintest.service.PersistentChatMemoryStore;
  3. import dev.langchain4j.data.segment.TextSegment;
  4. import dev.langchain4j.memory.chat.ChatMemoryProvider;
  5. import dev.langchain4j.memory.chat.MessageWindowChatMemory;
  6. import dev.langchain4j.model.embedding.EmbeddingModel;
  7. import dev.langchain4j.rag.content.retriever.ContentRetriever;
  8. import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
  9. import dev.langchain4j.store.embedding.EmbeddingStore;
  10. import dev.langchain4j.store.embedding.pgvector.DefaultMetadataStorageConfig;
  11. import dev.langchain4j.store.embedding.pgvector.PgVectorEmbeddingStore;
  12. import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore;
  13. import org.springframework.context.annotation.Bean;
  14. import org.springframework.context.annotation.Configuration;
  15. /**
  16. * config
  17. *
  18. * @author ludangxin
  19. * @date 2025/5/15
  20. */
  21. @Configuration
  22. public class AiConfiguration {
  23.     /**
  24.      * 聊天记忆 提供者
  25.      *
  26.      * @param persistentChatMemoryStore 对话内容持久化对象
  27.      * @return 对话记忆 provider
  28.      */
  29.     @Bean
  30.     public ChatMemoryProvider jdbcChatMemoryProvider(PersistentChatMemoryStore persistentChatMemoryStore) {
  31.         return memoryId -> MessageWindowChatMemory
  32.                 .builder()
  33.                 .id(memoryId)
  34.                 // 这里使用了自定义的会话存储对象, 可以通过其实现对话过程内容的持久化
  35.                 // 本地测试的话可以使用 InMemoryChatMemoryStore对象实现内存存储
  36.                 .chatMemoryStore(persistentChatMemoryStore)
  37.                 .maxMessages(5)
  38.                 .build();
  39.     }
  40.   
  41.     /**
  42.      * 向量存储对象
  43.      *
  44.      * @param embeddingModel 向量模型
  45.      * @return 向量存储对象
  46.      */
  47.     public EmbeddingStore<TextSegment> embeddingStore(EmbeddingModel embeddingModel) {
  48.         return PgVectorEmbeddingStore
  49.                 .builder()
  50.                 .host("localhost")                           // 必需:PostgresSQL 实例的主机
  51.                 .port(5431)                                  // 必需:PostgresSQL 实例的端口
  52.                 .database("postgres")                        // 必需:数据库名称
  53.                 .user("root")                                // 必需:数据库用户
  54.                 .password("123456")                          // 必需:数据库密码
  55.                 .table("my_embeddings")                      // 必需:存储嵌入的表名
  56.                 .dimension(embeddingModel.dimension())       // 必需:嵌入的维度
  57.                 .metadataStorageConfig(DefaultMetadataStorageConfig.defaultConfig()) // 元数据存储配置
  58.                 .build();
  59.     }
  60.     /**
  61.      * 内容检索器
  62.      *
  63.      * @param embeddingModel 向量模型
  64.      * @return 内容检索器
  65.      */
  66.     @Bean
  67.     public ContentRetriever contentRetriever(EmbeddingModel embeddingModel) {
  68.         return EmbeddingStoreContentRetriever
  69.                 .builder()
  70.                 .embeddingStore(this.embeddingStore(embeddingModel))
  71.                 .embeddingModel(embeddingModel)
  72.                 .maxResults(10)
  73.                 .minScore(0.65)
  74.                 .build();
  75.     }
  76. }
复制代码
4.3 聊天记忆持久化

实现了ChatMemoryStore接口, 这里测试使用的是map存储的, 生产环境中可以持久化到数据库中
chat过程中消息会通过ChatMemory调用ChatMemoryStore对聊天内容进行持久化/获取
  1. package com.ldx.langchaintest.service;
  2. import com.google.common.collect.ArrayListMultimap;
  3. import dev.langchain4j.data.message.ChatMessage;
  4. import dev.langchain4j.store.memory.chat.ChatMemoryStore;
  5. import org.springframework.stereotype.Service;
  6. import java.util.List;
  7. @Service
  8. public class PersistentChatMemoryStore implements ChatMemoryStore {
  9.     final ArrayListMultimap<Object, ChatMessage> messagesStore = ArrayListMultimap.create();
  10.     @Override
  11.     public List<ChatMessage> getMessages(Object memoryId) {
  12.         return messagesStore.get(memoryId);
  13.     }
  14.     @Override
  15.     public void updateMessages(Object memoryId, List<ChatMessage> messages) {
  16.         messagesStore.put(memoryId, messages.getLast());
  17.     }
  18.     @Override
  19.     public void deleteMessages(Object memoryId) {
  20.         messagesStore.removeAll(memoryId);
  21.     }
  22. }
复制代码
4.4 tools
  1. package com.ldx.langchaintest.tools;
  2. import dev.langchain4j.agent.tool.P;
  3. import dev.langchain4j.agent.tool.Tool;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.springframework.stereotype.Component;
  6. /**
  7. * tools
  8. *
  9. * @author ludangxin
  10. * @date 2025/5/15
  11. */
  12. @Slf4j
  13. @Component
  14. public class SysTools {
  15.     @Tool("根据用户的名称获取对应的code")
  16.     public String getUserCodeByUsername(@P("用户名称") String username) {
  17.         log.info("get user code by username:{}", username);
  18.         if ("张铁牛".equals(username)) {
  19.             return "003";
  20.         }
  21.         return "000";
  22.     }
  23. }
复制代码
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("
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册