一、前期准备与环境校验
在正式编写代码前,我们需要确认基础环境配置是否正确,以及你是否拥有具备调用权限的 DeepSeek API 密钥。
1、硬件与软件环境要求
DeepSeek API 是基于公有云的标准 HTTP 服务,对本地机器的硬件性能无特殊要求,能正常访问公网即可;但对软件依赖有明确限制,具体要求如下:
- Python 版本:需为 Python 3.8 及以上版本。这是因为 DeepSeek API 依赖的 OpenAI 官方 SDK 强制要求 Python 3.8 及以上的运行环境;如果使用低于 3.8 的版本,会在安装依赖或运行代码时触发兼容性错误。
- 操作系统:可在 Windows、macOS、Linux 等主流系统上运行,教程中的代码在不同系统下无明显差异。
2、检查 API 密钥
你需要提前准备一个有效的 DeepSeek API 密钥,这是调用服务的唯一身份凭证。密钥的获取和校验流程如下:
- 若尚未创建密钥,需登录 DeepSeek 官方控制台,进入「API 管理」→「密钥中心」,点击「创建 API 密钥」按钮生成。生成后务必将密钥复制并保存在安全的本地位置 ------ 该密钥仅在创建时可见,关闭对话框后将无法再次查看,若遗失只能重新生成。
- 新用户注册登录 DeepSeek 平台后,账户会自动附赠一定的 Tokens 调用额度。请在控制台中确认该额度是否处于有效状态,若账户无剩余额度或额度已过期,API 调用将返回认证或权限类错误。
- 为了验证你的 API 密钥是否有效,可以使用如 Apipost 或 Postman 这类 API 调试工具,或者使用命令行的 curl 工具直接发送测试请求。下面是一个使用 curl 命令验证密钥的示例(请将命令中的
YOUR_API_KEY替换为你实际保存的密钥字符串):
bash
curl -X POST https://api.deepseek.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"model": "deepseek-chat",
"messages": [{"role": "user", "content": "测试密钥有效性"}]
}'
如果配置正常,你会收到一个包含模型返回结果的 JSON 响应;如果请求失败,服务器会返回具体的错误码和原因,便于后续排查。
3、选择 API 兼容模式并安装依赖
DeepSeek API 提供了两种官方兼容模式,用户可根据现有技术栈选择合适的调用方式。两种模式的特点、依赖安装方法及适用场景如下:
3.1 方案一:使用 OpenAI 兼容模式(推荐)
这是 DeepSeek 官方文档明确推荐的调用方案 ------ 它的接口设计完全兼容 OpenAI 的 Python SDK,如果你之前有过 OpenAI API 的使用经验,几乎可以零成本直接迁移。
使用该方案前,需先安装 OpenAI 的官方 Python 包。推荐在独立的 Python 虚拟环境中执行安装命令,避免依赖冲突问题:
bash
pip install openai
我们将使用这个官方包来完成所有的 API 调用工作。
3.2 方案二:使用 DeepSeek 官方 SDK
DeepSeek 官方还推出了专属的 Python SDK 包,名为 deepseek-sdk,目前版本为 0.1.1。该方案的使用门槛更低,且原生支持同步、异步调用及流式响应等核心功能。
你可以通过以下命令安装该 SDK 包:
bash
pip install deepseek-sdk
不过,根据官方 PyPI 页面的项目更新记录,这个专属 SDK 的迭代优先级远低于 OpenAI 兼容方案,部分新的接口功能可能不会同步覆盖到该 SDK 中。
注意:无论选择哪种兼容模式,都要确保安装的是最新版本的 SDK 包,否则可能会因 API 服务升级导致兼容性问题。后续教程将基于更通用的 OpenAI 兼容模式展开。
4、安全防护:避免硬编码密钥
在编写正式代码前,必须重视 API 密钥的安全防护工作。将密钥直接硬编码在 Python 脚本中是一种极不安全的行为 ------ 如果代码被分享、上传到代码仓库,或者被其他项目人员不小心读取,会导致你的密钥被滥用,造成无法预估的损失。
推荐使用环境变量或 .env 这类本地环境配置文件来管理密钥。具体操作流程如下:
-
在你准备编写 Python 代码的项目根目录下,创建一个名为
.env的无后缀文件。 -
在该文件中,以
键=值的格式添加你的 DeepSeek API 密钥,以及 DeepSeek API 的官方端点地址(代码中会优先读取该环境变量,若未配置则自动使用默认地址,提升代码兼容性):bashDEEPSEEK_API_KEY=你的实际API密钥 DEEPSEEK_BASE_URL=https://api.deepseek.com -
接下来,我们需要让 Python 代码从这个
.env文件中读取配置信息。要实现这一功能,需要先在虚拟环境中安装python-dotenv库,它可以负责加载.env文件中的配置信息:bashpip install python-dotenv -
为了验证环境变量是否正常加载,可以编写如下测试代码,打印基础 URL 和密钥的前缀片段。如果读取失败,代码会默认使用官方的地址前缀,便于后续排查问题:
pythonimport os from dotenv import load_dotenv # 加载项目根目录下的.env文件中的配置信息 load_dotenv() # 从环境变量中读取API密钥和基础端点地址 api_key = os.getenv("DEEPSEEK_API_KEY") base_url = os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com") # 验证配置是否生效 if not api_key: raise ValueError("DEEPSEEK_API_KEY 环境变量未设置!") else: print(f"基础URL: {base_url}") print(f"密钥已加载,前缀为: {api_key[:6]}...")
重要提示 :
.env文件需要加入到版本控制软件的忽略列表中(例如 Git 项目的.gitignore文件),确保这个包含敏感信息的文件不会被意外提交到代码仓库中。
二、基础对话实现:编写代码调用 DeepSeek API
我们将从一个最基础的 "单轮问答" 示例入手,完整拆解 DeepSeek API 的调用逻辑。这个示例将覆盖客户端初始化、请求参数构造、响应结果解析的全流程,你可以将其作为功能模板,集成到自己的项目中。
1、完整代码示例
下面是一段可直接运行的基础对话代码,我们将基于 OpenAI 兼容模式实现:
python
# 加载环境变量(从.env文件中读取配置)
import os
from dotenv import load_dotenv
from openai import OpenAI, APIError, APIConnectionError, RateLimitError
load_dotenv() # 读取项目根目录下的.env文件中的配置信息
# 1. 初始化API客户端(关键配置步骤)
client = OpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"), # 从环境变量中读取密钥,避免硬编码
base_url=os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com") # DeepSeek官方端点地址,可根据实际需求修改
)
# 2. 构造对话请求的核心参数
try:
response = client.chat.completions.create(
model="deepseek-chat", # 指定要调用的模型,deepseek-chat是通用对话模型
messages=[
# System角色设定:用于定义AI助手的身份、回答风格、行文约束
{"role": "system", "content": "你是一个知识渊博、回答通俗易懂的AI技术文档工程师,回答技术问题时需提供简短的代码示例或步骤说明,回复内容为中文。"},
# User角色设定:用户的实际提问内容
{"role": "user", "content": "请解释一下Python中装饰器的工作原理?"}
],
max_tokens=1024, # 限制模型单次输出的最大令牌数,避免响应过长
temperature=0.7, # 控制回答的随机性,数值越高,回答越有创意
stream=False # 关闭流式输出,等待模型完整生成后再返回响应
)
# 3. 解析并打印API的响应结果
print("AI 回答:")
print(response.choices[0].message.content)
except APIConnectionError as e:
print("API连接失败,请检查网络连接或API端点地址!")
print(f"错误详情:{str(e)}")
except RateLimitError as e:
print("请求频率超过限制或账户额度不足,请稍后重试或充值!")
print(f"错误详情:{str(e)}")
except APIError as e:
print(f"API服务返回错误,状态码:{e.status_code}")
print(f"错误详情:{str(e)}")
except Exception as e:
print(f"发生未知错误:{str(e)}")
将这段代码保存为 deepseek_basic_chat.py 文件,然后在虚拟环境中执行该脚本,即可在控制台看到模型的返回结果。
2、代码分步说明
下面对上述代码的关键执行步骤进行详细拆解,理解这些步骤的逻辑,将帮助你在实际项目中更灵活地调整代码:
2.1 步骤 1:导入必要的库并加载环境变量
代码首先通过 load_dotenv() 函数加载项目根目录下的 .env 文件,将其中的配置信息注入到环境变量中。后续通过 os.getenv() 方法读取环境变量,尤其是 API 密钥这类敏感信息 ------ 这是行业内安全处理敏感信息的最佳实践。
如果你的项目不使用
.env文件,也可以在系统的环境变量中提前配置DEEPSEEK_API_KEY和DEEPSEEK_BASE_URL,代码会自动读取。
2.2 步骤 2:初始化客户端
OpenAI 类的实例化是与 DeepSeek API 建立连接的核心步骤。这里的关键参数配置逻辑如下:
api_key:传入从环境变量中读取的 DeepSeek API 密钥,用于身份认证。base_url:传入 DeepSeek API 的官方端点地址(默认值为https://api.deepseek.com)。如果使用第三方中转服务(如阿里云百炼),需将该地址修改为中转服务提供的专属端点地址,否则会出现连接错误。
2.3 步骤 3:构造请求参数
client.chat.completions.create() 方法是向 DeepSeek API 发送对话请求的核心入口,它包含了多个关键的请求参数。关于这些参数的具体定义和可选值,将在「下一节 --- 3、核心参数说明」中详细说明。
2.4 步骤 4:解析响应结果
DeepSeek API 的响应数据结构与 OpenAI 完全兼容,其中包含了模型生成的核心内容和元信息。通过 response.choices[0].message.content 可以提取模型返回的核心文本内容。除了核心的回答内容外,响应中还包含了其他有用的元信息,例如:
response.id:本次请求的唯一标识 ID,可用于问题定位或日志排查。response.model:实际处理请求的模型名称,用于验证是否调用了预期模型。response.usage:本次请求的令牌使用统计信息,包含输入令牌数、输出令牌数和总令牌数,可用于监控成本和额度使用情况。
2.5 步骤 5:异常处理逻辑
代码中通过 try-except 结构捕获了几类与 API 调用相关的常见异常,这是保证程序健壮性的关键步骤。关于这些异常的具体类型和处理方式,将在后续章节中详细说明。
3、核心参数说明
请求体中的参数会直接影响模型的回复内容和效果,正确设置这些参数是实现预期交互效果的前提。下面对代码中使用的核心参数进行详细说明:
3.1 必选参数
| 参数名 | 类型 | 说明 | 示例值 |
|---|---|---|---|
model |
string | 指定要调用的模型名称,必须是 DeepSeek API 支持的模型 | deepseek-chat |
messages |
array | 构造对话上下文的消息列表,是一个包含多个 JSON 对象的数组,每个 JSON 对象需包含 role 和 content 字段 |
[{"role": "user", "content": "你好"}] |
model 参数指定了本次请求要调用的模型类型,不同模型的能力、适用场景及成本、速度存在明显差异。
messages 参数是构造对话上下文的核心,它是一个包含多个消息对象的数组,每个消息对象都有 role 和 content 两个必填字段。其中 role 字段用于指定消息的角色,它决定了模型的对话立场、回答风格和行为限制,支持的角色值有三个:
system:系统角色,用于在对话开始前设定模型的身份定位、回答风格、行文约束和行为边界。这个角色的消息不会直接暴露给终端用户,但会引导模型的后续行为。user:用户角色,用于传递终端用户的实际提问或输入内容。assistant:助手角色,用于存储模型之前的历史回复内容。在构建多轮对话上下文时,需要将模型的历史回复以assistant角色的形式加入到消息列表中。
消息数组的顺序必须严格按照对话的实际发生时间排列,因为模型会根据消息的顺序来理解完整的对话上下文。
message 有时需要添加上下文,便于 AI 根据上下文进行更准确的回复,这时就需要将上下文对话一同发给 AI:
python# 1. 加载上下文对话数据 with open(对话数据文件, "r", encoding="utf-8") as f: session_data = json.load(f) # 2. 构建系统提示词 system_prompt = """自定义系统提示词""" # 3. 构建消息列表 messages = [{"role": "system", "content": system_prompt}] # 将上下文对话添加到消息列表中 for msg in session_data["messages"]: messages.append(msg) # 将用户最新消息添加到消息列表中 messages.append({"role": "user", "content": request.message})
DeepSeek API 提供了多种具有不同能力倾向的模型:
- 在通用对话场景下,
deepseek-chat模型是性价比最高的选择;- 如果任务有更强的逻辑推理或代码生成需求,可以选择
deepseek-reasoner模型。关于这两类模型的适用场景差异,可参考官方文档的说明。
3.2 可选参数
可选参数用于控制模型回复的效果和风格,DeepSeek API 提供了多个可调整的参数。下面是几个最常用的可选参数:
| 参数名 | 类型 | 说明 | 默认值 |
|---|---|---|---|
max_tokens |
integer | 限制模型单次请求中,生成回复的最大令牌数(包含标点、空格和换行符)。该值不能超过模型的上下文上限(例如 deepseek-chat 模型支持的上限为 8192) |
4096 |
temperature |
float | 控制模型回复的创意性或随机性。取值范围为 0 到 2 之间的数字。值越高,回复越随机、越有创意;值越低,回复越保守、越确定 |
1.0 |
top_p |
float | 控制模型回复的核心词汇候选范围,取值范围为 0 到 1 之间的数字。值越小,回复的词汇越精炼、越严谨;值越大,回复的词汇越丰富、越随机 |
0.95 |
stream |
boolean | 控制是否启用流式输出。设置为 True 时,模型会以打字机效果,将回复内容分块实时返回;设置为 False 时,模型会在完整生成回复后一次性返回 |
False |
stream_options |
Object | 流式输出相关选项。只有在 stream 参数为 true 时,才可设置此参数 |
关于这些参数的细节及使用限制,可参考 DeepSeek 官方的「对话补全」API 文档,其中有详细的定义和说明。
参数调优建议:参数的调整没有绝对的标准,需要根据具体的业务场景需求来定制。不过,DeepSeek 官方提供了一套经过验证的参数设置最佳实践,可以作为调优的参考基准:
- 代码生成、数学解题、逻辑推理类场景:需要模型给出精准、无偏差的结果,建议将
temperature设置为0.0,top_p设置为1.0。- 数据抽取、结构化分析类场景:需要模型基于给定数据生成结构化、规范的结果,建议将
temperature设置为1.0,top_p设置为0.95。- 通用对话、信息答疑类场景:需要模型给出自然、流畅的回复,建议将
temperature设置为1.3,top_p设置为0.95。- 多语言翻译类场景:需要模型给出语义精准、表达自然的结果,建议将
temperature设置为1.3,top_p设置为0.95。
需要特别注意的是,temperature 和 top_p 参数不建议同时调整。这是因为两个参数的作用效果存在重叠 ------ 如果同时修改,模型输出的随机性或创意性的实际调整幅度可能超出预期,导致回复效果不符合业务需求。通常情况下,只需要调整其中一个参数,就可以实现对回复风格的有效控制。
4、返回值说明
整条链路:
- 发起请求拿到 response 对象;
- 从 response 提取内容、token 消耗、模型名等元数据;
- 业务处理(清洗、过滤、结构化、json 解析等);
- 保存:保存对话记录,可存 json 文件 / sqlite / 内存会话。
🚩response 对象里面有什么:
python
response.id # 请求唯一ID,排查问题用
response.model # 实际使用模型
response.choices[0].message.role # assistant
response.choices[0].message.content # 核心回答文本
response.choices[0].finish_reason # stop正常结束;length输出被max_tokens截断
response.usage.prompt_tokens # 输入消耗token
response.usage.completion_tokens # 输出消耗token
response.usage.total_tokens # 合计token
注意:如果开启
stream=True流式模式,直接返回的不是完整 response 对象,返回迭代器,.usage默认拿不到,要设置stream_options={"include_usage":True}。
stream_options配置项说明:流式输出相关选项,只有在 stream 参数为 true 时,才可设置此参数
include_usage:如果设置为 true,在流式消息最后的data: [DONE]之前将会传输一个额外的块。此块上的 usage 字段显示整个请求的 token 使用统计信息,而 choices 字段将始终是一个空数组。所有其他块也将包含一个 usage 字段,但其值为 null。
4.1 非流式输出
python
# 调用OpenAI API进行对话
response = client.chat.completions.create(
model="deepseek-v4-pro",
messages=messages,
stream=False
)
# 获取响应数据
ai_response = response.choices[0].message.content
# 更新消息列表中的消息
messages.pop(0)
messages.append({"role": "assistant", "content": ai_response}) # 加入当前 AI 回复
session_data["messages"] = messages
说明:为什么
pop(0)?messages 的结构目前是
[system提示,历史消息..,用户提问],但保存到文件时不需要存 system 提示词(它每次都是动态生成的,从模板拼出来的),所以删掉第 1 条,只保留纯对话记录。
4.2 流式输出
python
stream = client.chat.completions.create(
model="deepseek-chat",
messages=messages,
temperature=0.7,
max_tokens=1024,
stream=True, # 开启流式
stream_options={"include_usage": True} # 必须开启,否则拿不到usage
)
last_chunk = None # 保存循环的最后一个chunk,用于拿usage、request_id
for chunk in stream:
# 每一轮覆盖上一轮保存,循环结束后last_chunk就是网络收到的最后一包数据
last_chunk = chunk
# delta 是增量内容,只有新生成的一小段文字
delta = chunk.choices[0].delta
if delta.content:
# 实时打印,实现打字机效果
print(delta.content, end="", flush=True)
# 把增量拼接到完整字符串
full_ai_text += delta.content
print("\n") # 流式结束换行
# ⚠️ 重点:usage / request_id / finish_reason 全部在 last_chunk
# 从 last_chunk 中解析出所有需要的内容
request_id = last_chunk.id
model_name = last_chunk.model
finish_reason = last_chunk.choices[0].finish_reason
循环遍历所有 chunk,用变量保存
last_chunk = chunk,循环结束后,last_chunk 就是网络收到的最后一块数据包。token 消耗统计就在 last_chunk.usage。
- 额外:即使开启
stream_options={"include_usage":True},usage 也只会出现在最后一块 chunk,前面所有块依旧是 None。不写这个参数,流式模式下所有 chunk 的 usage 全是 None,拿不到消耗统计。
5、常见错误处理
代码中通过 try-except 结构捕获了几类与 API 调用相关的常见异常,这是保证程序健壮性的关键步骤。在实际使用过程中,你可能会遇到以下几类常见的异常:
APIConnectionError:连接 API 服务失败,通常是由网络连接不稳定、API 端点地址修改错误、本地防火墙或安全软件拦截了请求等原因导致的。此时需检查网络连接、确认base_url配置是否正确,以及本地安全软件的拦截规则。RateLimitError:请求频率超限或账户额度不足,触发了 DeepSeek API 的访问频率控制规则,或者你的账户剩余额度已不足以支撑本次请求。此时需检查控制台中的剩余额度,以及代码的请求频率是否太过密集。APIError:API 服务端返回了异常响应,通常会附带具体的错误码和错误信息。这类错误的原因很多,包括请求参数格式错误、模型不可用、请求的上下文长度超限等,需要根据返回的错误详情进一步排查。
关于更多的错误码及对应的处理方案,可参考官方「错误码」文档或相关技术博客。下面是总结的常见错误码及对应的处理建议:
| 状态码 | 含义 | 建议操作 |
|---|---|---|
200 |
请求成功,服务器已正常处理请求 | 解析并读取返回的响应内容 |
401 |
认证失败,通常是 API 密钥缺失、格式错误或已过期 | 检查 API 密钥的格式及有效性,确认密钥是否有足够的调用额度 |
403 |
权限不足,通常是 API 密钥没有对应模型或接口的调用权限 | 联系服务管理员,确认密钥的访问权限配置 |
429 |
请求频率超限或账户额度不足,触发了服务端的流控规则或额度限制 | 降低代码的请求频率,或等待配额重置后再重试 |
500 |
服务端内部错误,通常是 DeepSeek API 服务端出现了临时异常 | 等待一段时间后再重试,若多次重试仍失败,需联系官方技术支持排查 |
需要强调的是,异常处理是生产级代码中必不可少的部分,它可以让程序在遇到非预期情况时,优雅地输出错误日志或提示信息,而不是直接崩溃退出。
下一节-Python 连接 DeepSeek API,OpenAI 两种对话方式基础实现
免责声明:本文档中描述的 API 调用方法及相关代码示例,均基于 DeepSeek 官方文档和公开技术社区的讨论内容。在实际使用过程中,因 API 版本差异、服务端接口升级、账户权限配置等导致的程序异常或数据风险,本文作者及 DeepSeek 官方不承担任何责任。请务必先在测试环境中完成充分验证后,再将逻辑部署到生产环境中。
本文档的内容会随着 DeepSeek API 的版本迭代和功能升级而更新,最新版本请以官方文档的内容为准。
(注:文档部分内容可能由 AI 生成,注意辨别)