跳到正文
土土金API

从官方 API 或其他 OpenAI 兼容服务迁移:换地址和 Key,分批切流量,留好回滚

迁移到土土金 API,代码通常只改 base_url、api_key 和模型名;上线前要核对模型列表、流式输出、错误码和限流的差异,再按小流量、半量、全量分批切换,旧服务保留到稳定为止。本文给出迁移清单、按比例分流的代码和回滚办法。

迁移到土土金 API,代码通常只改三处:base_url 换成 https://www.tutujin.com/v1,api_key 换成在控制台创建的 Key,model 换成本站模型广场里的名字。真正要花时间的是上线前的核对和上线后的切换:先用模型列表接口确认模型都在,再核对流式输出、错误码和限流的差异,然后按小流量、半量、全量分批把请求切过来。原来的服务一直保留到全量稳定为止,分流比例放在配置里,出问题时调回 0 就是回滚。

迁移前先确认

要确认的怎么确认
用到的接口本站支持对照下面的接口表;用 Claude 或 Gemini 原生 SDK 的,也有对应的原生接口
模型都有,名字对得上用新 Key 调用模型列表接口,见下文第 2 步
费用心里有数在模型与价格查单价,估算方法见大模型 API 价格怎么算
分组选好了分组决定线路和价格,见如何选分组

本站支持的接口:

接口方法与路径状态模型数
Chat CompletionsPOST/v1/chat/completions已实测681
ResponsesPOST/v1/responses原样转发5
Claude MessagesPOST/v1/messages已实测49
Gemini generateContentPOST/v1beta/models/{model}:generateContent已实测63
图像生成POST/v1/images/generations原样转发54
图像编辑POST/v1/images/edits原样转发31
Embeddings 向量POST/v1/embeddings已实测18
Rerank 重排序POST/v1/rerank原样转发6
语音合成 TTSPOST/v1/audio/speech原样转发8
语音识别 STTPOST/v1/audio/transcriptions原样转发1
Midjourney 绘图POST/mj/submit/imagine原样转发13
Suno 音乐POST/suno/submit/music原样转发2

「已实测」表示我们在本站完成过真实调用与扣费核对;「原样转发」表示请求按原格式转发给模型服务,参数以对应模型的官方说明为准。模型数为当前目录中支持该接口的模型数量。

第 1 步:创建 Key,改地址

在控制台「令牌」页创建一把迁移专用的 Key,设好额度上限和分组。然后按你原来用的方式改配置:

原来的调用方式要改的地方改成
OpenAI SDK,或其他 OpenAI 兼容服务base_url / baseURL,或环境变量 OPENAI_BASE_URLhttps://www.tutujin.com/v1
Anthropic SDKbase_url / baseURLhttps://www.tutujin.com
Google Gen AI SDKhttp_options 里的 base_urlhttps://www.tutujin.com
直接发 HTTP 请求完整地址例如 https://www.tutujin.com/v1/chat/completions

api_key 一律换成本站的 Key。只改环境变量就能切过来的项目:

cURL
export OPENAI_BASE_URL="https://www.tutujin.com/v1"
export OPENAI_API_KEY="sk-你的Key"

三种请求头的写法和各 SDK 的完整配置,见认证与 Base URL。

第 2 步:核对模型名

用新 Key 调用模型列表接口,返回的就是这把 Key 能调用的模型:

cURL
curl https://www.tutujin.com/v1/models \
  -H "Authorization: Bearer $TUTUJIN_API_KEY"

把代码里用到的每个模型名和返回结果逐个对上。同一个模型在不同平台的叫法可能不一样,以本站的名字为准;对不上的,在代码里做一张映射表。返回里没有某个模型,多半是 Key 的分组不提供它,在模型详情页查它有哪些分组,见模型列表接口。

第 3 步:核对行为差异

接口格式兼容,但有几处行为要按本站的情况处理:

