调用智谱AI异步请求流式方法回复

官方代码可以去查看https://github.com/MetaGLM/zhipuai-sdk-java-v4/blob/main/src/test/java/com/zhipu/oapi/AllToolsTest.java

效果展示

提问效果:
在这里插入图片描述
回答效果:
在这里插入图片描述

1、Maven配置

        <dependency>
            <groupId>cn.bigmodel.openapi</groupId>
            <artifactId>oapi-java-sdk</artifactId>
            <version>release-V4-2.3.0</version>
        </dependency>

2、yml配置

zm:
  zhipu:
    api-key: "申请一个key"

3、工具实体

package com.zm.naviTech.config;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

/*
 * @Author 落梨
 * @Date 2024-09-14 13:42
 * @Description:
 **/
@Configuration
@Data
public class ZhiPuKey {
    @Value("${zm.zhipu.api-key}")
    private String ApiKey;
}   

4、controller层

注意这里的callWithMessage里的方法可以自己设置自定义参数。
流式方法这里我做了内容的组合,方便插入数据库,后面插入的mapper可以不用看了,按照你自己的业务逻辑去处理,主要看异步流式方式。

package com.zm.naviTech.AIController;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.zhipu.oapi.ClientV4;
import com.zhipu.oapi.Constants;
import com.zhipu.oapi.service.v4.model.*;
import com.zm.naviTech.config.ZhiPuKey;
import com.zm.naviTech.constants.MessageDirectionConstant;
import com.zm.naviTech.entity.po.ChatgptMessage;
import com.zm.naviTech.mapper.ConversationMapper;
import com.zm.naviTech.utils.ThreadLocalUtil;
import io.reactivex.Flowable;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.angus.mail.imap.MessageCache;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;


/*
 * @Author 落梨
 * @Date 2024-09-14 13:39
 * @Description: 质谱AI
 **/
@Component
@Slf4j
public class ZhiPuAiChatController {
    @Resource
    private ZhiPuKey zhiPuKey;
    @Resource
    private ConversationMapper conversationMapper;


    private static final ObjectMapper mapper = new ObjectMapper();
    /**
     * @author 落梨
     * @description 调用接口
     **/
    public ModelApiResponse callWithMessage(String conversationId, String prompt) throws JsonProcessingException {
        log.info("==============质谱AI准备回答===================");
        //获取key
        String key = zhiPuKey.getApiKey();
        //生成客户端
        ClientV4 client = new ClientV4.Builder(key).build();
        //业务id
        String requestIdTemplate = conversationId;
        String requestId = String.format(requestIdTemplate, System.currentTimeMillis());
        //参数工具
        List<ChatTool> chatToolList = new ArrayList<>();
        ChatTool chatTool = new ChatTool();
        chatTool.setType("code_interpreter");
        chatToolList.add(chatTool);
        //携带消息体,这个实例 是 官方提供
        List<ChatMessage> messages = new ArrayList<>();
        ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(), prompt);
        messages.add(chatMessage);
        ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
                .model(Constants.ModelChatGLM4)
                .stream(Boolean.TRUE)
                .invokeMethod(Constants.invokeMethod)
                .messages(messages)
                .tools(chatToolList)
                .toolChoice("auto")
                .requestId(requestId)
                .build();
        //使用流式
        ModelApiResponse sseModelApiResp  = client.invokeModelApi(chatCompletionRequest);
        if (sseModelApiResp.isSuccess()) {
            AtomicBoolean isFirst = new AtomicBoolean(true);
            List<Choice> choices = new ArrayList<>();
            AtomicReference<ChatMessageAccumulator> lastAccumulator = new AtomicReference<>();
             mapStreamToAccumulator(sseModelApiResp.getFlowable())
                    .doOnNext(accumulator -> {
                        {
                            if (isFirst.getAndSet(false)) {
                                log.info("Response: ");
                            }
                            if (accumulator.getDelta() != null && accumulator.getDelta().getTool_calls() != null) {
                                String jsonString = mapper.writeValueAsString(accumulator.getDelta().getTool_calls());
                                log.info("tool_calls: {}", jsonString);
                            }
                            if (accumulator.getDelta() != null && accumulator.getDelta().getContent() != null) {
                                log.info(accumulator.getDelta().getContent());
                            }
                            choices.add(accumulator.getChoice());
                            lastAccumulator.set(accumulator);
                        }
                    })
                    .doOnComplete(System.out::println)
                    .lastElement()
                    .blockingGet();
            ChatMessageAccumulator chatMessageAccumulator = lastAccumulator.get();
            ModelData data = new ModelData();
            data.setChoices(choices);
            if (chatMessageAccumulator != null) {
                data.setUsage(chatMessageAccumulator.getUsage());
                data.setId(chatMessageAccumulator.getId());
                data.setCreated(chatMessageAccumulator.getCreated());
            }
            data.setRequestId(chatCompletionRequest.getRequestId());
            sseModelApiResp.setFlowable(null);// 打印前置空
            sseModelApiResp.setData(data);
        }
        //组合内容
        StringBuilder stringBuilder = new StringBuilder();
        List<Choice> choices = sseModelApiResp.getData().getChoices();
        for (Choice choice : choices) {
            stringBuilder.append(choice.getDelta().getContent());
        }
        log.info(stringBuilder.toString());
        String content = stringBuilder.toString();
        log.info("质谱ai的回答是:{}",content);
        //插入询问语句到数据库
        ChatgptMessage chatgptMessage = ChatgptMessage.builder()
                .userId(ThreadLocalUtil.getCurrentId())
                .messageDirection(MessageDirectionConstant.USER)
                .createTime(LocalDateTime.now())
                .conversationId(Long.valueOf(conversationId))
                .content(prompt).build();
        conversationMapper.insert(chatgptMessage);
        //插入回答语句到数据库
        ChatgptMessage chatgptMessage2 = ChatgptMessage.builder()
                .userId(ThreadLocalUtil.getCurrentId())
                .messageDirection(MessageDirectionConstant.AI)
                .createTime(LocalDateTime.now())
                .content(content)
                .conversationId(Long.valueOf(conversationId)).build();
        conversationMapper.insert(chatgptMessage2);
        log.info("==============回答完毕===================");
        return sseModelApiResp;
    }
    //流式操作
    public static Flowable<ChatMessageAccumulator> mapStreamToAccumulator(Flowable<ModelData> flowable) {
        return flowable.map(chunk -> {
            return new ChatMessageAccumulator(chunk.getChoices().get(0).getDelta(), null, chunk.getChoices().get(0), chunk.getUsage(), chunk.getCreated(), chunk.getId());
        });
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值