前言

在大语言模型(LLM)技术飞速发展的今天,如何将其高效集成到企业级应用中,已成为开发者面临的重要课题。SpringBoot 作为 Java 生态中构建微服务和企业级应用的主流框架,以其简化配置、快速开发的特性,成为无数开发者的首选工具;而 LangChain4J 则专为 Java 开发者打造,提供了连接大语言模型与实际业务场景的桥梁,让复杂的 LLM 应用开发变得模块化、可扩展。


一、代码示例

1.1 pom依赖

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-3-starter</artifactId>
            <version>1.2.23</version>
        </dependency>
       
        <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.25</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
            <version>3.5.7</version>
        </dependency>
        <!-- LangChain4j整合boot低阶版本       -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
            <version><version>1.0.1-beta6</version></version>
        </dependency>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-reactor</artifactId>
            <version>1.0.1-beta6</version>
        </dependency>
       
        <!-- LangChain4j整合boot高阶版本支持功能更多比如Tools RAG 等       -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-spring-boot-starter</artifactId>
            <version>1.0.1-beta6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <!--            <optional>true</optional>-->
        </dependency>
     

1.2 yml配置文件

langchain4j:
  open-ai:
    chat-model:
      api-key: api key
      base-url: 阿里百炼地址
      model-name: qwen-plus
      log-requests: true
      log-responses: true
      max-retries: 3
    streaming-chat-model:
      api-key: api key
      base-url: 阿里百炼地址
      model-name: qwen-plus
      log-requests: true
      log-responses: true
      max-retries: 3
spring:
  data:
    redis:
      port: 6379
      host: ip
      password: 密码
      database: 1

1.3 代码

Redis存储配置

package com.mk.springlangchain4j.store.message;

import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.ChatMessageDeserializer;
import dev.langchain4j.data.message.ChatMessageSerializer;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;

@Slf4j
@Component
public class MessageHistoryRedisStoreProvider implements ChatMemoryStore {
    public static final String MESSAGE_HISTORY_PREFIX = "message_record:";
    @Autowired
    StringRedisTemplate redis;

    @Override
    public List<ChatMessage> getMessages(Object memoryId) {
        List<String> messageHistoryList = redis.opsForList().range(MESSAGE_HISTORY_PREFIX + memoryId, 0, -1);
        List<ChatMessage> collect = messageHistoryList.stream().map(ChatMessageDeserializer::messageFromJson).toList();
        log.info("getMessages的messageHistory:{}",collect);
        return collect;
    }

    @Override
    public void updateMessages(Object memoryId, List<ChatMessage> messages) {
        log.info("updateMessages的messageHistory:{}",messages);
        redis.opsForList().rightPush(MESSAGE_HISTORY_PREFIX + memoryId,ChatMessageSerializer.messageToJson(messages.get(messages.size()-1)));
    }

    @Override
    public void deleteMessages(Object memoryId) {
        redis.delete(MESSAGE_HISTORY_PREFIX + memoryId);
    }
}

config配置

package com.mk.springlangchain4j.config;

@Configuration
public class LangChain4JConfig {
    @Autowired
    ChatModel chatModel;
    @Autowired
    StreamingChatModel streamingChatModel;
    @Autowired
    MessageHistoryRedisStoreProvider messageHistoryRedisStoreProvider;

    @Bean
    public CustomAiService customAiService(ChatMemoryProvider chatMemoryProvider) {
        return AiServices.builder(CustomAiService.class)
                .chatModel(chatModel)
                .streamingChatModel(streamingChatModel)
                .chatMemoryProvider(chatMemoryProvider)
                .build();
    }

    @Bean
    public ChatMemoryProvider chatMemoryProvider() {
        return memoryId -> MessageWindowChatMemory.builder()
                .maxMessages(20)
                .id(memoryId)
                .chatMemoryStore(messageHistoryRedisStoreProvider)
                .build();
    }
}

inferface层

package com.mk.springlangchain4j.service;

import dev.langchain4j.service.MemoryId;
import dev.langchain4j.service.UserMessage;
import reactor.core.publisher.Flux;

public interface CustomAiService {
	//阻塞式聊天
    String chat(String message);
	//普通流式聊天
    Flux<String> streamingChat(String message);
	//会话记忆聊天
    Flux<String> streamingChat(@MemoryId String memoryId, @UserMessage String message);
}

controller层

package com.mk.springlangchain4j.web;


@RestController
@CrossOrigin
@RequestMapping("/api/chat")
public class ChatController {
    @Autowired
    CustomAiService aiService;
	//带记忆存储的流式输出
    @PostMapping(value = "streamHis", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> streamingChatWithHistory(
            @RequestParam String memoryId,
            @RequestParam String sessionId,
            @RequestParam String userMessage) {
        return aiService.streamingChat(memoryId + ":" + sessionId, userMessage);
    }
}

二、效果演示

2.1 会话记忆聊天

在这里插入图片描述

会话记忆


总结

完结…

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