OpenAI SDK 调用 DeepSeek:从 HTTP 原理到项目实践
适用:W04首次接入,W05流式对话,W06知识库回答,W07动作规划,W08工作流解释节点。
先分清三个名字
SDK(Software Development Kit,软件开发工具包)在这里是一套模型调用客户端。安装 openai 并不意味着调用 OpenAI 的模型;本课程仍使用 DeepSeek 的服务地址、模型和密钥。SDK 帮我们发送请求、接收响应和分类异常;业务校验、工具权限、人工审批和费用控制仍由项目负责。
HTTP原理:业务代码 → 手写认证Header与JSON → HTTP请求 → DeepSeek
SDK实践:业务代码 → OpenAI客户端 → HTTP请求 → DeepSeek
共同验收:响应完整 → 读取用量 → 业务校验 → 展示或拒绝W04用同一消息对照两种方式,后续模型调用以SDK为主。保留HTTP知识是为了能查请求地址、参数和状态码,不要求每周重写一套网络客户端。
先安装和验证,再填配置
进入自己的项目目录,用TRAE选中该周虚拟环境;没有虚拟环境时先按已学步骤创建并选择解释器。
python -m pip install "openai==2.26.0"
python -m pip check
python -c "import sys, openai; print(sys.executable); print(openai.__version__)"本轮验证版本是2.26.0,不表示最新版;整周安装优先遵循该周requirements或锁文件,不自行升级其他依赖。SDK和HTTP底层库的版本应一起验证。
运行时填写环境变量,不把真实Key写入代码、截图、日志或Git:
$env:DEEPSEEK_API_KEY = "在本机填写,不发群聊"
$env:DEEPSEEK_MODEL = "填写实验卡中当前可用的模型名"执行真实调用前,核对模型可用性、余额、输入内容和输出上限。不要复制过期模型名或费率;费用是服务商收取的调用费用,使用SDK不会免除费用。W04已有被Git忽略的本地TOML配置仍供性能演示使用,本次不读取或改写其中的密钥。
同一条消息,两种写法
先预测:改用SDK后,请求最终发给谁?返回的正文、Token用量和失败状态是否还需要我们处理?
下面两段是最小通信对照,不是完整客服实现。每次运行一段都会发起一次真实请求;课堂先用离线替身演示,不要为比较语法重复消耗额度。
# 共同输入:模型来自当前实验卡,Key来自本机环境。
import os
import httpx
from openai import OpenAI
key = os.environ["DEEPSEEK_API_KEY"]
model = os.environ["DEEPSEEK_MODEL"]
messages = [{"role": "user", "content": "查询订单前需要提供什么?"}]HTTP原理示例:
with httpx.Client(timeout=30, follow_redirects=False) as client:
response = client.post(
"https://api.deepseek.com/chat/completions",
headers={"Authorization": "Bearer " + key},
json={"model": model, "messages": messages, "max_tokens": 128},
)
response.raise_for_status()
body = response.json()
print(body["choices"][0]["message"]["content"])SDK实践示例:
with OpenAI(api_key=key, base_url="https://api.deepseek.com",
timeout=30, max_retries=0) as client:
response = client.chat.completions.create(
model=model, messages=messages, max_tokens=128,
)
print(response.choices[0].message.content)
print(response.usage) # None表示服务端未提供,不是零消耗。| HTTP里看到的内容 | SDK里对应什么 | 仍需本人检查 |
|---|---|---|
| URL与认证Header | base_url、api_key | 指向DeepSeek,不是默认OpenAI服务 |
| JSON请求体 | create的命名参数 | model、messages、输出上限与业务条件 |
| 返回JSON | 带类型的响应对象,也可model_dump为字典 | finish_reason、正文类型、业务字段和usage |
| 状态码/连接异常 | APIStatusError、APITimeoutError、APIConnectionError | 是否重试、记录什么、如何安全提示 |
客户端对象不等于业务Provider Adapter。Adapter要继续把SDK结果翻译成课程已约定的结果,不把SDK对象直接塞进订单或会话状态。
参数和默认行为:这几处要看懂
max_retries=0:关闭SDK自动重试,避免一次课堂操作悄悄变成多次付费请求。是否允许重试由应用结合业务决定,写操作更不能直接重试。timeout=30:配置网络等待上限,不等于端到端业务总时限。W05还检查流式处理经过的时间;阻塞读取受网络超时控制。max_tokens:限制输出,不代表输入免费,也不代表账户硬预算。- DeepSeek特有字段通过
extra_body传入,例如extra_body={"thinking": {"type": "disabled"}};兼容接口不意味着所有模型支持所有参数。 response_format={"type": "json_object"}只约束JSON形式;金额、引用、允许的动作仍需业务代码检查。- 不把原始异常正文直接打印到学生屏幕:服务端错误可能包含请求信息。只记录安全错误类别和状态码,不输出Key。
W05:为什么流式不能只检查“收到了一些文字”
SDK常见写法 create(stream=True) 返回分块迭代器,正文通常从 chunk.choices[0].delta.content 读取;usage可能在没有choices的最后一块出现,不能用分块数量猜Token。
本课程既有要求还需要明确核对服务结束标记。普通分块迭代会隐藏 [DONE],因此当前Adapter使用公开入口 chat.completions.with_streaming_response.create(stream=True, ...),通过 response.iter_lines()检查SSE(服务器发送事件)行,再翻译成既有五种课堂事件。
完成必须同时看到有效正文、finish_reason=stop、[DONE];截断或缺结束标记返回ERROR。用户取消要关闭生成器和网络响应,记录本地CANCELLED,不提交最终assistant消息,也不新增第六种事件。用量缺失保持未知,取消不等于服务端未计费。
W06–W08:SDK只替换通信,不替换业务责任
- W06:先检查检索证据,再调用SDK;空证据零调用,模型伪造引用仍被拒绝。向量编码继续使用原有编码器,不能拿聊天客户端替代Embedding模型。
- W07:SDK返回的是不可信动作候选,Engine继续检查三工具范围、预算、停止与人工审批。SDK不获得创建工单权限。
- W08:图的筛选、状态、审批与恢复不变;显式开启SDK解释依赖时,模型只选择已有商品与用户偏好中匹配的事实,再由程序验证并渲染价格和引用。它是受限解释,不是自由推荐或算法评分。
- W08原有路由与售后流程默认仍走教学Fixture/Replay;接入一个真实解释节点不能证明全图已接真实服务,也不能替代Docker或新进程恢复验收。
迁移前后怎样证明没有退步
| 故障/风险 | 怎样发现 | 怎样处理与复验 |
|---|---|---|
| 装错解释器 | 打印解释器路径和SDK版本 | 选对虚拟环境后重装,运行pip check |
| 地址或认证错误 | 离线401测试与安全错误类别 | 检查本机配置,不展示Key;离线测试确认只有一次请求 |
| 自动重试导致调用变多 | HTTP替身统计429/超时请求数 | 显式max_retries=0,再断言一次动作一次请求 |
| 流中断却保存了最终回复 | 模拟缺DONE和用户取消 | 检查ERROR/CANCELLED、零最终提交及响应关闭 |
| 用量缺失被当成免费 | 去掉响应usage字段 | 保留未知,不生成零费用结论 |
| 换SDK后业务校验消失 | 输入伪造引用、未知工具、错误商品特征 | 保留原验证器,运行正常与反例测试 |
耗时仍用单调时钟测量;非流式总耗时、首段正文等待、整条业务链耗时分别记录。SDK解析开销也包含在实际调用耗时内,不能把离线替身结果当成真实性能提升。费用用真实usage乘当前已核实费率;模型或费率不匹配时保留待核对。
课后自己解释
- 为什么安装openai仍能使用DeepSeek?如果忘记base_url会怎样?
- SDK自动重试、Agent重规划和业务工单幂等分别解决什么问题?
- 看到stop但没有结束标记,为什么不能提交最终回复?
- 换SDK后,哪些业务测试应该一行不改仍然通过?
官方参考:DeepSeek首次调用;OpenAI Python客户端用法与错误处理。本页安装版本以本轮离线验证为准,真实服务仍需本人补验。