Anthropic 自己的 SDK 很出色,但整个 AI 生态已经统一采用 OpenAI 客户端形式——每个示例、每个框架适配器、每个“hello world”教程都假定你手边有一个 OpenAI(...) 实例。将代码迁移为直接调用 Anthropic SDK 是一次有意义的重构。
其实不必如此。本文将展示如何在不修改 OpenAI SDK 的情况下,通过 Kunavo 调用 Claude Opus 4.7、Sonnet 4.6 和 Haiku 4.5。相同的 SDK、类型、流式传输和工具调用。唯一需要更改的是 base_url。
最小改动
安装 Python 的 openai 包后,完整迁移如下。
from openai import OpenAI
client = OpenAI(
api_key="sk-kn-...",
base_url="https://api.kunavo.com/v1", # the only line that changes
)
resp = client.chat.completions.create(
model="claude-sonnet-4-6", # a Claude slug, not gpt-4o
messages=[
{"role": "system", "content": "You are a senior platform engineer."},
{"role": "user", "content": "Critique this SQL migration..."},
],
)
print(resp.choices[0].message.content)api_key 变为你的 Kunavo 密钥(在 /app/keys 中创建)。base_url 指向我们的网关。模型 ID 从 gpt-4o 切换为 Claude slug——claude-opus-4-7、claude-sonnet-4-6、claude-haiku-4-5。请求正文、响应结构以及 SDK 中的每个辅助工具,行为都与调用 OpenAI 时完全相同。
流式传输
流式传输的工作方式完全相同。Kunavo 将 Anthropic 的 SSE 分块转发为 OpenAI 的 chat.completion.chunk 格式,因此现有的异步迭代模式无需修改即可运行。
for chunk in client.chat.completions.create(
model="claude-opus-4-7",
messages=[{"role": "user", "content": "Explain Raft in 200 words."}],
stream=True,
):
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)工具调用 / 函数调用
Anthropic 的工具调用协议在语义上与 OpenAI 的函数调用相同——区别只在协议层。Kunavo 会双向转换 tools 数组、响应 tool_calls 和后续 tool 消息。使用 tool_choice="auto"、"none" 或命名工具均可,它们都会被映射。
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather in a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["city"],
},
},
}
]
resp = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
tools=tools,
tool_choice="auto",
)
print(resp.choices[0].message.tool_calls)视觉能力
Claude 从 3.5 起就支持多模态;传递图像时使用标准的 OpenAI content: [{ type: 'text' }, { type: 'image_url' }] 数组。image_url.url 可以是 https URL 或 data: base64 URI。
resp = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "What's in this image?"},
{"type": "image_url",
"image_url": {"url": "https://example.com/cat.jpg"}},
],
}],
)何时应使用原生 Anthropic SDK
某些 Anthropic 专属功能无法用 OpenAI 形式表达——最重要的是用于提示词缓存的 cache_control 指令和扩展的 thinking token。如果需要其中任一功能,请切换 SDK,但保留同一个密钥:Kunavo 也提供原生 /v1/messages 端点,因此只需更改 base_url,Anthropic 的 SDK 同样可以工作。
from anthropic import Anthropic
client = Anthropic(
api_key="sk-kn-...",
base_url="https://api.kunavo.com", # SDK appends /v1/messages
)
resp = client.messages.create(
model="claude-opus-4-7",
max_tokens=1024,
system="You are a senior platform engineer.",
messages=[{"role": "user", "content": "What is a hot standby?"}],
)
print(resp.content[0].text)完整的直通参数列表请参阅原生 Messages API 文档,提示词缓存如何在重复提示词上最多节省 90% 输入成本,请参阅 /docs/caching。
提示词缓存本身并不需要切换 SDK。对于较长的提示词,Kunavo 会在 OpenAI 形式的路由上为你设置缓存断点:设在系统提示词、工具定义,以及已包含 assistant 回合的对话的最后一条消息上。你自己加在系统消息、用户消息或工具定义上的 cache_control 会转发给 Claude。
你放弃的功能,以及获得的功能
OpenAI 形式的路由是转换协议,而不是原生协议。有两项小功能无法跨越边界:
- 思考控制——此路由不会将
thinking和reasoning_effort转发给 Claude。若要启用或调整扩展思考,请使用原生 Messages API。 - 思考输出——模型进行思考时,响应中不会包含这些思考内容,usage 对象里也没有单独的思考计数:思考 token 计入
completion_tokens。
你获得的收益很大:在 Claude、GPT、GPT-Image、Veo 及目录中其他模型之间使用一个 SDK;根据模型不同,低于上游官方价格;使用本地货币的 Stripe 原生计费;没有静默模型替换——故障转移会更换供应商,但不会更换模型,而且控制台会逐项列出每次调用的模型、token 和成本。
两分钟确认
在 kunavo.com/app/signup 注册——充值 $10 即可覆盖数千次 Claude 调用,按需付费,余额永不过期。填入你的 base_url,将模型 ID 替换为 Claude slug,然后运行现有测试套件。如果有任何内容无法顺利转换,请发送邮件至 contact@kunavo.com——我们会阅读每一条消息。