Skip to content

GLM

基础

依赖

maven
        <dependency>
            <groupId>ai.z.openapi</groupId>
            <artifactId>zai-sdk</artifactId>
            <version>0.3.3</version>
        </dependency>

配置

yml
ai:
  apikey: your-api-key-here
  model: glm-5

编写配置类

java


@Configuration
@Data
@ConfigurationProperties(prefix = "ai")
public class AiConfig {

    /**
     * AI API Key
     */
    private String apiKey;
    /**
     * 模型名称
     */
    private String model;

    @Bean
    public ZhipuAiClient zhipuAiClient(){
        return   ZhipuAiClient.builder().ofZHIPU()
                .apiKey(apiKey)
                .build();
    }
}

​ ThrowUtils.throwIf(.........); //判断参数是否合法

java


@Slf4j
@Component
public class AiManager {

    private static final float STABLE_TEMPERATURE  = 0.05f;
    private static final float UNSTABLE_TEMPERATURE  = 0.90f;//值越大越随机

    @Resource
    private ZhipuAiClient zhipuAiClient;

    @Resource
    private AiConfig aiConfig;

    
      /**
       * 流式请求(稳定)
      */
    public Flowable<ModelData> doStreamStableRequest(String systemMsg, String userMsg) {
        List<ChatMessage> messages = new ArrayList<>();
        messages.add(new ChatMessage(ChatMessageRole.SYSTEM.value(), systemMsg));
        messages.add(new ChatMessage(ChatMessageRole.USER.value(), userMsg));
        return doStreamRequest(messages, STABLE_TEMPERATURE);
    }
    
     /**
       * 流式请求
      */
    public Flowable<ModelData> doStreamRequest(List<ChatMessage> messages,Float temperature){
        ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
                .model(aiConfig.getModel())
                .stream(true)
                .temperature(temperature)
                .messages(messages)
                .build();


        ChatCompletionResponse response = zhipuAiClient.chat().createChatCompletion(request);
        return response.getFlowable();
    }

   /**
     * AI同步请求(答案较稳定)
     * @param systemMsg
     * @param userMsg
     * @return
     */
    public String doStableSyncRequest(String systemMsg, String userMsg){

        return doRequest(systemMsg,userMsg,false,STABLE_TEMPERATURE);

    }
    /**
     * AI同步请求(答案较随机)
     * @param systemMsg
     * @param userMsg
     * @return
     */
    public String doUnStableSyncRequest(String systemMsg, String userMsg){

        return doRequest(systemMsg,userMsg,false,UNSTABLE_TEMPERATURE);

    }

/**
     * AI同步请求
     * @param systemMsg
     * @param userMsg
     * @param temperature
     * @return
     */
public String doSyncRequest(String systemMsg, String userMsg,Float  temperature){

    return doRequest(systemMsg,userMsg,false,temperature);

}

/**
     * 通用AI请求
     * @param systemMsg  系统提示词
     * @param userMsg  用户提示词
     * @param stream 是否流式返回
     * @param temperature 生成随机性(值越大越随机)
     * @return
     */
    public String doRequest(String systemMsg, String userMsg,Boolean stream,Float temperature){

        List<ChatMessage> messages = new ArrayList<>();
        ChatMessage systemChatMsg= new ChatMessage(ChatMessageRole.SYSTEM.value(),systemMsg);
        ChatMessage userChatMsg= new ChatMessage(ChatMessageRole.USER.value(),userMsg);

        messages.add(systemChatMsg);
        messages.add(userChatMsg);
        // 获取回复
        return doRequest(messages,stream,temperature);

    }

