目录
以实战角度出发,给出java、python、Node.js三种对接方式,可以快捷便利的引入到自己的项目中,快速实现deepseek接入。
1、创建API key
[DeepSeek]: "deepseek API key"
这个key创建时务必要记录到本地,创建完成后是不能够查看的,如果遗忘了,那么跟这个key关联的记录就找不回来了,需要重新创建key去使用。
需要注意的是:在使用的过程中不要将key暴露在外,比如前端明文传输或者写死在前端代码中,如果造成key泄露,泄露的key会被禁用,同样会导致历史记录丢失。
2、java对接
2.1、pom文件添加依赖
deepseek支持httpclient方式调用API接口,在此引入apache的httpclient包或者OkHttp包(根据自己的实际情况,引用一种即可),如果已经有引用,则可忽略此步骤
<!-- Apache HttpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<!-- OkHttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
2.2、创建请求demo
Apache httpclient示例:
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class DeepSeekClient {
private static final String API_URL = "https://api.deepseek.com/chat/completions";
private static final String API_KEY = "your API Keys"; //这里改成你自己的qpi keys
// 传入提问
public static String getDeepSeek(String problem) throws IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost request = new HttpPost(API_URL);
request.setHeader("Content-Type", "application/json");
request.setHeader("Authorization", "Bearer " + API_KEY);
// 请求体
String requestBody = String.format(
"{\"model\": \"deepseek-chat\", \"messages\": [{\"role\": \"user\", \"content\": \"%s\"}], \"stream\": false}",problem);
request.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
// 发送请求并获取响应
try (CloseableHttpResponse response = client.execute(request)) {
// 返回响应内容
return EntityUtils.toString(response.getEntity());
}
}
public static void main(String[] args) throws IOException {
System.out.println(getDeepSeek("deepseek有自己的意识吗"));
}
}
OkHttp示例:
import okhttp3.*;
import java.io.IOException;
public class DeepSeekClient {
private static final String API_URL = "https://api.deepseek.com/chat/completions";
private static final String API_KEY = "your-api-key";
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String json="""
{
"model": "deepseek-chat",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "deepseek有自己的意识吗"}
],
"stream": false
}
""";
RequestBody body = RequestBody.create(mediaType, json);
Request request = new Request.Builder()
.url(API_URL)
.post(body)
.addHeader("Authorization", "Bearer " + API_KEY)
.addHeader("Content-Type", "application/json")
.build();
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful() && response.body() != null) {
System.out.println(response.body().string());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
返回结果是一个json串,直接解析即可
需要注意的是,API_URL和API_KEY一般都是写在配置文件中,上文demo写在代码里只是为了代码可读性更高。
2.3、实际拓展(流式输出)
在实际使用场景中,为了提升响应速度,一般都会使用流式输出,demo如下:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhiwonders.paperserver.service.IAuthService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@RestController
@RequestMapping("/api/v1")
@Slf4j
public class OpenAIController {
@Value("${ai.config.deepseek.apiKey}")
private String API_KEY;
@Value("${ai.config.deepseek.baseUrl}")
private String API_URL;
@Autowired
private IAuthService authService;
private final ExecutorService executorService = Executors.newCachedThreadPool();
private final ObjectMapper objectMapper = new ObjectMapper();
@PostMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter chat(
SseEmitter emitter = new SseEmitter(-1L);
executorService.execute(() -> {
try {
log.info("流式回答开始,问题:{}", question);
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpPost request = new HttpPost(API_URL);
request.setHeader("Content-Type", "application/json");
request.setHeader("Authorization", "Bearer " + API_KEY);
Map<String, Object> message = new HashMap<>();
message.put("role", "user");
message.put("content", question);
Map<String, Object> requestMap = new HashMap<>();
requestMap.put("model", "deepseek-chat");
requestMap.put("messages", Collections.singletonList(message));
// 使用流式:true,不使用流式:false
requestMap.put("stream", true);
String requestBody = objectMapper.writeValueAsString(requestMap);
request.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
try (CloseableHttpResponse response = client.execute(request);
BufferedReader reader = new BufferedReader(
new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("data: ")) {
String jsonData = line.substring(6);
if ("[DONE]".equals(jsonData)) {
break;
}
JsonNode node = objectMapper.readTree(jsonData);
String content = node.path("choices")
.path(0)
.path("delta")
.path("content")
.asText("");
if (!content.isEmpty()) {
emitter.send(content);
}
}
}
log.info("流式回答结束,{}",question);
emitter.complete();
}
} catch (Exception e) {
log.error("处理 Deepseek 请求时发生错误", e);
emitter.completeWithError(e);
}
} catch (Exception e) {
log.error("处理 Deepseek 请求时发生错误", e);
emitter.completeWithError(e);
}
});
return emitter;
}
}
调用接口测试:
curl -v -X POST \
http://localhost:port/api/v1/chat \
-H "Content-Type: application/json" \
-d '"deepseek有自己的思维吗"' \
--no-buffer
3、python对接
3.1、导入库
# 这里导入了requests库,它是Python中用于发送HTTP请求的常用库,而json库则用于处理JSON数据,因为API请求和响应通常使用JSON格式
import requests
import json
如果没有requests库,可直接安装
pip install requests
3.2、项目结构
deepseek-project/
├── main.py # 主程序
└── conversation.txt # 对话记录文件
3.3、代码实现
import os
import json
import time
import requests
from datetime import datetime
def save_to_file(file, content, is_question=False):
"""保存对话内容到文件"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
if is_question:
file.write(f"\n[{timestamp}] Question:\n{content}\n\n[{timestamp}] Answer:\n")
else:
file.write(content)
def main():
# 配置
url = "https://api.siliconflow.cn/v1/chat/completions"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY" # 替换为你的 API Key
}
# 打开文件用于保存对话
with open("conversation.txt", "a", encoding="utf-8") as file:
while True:
# 获取用户输入
question = input("\n请输入您的问题 (输入 q 退出): ").strip()
if question.lower() == 'q':
print("程序已退出")
break
# 保存问题
save_to_file(file, question, is_question=True)
# 准备请求数据
data = {
"model": "deepseek-ai/DeepSeek-V3",
"messages": [
{
"role": "user",
"content": question
}
],
# 是否开启流式推理, 默认为False, 表示不开启流式推理,True为开启流式输出
"stream": True,
"max_tokens": 2048,
"temperature": 0.7,
"top_p": 0.7,
"top_k": 50,
"frequency_penalty": 0.5,
"n": 1,
"response_format": {
"type": "text"
}
}
try:
# 发送流式请求
response = requests.post(url, json=data, headers=headers, stream=True)
response.raise_for_status() # 检查响应状态
# 处理流式响应
for line in response.iter_lines():
if line:
line = line.decode('utf-8')
if line.startswith('data: '):
if line == 'data: [DONE]':
continue
try:
content = json.loads(line[6:]) # 去掉 'data: ' 前缀
if content['choices'][0]['delta'].get('content'):
chunk = content['choices'][0]['delta']['content']
print(chunk, end='', flush=True)
file.write(chunk)
file.flush()
except json.JSONDecodeError:
continue
# 添加分隔符
print("\n----------------------------------------")
file.write("\n----------------------------------------\n")
file.flush()
except requests.RequestException as e:
error_msg = f"请求错误: {str(e)}\n"
print(error_msg)
file.write(error_msg)
file.flush()
if __name__ == "__main__":
main()
运行程序:
python main.py
代码详解:
-
请求头(headers)
-
Content-Type 指定请求体的数据格式为JSON
-
Authorization 包含用于身份验证的API密钥,实际使用时需要替换为真实的API Key
-
-
请求体(data)
-
modle 指定使用的模型为 deepseek-ai/DeepSeek-V3
-
max_tokens 限制生成的文本最多包含2048个token
-
messages 列表包含系统消息和用户消息,系统消息要求智能助手提供解答问题的思维链,用户消息询问DeepSeek技术创新有哪些
-
stream 控制是否开启流式推理,这里设置为
True
表示开启 -
temperature 控制采样随机性,值为0.7表示模型具有一定的创造性
-
-
save_to_file函数
-
生成时间戳
-
格式化保存问题和答案
-
自动刷新文件缓冲区
-
3.4、交互方式
-
输入问题进行对话
-
输入 ‘q’ 退出程序
-
查看 conversation.txt 获取对话记录
4、Node.js对接
4.1、环境准备
4.1.1、系统要求
-
Node.js 14.0 或更高版本
-
npm 包管理器
4.1.2、项目结构
deepseek-project/
├── main.js # 主程序
├── package.json # 项目配置文件
└── conversation.txt # 对话记录文件
4.1.3、安装依赖
# 在项目目录下打开命令行,执行:
# 安装项目依赖
npm install
# 如果出现权限问题,可以尝试:
sudo npm install # Linux/Mac
# 或
npm install --force # Windows
此命令会安装 package.json 中定义的所有依赖项:
-
axios: 用于发送 HTTP 请求
-
moment: 用于时间格式化
如果安装过程中遇到网络问题,可以尝试使用国内镜像:
# 设置淘宝镜像
npm config set registry https://registry.npmmirror.com
# 然后重新安装
npm install
4.1.4、运行程序
安装完依赖后,使用以下命令启动程序:
# 使用 npm 启动
npm start
# 或者直接使用 node
node main.js
如果遇到权限问题:
# Linux/Mac
sudo npm start
# Windows (以管理员身份运行命令提示符)
npm start
4.2、代码实现
4.2.1、package.json
{
"name": "deepseek-chat",
"version": "1.0.0",
"description": "DeepSeek API chat implementation in Node.js",
"main": "main.js",
"scripts": {
"start": "node main.js"
},
"dependencies": {
"axios": "^1.6.2",
"moment": "^2.29.4"
}
}
4.2.2、main.js
const fs = require('fs').promises;
const readline = require('readline');
const axios = require('axios');
const moment = require('moment');
class DeepSeekChat {
constructor() {
this.url = 'https://api.siliconflow.cn/v1/chat/completions';
this.apiKey = 'YOUR_API_KEY'; // 替换为你的 API Key
this.logFile = 'conversation.txt';
}
async saveToFile(content, isQuestion = false) {
const timestamp = moment().format('YYYY-MM-DD HH:mm:ss');
const text = isQuestion
? `\n[${timestamp}] Question:\n${content}\n\n[${timestamp}] Answer:\n`
: content;
await fs.appendFile(this.logFile, text);
}
async chat() {
// 创建命令行接口
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// 使用 Promise 封装问题输入
const question = (prompt) => new Promise((resolve) => rl.question(prompt, resolve));
try {
while (true) {
const userInput = await question('\n请输入您的问题 (输入 q 退出): ');
if (userInput.trim().toLowerCase() === 'q') {
console.log('程序已退出');
break;
}
// 保存问题
await this.saveToFile(userInput, true);
// 准备请求数据
const data = {
model: 'deepseek-ai/DeepSeek-V3',
messages: [
{
role: 'user',
content: userInput
}
],
stream: true,
max_tokens: 2048,
temperature: 0.7,
top_p: 0.7,
top_k: 50,
frequency_penalty: 0.5,
n: 1,
response_format: {
type: 'text'
}
};
try {
// 发送流式请求
const response = await axios({
method: 'post',
url: this.url,
data: data,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
},
responseType: 'stream'
});
// 处理流式响应
response.data.on('data', async (chunk) => {
const lines = chunk.toString().split('\n');
for (const line of lines) {
if (line.trim() === '') continue;
if (line.trim() === 'data: [DONE]') continue;
if (line.startsWith('data: ')) {
try {
const json = JSON.parse(line.slice(6));
if (json.choices[0].delta.content) {
const content = json.choices[0].delta.content;
process.stdout.write(content);
await this.saveToFile(content);
}
} catch (e) {
continue;
}
}
}
});
// 等待响应完成
await new Promise((resolve) => {
response.data.on('end', async () => {
console.log('\n----------------------------------------');
await this.saveToFile('\n----------------------------------------\n');
resolve();
});
});
} catch (error) {
const errorMsg = `请求错误: ${error.message}\n`;
console.error(errorMsg);
await this.saveToFile(errorMsg);
}
}
} finally {
rl.close();
}
}
}
// 运行程序
async function main() {
const chatbot = new DeepSeekChat();
await chatbot.chat();
}
main().catch(console.error);
4.3、代码详解
4.3.1、类结构
-
DeepSeekChat
: 主类,封装所有功能 -
constructor
: 构造函数,初始化配置 -
saveToFile
: 异步保存对话记录 -
chat
: 主对话循环
4.3.2、关键功能
4.3.2.1、文件操作
async saveToFile(content, isQuestion = false) {
const timestamp = moment().format('YYYY-MM-DD HH:mm:ss');
const text = isQuestion
? `\n[${timestamp}] Question:\n${content}\n\n[${timestamp}] Answer:\n`
: content;
await fs.appendFile(this.logFile, text);
}
4.3.2.2、流式处理
response.data.on('data', async (chunk) => {
const lines = chunk.toString().split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const json = JSON.parse(line.slice(6));
if (json.choices[0].delta.content) {
const content = json.choices[0].delta.content;
process.stdout.write(content);
await this.saveToFile(content);
}
}
}
});
4.3.3、参数说明
-
model
: 使用的模型名称 -
stream
: 启用流式输出 -
max_tokens
: 最大输出长度 (2048) -
temperature
: 控制随机性 (0.7) -
top_p
,top_k
: 采样参数 -
frequency_penalty
: 重复惩罚系数
4.4、错误处理
代码包含完整的错误处理机制:
-
网络请求错误处理
-
JSON 解析错误处理
-
文件操作错误处理
-
优雅退出处理
4.5、使用方法
4.5.1、修改配置
在 main.js
中替换 YOUR_API_KEY
为你的实际 API Key。
4.5.2、交互方式
-
输入问题进行对话
-
输入 ‘q’ 退出程序
-
查看 conversation.txt 获取对话记录