java流式实现chatGPT会话功能

简介: java流式实现chatGPT会话功能

环境

SpringBoot2.x

Maven3.x

JDK1.8


具体步骤

1. 了解相关api信息

首先前往openai api官网OpenAI API,登录自己的账号,然后选择API reference,然后就可以查看相关的模型比如“gpt-3.5-turbo”,还有很多的api。

这里是一些请求体信息:

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-3.5-turbo",
    "messages": [
      {
        "role": "system",
        "content": "You are a helpful assistant."
      },
      {
        "role": "user",
        "content": "Hello!"
      }
    ]
  }'


这里是响应信息:

{
  "id": "chatcmpl-123",
  "object": "chat.completion",
  "created": 1677652288,
  "model": "gpt-3.5-turbo-0125",
  "system_fingerprint": "fp_44709d6fcb",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "\n\nHello there, how may I assist you today?",
    },
    "logprobs": null,
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 9,
    "completion_tokens": 12,
    "total_tokens": 21
  }
}

最重要的是key,如果是新号则去申请,会送一个5美元的key,或者购买一个key。对了,国内的话需要设置代理才能访问。


2. 创建SpringBoot工程

创建工程后添加依赖

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

请求参数类:

public class ChatParams {
    // 模型
    private String model = "gpt-3.5-turbo";
 
    // 消息列表,获取上下文携带返回消息
    private List<ChatMessage> messages;
 
    // 采样温度,较高的值(如 0.8)将使输出更加随机,而较低的值(如 0.2)将使其更加集中和确定
    @DecimalMin("0.0")
    @DecimalMax("2.0")
    private Double temperature = 1.0;
 
    // 核心采用,其中模型考虑具有top_p概率质量的令牌的结果。因此,0.1 意味着只考虑包含前 10% 概率质量的结果集
    @DecimalMin("0.0")
    @DecimalMax("1.0")
    private Double top_p = 1.0;
 
    // 结果数,如果需要返回多个结果可以设置 n > 1
    @Min(1)
    private Integer n = 1;
 
    // 当前用户id,用于处理滥用行为
    private Long userId;
}

注意,本次是进行流式响应,所以还需一个stream参数:

public class ChatStreamParams extends ChatParams{
    private boolean stream = true;
}

后端使用WebClient向apenai api发起post请求以获得流式数据

@Transactional
    @Override
    public void chatStream2(ChatStreamParams chatParams, String chatId, String userId, Session session) {
        Flux<String> stringFlux = webClient.post()
                .uri(apiHost+"/v1/chat/completions")
                .header("Authorization", "Bearer " + apiKey)
                .bodyValue(chatParams)
                .retrieve()
                .bodyToFlux(String.class);
        stringFlux
                .takeWhile(data -> {
                    try {
                        JSONObject json = new JSONObject(data);
                        JSONArray choices = json.getJSONArray("choices");
                        String finish_reason = choices.getJSONObject(0).getString("finish_reason");
                        if (finish_reason.equals("stop")) {
                            String content = contentBuilder.toString();
                            System.out.println("content"+contentBuilder);
                            gptMessageService.save(chatId, Long.valueOf(userId), content, SystemConstants.MESSAGE_TYPE_GPT);
                            contentBuilder.setLength(0);
                        }
                        return !finish_reason.equals("stop"); // 继续处理数据,直到遇到停止条件
                    } catch (Exception e) {
                        e.printStackTrace();
                        return false; // 数据格式异常,停止处理数据
                    }
                })
                .subscribe(
                data -> {
                    try {
                        JSONObject json = new JSONObject(data);
                        JSONArray choices = json.getJSONArray("choices");
                        String finish_reason = choices.getJSONObject(0).getString("finish_reason");
                        if (finish_reason.equals("stop")) {
                            return;
                        }
                        String delta = choices.getJSONObject(0).getString("delta");
                        System.out.println(data);
                        JSONObject msg = new JSONObject(delta);
                        String content = msg.getString("content");
                        // 拼接消息,保存到数据库
                        contentBuilder.append(content);
                        session.getBasicRemote().sendText(content);
                    }catch (Exception e) {
                        e.printStackTrace();
                    }
                },
                error -> {
                    System.out.println("错误");
                    error.printStackTrace();
                }
        );
    }

