0


为系统接入 Kimi AI 智能大模型(附源码)

前言

Kimi 是月之暗面公司出品的人工智能大模型助手,在国内中文大模型中算还是不错的。接下来我们将详细介绍,如何接入 Kimi AI 智能大模型,并提供可使用的生产代码(Java)。

Kimi 官方的 API 文档有点过于简单了,不过它的 API 可兼容 OpenAI 的 SDK,使用支持 OpenAI 的 SDK 可以直接使用 Kimi API 的基本能力。但我们接下来介绍如何直接与 Kimi API 交互,以及介绍它的主要服务接口。

获取令牌

要使用 Kimi 的 API,首先需要注册并获取 API Key。注册账号非常简单,就不过多赘述了。

注册完成后,进入控制台,在 API Key 管理中新建 Key,输入一个名字。

在这里插入图片描述

注意自己保存好 Key,控制台上不能再次获取到,如果丢失了只能重新生成一个。

这个 Key 就是我们调用 Kimi API 的令牌。

使用

Kimi API 支持 Restful 请求,我们可以包装构建自己的客户端,并像 Kimi 服务器发起请求。

客户端

首先,我们用 OKHttp 来构建一个请求客户端。

publicclassMoonShotClient{publicstaticfinalStringMOONSHOT_BASE="https://api.moonshot.cn/v1";privatefinalOkHttpClient httpClient;// 服务端基础路径privatefinalString baseUrl;// API KeyprivatefinalString accessToken;// json 序列化privatefinalObjectMapper objectMapper;publicMoonShotClient(String baseUrl,String accessToken,OkHttpClient httpClient){this.baseUrl = baseUrl;this.accessToken = accessToken;if(Objects.isNull(httpClient)){// 初始化 okhttp 客户端,可自定义配置参数,或从其他配置文件获取this.httpClient =newOkHttpClient.Builder().connectTimeout(30,TimeUnit.SECONDS).readTimeout(30,TimeUnit.SECONDS).callTimeout(30,TimeUnit.SECONDS).build();}else{this.httpClient = httpClient;}this.objectMapper =newObjectMapper();this.objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);}publicMoonShotClient(String accessToken,OkHttpClient httpClient){this(MOONSHOT_BASE, accessToken, httpClient);}publicMoonShotClient(String accessToken){this(accessToken,null);}}

单轮对话

单轮对话就是一次性的问题,需要 Kimi 返回问题的答案。

请求路径是

/chat/completions

,请求体是一个 JSON 对象,类似下面这样:

{model:"moonshot-v1-8k",messages:[{"role":"system","content":"你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长中文和英文的对话。你会为用户提供安全,有帮助,准确的回答。同时,你会拒绝一切涉及恐怖主义,种族歧视,黄色暴力等问题的回答。Moonshot AI 为专有名词,不可翻译成其他语言。"},{"role":"user","content":"你好,我叫李雷,1+1等于多少?"}],temperature:0.3,}

其中,model 是模型 ID,目前支持 moonshot-v1-8k,moonshot-v1-32k,moonshot-v1-128k。

messages 是对话的消息数组,其中的 role 是角色,只支持 system,user,assistant,content 是消息内容,不能为空。

有个 stream 控制返回类型,默认 false,是非流式返回,设置为 true 则采用流式返回。

只有 model 和 messages 是必选参数,其他的都是可选参数,详细的参数说明可参考字段说明。

我们先来构建请求体对象(下面使用了 Lombok 简化代码)。

@Data@ToString@AllArgsConstructor@NoArgsConstructorpublicclassChatMessage{privateString role;privateString content;}@Data@ToString@AllArgsConstructor@NoArgsConstructorpublicclassChatCompletionsRequestBody{privateString model;privateList<ChatMessage> messages;privatedouble temperature;// ... 其他参数}

Kimi 返回的响应体也是一个 JSON 对象。

对于非流式返回,一次返回完整的数据,结构如下所示:

{"id":"cmpl-04ea926191a14749b7f2c7a48a68abc6","object":"chat.completion","created":1698999496,"model":"moonshot-v1-8k","choices":[{"index":0,"message":{"role":"assistant","content":" 你好,李雷!1+1等于2。如果你有其他问题,请随时提问!"},"finish_reason":"stop"}],"usage":{"prompt_tokens":19,"completion_tokens":21,"total_tokens":40}}

对于流式返回,结果会一条条返回,每条是按顺序的几个词,适合于生产环境中较大的结果。

data:{"id":"cmpl-1305b94c570f447fbde3180560736287","object":"chat.completion.chunk","created":1698999575,"model":"moonshot-v1-8k","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}data:{"id":"cmpl-1305b94c570f447fbde3180560736287","object":"chat.completion.chunk","created":1698999575,"model":"moonshot-v1-8k","choices":[{"index":0,"delta":{"content":"你好"},"finish_reason":null}]}...data:[DONE]

我们也构建一个 Java 对象来接收响应体。

@Data@ToStringpublicclassChatCompletionsResponseBody{privateString id;privateString object;privatelong created;privateString model;privateList<Choice> choices;privateUsage usage;@Data@ToStringpublicstaticclassChoice{privatelong index;privateChatMessage message;privateString finishReason;}@Data@ToStringpublicstaticclassUsage{privatelong promptTokens;privatelong completionTokens;privatelong totalTokens;}}

然后编写调用的方法,在客户端代码中添加对话的方法。

@NullablepublicChatCompletionsResponseBodychatCompletions(@NullableChatCompletionsRequestBody body)throwsIOException{if(Objects.isNull(body)){returnnull;}// 构建请求体RequestBody requestBody =RequestBody.create(this.objectMapper.writeValueAsString(body),MediaType.parse("application/json;charset=utf-8"));Request request =newRequest.Builder().url(this.baseUrl +"/chat/completions").addHeader("Authorization","Bearer "+this.accessToken).post(requestBody).build();// 发起请求finalCall call =this.httpClient.newCall(request);Response response = call.execute();if(response.isSuccessful()){// 请求成功ResponseBody responseBody = response.body();if(Objects.nonNull(responseBody)){String content = responseBody.string();returnthis.objectMapper.readValue(content,ChatCompletionsResponseBody.class);}}else{// 请求异常ResponseBody responseBody = response.body();if(Objects.nonNull(responseBody)){String content = responseBody.string();thrownewMoonShotRequestException(content);}}returnnull;}

返回的响应体就包含了 Kimi 给我们的答案。

多轮对话

多轮对话可以让 Kimi 掌握之前对话的上下文,提供更准备的回答。我们可以将之前对话的结果传递给下一个对话。

// history 是上一个请求响应体中 choices 的 messageChatMessage history =newChatMessage("system","...");ChatMessage chatMessage1 =newChatMessage("system","...");ChatMessage chatMessage2 =newChatMessage("user","...");ChatCompletionsRequestBody body =newChatCompletionsRequestBody("moonshot-v1-8k",Arrays.asList(history, chatMessage1, chatMessage2),0.3);

然后一起发送请求即可。

上传文件

Kimi 支持从文件中学习并回答问题,支持多种格式的文件,如 PDF、Word、Excel、PPT、图片文件、文本文件等,同时 Kimi 的 API 提供了强大的 OCR 能力,对于 PDF、图片等格式的文件可自动提取识别文字。然后就可以将提取的文字发送给对话接口作为上下文。上传文件的接口路径是

/files

,通过 multipart 表单上传文件。我们在客户端类中添加上传文件的方法。

@NullablepublicFileUploadResponseBodyuploadFile(byte[] bytes,String filename,String contentType)throwsIOException{if(Objects.isNull(bytes)||!StringUtils.hasText(filename)){returnnull;}// 创建请求体RequestBody fileBody =RequestBody.create(bytes,MediaType.parse(contentType));MultipartBody requestBody =newMultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("file", filename, fileBody).addFormDataPart("purpose","file-extract").build();Request request =newRequest.Builder().url(this.baseUrl +"/files").addHeader("Authorization","Bearer "+this.accessToken).header("Content-Type","multipart/form-data").post(requestBody).build();// 发起请求finalCall call =this.httpClient.newCall(request);try(Response response = call.execute()){ResponseBody body = response.body();if(response.isSuccessful()){// 请求成功if(Objects.nonNull(body)){String content = body.string();returnthis.objectMapper.readValue(content,FileUploadResponseBody.class);}}else{// 请求失败if(Objects.nonNull(body)){String content = body.string();thrownewMoonShotRequestException(content);}}}returnnull;}

响应对象的类型如下,其中 id 为上传后生成的文件 ID。

@Data@ToStringpublicclassFileUploadResponseBody{privateString id;privateString object;privatelong bytes;privatelong createdAt;privateString filename;privateString purpose;privateString status;privateString status_details;}

然后使用文件 ID 获取文件内容,接口路径是

/files/{file_id}/content

。我们在客户端类中添加获取文件内容的方法。

@NullablepublicFileContentResponseBodygetFileContent(String fileId)throwsIOException{if(!StringUtils.hasText(fileId)){returnnull;}// 构建请求体Request request =newRequest.Builder().url(this.baseUrl +"/files/"+ fileId +"/content").addHeader("Authorization","Bearer "+this.accessToken).get().build();// 发起请求finalCall call =this.httpClient.newCall(request);try(Response response = call.execute()){ResponseBody body = response.body();if(response.isSuccessful()){// 请求成功if(Objects.nonNull(body)){String content = body.string();returnthis.objectMapper.readValue(content,FileContentResponseBody.class);}}else{// 请求失败if(Objects.nonNull(body)){String content = body.string();thrownewMoonShotRequestException(content);}}}returnnull;}

响应对象如下,其中 content 即是文件的内容。

@Data@ToStringpublicclassFileContentResponseBody{privateString content;privateString fileType;privateString filename;privateString title;privateString type;}

另外也支持文件的 Restful 查询列表、详情和删除接口,路径分别是

GET /files

GET /files/{file_id}

DELETE /files/{file_id}

上面提供了发起对话的接口对接,同时也支持文件上传,就可以自己实现一个和官方对话窗口一样的界面了。

在这里插入图片描述

最后,提醒大家注意 Kimi 的 API 已经开始收费了,具体的收费政策请参考官网。


本文转载自: https://blog.csdn.net/wwtg9988/article/details/141090679
版权归原作者 火眼9988 所有, 如有侵权,请联系我们删除。

“为系统接入 Kimi AI 智能大模型(附源码)”的评论:

还没有评论