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