用 OpenAI SDK 调 DeepSeek、Qwen 和 GLM:只改一个 base_url
2 分钟阅读作者 genmux API Team
如果你的代码里已经在调用 openai.chat.completions.create(...),那么通过 genmux 切到 DeepSeek、Qwen3 或豆包只是两行改动:把 base_url 指向 https://api.genmux.tech/v1,再换一把 API 密钥。往下的一切——请求结构、响应结构、流式——都保持不变。本文是「OpenAI 兼容」在这里究竟覆盖了什么的逐字段参考。(GLM 和 Kimi 因上游修复暂时下架——同时也会有更多模型陆续上线。)
两行完成迁移
from openai import OpenAI
client = OpenAI(
base_url="https://api.genmux.tech/v1", # was https://api.openai.com/v1
api_key="nb_live_...", # your genmux key
)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.genmux.tech/v1",
apiKey: process.env.GENMUX_API_KEY,
});在这之后的每一次调用,看起来都和对着 OpenAI 自家 API 时一模一样——方法名相同、响应对象相同——只是 model 指向 genmux 的某个 id。从 v0.4.0 起,这也包括函数调用和 JSON 模式,正是它们让这个接口可以直接作为编程智能体的后端。
支持哪些字段
POST /v1/chat/completions 接受这些标准字段:
| 字段 | 是否支持 | 说明 |
|---|---|---|
model | 支持 | 价格表里的任意 id,例如 deepseek-v4-pro、qwen3-max、doubao-seed-2-pro,以及后续上线的更多模型 |
messages | 支持 | role: system | user | assistant、content |
max_tokens | 支持 | 决定预留额度;超过模型 max_output_tokens 的值会被收敛,而不是拒绝 |
temperature、top_p、stop | 支持 | 标准采样控制 |
stream | 支持 | 服务端推送事件;最后一个分块携带 usage;工具调用以 delta.tool_calls 到达 |
tools、tool_choice | 支持,7 个模型 | 函数调用,由 genmux 模拟实现;assistant 的 tool_calls 和 role: tool 消息的往返与 OpenAI 一致。其他模型返回 400 tools_unsupported |
response_format | 支持 | json_object 和 json_schema({name, schema});非流式回复会被校验,自动重试一次,之后返回 502 json_invalid。不能与 tools 同时使用 |
reasoning_effort | 支持 | 在支持思维链的模型上,none/minimal 关闭思维链,low…xhigh 开启 |
enable_thinking | genmux 扩展 | 仅支持思维链的模型(见下文) |
web_search | genmux 扩展 | 仅 Doubao Seed 2.0 Pro |
函数调用与 JSON 模式
tools 在 GET /v1/models 中标记 params_schema.tools: true 的七个模型上可用:deepseek-v4-pro、deepseek-v4-flash、deepseek-v3、qwen3-7-max、qwen3-max、doubao-seed-2-pro 和 doubao-seed-2-code。上游网关会丢掉 tools 字段,所以 genmux 把这些定义渲染进 system prompt,再把回复解析回标准的 tool_calls——这些定义会计入 prompt token(每个工具约 40 个,外加 schema),而 tool_choice: required 只是一条模型可能忽略的指令。把 tools 发给 qwen3-6-flash、doubao-seed-2-lite 或 doubao-seed-2-mini 会返回 400 tools_unsupported。实现细节和实测通过率见工具调用那篇。
response_format 接受 {"type":"json_object"} 和 {"type":"json_schema","json_schema":{"name":…,"schema":{…}}}。非流式回复会按 JSON Schema 2020-12 校验;失败会把校验器的错误反馈回去自动重试一次,第二次仍失败则以 502 json_invalid 结束,两次尝试都计费。流式响应不做校验,且 JSON 模式不能与 tools 出现在同一个请求里。
哪些不支持
有三样东西会返回 400 unsupported_parameter,而不是被静默忽略:
n > 1——每个请求只返回一个补全。- 旧版
functions——请用tools;已废弃的functions/function_call组合会被拒绝。 logprobs——没有任何上游返回它。
以下会被接受但忽略,好让旧的客户端代码继续能跑:stream_options、parallel_tool_calls、seed、user、metadata、store、logit_bias,以及每条消息上的 name。
读取用量和费用
响应是标准的 chat.completion(或一串 chat.completion.chunk),在 usage 上扩展了计费字段:
{
"id": "gnx_9f2c...",
"object": "chat.completion",
"model": "qwen3-max",
"choices": [{ "index": 0, "message": { "role": "assistant", "content": "..." }, "finish_reason": "stop" }],
"usage": {
"prompt_tokens": 128,
"completion_tokens": 342,
"total_tokens": 470,
"cost": 0.276,
"cost_source": "vendor"
}
}id 就是 genmux 的任务 id——如果你用不上,OpenAI SDK 会直接忽略它;但你想事后用 GET /v1/generations/{id} 查这次调用,或用 GET /v1/generations?capability=text.chat 列出账户下所有对话调用时,它就在那里。cost 的单位是积分;cost_source 在上游上报了精确用量时是 vendor,在由 genmux 按 token 数算出来时是 estimated(流式调用总是后者)。
值得显式处理的错误
对话路由上的错误采用 OpenAI 的结构——{"error":{"message","type","code","param","request_id"}},type 取值为 invalid_request_error、authentication_error、permission_error、insufficient_quota、rate_limit_error、not_found_error、server_error 之一——所以 OpenAI SDK 的异常类可以原样对应上。(genmux 的其他路由仍使用 RFC 7807 的 problem+json。)
| 状态码 | Code | 含义 |
|---|---|---|
| 400 | unsupported_parameter | 发送了上文列出的被拒字段之一(n>1、functions、logprobs) |
| 400 | tools_unsupported | 向三个没有该标志的模型之一发送了 tools |
| 400 | context_length_exceeded | prompt + max_tokens 超出模型的上下文窗口 |
| 402 | insufficient_credits | 余额不足以覆盖预留;没有生成任何内容,也没有计费 |
| 502 | json_invalid | JSON 模式的回复两次都没通过 schema 校验;两次尝试都计费 |
思维链,如果模型支持的话
enable_thinking 在 DeepSeek V4(Pro 和 Flash)、Qwen3.7-Max、Qwen3-Max,以及 Doubao Seed 2.0 Pro/Code/Lite 上可用,后续上线的模型也会陆续支持——发给不支持推理的模型会被直接忽略。推理 token 按 completion token 计费;在高流量接口上打开它之前,先看思维链是怎么计费的。
流式格式不变
stream: true 返回的 SSE 格式,正是你的 OpenAI 集成已经在解析的那一种——data: {...}\n\n 行,以 data: [DONE] 收尾。唯一要补的一点:[DONE] 之前的最后一个分块 choices 数组为空、usage 对象有值,那才是你的费用统计该读的地方。Python 和 Node 的完整解析代码见流式指南。
开始使用
改一下 base_url,换上 genmux 的密钥,你 OpenAI 集成的其余部分就继续能跑——包括工具调用和 JSON 模式,只要它没有依赖 n>1、旧版 functions 或 logprobs。各智能体(OpenCode、aider、Cline、Roo Code、Continue)的配置见编程智能体页面。完整接口说明和当前模型目录见文档;各模型价格见价格页。