| 模型 | 请求 | 输入 | 输出 | 合计 tokens | 首字 | 速度 |
|---|
| 模型 id | 名称 | 上下文 | 输出上限 | 工具 | 图片 | 推理 | 实测速度 |
|---|
id 填进客户端的模型名即可调用;调用地址统一是你自己的网关,不需要区分厂商。本网关对外就是一个 OpenAI 兼容接口。任何能填「自定义 API 地址 + 密钥」的客户端、插件或你自己的代码, 都能接上——不需要装任何东西,不需要改 hosts,也不需要区分模型是哪个厂商的。
两个端点就够用了:
POST /v1/chat/completions — 对话(支持流式 stream:true、工具调用、多模态输入,协议与 OpenAI 完全一致)。GET /v1/models — 列出这把密钥可用的模型。请求体里 model 填下面「可用模型」表里的 id。密钥放在请求头,不要放进网址。
"stream": false)时,客户端在整段回答生成完之前
收不到任何一个字节,只能干等。本网关实测:解码速度中位 102 tok/s(这个不慢),
但第一个字到来之前平均要等 29 秒——长上下文要先做 prefill。开流式,这 29 秒里客户端能看到
连接是活的、字在逐段往外走;不开流式,完全相同的等待在用户眼里就是「卡死了」。
# 最小可跑示例(-N = 关掉 curl 自身的输出缓冲,否则看不到流式的效果)
curl -N … \
-H "Authorization: Bearer sk-wb-…" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.3",
"messages": [{"role": "user", "content": "你好"}],
"stream": true
}'
# pip install openai
from openai import OpenAI
client = OpenAI(
base_url="…/v1",
api_key="sk-wb-…",
# 首字可能等几十秒(长上下文),读超时别设 30s 以内
timeout=180.0,
)
# stream=True:边生成边收,别用非流式
with client.chat.completions.stream(
model="glm-5.3",
messages=[{"role": "user", "content": "你好"}],
) as s:
for ev in s:
if ev.type == "content.delta":
print(ev.delta, end="", flush=True)
// npm i openai
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "…/v1",
apiKey: "sk-wb-…",
timeout: 180000, // 首字可能等几十秒
});
// stream: true —— 边生成边收
const stream = await client.chat.completions.create({
model: "glm-5.3",
messages: [{ role: "user", content: "你好" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || "");
}
关于流式:把 "stream": true 传进去就是 SSE 流,事件格式与 OpenAI 一致
(data: {...} 分片,末行 data: [DONE])。各家客户端默认都是流式,不用额外配置。
如果某个客户端的回答总是「顿很久再一次性蹦出来」,那就是它把流式关了——去它的设置里找
「流式输出 / Stream / Typewriter effect」打开。
「接入自定义模型」在这套体系里就是两件事:知道有哪些 id,然后把它们写进客户端能读到的一份配置里。
(1)先拿模型清单。页面上「可用模型」那张表就是你这把密钥能调的全部模型; 也可以用接口取:
curl … \
-H "Authorization: Bearer sk-wb-…"
(2)写进 models.json。WorkBuddy / CodeBuddy 这一系客户端从
models.json 读模型表,格式如下(顶层数组或 {"models":[…]} 两种都认):
{
"models": [
{
"id": "glm-5.3",
"name": "GLM 5.3",
"vendor": "小羊wb工具",
"apiKey": "sk-wb-…",
"url": "…",
"maxInputTokens": 1000000,
"maxOutputTokens": 8192,
"supportsToolCall": true,
"supportsImages": false,
"supportsReasoning": true
}
]
}
字段含义:
| 字段 | 必填 | 说明 |
|---|---|---|
| id | 是 | 模型 id。请求里 model 写的什么,这里就写什么 |
| name | 否 | 客户端里显示的名字(中文可以,随便起) |
| vendor | 否 | 来源分组,一般统一填 小羊wb工具,方便一起管 |
| apiKey | 是 | 你本人的密钥,别贴给别人 |
| url | 是 | 填上面的对话接口全地址(到 /v1/chat/completions) |
| maxInputTokens | 否 | 上下文上限,按页面表格里的值填 |
| maxOutputTokens | 否 | 单次输出上限 |
| supportsToolCall | 否 | 是否支持工具调用(函数调用) |
| supportsImages | 否 | 是否支持图片输入 |
| supportsReasoning | 否 | 是否支持思维链 / 推理模式 |
放到哪:按下列顺序找,写进已经存在的那个目录;一个都没有就建第 2 条。
| 顺序 | Windows | macOS |
|---|---|---|
| 1 | %WORKBUDDY_CONFIG_DIR% / %CODEBUDDY_CONFIG_DIR% | $WORKBUDDY_CONFIG_DIR / $CODEBUDDY_CONFIG_DIR |
| 2 | %USERPROFILE%\.workbuddy | ~/.workbuddy |
| 3 | %USERPROFILE%\.codebuddy | ~/.codebuddy |
| 4 | %APPDATA%\CodeBuddy | ~/Library/Application Support/CodeBuddy |
| 5 | — | ~/Library/Application Support/WorkBuddy |
合并规则:已有 models.json 时按 id 合并——同名 id 以本网关为准,
你自己加的其它模型一条都不会丢。改完完全退出客户端(含托盘 / 菜单栏图标)再启动。
下面这些都是「填地址 + 填密钥」这一套路,差别只是入口在哪。凡是标注 兼容 OpenAI 的,都可以直接接。
"stream": true;读超时(timeout)设到 120s 以上,
别用默认的 30s——首字可能等几十秒(长上下文要先做 prefill)。models.json。用本页/一键配置页下载脚本双击运行即可,然后重启客户端。
配置目录见上一节那张表。…;
在模型列表里 Add model,名字填模型 id(如 glm-5.3)。
记得把其它内置模型关掉,避免走回官方。ANTHROPIC_BASE_URL=…、
ANTHROPIC_AUTH_TOKEN=sk-wb-…,
再配 ANTHROPIC_MODEL 为模型 id。…,API Key 填你的密钥,Model ID 填模型 id。…,密钥填你的;再到「模型」里添加要用的 id。…(有些客户端要求带 /v1),
Key 填你的密钥,模型名手填 id。…,密钥填你的,模型填一个便宜的 id 即可。…,Key 填你的,Model 填 id。base_url + api_key 两行。Python、Node、Go、Java、C# 的官方 SDK 都可以直接指向本网关。多模态(图片输入)——和 OpenAI 一样用内容数组,模型需支持图片(见「可用模型」表的“图片”列):
{
"model": "glm-5v-turbo",
"messages": [{
"role": "user",
"content": [
{ "type": "text", "text": "这张图里是什么?" },
{ "type": "image_url",
"image_url": { "url": "data:image/png;base64,iVBORw0…" } }
]
}]
}
工具调用(Function Calling)——照 OpenAI 的 tools 字段传,
返回的 tool_calls 也是同一结构,客户端 SDK 都认:
{
"model": "glm-5.3",
"messages": [{ "role": "user", "content": "北京现在几点?" }],
"tools": [{
"type": "function",
"function": {
"name": "get_time",
"description": "查询某城市的当前时间",
"parameters": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
}]
}
推理模式——支持推理的模型(见“推理”列)在流式返回里会带
reasoning_content 字段;客户端一般会自动折叠显示,不用手动处理。
上下文与输出上限——每个模型的 maxInputTokens /
maxOutputTokens 以「可用模型」表为准。超长请求会被上游拒绝,建议客户端就按表里的值配。
| 现象 | 多半是 | 怎么办 |
|---|---|---|
401 密钥无效 | 没填全、多了空格、或者用了面板的主密钥 | 回本页复制完整密钥(sk-wb- 开头,不要尾部空格) |
403 / 提示额度用完 | token 或调用次数额度用满 | 本页看「剩余 tokens」;已归零就找管理员加额 |
404 model not found | 模型 id 写错,或这把密钥没有该模型的权限 | 对照本页「可用模型」表,一字不差地填 id |
429 请求过频 | 短时间并发太高(多客户端共用一把密钥更常见) | 降并发;多设备建议各用各的密钥 |
502 / 503 上游不可用 | 厂商侧抖动或账号池暂无可用号 | 稍后重试;持续不通找管理员 |
| 连不上 / 超时 | 地址填错,或客户端要求带 /v1 而你少填了 | 确认填的是 …;需要 /v1 的客户端就填 …/v1 |
| 客户端里看不到模型 | 没重启,或写进了客户端不读的目录 | 完全退出(含托盘 / 菜单栏图标)再开;核对配置目录表 |
| 回复里出现别的模型名 | 客户端把请求发去了官方地址 | 检查 Base URL 覆盖是否生效,关掉同列表里的其它提供商 |
自查最快的一步:直接用上面的 cURL 示例打一条最小请求。
能通说明密钥与地址没问题,问题在客户端配置;不通就看返回体的 error.message。