jdk 8 、集成langchain4j,调用open-ai模型的多轮对话demo

文章目录

  • 前言
    • [jdk 8 、集成langchain4j,调用open-ai模型的多轮对话demo](#jdk 8 、集成langchain4j,调用open-ai模型的多轮对话demo)
      • [1. pom](#1. pom)
      • [2. controller](#2. controller)
      • [3. service](#3. service)

前言

如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。

而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


jdk 8 、集成langchain4j,调用open-ai模型的多轮对话demo

凑数的,废话就不说了,下面是源码:
注意:如果你在大陆的话,调用这个模型可能不太方便,而且目前如果你的key,没有绑定海外信用卡的话,也会拦截,目前申请key的话,会有5美元的额度,试完就要花钱了。

1. pom

bash 复制代码
 <!-- 核心 -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-core</artifactId>
            <version>0.24.0</version>
        </dependency>
        <!-- OpenAI 调用支持 -->
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-open-ai</artifactId>
            <version>0.24.0</version>
        </dependency>


        <!-- ai end -->

2. controller

java 复制代码
package org.example.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.example.annotation.CommonLog;
import org.example.exception.model.ResponseResult;
import org.example.service.ChatService;
import org.example.vo.ai.AiChatResponse;
import org.example.vo.ai.ChatRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
* @author 杨镇宇
* @date 2025/6/17 11:12
* @version 1.0
*/
@Api(value = "AI 对话", tags = {" AI 对话"})
@Slf4j
@RestController
@RequestMapping(value="api/ai")
public class AiController {

    @Autowired
    private ChatService service;


    @ApiOperation(value = "aiChat 对话", notes = "aiChat 对话")
    @CrossOrigin(origins = "*")
    @CommonLog(methodName = "aiChat 对话",className = "AiController#aiChat",url = "api/ai/aiChat")
    @RequestMapping(value = "/aiChat", method = RequestMethod.POST)
    public ResponseResult aiChat(@RequestBody ChatRequest request) {
        AiChatResponse chat = service.aiChat(request);
        return ResponseResult.ok(chat);
    }
   

}

3. service

java 复制代码
public interface ChatService {
    /**
     * 处理聊天请求
     * @param request
     * @return
     */
    AiChatResponse aiChat(ChatRequest request);

}
java 复制代码
/**
* @author 杨镇宇
* @date 2025/6/17 09:16
* @version 1.0
*/
@Slf4j
@Service
public class ChatServiceImpl implements ChatService {

    @Resource
    private ChatMemoryService memoryService;
    // 每位用户的消息历史,最多保留 30 条
    private final Map<String, Deque<Object>> historyMap = new ConcurrentHashMap<>();

    // OpenAI 聊天模型实例
    private final OpenAiChatModel chatModel;

    // 系统背景提示(也可以从配置或文件加载)
    private static final String SYSTEM_HEADER =
            "你是一名小说 AI 助手,并且用活泼,欢快的语气回答我问题\n";

    public ChatServiceImpl(@Value("${openAi.api-key}") String apiKey) {
        this.chatModel = OpenAiChatModel.builder()
                .apiKey(apiKey)
                .modelName("gpt-3.5-turbo")
                .build();
    }

    /**
     *  处理聊天请求
     */
    public AiChatResponse aiChat(ChatRequest request) {
        String userId = request.getUserId();
        String message = request.getMessage();
        boolean reset = Boolean.TRUE.equals(request.getReset());

        // 1. 取或清空历史
        Deque<String> history = memoryService.getHistory(userId, reset);

        // 2. 调用 OpenAI
        /**
         * "system":系统设定(决定 AI 人设或背景)
         * "user":用户发出的问题
         * "assistant":AI 的回复
         */
        List<ChatMessage> chatMessages  = Lists.newArrayList();
        // 这是 AI 的"背景设定
        chatMessages .add(SystemMessage.from(SYSTEM_HEADER));
        //  拼接的历史对话 + 当前问题
        for (String msg : history) {
            if (msg.startsWith("User: ")) {
                chatMessages.add(UserMessage.from(msg.substring(6)));
            } else if (msg.startsWith("AI: ")) {
                chatMessages.add(AiMessage.from(msg.substring(6)));
            }
        }
        // 当前问题
        chatMessages.add(UserMessage.from(message));

       // 3. 调用 OpenAI 进行对话生成
        Response<AiMessage> generate = chatModel.generate(chatMessages);
        String aiReply = generate.content().toString();
        // 5. 保存对话历史(加上用户问和AI答)
        memoryService.addMessage(userId, "User: " + message);
        memoryService.addMessage(userId, "AI: " + aiReply);
        // 6. 返回你自己定义的响应对象
        AiChatResponse response = new AiChatResponse();
        response.setAnswer(aiReply);
        return response;
    }


}

历史对话管理:

java 复制代码
/**
* @author 杨镇宇
* @date 2025/6/17 09:33
* @version 1.0
*/

public interface ChatMemoryService {
    /**
     * 获取或初始化用户历史,并根据 reset 标志决定是否清空
     */
    Deque<String> getHistory(String userId, boolean reset);
    /**
     * 添加一条消息到用户历史,同时保证不超过最大条数
     */
    void addMessage(String userId, String message);



}
java 复制代码
package org.example.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.example.kimi.config.KimiProperties;
import org.example.kimi.support.KimiChatUtils;
import org.example.service.ChatMemoryService;
import org.example.vo.ai.ChatRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Deque;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * ChatMemoryService:管理每个用户的对话历史,限制条数并自动清理最旧消息
* @author 杨镇宇
* @date 2025/6/17 09:32
* @version 1.0
*/

@Slf4j
@Service
public class ChatMemoryServiceImpl implements ChatMemoryService {




    private static final int MAX_HISTORY = 50;
    /** Key = userId, Value = Deque of lines like "User: ..." or "AI: ..." */
    private final Map<String, Deque<String>> historyMap = new ConcurrentHashMap<>();

    /**
     * 获取某用户的历史 Deque。若 reset=true,则清空并重新创建。
     */
    public Deque<String> getHistory(String userId, boolean reset) {
        if (reset) {
            historyMap.remove(userId);
        }
        return historyMap.computeIfAbsent(userId, id -> new LinkedList<>());
    }

    /**
     * 向该用户历史中添加一条新记录(前面已用 "User: " 或 "AI: " 前缀),并自动丢弃最旧超出部分。
     */
    public void addMessage(String userId, String message) {
        Deque<String> history = historyMap.computeIfAbsent(userId, id -> new LinkedList<>());
        history.addLast(message);
        if (history.size() > MAX_HISTORY) {
            history.removeFirst();
        }
    }


}
相关推荐
一只猿Hou15 分钟前
java分页插件| MyBatis-Plus分页 vs PageHelper分页:全面对比与最佳实践
java·mybatis
程序员弘羽21 分钟前
C++ 第四阶段 内存管理 - 第二节:避免内存泄漏的技巧
java·jvm·c++
旷世奇才李先生25 分钟前
Tomcat 安装使用教程
java·tomcat
【ql君】qlexcel27 分钟前
Notepad++ 复制宏、编辑宏的方法
开发语言·javascript·notepad++··宏编辑·宏复制
程序员陆通33 分钟前
Vibe Coding开发微信小程序实战案例
微信小程序·小程序·notepad++·ai编程
Zevalin爱灰灰36 分钟前
MATLAB GUI界面设计 第六章——常用库中的其它组件
开发语言·ui·matlab
勤奋的知更鸟38 分钟前
Java 编程之策略模式详解
java·设计模式·策略模式
qq_49244844640 分钟前
Java 访问HTTP,信任所有证书,解决SSL报错问题
java·http·ssl
爱上语文43 分钟前
Redis基础(4):Set类型和SortedSet类型
java·数据库·redis·后端
冰糖猕猴桃44 分钟前
【Python】进阶 - 数据结构与算法
开发语言·数据结构·python·算法·时间复杂度、空间复杂度·树、二叉树·堆、图