对接kimi,打造聊天机器人,生成文档摘要

本文介绍了月之暗面在2023年推出的Kimi智能助手,它支持学术论文翻译、法律问题辅助和API文档理解等功能。文章详细展示了如何获取APIKey,以及如何通过OkHttp库实现与Kimi的简单对话和文档摘要功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Kimi,是月之暗面于2023年10月推出的一款智能助手,主要应用场景为专业学术论文的翻译和理解、辅助分析法律问题、快速理解API开发文档等,是全球首个支持输入20万汉字的智能助手产品

1.登录,获取API Key

打开网址Moonshot AI - 开放平台 ,可以看到官网比较简洁,有两部分构成,api文档和用户中心

点击用户中心,可以用微信登录,然后在API Key管理中新建一个key,记录下来

2.引入依赖 

由于跟kimi对接需要用到SSE(Server Send Event),我们使用okhttp库

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.25</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.10.0</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp-sse</artifactId>
            <version>4.10.0</version>
        </dependency>

3.实现简单的对话

@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class Message {

    private String role;

    private String content;

}
public enum RoleEnum {
    system,
    user,
    assistant;
}

public class MoonshotAiUtils {
    private static final String API_KEY = "api key";
    private static final String MODELS_URL = "https://api.moonshot.cn/v1/models";
    private static final String FILES_URL = "https://api.moonshot.cn/v1/files";
    private static final String ESTIMATE_TOKEN_COUNT_URL = "https://api.moonshot.cn/v1/tokenizers/estimate-token-count";
    private static final String CHAT_COMPLETION_URL = "https://api.moonshot.cn/v1/chat/completions";

    public static String getModelList() {
        return getCommonRequest(MODELS_URL)
                .execute()
                .body();
    }

    public static String uploadFile(@NonNull File file) {
        return getCommonRequest(FILES_URL)
                .method(Method.POST)
                .header("purpose", "file-extract")
                .form("file", file)
                .execute()
                .body();
    }

    public static String getFileList() {
        return getCommonRequest(FILES_URL)
                .execute()
                .body();
    }

    public static String deleteFile(@NonNull String fileId) {
        return getCommonRequest(FILES_URL + "/" + fileId)
                .method(Method.DELETE)
                .execute()
                .body();
    }

    public static String getFileDetail(@NonNull String fileId) {
        return getCommonRequest(FILES_URL + "/" + fileId)
                .execute()
                .body();
    }

    public static String getFileContent(@NonNull String fileId) {
        return getCommonRequest(FILES_URL + "/" + fileId + "/content")
                .execute()
                .body();
    }

    public static String estimateTokenCount(@NonNull String model, @NonNull List<Message> messages) {
        String requestBody = new JSONObject()
                .putOpt("model", model)
                .putOpt("messages", messages)
                .toString();
        return getCommonRequest(ESTIMATE_TOKEN_COUNT_URL)
                .method(Method.POST)
                .header(Header.CONTENT_TYPE, ContentType.JSON.getValue())
                .body(requestBody)
                .execute()
                .body();
    }

    @SneakyThrows
    public static String chat(@NonNull String model, @NonNull List<Message> messages) {
        StringBuilder sb = new StringBuilder();
        String requestBody = new JSONObject()
                .putOpt("model", model)
                .putOpt("messages", messages)
                .putOpt("stream", true)
                .toString();
        Request okhttpRequest = new Request.Builder()
                .url(CHAT_COMPLETION_URL)
                .post(RequestBody.create(requestBody, MediaType.get(ContentType.JSON.getValue())))
                .addHeader("Authorization", "Bearer " + API_KEY)
                .build();
        Call call = new OkHttpClient().newCall(okhttpRequest);
        Response okhttpResponse = call.execute();
        BufferedReader reader = new BufferedReader(okhttpResponse.body().charStream());
        try {
            String line;
            while ((line = reader.readLine()) != null) {
                if (StrUtil.isBlank(line)) {
                    continue;
                }
                if (JSONUtil.isTypeJSON(line)) {
                    Optional.of(JSONUtil.parseObj(line))
                            .map(x -> x.getJSONObject("error"))
                            .map(x -> x.getStr("message"))
                            .ifPresent(x -> System.out.println("error: " + x));
                    JSONObject jsonObject = JSONUtil.parseObj(line);
                    throw new ServiceFailException(jsonObject.getJSONObject("error").getStr("message"));
                }
                line = StrUtil.replace(line, "data: ", StrUtil.EMPTY);
                if (StrUtil.equals("[DONE]", line) || !JSONUtil.isTypeJSON(line)) {
                    return sb.toString();
                }
                Optional.of(JSONUtil.parseObj(line))
                        .map(x -> x.getJSONArray("choices"))
                        .filter(CollUtil::isNotEmpty)
                        .map(x -> (JSONObject) x.get(0))
                        .map(x -> x.getJSONObject("delta"))
                        .map(x -> x.getStr("content"))
                        .ifPresent(x -> sb.append(x));
            }
            return sb.toString();
        } finally {
            IoUtil.close(reader);
        }
    }

