DeepSeek API 用与 OpenAI 兼容的格式,理论上把 base_url 换成 api.deepseek.com、换上自己的 key,现有 OpenAI SDK 代码就能跑。但真用起来,几个和 OpenAI 不一样的地方会让人踩坑。这篇按官方文档把最常见的误区捋一遍。
base_url 与 /v1 前缀
官方文档明确写了一点容易误读的地方:为了兼容 OpenAI,base_url 也可以写 api.deepseek.com/v1,但这个 v1 和模型版本没有任何关系,只是为了匹配 OpenAI SDK 默认路径。别看到 v1 就以为在调某个 v1 模型。
模型名的分工
deepseek-chat 和 deepseek-reasoner 两个名字,对应的是同一个模型 DeepSeek-V3.2 的两种模式:chat 是非思考模式,reasoner 是思考模式,上下文长度都是 128K。日常的对话、生成、抽取用 deepseek-chat;需要多步推理、复杂代码、数学这类重活再上 deepseek-reasoner。判断标准很简单:默认 chat,只有明显需要推理的回合才切 reasoner——思考模式输出里带着思考过程,token 消耗更高。
from openai import OpenAI
client = OpenAI(api_key="你的 key", base_url="https://api.deepseek.com")
resp = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": "用一句话解释 RAG"}],
stream=False,
)
print(resp.choices[0].message.content)
reasoner 的 reasoning_content
用 deepseek-reasoner 时,响应里除了 content(最终答案),还有一个 reasoning_content 字段,装着模型的思考过程。很多人只取 content,把思考内容丢了——这在流式场景里最容易漏:reasoning_content 也是分片流式返回的,得在循环里一并拼起来。反过来,如果只要答案,思考过程可以忽略,但它能帮你判断模型有没有跑偏。
流式输出的拼接
设 stream=True 之后,返回的是逐片增量。下游还要用完整文本的话,得自己在循环里累加。做流式 UI 时别依赖片段的边界去改状态,自己按内容类型发结构化事件更稳。
stream = client.chat.completions.create(
model="deepseek-chat",
messages=[{"role": "user", "content": "写一段简介"}],
stream=True,
)
buf = []
for chunk in stream:
delta = chunk.choices[0].delta.content or ""
buf.append(delta)
print(delta, end="", flush=True)
full = "".join(buf)
JSON 输出的前提
要模型稳定返回 JSON,用 response_format 指定 json_object,但官方有个硬性要求:prompt 里必须出现 json 这个词,否则会报错。另外用 json_object 时,输出里不要混入多余的解释文字,配合合理的 system 提示约束结构更稳。
自动上下文缓存
DeepSeek 会自动做磁盘级的前缀缓存:重复的输入前缀(比如固定的 system 提示、长文档、few-shot 示例)命中缓存后,按更低的 cache-hit 价计费,不需要改任何代码或加 header。这对「长 system 提示 + 短用户输入」的对话、批处理同构请求这类工作负载,省的是实打实的成本。代价是前缀要稳定——前缀一变,缓存就失配。
函数调用与迁移成本
DeepSeek 的函数调用走 OpenAI 兼容的 tools 参数,迁移时几乎不用动代码。从 OpenAI 切过来的改动,官方口径就是两行:base_url 换成 api.deepseek.com、换 key,模型名改成 deepseek-chat 或 deepseek-reasoner,聊天、流式、函数调用都不需要额外改。真正要留意的,是模型能力上的差异——reasoner 的思考模式 token 消耗更大,同一个「带思考」的调用,成本结构跟 OpenAI 的 reasoning 模型不完全一样,迁移后要重新估量。
并发与成本
官方没有默认的硬性限速,容量是共享的,高峰时段可能被降速,企业可以申请专用配额。成本上按 token 计费、无月租无座席费,从预付余额后付扣款。控制成本的关键是两处:默认用 chat 而不是 reasoner(思考 token 更贵),以及尽量让请求前缀稳定以吃满缓存命中。