vue+springboot实现gpt流式输出

单次询问为例

后端

controller

  @GetMapping(value = "/chatWithAIStream",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux chatWithAIStream(String prompt,String model) {
        String message = "给gpt发送的消息"
        return chatModel.chatwithStream(message,prompt,model);

    }

工具类

@Slf4j
@Component
public class ChatModel {
    @Value("${gpt.base_url}")
    private String chatEndpoint;
    @Value("${gpt.api_key}")
    private String apiKey;
    public Flux chatwithStream(String rdaResult, String prompt,String model) {
        // 创建一个参数Map,用于构建请求体
        Map paramMap = new HashMap<>();
        {
            // 指定使用的模型
            paramMap.put("model", model);

            // 创建一个列表,用于存储对话消息
            List> dataList = new ArrayList<>();
            {
                dataList.add(new HashMap() {{
                    put("role", "system");  // 设置角色为"系统" 你是一个生物信息学专家,下面是我的RDA分析结果,解释变量为理化性质含量,响应变量为微生物含量,分析几个最能影响微生物含量的理化性质,为我的生产提供建议
                    put("content", prompt);
                }});
                // 添加用户输入的消息到列表中
                dataList.add(new HashMap() {{
                    put("role", "user");  // 设置角色为"用户"
                    put("content", rdaResult);  // 设置用户输入的内容
                }});
            }
            // 将消息列表加入参数Map
            paramMap.put("messages", dataList);
            paramMap.put("stream", true);  // 启用流式返回
        }
        // 发起HTTP请求,发送到聊天API端点

       return Flux.create( sink -> {
           int retryCount = 3;
                   while (retryCount > 0) {
            try {
                // 创建HTTP客户端
                HttpClient client = HttpClient.newBuilder()
                        .connectTimeout(Duration.ofSeconds(80))  // 设置连接超时时间
                        .build();
                HttpRequest request = HttpRequest.newBuilder()
                        .uri(URI.create(chatEndpoint))
                        .header("Authorization", "Bearer " + apiKey)
                        .header("Content-Type", "application/json")
                        .POST(HttpRequest.BodyPublishers.ofString(JSONUtil.toJsonStr(paramMap))) // 转换为JSON请求体
                        .build();

                // 发起异步请求
                CompletableFuture> future = client.sendAsync(request, HttpResponse.BodyHandlers.ofInputStream());
//thenAccept 是 CompletableFuture 的一个方法,它会在 future 异步操作完成后执行传入的回调函数,回调函数的参数 response 即为异步操作完成时返回的 HttpResponse 对象。
                future.thenAccept(response -> {
                    try (InputStream inputStream = response.body()) {
                        Scanner scanner = new Scanner(inputStream, "UTF-8");
                        while (scanner.hasNextLine()) {
                            String line = scanner.nextLine();
                            if (!line.trim().isEmpty()) {
                                // 将每一行的数据作为事件推送到客户端
                                sink.next(line);
                            }
                        }
                        sink.complete(); // 完成流
                    } catch (Exception e) {
                        sink.error(e); // 出现错误时传递错误
                    }
                }).join(); // 等待异步操作完成
                break;  // 请求成功,退出重试循环
            } catch (Exception e) {
                log.error("请求失败,正在重试...", e);
                retryCount--;
                if (retryCount == 0) {
                    sink.error(e); // 出现错误时传递错误
                } }}
        });



    }}

前端

template:有一个等待的效果

script


css


你可能感兴趣的:(vue.js,spring,boot,gpt)