方面本站的情况代码里要做的
余额不足返回 403,错误码 insufficient_user_quota;OpenAI 官方返回的是 429把 403 单独处理:提醒充值,不要放进重试队列
分组里没有这个模型返回 503,错误码 model_not_found不要无限重试,换模型名或换分组
错误体error 对象里的 code 经常是空字符串,message 末尾带 request id按 HTTP 状态码判断,记录完整错误响应,排查时把 request id 发给客服
限流429,额度随线路和负载变化,不公布固定数字退避重试,设并发上限,见限流说明
流式输出Chat Completions 的流式输出已在本站实测;数据开始返回后出错,表现为流提前结束、收不到 data: [DONE]把没收到结束标记的流当作失败处理
参数支持非 OpenAI 模型对 response_format、tools、reasoning_effort 等参数的支持各不相同不支持的参数可能被忽略或返回 400,换模型后先用少量请求验证
用量字段响应的 usage 返回输入、输出 tokens,命中缓存时有缓存 tokens在你自己的系统里按 usage 记账,再和控制台核对

完整的状态码对照见错误码与重试,计费字段的说明见计费与用量。

第 4 步:分批切换

不要一次全量切换。按比例分流,每一阶段都看过数据再进下一阶段:

阶段发到本站的比例看什么进入下一阶段的条件
离线验证不接线上流量用一批真实的历史请求对比输出质量、延迟和花费结果可以接受
小流量5% 左右错误率、延迟、单次请求的花费稳定运行一段时间,没有新增的错误类型
半量50%同上,再看高峰时段有没有 429高峰期也稳定
全量100%同上稳定后再下线原来的服务

分流按用户或会话固定:同一个用户始终走同一边,对比效果、排查问题都更清楚。比例放在环境变量或配置中心里,调整和回滚都不用改代码:

import os
import zlib

from openai import OpenAI

tutujin = OpenAI(base_url="https://www.tutujin.com/v1", api_key=os.environ["TUTUJIN_API_KEY"])
legacy = OpenAI(base_url=os.environ["OLD_BASE_URL"], api_key=os.environ["OLD_API_KEY"])

# 原服务的模型名 → 本站的模型名,比如原平台的名字带厂商前缀
MODEL_MAP = {"openai/gpt-4.1-mini": "gpt-5.4-mini"}


def rollout() -> float:
    # 0 = 全部走原服务,1 = 全部走本站;每次读取,改配置立即生效
    return float(os.environ.get("TUTUJIN_ROLLOUT", "0"))


def chat(user_id: str, model: str, messages: list):
    bucket = zlib.crc32(user_id.encode()) % 100  # 同一个用户永远落在同一个桶
    if bucket < rollout() * 100:
        return tutujin.chat.completions.create(model=MODEL_MAP.get(model, model), messages=messages)
    return legacy.chat.completions.create(model=model, messages=messages)

Python 和 Node.js 两个版本对同一个用户算出的桶相同,两种语言的服务混用也能保持一致。每个阶段都在控制台「操作日志」里按令牌名称筛选这把迁移 Key,核对请求数、错误和花费,再和你自己系统里按 usage 记的账对一遍。

回滚

  • 发现问题,先把分流比例调回 0,请求立刻全部回到原来的服务,不用改代码、不用重新部署。
  • 全量之后,原来服务的账号和 Key 先别注销,保留到新服务稳定运行一段时间。
  • 回滚之后,用操作日志里的时间、模型和错误信息定位原因;需要我们协助时,把错误里的 request id 发给客服微信 JsnonoChat。

切换完成后

常见问题

迁移要改多少代码?

用 OpenAI SDK 的项目,一般只改 base_url、api_key 和模型名。另外要单独处理一个差异:余额不足时本站返回 403,不是 OpenAI 的 429,不能放进重试队列。

迁移期间能同时用原来的服务和土土金 API 吗?

能。分批切换时两边并行:按比例把一部分请求发到本站,其余照旧,确认稳定后再逐步提高比例。

模型名和原平台不一样怎么办?

以本站模型广场和模型列表接口返回的名字为准,在代码里维护一张模型名映射表,切换时按表替换。

本站的限流额度是多少?

不公布固定数字,额度随线路和负载变化。按退避重试和并发上限来设计调用;长期需要更高并发,加客服微信 JsnonoChat 说明模型、分组和请求规模。

出了问题怎么回滚?

把分流比例调回 0,请求就全部回到原来的服务。分流比例放在环境变量或配置中心里,回滚不用改代码、不用重新部署。