对话
POST /v1/chat/completions
在文本模型上创建一次对话补全。请求和响应兼容 OpenAI;同步返回——回复就在响应里(或流式返回,见下)。积分按预估 prompt 加上 min(max_tokens, default_max_tokens) 个输出 token 预留,调用结束时按实际用量结算;没有产生 token 则不扣费。
请求头
| 请求头 | 必填 | 说明 |
|---|---|---|
| Authorization | 是 | Bearer <API 密钥> |
| Content-Type | 是 | application/json |
| Idempotency-Key | 否 | 这里的 Idempotency-Key 是可选的。重复使用会返回 409 idempotency_key_reused. |
请求体
| 字段 | 类型 | 说明 |
|---|---|---|
| model | string | 必填。来自 GET /v1/models 的文本模型 id,例如 "qwen3.8-max"。 |
| messages | array | 必填。{role: "system" | "user" | "assistant", content: string | parts[]}。内容片段(text、image_url)与 OpenAI API 一致;image_url 仅在 vision: true 的模型上可用。 |
| max_tokens | integer | 回复上限。不超过模型的 max_output_tokens;默认为 default_max_tokens。推理 token 也计入其中。 |
| temperature | number | 0–2。默认取模型的 default_params。 |
| top_p | number | 0–1。 |
| stop | string[] | 最多 4 个停止序列。 |
| stream | boolean | 默认 false。设为 true → text/event-stream,见「流式输出」。 |
| enable_thinking | boolean | 扩展参数。作答前先推理,结果以 reasoning_content 返回。仅在 thinking: true 的模型上可用。 |
| web_search | boolean | 扩展参数。允许模型查阅网络。仅在 web_search: true 的模型上可用。 |
| reasoning_effort | string | none / minimal 关闭思维链,low … xhigh 开启。仅在 thinking: true 的模型上可用。 |
| tools | array | OpenAI 函数定义。仅在 tools: true 的模型上可用;见 工具调用。 |
| tool_choice | string | object | auto · none · required · {type: "function", function: {name}}。 |
| response_format | object | {type: "json_object"} 或 {type: "json_schema", json_schema: {name, schema}};见 结构化输出。 |
不支持——会以 400 拒绝,unsupported_parameter,绝不静默忽略: n > 1, functions (legacy), logprobs.
curl -s -X POST https://api.genmux.tech/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"qwen3.8-max","messages":[{"role":"user","content":"Explain idempotency keys in two sentences."}],"max_tokens":200}'响应 200 OK
{
"id": "0d8b6a3e-2f1c-4a5b-9c1d-7e2f3a4b5c6d",
"object": "chat.completion",
"created": 1756411279,
"model": "qwen3.8-max",
"choices": [
{"index": 0, "message": {"role": "assistant", "content": "An idempotency key is …"}, "finish_reason": "stop"}
],
"usage": {"prompt_tokens": 31, "completion_tokens": 58, "total_tokens": 89, "cost": 0.004, "cost_source": "vendor"}
}usage.cost 是本次扣除的积分(小数,最多 3 位);cost_source 在上游报告 token 数时为 "vendor","estimated" 表示是本地统计的。
限制
| 字段 | 限制 |
|---|---|
| max_tokens | 不超过模型的 max_output_tokens;默认取 default_max_tokens。若 prompt 长到没有空间生成回复,会返回 400 context_length_exceeded。 |
| stop | 最多 4 个字符串。 |
| temperature | 0–2。 |
| messages | 上下文窗口内任意数量的 system、user 和 assistant 轮次。image_url 部分仅在 vision: true 的模型上可用。 |
流式输出
设置 "stream": true 后,响应是 text/event-stream。每一行 data: 携带一个 chat.completion.chunk;最后一个分块的 choices 数组为空并带上 usage 块(含本次扣除的积分),流以此结束:data: [DONE].
curl -sN -X POST https://api.genmux.tech/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"qwen3.8-max","messages":[{"role":"user","content":"Explain idempotency keys in two sentences."}],"stream":true}'data: {"id":"0d8b6a3e-…","object":"chat.completion.chunk","model":"qwen3.8-max","choices":[{"index":0,"delta":{"role":"assistant","content":"An"},"finish_reason":null}]}
data: {"id":"0d8b6a3e-…","object":"chat.completion.chunk","model":"qwen3.8-max","choices":[{"index":0,"delta":{"content":" idempotency"},"finish_reason":null}]}
…
data: {"id":"0d8b6a3e-…","object":"chat.completion.chunk","model":"qwen3.8-max","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"id":"0d8b6a3e-…","object":"chat.completion.chunk","model":"qwen3.8-max","choices":[],"usage":{"prompt_tokens":31,"completion_tokens":58,"total_tokens":89,"cost":0.004,"cost_source":"estimated"}}
data: [DONE]若上游在流中途失败,会发送一帧错误代替 usage 分块,流仍以 [DONE] 结束;预留按实际生成的内容结算,GET /v1/generations/{id} 会显示最终费用。
data: {"error": {"code": "upstream_error", "message": "the model provider closed the connection"}}
data: [DONE]关闭连接即停止生成。中断前已生成的 token 会计费,其余不计。
OpenAI SDK
该接口使用 OpenAI 的 chat completions 方言,因此官方 SDK 无需改动即可使用:把 base_url 指向 https://api.genmux.tech/v1,并把你的密钥作为 api_key 传入。模型 id 用我们的(见 GET /v1/models),不是厂商的。
curl -s -X POST https://api.genmux.tech/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"qwen3.8-max","messages":[{"role":"user","content":"Explain idempotency keys in two sentences."}],"max_tokens":200}'import os
from openai import OpenAI
client = OpenAI(base_url="https://api.genmux.tech/v1", api_key=os.environ["API_KEY"])
completion = client.chat.completions.create(
model="qwen3.8-max",
messages=[{"role": "user", "content": "Explain idempotency keys in two sentences."}],
max_tokens=200,
)
print(completion.choices[0].message.content)
print(completion.usage.model_extra["cost"], "credits")
stream = client.chat.completions.create(model="qwen3.8-max", messages=[{"role": "user", "content": "Hi"}], stream=True)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
if chunk.usage:
print("\n", chunk.usage.total_tokens, "tokens,", chunk.usage.model_extra["cost"], "credits")import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://api.genmux.tech/v1", apiKey: process.env.API_KEY });
const completion = await client.chat.completions.create({
model: "qwen3.8-max",
messages: [{ role: "user", content: "Explain idempotency keys in two sentences." }],
max_tokens: 200,
});
console.log(completion.choices[0].message.content, completion.usage.cost);
const stream = await client.chat.completions.create({ model: "qwen3.8-max", messages: [{ role: "user", content: "Hi" }], stream: true });
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
if (chunk.usage) console.log(`\n${chunk.usage.total_tokens} tokens, ${chunk.usage.cost} credits`);
}支持:model、messages(system/user/assistant;视觉模型上的 image_url 部分)、max_tokens、temperature、top_p、stop、stream,以及作为额外请求体字段传入的扩展 enable_thinking 和 web_search。
同样支持:在 tools: true 的模型上使用 tools / tool_choice(见「工具调用」)、response_format 的 json_object / json_schema(见「结构化输出」)、reasoning_effort。会以 400 unsupported_parameter 拒绝:n > 1、旧版 functions 字段、logprobs。接受但忽略:stream_options、parallel_tool_calls、seed、user、metadata、store、logit_bias 以及 message 的 name。
从补全结果(同步)或最后一个分块(流式)读取 usage:cost 就是本次扣除的积分。
工具调用
在目录条目标注 tools: true 的模型上支持 OpenAI 函数调用。发送 tools + tool_choice(auto · none · required · {type: "function", function: {name}});回复会带上 message.tool_calls,finish_reason 为 tool_calls;用带有对应 tool_call_id 的 role: tool 消息把结果传回。函数调用由本 API 模拟实现——工具被渲染进 system prompt,回复再解析回来——因此线上格式与 OpenAI 完全一致,而模型本身从未见过原生的 tools 字段。
当前 tools: true 的模型:doubao-seed-2-pro, doubao-seed-2-code, kimi-k3, claude-opus-5-5, claude-fable-5-1, gpt-6-astra, gpt-5.6-terra, qwen3.8-max. 向其他模型发送 tools 会返回 400 tools_unsupported。
from openai import OpenAI
client = OpenAI(base_url="https://api.genmux.tech/v1", api_key="nb_live_...")
tools = [{"type": "function", "function": {"name": "get_weather", "description": "Weather by city",
"parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}}}]
r = client.chat.completions.create(model="qwen3.8-max",
messages=[{"role": "user", "content": "Weather in Paris?"}], tools=tools)
call = r.choices[0].message.tool_calls[0] # call.function.name == "get_weather"
# run your function, then send the result back:
r2 = client.chat.completions.create(model="qwen3.8-max", tools=tools, messages=[
{"role": "user", "content": "Weather in Paris?"},
r.choices[0].message,
{"role": "tool", "tool_call_id": call.id, "content": "18°C, cloudy"},
])
print(r2.choices[0].message.content){
"id": "0d8b6a3e-…",
"object": "chat.completion",
"model": "qwen3.8-max",
"choices": [
{"index": 0, "finish_reason": "tool_calls", "message": {"role": "assistant", "content": null,
"tool_calls": [{"id": "call_1", "type": "function", "function": {"name": "get_weather", "arguments": "{\"city\": \"Paris\"}"}}]}}
],
"usage": {"prompt_tokens": 96, "completion_tokens": 21, "total_tokens": 117, "cost": 0.003, "cost_source": "vendor"}
}设置 stream: true 后,调用会以 delta.tool_calls 分块到达——先是 index、id 和名称,然后是分片的参数——随后是一个 finish_reason 为 tool_calls 的分块和照常的 usage 分块。
data: {"id":"0d8b6a3e-…","object":"chat.completion.chunk","model":"qwen3.8-max","choices":[{"index":0,"delta":{"role":"assistant","tool_calls":[{"index":0,"id":"call_1","type":"function","function":{"name":"get_weather","arguments":""}}]},"finish_reason":null}]}
data: {"id":"0d8b6a3e-…","object":"chat.completion.chunk","model":"qwen3.8-max","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"city\": \"Paris\"}"}}]},"finish_reason":null}]}
data: {"id":"0d8b6a3e-…","object":"chat.completion.chunk","model":"qwen3.8-max","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}]}
data: {"id":"0d8b6a3e-…","object":"chat.completion.chunk","model":"qwen3.8-max","choices":[],"usage":{"prompt_tokens":96,"completion_tokens":21,"total_tokens":117,"cost":0.003,"cost_source":"estimated"}}
data: [DONE]限制
| 字段 | 限制 |
|---|---|
| tools | 最多 128 个定义,总量不超过 64 KiB。每个定义都会消耗 prompt token:约 40 个,外加它的 JSON schema。 |
| tool_choice | auto(默认)、none、required 或指定函数。required 和指定函数是模型通常会遵守的指令;小模型偶尔会改用自然语言作答。 |
| 并行调用 | 模型通常每轮只发一个工具调用;parallel_tool_calls 会被接受但忽略。智能体是循环工作的,多步任务依然能完成。 |
| strict | 接受但忽略——上游没有受约束解码。 |
| response_format | 不能与 tools 在同一个请求中同时使用。 |
| max_tokens | 超过 max_output_tokens 的值会被收敛,而不是拒绝。工具模型的默认回复预算是 8192 token。 |
结构化输出
传入 response_format,取值 {"type": "json_object"} 或 {"type": "json_schema", "json_schema": {"name", "schema"}}({name, schema},JSON Schema 2020-12),模型会被要求只用 JSON 作答。非流式回复会被校验:失败时 API 会把校验错误反馈给模型并自动重试一次;第二次仍失败则返回 502 json_invalid,两次尝试都计费。流式回复不做校验。response_format 与 tools 不能同时使用。
curl -s -X POST https://api.genmux.tech/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"qwen3.8-max",
"messages":[{"role":"user","content":"Extract the city and the date: meet me in Paris on 3 March"}],
"response_format":{"type":"json_schema","json_schema":{"name":"event",
"schema":{"type":"object","properties":{"city":{"type":"string"},"date":{"type":"string"}},"required":["city","date"],"additionalProperties":false}}}}'{"id": "…", "object": "chat.completion", "model": "qwen3.8-max", "choices": [{"index": 0, "message": {"role": "assistant", "content": "{\"city\": \"Paris\", \"date\": \"2026-03-03\"}"}, "finish_reason": "stop"}], "usage": {…}}