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();
        }
    }


}
相关推荐
花开富贵ii1 小时前
代码随想录算法训练营四十三天|图论part01
java·数据结构·算法·深度优先·图论
布朗克1682 小时前
Java 10 新特性及具体应用
java·开发语言·新特性·java10
说私域4 小时前
基于开源AI智能客服、AI智能名片与S2B2C商城小程序的微商服务优化及复购转介绍提升策略研究
人工智能·小程序
ZZHow10245 小时前
JavaWeb开发_Day05
java·笔记·web
CHEN5_025 小时前
【Java虚拟机】垃圾回收机制
java·开发语言·jvm
Warren985 小时前
Lua 脚本在 Redis 中的应用
java·前端·网络·vue.js·redis·junit·lua
HalvmånEver5 小时前
在 C++ :x86(32 位)和 x64(64 位)的不同
开发语言·c++·学习
之歆6 小时前
Al大模型-本地私有化部署大模型-大模型微调
人工智能·pytorch·ai作画
amy_jork7 小时前
npm删除包
开发语言·javascript·ecmascript
浪成电火花8 小时前
(deepseek!)deepspeed中C++关联部分
开发语言·c++