Python 连接 DeepSeek API,OpenAI

一、前期准备与环境校验

在正式编写代码前,我们需要确认基础环境配置是否正确,以及你是否拥有具备调用权限的 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 密钥,这是调用服务的唯一身份凭证。密钥的获取和校验流程如下:

  1. 若尚未创建密钥,需登录 DeepSeek 官方控制台,进入「API 管理」→「密钥中心」,点击「创建 API 密钥」按钮生成。生成后务必将密钥复制并保存在安全的本地位置 ------ 该密钥仅在创建时可见,关闭对话框后将无法再次查看,若遗失只能重新生成。
  2. 新用户注册登录 DeepSeek 平台后,账户会自动附赠一定的 Tokens 调用额度。请在控制台中确认该额度是否处于有效状态,若账户无剩余额度或额度已过期,API 调用将返回认证或权限类错误。
  3. 为了验证你的 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 这类本地环境配置文件来管理密钥。具体操作流程如下:

  1. 在你准备编写 Python 代码的项目根目录下,创建一个名为 .env 的无后缀文件。

  2. 在该文件中,以 键=值 的格式添加你的 DeepSeek API 密钥,以及 DeepSeek API 的官方端点地址(代码中会优先读取该环境变量,若未配置则自动使用默认地址,提升代码兼容性):

    bash 复制代码
    DEEPSEEK_API_KEY=你的实际API密钥
    DEEPSEEK_BASE_URL=https://api.deepseek.com
  3. 接下来,我们需要让 Python 代码从这个 .env 文件中读取配置信息。要实现这一功能,需要先在虚拟环境中安装 python-dotenv 库,它可以负责加载 .env 文件中的配置信息:

    bash 复制代码
    pip install python-dotenv
  4. 为了验证环境变量是否正常加载,可以编写如下测试代码,打印基础 URL 和密钥的前缀片段。如果读取失败,代码会默认使用官方的地址前缀,便于后续排查问题:

    python 复制代码
    import 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_KEYDEEPSEEK_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、核心参数说明

请求体中的参数会直接影响模型的回复内容和效果,正确设置这些参数是实现预期交互效果的前提。下面对代码中使用的核心参数进行详细说明:

参考:官方 Chat Completions API

3.1 必选参数

参数名 类型 说明 示例值
model string 指定要调用的模型名称,必须是 DeepSeek API 支持的模型 deepseek-chat
messages array 构造对话上下文的消息列表,是一个包含多个 JSON 对象的数组,每个 JSON 对象需包含 rolecontent 字段 [{"role": "user", "content": "你好"}]

model 参数指定了本次请求要调用的模型类型,不同模型的能力、适用场景及成本、速度存在明显差异。

messages 参数是构造对话上下文的核心,它是一个包含多个消息对象的数组,每个消息对象都有 rolecontent 两个必填字段。其中 role 字段用于指定消息的角色,它决定了模型的对话立场、回答风格和行为限制,支持的角色值有三个:

  1. system:系统角色,用于在对话开始前设定模型的身份定位、回答风格、行文约束和行为边界。这个角色的消息不会直接暴露给终端用户,但会引导模型的后续行为。
  2. user:用户角色,用于传递终端用户的实际提问或输入内容。
  3. 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 控制模型回复的创意性或随机性。取值范围为 02 之间的数字。值越高,回复越随机、越有创意;值越低,回复越保守、越确定 1.0
top_p float 控制模型回复的核心词汇候选范围,取值范围为 01 之间的数字。值越小,回复的词汇越精炼、越严谨;值越大,回复的词汇越丰富、越随机 0.95
stream boolean 控制是否启用流式输出。设置为 True 时,模型会以打字机效果,将回复内容分块实时返回;设置为 False 时,模型会在完整生成回复后一次性返回 False
stream_options Object 流式输出相关选项。只有在 stream 参数为 true 时,才可设置此参数

关于这些参数的细节及使用限制,可参考 DeepSeek 官方的「对话补全」API 文档,其中有详细的定义和说明。

参数调优建议:参数的调整没有绝对的标准,需要根据具体的业务场景需求来定制。不过,DeepSeek 官方提供了一套经过验证的参数设置最佳实践,可以作为调优的参考基准:

  • 代码生成、数学解题、逻辑推理类场景:需要模型给出精准、无偏差的结果,建议将 temperature 设置为 0.0top_p 设置为 1.0
  • 数据抽取、结构化分析类场景:需要模型基于给定数据生成结构化、规范的结果,建议将 temperature 设置为 1.0top_p 设置为 0.95
  • 通用对话、信息答疑类场景:需要模型给出自然、流畅的回复,建议将 temperature 设置为 1.3top_p 设置为 0.95
  • 多语言翻译类场景:需要模型给出语义精准、表达自然的结果,建议将 temperature 设置为 1.3top_p 设置为 0.95

需要特别注意的是,temperaturetop_p 参数不建议同时调整。这是因为两个参数的作用效果存在重叠 ------ 如果同时修改,模型输出的随机性或创意性的实际调整幅度可能超出预期,导致回复效果不符合业务需求。通常情况下,只需要调整其中一个参数,就可以实现对回复风格的有效控制。

4、返回值说明

整条链路:

  1. 发起请求拿到 response 对象;
  2. 从 response 提取内容、token 消耗、模型名等元数据;
  3. 业务处理(清洗、过滤、结构化、json 解析等);
  4. 保存:保存对话记录,可存 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

参考:官方 Chat Completions API

注意:如果开启 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 生成,注意辨别)

相关推荐
-凌凌漆-1 小时前
【freertos】Task创建(v2)
java·开发语言·算法
牛油果子哥q1 小时前
C++内存模型与深浅拷贝万字详解:栈堆静态内存布局、深浅拷贝底层差异、内存泄漏根治、拷贝崩溃踩坑、手写深拷贝实战
java·开发语言·c++
曹牧2 小时前
C#:函数参数指定默认值
开发语言·c#
intQ72 小时前
个人博客搭建过程
程序员·ai编程
特立独行的猫a2 小时前
AI 智能硬件:下一个风口的底层逻辑与产品机会
人工智能·ai·智能硬件·趋势·风口·机会
掘金酱2 小时前
Vibe作品广场首发挑战来啦!发布作品,赢富士拍立得等千元好礼
openai·ai编程·vibecoding
Lambert2812 小时前
Spring AI 2.0 升级实战:9 个破坏性变更逐条迁移
aigc·ai编程
打呵欠的猫2 小时前
我用 AI 写了一个"需求翻译器",产品的 PRD 直接变成开发任务清单
前端·ai编程
TechEdu2026062 小时前
[人工智能]SciPy在工程计算中的作用与实践
人工智能·ai·scipy