    /**
     * 通用AI请求
     * @param messages
     * @param stream
     * @param temperature
     * @return
     */
    public String doRequest(List<ChatMessage> messages,Boolean stream,Float temperature){

            ThrowUtils.throwIf(messages == null || messages.isEmpty(), ErrorCode.PARAMS_ERROR, "消息列表不能为空");
            ThrowUtils.throwIf(aiConfig == null || aiConfig.getModel() == null, ErrorCode.SYSTEM_ERROR, "AI配置未初始化");

        ChatCompletionCreateParams request = ChatCompletionCreateParams.builder()
                .model(aiConfig.getModel())
                .stream(stream)
                .temperature(temperature)
                .messages(messages)
                .build();
        log.info("请求信息:{}", request);
        ChatCompletionResponse response = zhipuAiClient.chat().createChatCompletion(request);

        // 获取回复
        try {
                ThrowUtils.throwIf(response == null, ErrorCode.SYSTEM_ERROR, "请求失败:响应为空");
                ThrowUtils.throwIf(response.getData() == null, ErrorCode.SYSTEM_ERROR, "请求失败:响应数据为空");
                ThrowUtils.throwIf(response.getData().getChoices() == null || response.getData().getChoices().isEmpty(), ErrorCode.SYSTEM_ERROR, "请求失败:响应数据格式错误");
                ThrowUtils.throwIf(response.getData().getChoices().get(0).getMessage() == null, ErrorCode.SYSTEM_ERROR, "请求失败:回复内容为空");

            ChatMessage replyMessage = response.getData().getChoices().get(0).getMessage();
            String reply = replyMessage.getContent().toString();

            log.info("AI回复:{}", reply);
            
            return reply;
        } catch (Exception e) {
            log.error("处理AI响应时发生异常,request: {}", request);
            log.error("处理AI响应时发生异常,response: {}", response);
            log.error("处理AI响应时发生异常", e);
            return null;
        }
    }
}

普通调用(同步返回)

适合:接口直接返回结果、简单业务,但返回速度较慢

java
@RestController
@RequestMapping("/ai")
public class AiController {

    @Resource
    private AiManager aiManager;

    /**
     * 普通同步调用
     */
    @GetMapping("/sync")
    public String sync(@RequestParam String msg) {

        String systemPrompt = "你是一个专业的助手";
        
        // 调用稳定版本(推荐)
        return aiManager.doStableSyncRequest(systemPrompt, msg);

        // 如果你想自定义随机性:
        // return aiManager.doSyncRequest(systemPrompt, msg, 0.7f);
    }
}

请求示例:

GET /ai/sync?msg=解释一下Redis缓存穿透

返回:

Redis缓存穿透是指...

流式调用(SSE 实时返回)

适合:

  • ChatGPT 打字效果
  • 长文本生成
  • 前端逐步渲染
java
@RestController
@RequestMapping("/ai")
public class AiStreamController {

    @Resource
    private AiManager aiManager;

    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter stream(@RequestParam String msg) {

        SseEmitter emitter = new SseEmitter(0L); // 不超时

        Flowable<ModelData> flowable =
                aiManager.doStreamStableRequest("你是一个专业助手", msg);

        flowable.subscribe(
                data -> {
                    try {
                        // 关键:拿到每一段内容
                        if (data.getChoices() != null && !data.getChoices().isEmpty()) {
                            Object content = data.getChoices().get(0).getDelta().getContent();
                            if (content != null) {
                                emitter.send(content.toString());
                            }
                        }
                    } catch (Exception e) {
                        emitter.completeWithError(e);
                    }
                },
                emitter::completeWithError,
                emitter::complete
        );
        return emitter;
    }
}

进阶

多模态(图片 + 文本)

java
public String imageChat(String imageUrl, String question) {

    List<ChatMessage> messages = new ArrayList<>();

messages.add(new ChatMessage("system", "你是一个图像分析助手"));

// 多模态 content(关键)
List<Object> contentList = new ArrayList<>();

contentList.add(Map.of(
        "type", "input_text",
        "text", question
));

contentList.add(Map.of(
        "type", "input_image",
        "image_url", imageUrl
));

ChatMessage userMsg = new ChatMessage();
userMsg.setRole("user");
userMsg.setContent(contentList);

messages.add(userMsg);

return doRequest(messages, false, 0.3f);
}