不墨 Router

发布于 2026 年 10 月 24 日 星期六

Qwen、GLM、MiniMax 一个 Key 切换:Python 按任务选模型

用 Python 标准库和一个 Router Key 调用 Qwen、GLM、MiniMax。示例按任务标签选择模型,区分业务路由、故障重试与质量评测。

Qwen、GLM、MiniMax 一个 Key 切换:Python 按任务选模型

用一个 Router Key 切换 Qwen、GLM、MiniMax,可以保留同一个接口地址,只改变请求里的 model。 如果希望“摘要走 A、校对走 B、草稿走 C”,在应用里用一个任务映射表就够了,不需要先搭建另一套网关。

以下例子用 Python 标准库发送 Chat Completions 请求。任务分配是演示规则,不是三款模型的能力排名,更不是 Router 会自动识别任务并替你选模型。

先复制真实的模型 ID

2026-10-24 核对 Router 模型接口 后,本文使用以下三个 ID:

  • Qwen:qwen/qwen3.8-flash。
  • GLM:glm/glm-5.3。
  • MiniMax:minimax/MiniMax-M3。

完整请求 URL 为 https://router.bumo.cc/v1/chat/completions。模型展示名、原厂 ID 与网关 ID 可能不同,MiniMax 的大小写也不要改。公开列表证明条目存在,不保证每个账号、每个时刻的推理请求都成功。

一份可以直接保存运行的 Python 示例

先在 Router 创建自己的 API Key。macOS / Linux 终端设置:

export BUMO_API_KEY="替换为你的RouterKey"

保存下面代码为 route_model.py。无需安装第三方依赖,使用 Python 3 运行;每次执行只发一条请求,不会依次调用三个模型。

import argparse
import json
import os
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen

MODELS = {
    "summary": "qwen/qwen3.8-flash",
    "review": "glm/glm-5.3",
    "draft": "minimax/MiniMax-M3",
}

parser = argparse.ArgumentParser()
parser.add_argument("task", choices=MODELS)
parser.add_argument("text")
args = parser.parse_args()
if not args.text.strip():
    parser.error("text 不能为空")

model = MODELS[args.task]
payload = {
    "model": model,
    "messages": [{"role": "user", "content": args.text}],
    "stream": False,
    "max_tokens": 2048,
}
request = Request(
    "https://router.bumo.cc/v1/chat/completions",
    data=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
    headers={
        "Authorization": "Bearer " + os.environ["BUMO_API_KEY"],
        "Content-Type": "application/json",
    },
    method="POST",
)
try:
    with urlopen(request, timeout=120) as response:
        result = json.load(response)
except HTTPError as error:
    detail = error.read().decode("utf-8", errors="replace")
    raise SystemExit(f"HTTP {error.code}: {detail}")
except (URLError, TimeoutError) as error:
    raise SystemExit(f"连接或超时错误:{error}")

choice = result["choices"][0]
print("requested_model:", model)
print("returned_model:", result.get("model"))
print("finish_reason:", choice.get("finish_reason"))
print(choice["message"].get("content") or "(没有最终文本,请检查输出预算)")
print("usage:", result.get("usage"))

分别试一个任务时,可使用以下命令。三行各自都是一次可能计费的调用,按需要选一行运行:

python route_model.py summary '请概括:这个 API 将多个模型统一在同一入口。'
python route_model.py review '检查这句话是否有歧义:所有请求都能立即完成。'
python route_model.py draft '写一段简短的版本更新通知,说明新增导出功能。'

代码中的 choices=MODELS 会拒绝未定义的任务标签,而不是静默切到一个默认模型。Key 只从环境读取;提交代码时不需要把 Key 一起提交。请求构造方式可对照 Python urllib.request 文档。

一把 Key 统一的是接入,不是模型行为

同一个 messages 结构减少了接入差异,但输出长度、分词、推理过程和工具调用仍有模型差别。这个示例只验证文本,没传图片、工具定义或强制 JSON Schema;不能把文本成功理解成这些能力也通过了验收。

max_tokens=2048 是示例上限,不保证每个任务都足够。先检查 finish_reason:若因长度停止,保留原始结果、调整任务范围或预算后再决定是否重跑。不要看到空正文就自动换贵模型,否则一个参数问题会变成持续增加的成本。

什么时候用固定模型,什么时候按任务路由

只做一种业务、样本很少时,固定一个模型更容易排错。出现两类明显不同的任务,并且手头有代表性样例后,再把映射表作为可评测的业务配置。

可以为每类任务整理 20 条脱敏样例,用三个模型各跑同样的输入,记录答案是否可用、请求耗时、token 用量、是否重跑。先写清“可用”标准:摘要是否漏掉金额与日期,校对是否改错事实,草稿是否符合长度和语气。不要用模型给自己的分数代替人工抽样判断。

最便宜的单次调用未必是最便宜的成功任务。比较成本时,分母用通过验收的任务数,分子合计所有尝试的费用;同一任务连续失败三次的支出也要算进去。

任务路由与故障重试要分开

任务路由发生在请求之前,回答“这类任务交给谁”。重试发生在错误之后,回答“这次失败是否值得再试”。上面示例没有自动重试,也没有自动切备用模型,避免把失败原因掩盖掉。

401、余额不足或格式错误,应先修正配置。临时限流可以在应用层设置有上限的退避;超时后服务端可能仍在生成,不能默认重发免费。如果以后增加备用模型,日志同时保存请求模型与响应模型,并对质量、单价和用户授权做约束。

验证范围: 三个 ID 已对照实时公开列表;示例通过语法检查及本地模拟 HTTP 的路径、鉴权、任务映射、成功与错误分支检查。未使用真实计费 Key 测试三款模型,也未据此宣称质量高低。

到 Router 获取 Key 和当前模型 ID,先选一个任务运行,再按自己的样例调整映射。

继续阅读