参数释义:

chatParams:发送给api的请求参数;

chatId: 会话id;

userId: 用户id;

session: WebSocket的session,前后端流式响应会用到websoket

apiHost: 代理地址;

apiKey: key

注意:在subscribe回调函数里拿到流式数据,在takeWhile回调函数里设置停止条件


好了,通过这些步骤应该能流式响应了,如果遇到啥问题可以留言哦,看到会回。  


目录
相关文章
|
16天前
|
Java 开发者
Java多线程教程:使用ReentrantLock实现高级锁功能
Java多线程教程:使用ReentrantLock实现高级锁功能
19 1
|
9天前
|
存储 算法 Shell
调试休眠和挂起功能【ChatGPT】
调试休眠和挂起功能【ChatGPT】
|
11天前
|
前端开发 开发者 安全
JSF支付功能大揭秘:探索如何在Java世界中实现安全无缝的在线支付体验
【8月更文挑战第31天】在电子商务和在线交易日益普及的今天,实现在线支付功能已成为许多Web应用的必备需求。JavaServer Faces (JSF) 作为一种流行的Java Web框架,提供了丰富的组件和工具来构建用户界面,包括与支付网关集成以实现在线支付。支付网关是处理信用卡和借记卡支付的系统,在商家和银行之间起到桥梁作用。本文将探讨如何使用JSF与支付网关集成,以及实现在线支付功能时需要考虑的关键点
24 0
|
2月前
|
存储 NoSQL Java
Java中使用redis的bitMap实现签到功能
这个实现示例提供了一种灵活、高效的方式,展示了如何使用Redis来解决现实中的问题。
88 2
|
29天前
|
JavaScript 前端开发 网络协议
WebSocket在Java Spring Boot+Vue框架中实现消息推送功能
在现代Web应用中,实时消息提醒是一项非常重要的功能,能够极大地提升用户体验。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为实现实时消息提醒提供了高效且低延迟的解决方案。本文将详细介绍如何在Java Spring Boot后端和Vue前端框架中利用WebSocket实现消息提醒功能。
|
2月前
|
分布式计算 DataWorks Java
DataWorks操作报错合集之使用ODPS Tunnel Upload功能时,遇到报错:Java 堆内存不足,该如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
2月前
|
搜索推荐 Java API
如何在Java应用中实现全文搜索功能
如何在Java应用中实现全文搜索功能
|
2月前
|
并行计算 Java 大数据
Java中的函数式接口与流式编程
Java中的函数式接口与流式编程
|
2月前
|
搜索推荐 Java 大数据
Java中的数据流处理与流式计算实现
Java中的数据流处理与流式计算实现
|
2月前
|
SQL XML JavaScript
【若依Java】15分钟玩转若依二次开发,新手小白半小时实现前后端分离项目,springboot+vue3+Element Plus+vite实现Java项目和管理后台网站功能
摘要: 本文档详细介绍了如何使用若依框架快速搭建一个基于SpringBoot和Vue3的前后端分离的Java管理后台。教程涵盖了技术点、准备工作、启动项目、自动生成代码、数据库配置、菜单管理、代码下载和导入、自定义主题样式、代码生成、启动Vue3项目、修改代码、以及对代码进行自定义和扩展,例如单表和主子表的代码生成、树形表的实现、商品列表和分类列表的改造等。整个过程详细地指导了如何从下载项目到配置数据库,再到生成Java和Vue3代码,最后实现前后端的运行和功能定制。此外,还提供了关于软件安装、环境变量配置和代码自动生成的注意事项。
1196 2