关于最近热度爆炸的DeepSeek是什么我就不多做说明了,接下来直接进入主题--派聪明集成DeepSeek大模型上。
派聪明的响应架构
翻了一下之前的系列教程,发现派聪明的整体设计还没有给大家正式的介绍过,那么就趁着这个机会,把这块补上
三层交互:
- 前端交互层:基于websocket的主站 + 基于http的微信公众号问答方式
- Chat门面层:对上提供统一的交互体验,对下路由选择具体的大模型进行交互
- 大模型服务层:对接大模型,实现具体问答
基于上面的设计架构,当我们需要新集成一个大模型时,重点关注的就是 ChatService
的实现,而与用户的交互层则无需改动
DeepSeek集成准备工作
接下来我们看一下如何进行集成DeepSeek,看一下如何在派聪明中新加一个大模型
2.1 账号注册
进入官方开放平台,按照个人实际需要,注册账号 https://platform.deepseek.com/sign_in
注册之后,进入 API Keys,创建一个新的 API key
我们需要拿到的就是 sk-3eeca****
2.2 官方对接文档
接下来我们打开 DeepSeek 开放平台的接入文档,看一下如何接入他们的openApi
2.2.1 鉴权方式:
https://api-docs.deepseek.com/zh-cn/
从示例上可以明确看到,鉴权采用的是 HTTP Basic Auth认证
方式,直接在请求头中携带上面创建的 API key
2.2.2 问答交互:
https://api-docs.deepseek.com/zh-cn/api/create-chat-completion
关键的问答交互,则主要是对话补全接口
关键的请求参数如下
- Messages: 对话内容
- Role: 角色,用于AI了解它应该如何行为以及谁在发起调用
- system: 了解它应该如何行为以及谁在发起调用, 如 content = 你现在是一个资深后端java工程师
- user: 消息/提示来自最终用户或人类
- assistant: 消息是助手(聊天模型)的响应 --> 即ai的返回结果,在多轮对话中,我们需要将之前的聊天记录传递给机器人,以获取更好的结果
- Content:具体的内容
- Role: 角色,用于AI了解它应该如何行为以及谁在发起调用
- Model: 模型选择,官方当前支持两个:deepseek-chat + deepseek-reasoner(推理模型)
- Stream: true表示流式返回/false表示一次全部返回
2.2.3 多轮对话:
https://api-docs.deepseek.com/zh-cn/guides/multi_round_chat
需要注意的是,现在的大模型开放平台基本上都是无状态的api,不记录用户的问答上下文;可以简单理解为,你的每一次问答,对它而言,都是一次全新的交互
那么问题来了,在我们实际体验的官方聊天机器人中,很明显是有状态的啊,我可以让它修改上次回答的内容,或者按照我得想法,对之前的回答进行扩充,这是怎么做到的呢?
- 再一次新的提问中,将之前的交互内容,同样塞入
messages
中,传为参数传递过去,即将对话历史拼接好之后给它,从而实现多轮对话
实现方式也比较简单,一个多轮对话的示例如下:
在第一轮请求时,传递给 API 的 messages
为:
[
{"role": "user", "content": "What's the highest mountain in the world?"}
]
在第二轮请求时:
- 要将第一轮中模型的输出添加到
messages
末尾 - 将新的提问添加到
messages
末尾
最终传递给 API 的 messages
为:
[
{"role": "user", "content": "What's the highest mountain in the world?"},
{"role": "assistant", "content": "The highest mountain in the world is Mount Everest."},
{"role": "user", "content": "What is the second?"}
]
2.3 接口调用测试
看完官方的接口文档之后,你会惊讶的发现,实现DeepSeek的问答交流应该是一个非常简单的事情,发送一个http请求而言,能有什么难度呢?
直接借助我们最熟悉的SpringBoot的RestTemplate分分钟就可以实现接口交互
public String chat(String prompt, int maxTokens) {
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer sk-xxx");
headers.setContentType(MediaType.APPLICATION_JSON);
Map<String, Object> body = new HashMap<>();
body.put("model", "deepseek-chat");
body.put("stream", false);
body.put("max_tokens", maxTokens);
Map<String, String> msg = new HashMap<>();
msg.put("role", "user");
msg.put("content", prompt);
body.put("messages", Arrays.asList(msg));
HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body, headers);
return restTemplate.postForObject("https://api.deepseek.com/chat/completions", entity, String.class);
}
@Test
public void testChat() {
String prompt = "说个段子";
String res = chat(prompt, 300);
res = JSONUtil.toJsonPrettyStr(JSONUtil.parseObj(res));
System.out.println(res);
}
输出内容如下:
对于java
回复