客户端集成
把任意 OpenAI SDK 指向 Cordy Gateway——鉴权、流式、工具调用、嵌入、路由请求头与产品化扩展。
Cordy Gateway 使用 OpenAI API。任何能指定自定义 base_url 的客户端或 SDK,除了 URL 与密钥外无需改动代码即可工作。本页端到端展示常见集成模式。
连接
在你的客户端上设置两项:
- Base URL:
https://<host>:8002/v1(仅本地无 TLS 试用时使用http://)。 - API key: 一个以
wnx_为前缀的密钥,作为 bearer 令牌发送。
鉴权接受两种请求头之一:
Authorization: Bearer wnx_<key>
或
X-API-Key: wnx_<key>
标准 OpenAI SDK 会自动使用 Authorization: Bearer 形式。API 密钥必须放在请求头中——URL 查询串中的密钥不被接受。
Python
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["CORDY_API_KEY"], # wnx_...
base_url=os.environ["CORDY_BASE_URL"], # https://<host>:8002/v1
)
JavaScript / TypeScript
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.CORDY_API_KEY, // wnx_...
baseURL: process.env.CORDY_BASE_URL, // https://<host>:8002/v1
});
全文中,model 都是在 Admin 中配置的公开模型 slug,而非厂商模型名。
对话补全
非流式
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "你是一个简洁的助手。"},
{"role": "user", "content": "用一行话介绍 Cordy Gateway。"},
],
temperature=0.7,
max_tokens=256,
)
print(resp.choices[0].message.content)
const resp = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{ role: "system", content: "你是一个简洁的助手。" },
{ role: "user", content: "用一行话介绍 Cordy Gateway。" },
],
temperature: 0.7,
max_tokens: 256,
});
console.log(resp.choices[0].message.content);
每个对话请求都必须至少包含一条 user 消息;仅有 system 或仅有 assistant 的历史会以 400 被拒绝。
流式(SSE)
设置 stream=True 以在生成过程中接收服务端事件(server-sent events)。流以 [DONE] 哨兵结束。
stream = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "流式输出一首关于路由的短诗。"}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)
print()
const stream = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "流式输出一首关于路由的短诗。" }],
stream: true,
});
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content;
if (delta) process.stdout.write(delta);
}
若上游流在没有 finish reason 的情况下关闭,网关会在 [DONE] 之前发出一个带内的 stream_interrupted 错误事件,使客户端能区分正常结束与截断。路由请求头(X-Channel-Id、X-Provider、X-Failover-Count)在流式响应与非流式响应上均存在。
用 curl 查看原始 SSE:
curl -N "$CORDY_BASE_URL/chat/completions" \
-H "Authorization: Bearer $CORDY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini","stream":true,"messages":[{"role":"user","content":"hi"}]}'
工具 / 函数调用
工具调用使用标准的 OpenAI tools 与 tool_choice 字段。若传入 tool_choice,则也必须传入非空的 tools 列表。
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取某城市的当前天气。",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}
]
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "巴黎现在天气怎么样?"}],
tools=tools,
tool_choice="auto",
)
msg = resp.choices[0].message
if msg.tool_calls:
call = msg.tool_calls[0]
print(call.function.name, call.function.arguments)
const tools = [
{
type: "function",
function: {
name: "get_weather",
description: "获取某城市的当前天气。",
parameters: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"],
},
},
},
];
const resp = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "巴黎现在天气怎么样?" }],
tools,
tool_choice: "auto",
});
const msg = resp.choices[0].message;
if (msg.tool_calls) {
const call = msg.tool_calls[0];
console.log(call.function.name, call.function.arguments);
}
你可以把 assistant 消息回写进 messages(规范的多轮模式),把你的工具结果作为 role: "tool" 消息追加,再次调用以让模型使用该结果。
嵌入
emb = client.embeddings.create(
model="text-embedding-3-small",
input=["第一段文档", "第二段文档"],
)
print(len(emb.data), "个向量")
print(len(emb.data[0].embedding), "维")
const emb = await client.embeddings.create({
model: "text-embedding-3-small",
input: ["第一段文档", "第二段文档"],
});
console.log(emb.data.length, "个向量");
input 接受单个字符串或字符串数组。空输入会以 400 被拒绝。
仅支持文本
网关目前仅支持文本。对话消息的 content 可以是普通字符串,或一个 {"type": "text", "text": "..."} 分片数组(会被拼接)。任何非文本分片——image_url、audio 等多模态类型——都会以清晰的 400 错误被拒绝。请勿发送图像或音频。
产品化扩展
在 OpenAI 标准接口之外,网关还暴露只读的产品化接口,你的客户端可用同一密钥调用(它们需要 balance 作用域)。
余额与配额
curl -sS "$CORDY_BASE_URL/balance" -H "Authorization: Bearer $CORDY_API_KEY"
返回该密钥的令牌配额(quota_limit、quota_used、quota_remaining)以及所属用户的预付 credit_balance_usd。
订阅
curl -sS "$CORDY_BASE_URL/subscriptions" -H "Authorization: Bearer $CORDY_API_KEY"
返回用户的等级、套餐、订阅状态与功能摘要。
套餐目录
curl -sS "$CORDY_BASE_URL/packages" -H "Authorization: Bearer $CORDY_API_KEY"
返回平台套餐的只读目录(等级、配额上限、定价)。
用量分析
curl -sS "$CORDY_BASE_URL/account/analytics?period_days=30" \
-H "Authorization: Bearer $CORDY_API_KEY"
返回已鉴权用户自身在一个滚动窗口内聚合的用量、时延与成本。period_days 接受 1–365(默认 30);越界值会被夹取。注意:此接口仅在 /v1 前缀下可用。
请求头
你可以按请求影响路由与可靠性:
| 请求头 | 取值 | 作用 |
|---|---|---|
X-Routing-Strategy | weighted、cheapest、fastest、region_aware | 覆盖本请求的路由策略。 |
X-Region | 区域代码,例如 us-east | 为 region_aware 路由设置调用方区域。 |
Idempotency-Key | 任意唯一字符串 | 为 POST 提供重放保护:TTL 内的重复请求返回已存响应,而不再次调用上游。也接受 X-Idempotency-Key。 |
示例——最便宜路由 + 幂等键:
curl -sS "$CORDY_BASE_URL/chat/completions" \
-H "Authorization: Bearer $CORDY_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Routing-Strategy: cheapest" \
-H "Idempotency-Key: order-4711-attempt-1" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"hi"}]}'
用 OpenAI SDK 传自定义请求头:
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "hi"}],
extra_headers={"X-Routing-Strategy": "fastest"},
)
const resp = await client.chat.completions.create(
{ model: "gpt-4o-mini", messages: [{ role: "user", content: "hi" }] },
{ headers: { "X-Routing-Strategy": "fastest" } },
);
响应头
成功响应包含可供你记录或呈现的可观测性请求头:
| 请求头 | 含义 |
|---|---|
X-Channel-Id | 服务本请求的通道。 |
X-Provider | 所用的上游供应商。 |
X-Failover-Count | 成功前尝试了多少个通道。 |
X-Routing-Overhead-Ms | 路由所耗时间,不含上游调用。 |
X-Idempotency-Status | 重放了已存响应时为 hit;未适用幂等时为 skipped。 |
错误处理
错误使用 OpenAI 风格的信封:{"error": {"type", "message", "code", ...}}。你的客户端应显式处理的有:
402 insufficient_credits——账户预付信用耗尽。应停止并充值,而非重试;重试会同样失败。429带code: quota_exceeded(月度令牌配额)或速率限制码——退避后稍后重试,或提高上限。401——密钥缺失、无效、已吊销、未激活或已过期。不要用同一密钥重试。403 scope_denied——密钥缺少该接口的作用域。签发一个具备正确作用域的密钥。503 auth_service_unavailable——瞬时的鉴权基础设施问题。遵循Retry-After并重试。
完整错误表见 API 参考。
关于 Cordy 客户端应用的说明
Cordy 自家的终端用户客户端应用是独立产品。它们可选择性地将某个 Cordy Gateway 部署指定为后端,但并非必需——如上所示,任何兼容 OpenAI 的客户端都可直接对网关工作。