Bootstrap

跨平台实战,Java/Python/Node.js全攻略助你1小时接入DeepSeek

目录

1、创建API key

2、java对接

2.1、pom文件添加依赖

2.2、创建请求demo

2.3、实际拓展(流式输出)

3、python对接

3.1、导入库

3.2、项目结构

3.3、代码实现

3.4、交互方式

4、Node.js对接

4.1、环境准备

4.1.1、系统要求

4.1.2、项目结构

4.1.3、安装依赖

4.1.4、运行程序

4.2、代码实现

4.2.1、package.json

4.2.2、main.js

4.3、代码详解

4.3.1、类结构

4.3.2、关键功能

4.3.2.1、文件操作

4.3.2.2、流式处理

4.3.3、参数说明

4.4、错误处理

4.5、使用方法

4.5.1、修改配置

4.5.2、交互方式


以实战角度出发,给出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、交互方式

  1. 输入问题进行对话

  2. 输入 ‘q’ 退出程序

  3. 查看 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、交互方式
  1. 输入问题进行对话

  2. 输入 ‘q’ 退出程序

  3. 查看 conversation.txt 获取对话记录

;