需求:
使用java封装kimi接口为http接口,并把调用kimi时的传参和返回数据,保存到mysql数据库中
自己记录一下,以做备忘。
具体步骤如下:
1.申请apiKey
访问:Moonshot AI - 开放平台使用手机号+手机号验证码登录
登录后,在如下界面申请:
最多可以保留 5 个 API 密钥,密钥只会在新建后显示一次,请妥善保存。不要与他人共享 API Key,或将其暴露在客户端代码中。为了账户安全,一旦 API 密钥被发现泄露,Moonshot AI 可能会将其禁用。
默认token数量如下:
2.编写Java代码对接kimi
2.1对接kimi日志表
CREATE TABLE `ai_api_log` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`api_key` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'app_key',
`api_ip` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'API调用外网IP',
`api_method` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'API方法',
`api_para` text COLLATE utf8mb4_unicode_ci COMMENT 'API参数',
`api_result` text COLLATE utf8mb4_unicode_ci COMMENT 'API返回消息',
`create_time` datetime DEFAULT NULL COMMENT '创建时间 ',
PRIMARY KEY (`id`),
KEY `open_api_log_creat_time` (`create_time`),
KEY `open_api_log_method` (`api_method`),
KEY `open_api_log_app_key` (`api_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='api日志'
表对应的实体类
package com.example.ai.domain;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("ai_api_log")
public class AIApiLog extends BaseEntity {
private static final long serialVersionUID=1L;
public static String METHOD_KIMI_CHAT="kimi_chat";
private Integer id;
private String apiKey;
private String apiIp;
private String apiMethod;
private String apiPara;
private String apiResult;
private Date createTime;
}
2.2对接kimi核心代码
package com.example.ai.service;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONObject;
import com.example.ai.config.AiConfig;
import com.example.ai.constant.PathConstant;
import com.example.ai.network.ChatMessage;
import com.example.ai.util.JsonUtil;
import com.example.ai.network.ChoicesInfo;
import com.example.ai.network.HttpResponse;
import com.example.ai.network.ResponseType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import org.apache.commons.lang3.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @date 2023/2/13
**/
@Service
public class AiKimiService {
@Autowired
AiConfig aiConfig;
@Autowired
AIApiLogService aIApiLogService;
//webflux的client
private WebClient webClient;
//用于读取第三方的返回结果
private ObjectMapper objectMapper = new ObjectMapper();
public String completions( String content)throws IOException{
HttpResponse response = this.getJsonResponse(content);
ChoicesInfo choicesInfo = response.getChoices().get(0);
return StringEscapeUtils.unescapeJava(choicesInfo.getMessage().getContent());
}
public HttpResponse getJsonResponse(String message) throws IOException {
List<ChatMessage> messages=new ArrayList<>();
ChatMessage chatMessage=new ChatMessage();
chatMessage.setRole("user");
chatMessage.setContent(message);
messages.add(chatMessage);
String requestBody = new JSONObject()
.putOpt("model", "moonshot-v1-8k")
.putOpt("messages", messages)
.putOpt("response_format",new ResponseType())
.putOpt("frequency_penalty",0.5)
.putOpt("stream", false)
.toString();
Request okhttpRequest = new Request.Builder()
.url(aiConfig.getBaseUrl()+ PathConstant.COMPLETIONS.CREATE_CHAT_COMPLETION)
.post(RequestBody.create(requestBody, okhttp3.MediaType.get(ContentType.JSON.getValue())))
.addHeader("Authorization", "Bearer " + aiConfig.getApiKey())
.build();
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(60,TimeUnit.SECONDS)
.writeTimeout(60,TimeUnit.SECONDS)
.build();
Call call = okHttpClient.newCall(okhttpRequest);
Response okhttpResponse = call.execute();
String json = okhttpResponse.body().string();
aIApiLogService.saveOrUpdate(requestBody,json);
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+"----"+json);
return JsonUtil.jsonToClass(json,HttpResponse.class);
}
@PostConstruct
public void postConstruct() {
this.webClient = WebClient.builder()//创建webflux的client
.baseUrl(aiConfig.getBaseUrl())//填写对应的api地址
.defaultHeader("Content-Type", "application/json")//设置默认请求类型
.build();
}
private Flux<HttpResponse> handleWebClientResponse(String resp) {
if (StrUtil.equals("[DONE]",resp)){//[DONE]是消息结束标识
return Flux.empty();
}
try {
JsonNode jsonNode = objectMapper.readTree(resp);
HttpResponse result = objectMapper.treeToValue(jsonNode, HttpResponse.class);//将获得的结果转成对象
return Flux.just(result);//返回获得的结果
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
}
2.3运行效果
3.完整项目源码
下载地址: Java对接kimi完整项目源码