后端接入deepseek的api

DeepSeek 提供了兼容 OpenAI 格式的 API,这意味着你可以用熟悉的 openai SDK 直接接入,只需改一下 baseURL

本文从零开始,带你完成 Node.js 后端接入 DeepSeek 的全流程。

为什么选 DeepSeek?

  • 兼容 OpenAI 格式:无需学习新 SDK,迁移成本极低
  • 价格实惠:相比 GPT-4 系列,成本大幅降低
  • 中文能力强:对中文场景的理解和生成表现出色
  • 模型丰富:提供通用对话、推理专用等多个模型

可用模型

模型 ID用途特点
deepseek-chat通用对话日常使用首选,兼顾速度与质量
deepseek-reasoner深度推理数学、编程、逻辑推理更强

根据场景选择:一般问答用 deepseek-chat,复杂推理用 deepseek-reasoner

环境准备

1. 获取 API Key

登录 DeepSeek 开放平台,在 API Keys 页面创建密钥。

2. 安装依赖

1
npm install openai

DeepSeek 兼容 OpenAI SDK,不需要额外安装其他包。

基础调用

非流式(一次性返回)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import OpenAI from 'openai';

const client = new OpenAI({
baseURL: 'https://api.deepseek.com',
apiKey: 'sk-your-api-key',
});

const completion = await client.chat.completions.create({
model: 'deepseek-chat',
messages: [
{ role: 'system', content: '你是一个有用的助手。' },
{ role: 'user', content: '用通俗的语言解释什么是 HTTPS。' },
],
});

console.log(completion.choices[0].message.content);

流式输出(逐字返回)

适合需要实时展示回复的场景,如聊天界面:

1
2
3
4
5
6
7
8
9
10
11
12
const stream = await client.chat.completions.create({
model: 'deepseek-chat',
messages: [{ role: 'user', content: '写一首关于夏天的诗' }],
stream: true,
});

for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content;
if (content) {
process.stdout.write(content); // 逐字输出
}
}

多轮对话

维护 messages 数组,每次把 AI 的回复追加进去:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [
{ role: 'system', content: '你是一个编程助手。' },
];

async function chat(userInput: string): Promise<string> {
messages.push({ role: 'user', content: userInput });

const completion = await client.chat.completions.create({
model: 'deepseek-chat',
messages,
});

const reply = completion.choices[0].message.content || '';
messages.push({ role: 'assistant', content: reply });

return reply;
}

// 连续对话
await chat('JavaScript 有哪些基本数据类型?');
await chat('那 Symbol 类型有什么实际用途?'); // AI 会记住上一轮上下文

错误处理与重试

生产环境必须处理网络波动和限流:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
async function callWithRetry(
messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[],
maxRetries = 3
): Promise<string> {
for (let i = 0; i < maxRetries; i++) {
try {
const completion = await client.chat.completions.create({
model: 'deepseek-chat',
messages,
stream: false,
timeout: 30000,
});
return completion.choices[0].message.content || '';
} catch (error: any) {
if (error.status === 429 || error.status >= 500) {
const delay = Math.pow(2, i) * 1000; // 指数退避:1s, 2s, 4s
console.warn(`请求失败 (${error.status}),${delay}ms 后重试...`);
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
throw new Error(`已重试 ${maxRetries} 次,仍然失败`);
}

Midway.js 集成示例

如果你用的是 Midway.js 框架,可以封装一个 Service:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// src/service/deepseek.service.ts
import { Provide, Init } from '@midwayjs/core';
import OpenAI from 'openai';

@Provide()
export class DeepSeekService {
private client: OpenAI;

@Init()
async init() {
this.client = new OpenAI({
baseURL: 'https://api.deepseek.com',
apiKey: process.env.DEEPSEEK_API_KEY,
});
}

async chat(userMessage: string, context: string[] = []): Promise<string> {
const messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [
{ role: 'system', content: '你是98潮玩的智能助手。' },
...context.map((c, i) => ({
role: i % 2 === 0 ? 'user' as const : 'assistant' as const,
content: c,
})),
{ role: 'user', content: userMessage },
];

const completion = await this.client.chat.completions.create({
model: 'deepseek-chat',
messages,
});

return completion.choices[0].message.content || '';
}

async chatStream(
userMessage: string,
onChunk: (text: string) => void
): Promise<void> {
const stream = await this.client.chat.completions.create({
model: 'deepseek-chat',
messages: [{ role: 'user', content: userMessage }],
stream: true,
});

for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content;
if (content) onChunk(content);
}
}
}

最佳实践

1. API Key 安全

永远不要把 Key 硬编码:

1
2
3
4
5
// ❌ 错误
const client = new OpenAI({ apiKey: 'sk-abc123' });

// ✅ 正确:用环境变量
const client = new OpenAI({ apiKey: process.env.DEEPSEEK_API_KEY });

2. System Prompt 设计

好的系统提示词能显著提升回复质量:

1
2
3
4
5
const systemPrompt = `你是98潮玩平台的智能助手。请遵守以下规则:
- 只回答游戏、潮玩相关的问题
- 如果用户问无关问题,礼貌引导回正题
- 回答简洁,不超过200字
- 不编造不确定的信息`;

3. Token 消耗控制

几点省钱技巧:

  • max_tokens 限制单次回复长度,防止费用失控
  • 多轮对话时裁剪历史,避免超出上下文窗口(64K token)
  • temperature 控制随机性:0.0 最确定,1.0 最发散
1
2
3
4
5
6
const completion = await client.chat.completions.create({
model: 'deepseek-chat',
messages,
max_tokens: 500,
temperature: 0.7,
});

总结

DeepSeek 接入非常简单——和用 OpenAI 的体验几乎一致,改个 baseURL 就行。记住几个关键点:

  1. API Key 用环境变量管理,不要硬编码
  2. 生产环境做好错误重试和超时处理
  3. 善用 System Prompt 引导模型行为
  4. 注意 Token 消耗,控制成本

如果你已经在用 OpenAI 的 SDK,切换到 DeepSeek 几乎零成本。