java对接kimi详细说明,附完整项目

需求:

使用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日志'

表对应的实体类

java 复制代码
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核心代码

java 复制代码
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完整项目源码

相关推荐
火烧屁屁啦10 分钟前
【JavaEE进阶】初始Spring Web MVC
java·spring·java-ee
飞飞-躺着更舒服14 分钟前
【QT】实现电子飞行显示器(改进版)
开发语言·qt
w_312345424 分钟前
自定义一个maven骨架 | 最佳实践
java·maven·intellij-idea
岁岁岁平安27 分钟前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
武昌库里写JAVA30 分钟前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
Q_192849990637 分钟前
基于Spring Boot的九州美食城商户一体化系统
java·spring boot·后端
张国荣家的弟弟1 小时前
【Yonghong 企业日常问题 06】上传的文件不在白名单,修改allow.jar.digest属性添加允许上传的文件SH256值?
java·jar·bi
ZSYP-S1 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos1 小时前
c++------------------函数
开发语言·c++
yuanbenshidiaos1 小时前
C++----------函数的调用机制
java·c++·算法