    private static HttpRequest getCommonRequest(@NonNull String url) {
        return HttpRequest.of(url).header(Header.AUTHORIZATION, "Bearer " + API_KEY);
    }
}

@RestController
@RequestMapping("/kimi")
@Tag(name = "kimi管理")
public class KimiController extends BaseController {
    // 演示用,实际要存入用户session
    private List<Message> messages = new ArrayList<>();

    @Operation(summary = "聊天")
    @GetMapping("chat")
    public Result chat(String content) {
        Message message = new Message(RoleEnum.user.name(), content);
        messages.add(message);
        // 模型列表 https://platform.moonshot.cn/docs/intro#%E6%A8%A1%E5%9E%8B%E5%88%97%E8%A1%A8
        String result = MoonshotAiUtils.chat("moonshot-v1-8k", messages);
        return resultOk(result);
    }
}

代码都挺简单的,需要注意的是用户的多次问答需要放到一个list中一起发送给kimi,这样kimi才能根据上下文回答问题

4.提取文档摘要 

提取文档摘要我们先要把文档上传到kimi获取一个content,再调用聊天接口给提示词就行了

    @Operation(summary = "提取文档摘要")
    @GetMapping("docSummary")
    public Result docSummary() {
        String hint = "请简要描述文档中的内容";
        String content = MoonshotAiUtils.uploadFile(new File("d:/read.docx"));
        List<Message> messages = CollUtil.newArrayList(
                new Message(RoleEnum.system.name(), content),
                new Message(RoleEnum.user.name(), hint)
        );
        String result = MoonshotAiUtils.chat("moonshot-v1-32k", messages);
        return resultOk(result);
    }

### 关于JavaKimi集成 对于希望将Java应用程序与Kimi API或SDK进行集成的情况,当前提供的引用资料并未直接提及有关名为“Kimi”的特定API或SDK的信息。然而,在处理第三方服务集成时的一般做法可以提供指导。 通常情况下,当涉及到通过Java实现与其他平台的服务对接时,官方文档是最权威的第一手资源。如果存在针对Kimi的官方开发指南,则应优先遵循该指南中的说明来完成必要的配置和编码工作[^1]。 考虑到可能存在的语言差异和服务特性,建议采取如下方法: #### 使用HTTP请求库调用RESTful接口 许多现代Web服务都提供了基于HTTP协议的标准RESTful API接口供开发者使用。在这种场景下,可以通过发送GET, POST等类型的HTTP请求来进行数据交互。在Java环境中,可以选择Apache HttpClient、OkHttp或是Spring框架自带的RestTemplate作为工具类来简化这一过程。 ```java // Example using RestTemplate from Spring Framework import org.springframework.web.client.RestTemplate; public class KimiIntegrationExample { private static final String KIMI_API_URL = "https://api.kimi.example.com"; public void callKimiApi() { RestTemplate restTemplate = new RestTemplate(); String result = restTemplate.getForObject(KIMI_API_URL + "/endpoint", String.class); System.out.println(result); } } ``` #### 利用现有的客户端库(如果有) 部分服务商还会为其产品准备专门设计的语言绑定版本——即所谓的客户端库(Client Library),它们往往封装好了底层通信细节并暴露易于使用的高层抽象给最终用户。假如Kimi也发布了类似的Java版客户端库的话,那么可以直接引入依赖项并通过其定义的方法快速上手。 需要注意的是,上述讨论均假设了一个虚构的服务名称“Kimi”,实际操作前应当查阅具体目标系统的官方文档获取最准确的技术支持信息。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值