渡 AI
← 返回博客
· 渡 AI 团队 迁移OpenAISDK实战

从 OpenAI 官方 SDK 迁移到中转:5 分钟搞定,附完整代码示例

国内开发者怎么把已有的 OpenAI Python / Node.js / Go 代码无缝切到 渡 AI 中转?改 base_url 一行的事,但有几个坑要避开。

一句话:改一行 base_url + 换一个 API Key,其余代码完全不动。但流式、Function Calling、Vision 这三类调用要看清楚。

很多团队迁移卡在”是不是要重写”。答案是不需要。OpenAI 与 Anthropic 官方 SDK 都把 base_url 设成了可配置参数,我们的中转 100% 协议兼容。

Python

# 改之前
from openai import OpenAI
client = OpenAI(api_key="sk-proj-xxxxxxxx")

# 改之后
from openai import OpenAI
client = OpenAI(
    api_key="sk-xxxxxxxx",                           # 你的 渡 AI Key
    base_url="https://api.tathr.com/v1",      # 我们的端点
)

# 其余代码完全不变
resp = client.chat.completions.create(
    model="gpt-5",
    messages=[{"role": "user", "content": "你好"}],
)

推荐做法:把 api_keybase_url 都从环境变量读:

import os
client = OpenAI(
    api_key=os.environ["LLM_API_KEY"],
    base_url=os.environ.get("LLM_BASE_URL", "https://api.openai.com/v1"),
)

这样测试环境用我们的中转、CI 里跑官方、生产再切回中转,都不用改代码。

Node.js / TypeScript

import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.LLM_API_KEY,
  baseURL: 'https://api.tathr.com/v1',  // 注意 baseURL(驼峰)
});

const completion = await client.chat.completions.create({
  model: 'claude-sonnet-4-6',
  messages: [{ role: 'user', content: '写一首诗' }],
});

Go

import "github.com/sashabaranov/go-openai"

config := openai.DefaultConfig("sk-xxxxxxxx")
config.BaseURL = "https://api.tathr.com/v1"
client := openai.NewClientWithConfig(config)

LangChain / LlamaIndex

# LangChain
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
    model="gpt-5",
    openai_api_key="sk-xxxxxxxx",
    openai_api_base="https://api.tathr.com/v1",
)

# LlamaIndex
from llama_index.llms.openai import OpenAI as LIOpenAI
llm = LIOpenAI(
    model="claude-opus-4-7",
    api_key="sk-xxxxxxxx",
    api_base="https://api.tathr.com/v1",
)

Anthropic Python SDK(如果你想用原生协议)

我们也支持 Anthropic 原生协议,base_url 不同:

from anthropic import Anthropic

client = Anthropic(
    api_key="sk-xxxxxxxx",                            # 同一个 渡 AI Key
    base_url="https://api.tathr.com/anthropic",
)

resp = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=1024,
    messages=[{"role": "user", "content": "你好"}],
)

何时用 OpenAI 兼容协议、何时用 Anthropic 原生?

  • 90% 场景用 OpenAI 兼容 —— 一套代码两家模型通吃。
  • 需要 Claude 独有特性时用原生:cache_control 显式标记、thinking 模式、tool_choice: any

三个常见迁移坑

坑 1:流式 SSE 的 data: 前缀

OpenAI 流式响应每行是 data: {...},结束以 data: [DONE]我们完全一致,但如果你用了自己手写的 fetch + ReadableStream(没用 SDK),注意:

  • 行尾可能是 \n 也可能是 \r\n,要兼容。
  • [DONE] 不是 JSON,别 JSON.parse 它。
  • 中间可能有空行(heartbeat),跳过即可。

直接用官方 SDK 的 stream=True 就不用管这些。

坑 2:Function Calling 的 schema

OpenAI 的 tools 数组和 Anthropic 的 tools 数组结构不一样

// OpenAI 风格(兼容协议下统一用这个)
{
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_weather",
      "parameters": { "type": "object", "properties": {...} }
    }
  }]
}

// Anthropic 原生
{
  "tools": [{
    "name": "get_weather",
    "input_schema": { "type": "object", "properties": {...} }
  }]
}

走 OpenAI 兼容协议时,所有模型(包括 Claude)都用 OpenAI 风格。我们内部会翻译。

坑 3:模型名要严格一致

不要写 gpt5GPT-5gpt-5.0,必须严格 gpt-5。错误会返回:

{ "error": { "code": "model_not_found", "message": "The model `gpt5` does not exist" } }

完整模型名列表见 模型矩阵

测试迁移是否成功

最简单方式:把你现有的一个 e2e 测试跑两次,一次用官方端点、一次用我们的端点,对比结果。

import os
from openai import OpenAI

def test_chat(base_url, api_key):
    client = OpenAI(api_key=api_key, base_url=base_url)
    resp = client.chat.completions.create(
        model="gpt-5-mini",
        messages=[{"role": "user", "content": "1+1=?"}],
        max_tokens=10,
    )
    return resp.choices[0].message.content

print(test_chat("https://api.openai.com/v1", os.environ["OPENAI_KEY"]))
print(test_chat("https://api.tathr.com/v1", os.environ["DUAI_KEY"]))

两个都应该返回 2。如果中转返回错误,把 Key、模型名、base_url 三个都重新核对一遍。

免费注册,立即迁移 →

让 Claude 与 OpenAI
直接为你服务

免去 VPN、信用卡、代理的所有麻烦。注册即用,赠 ¥10 体验额度。