BUZZ AI Gateway
文档 · 指南 · OpenAI SDK

用 OpenAI SDK 调 BUZZ

一个 SDK,一个 base URL,所有支持的模型家族。把官方 OpenAI client 指向 https://buzzai.cc/v1,改一下 model 名,就能调 Claude / Gemini / Grok / GPT。流式、Tool Use、重试策略、可观测性 wrapper 全部不用动。

POST https://buzzai.cc/v1/chat/completions
原理。 BUZZ 在 /v1 暴露 OpenAI 兼容的 chat.completions 端点。网关用 chat.completions 解析你的请求,根据 model 字段分发到对应上游,响应再翻译回 OpenAI 形状。OpenAI 自家模型走原生透传;Claude / Gemini / Grok 由网关在协议之间做桥接。

1. 安装与配置

装官方 client 即可,没有 BUZZ 专用包。

pip install openai
npm install openai

构造 client 时只填两个字符串:base_urlapi_key

from openai import OpenAI

client = OpenAI(
    api_key="sk-YOUR_BUZZ_KEY",
    base_url="https://buzzai.cc/v1",
)
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.BUZZ_API_KEY,
  baseURL: "https://buzzai.cc/v1",
});

两个 SDK 都会以 Authorization: Bearer <value> 形式发送 key,BUZZ 直接接受。sk- 前缀可有可无 — 服务端会剥离前缀。

2. 调 Claude

model 填 Claude ID,正常调 chat.completions.create 即可。网关把请求转成 Anthropic Messages 格式调上游,再把响应转回 OpenAI ChatCompletion,你的代码继续按 OpenAI 形状解析。

resp = client.chat.completions.create(
    model="claude-haiku-4-5-20251001",
    messages=[
        {"role": "system", "content": "你是一个严谨的技术写作者。"},
        {"role": "user", "content": "用三句话解释 content-addressable storage。"},
    ],
    temperature=0.3,
    max_tokens=400,
)

print(resp.choices[0].message.content)
print(resp.usage)
const resp = await client.chat.completions.create({
  model: "claude-haiku-4-5-20251001",
  messages: [
    { role: "system", content: "你是一个严谨的技术写作者。" },
    { role: "user", content: "用三句话解释 content-addressable storage。" },
  ],
  temperature: 0.3,
  max_tokens: 400,
});

console.log(resp.choices[0].message.content);
curl -sS https://buzzai.cc/v1/chat/completions \
  -H "Authorization: Bearer $BUZZ_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-haiku-4-5-20251001",
    "messages": [
      {"role": "system", "content": "你是一个严谨的技术写作者。"},
      {"role": "user", "content": "用三句话解释 content-addressable storage。"}
    ],
    "max_tokens": 400
  }'

常用 Claude 模型 ID(实时列表见 GET /v1/models):

3. 调 Gemini、Grok、GPT

切家族就是改 model 名。同一个 client、同一段调用、同一套重试 wrapper。

# 同一个 client,不同模型家族
gemini = client.chat.completions.create(
    model="gemini-2.5-pro",
    messages=[{"role": "user", "content": "总结这份会议记录..."}],
)

grok = client.chat.completions.create(
    model="grok-4",
    messages=[{"role": "user", "content": "本周市场发生了什么?"}],
)

gpt = client.chat.completions.create(
    model="gpt-5",
    messages=[{"role": "user", "content": "给出一份迁移方案大纲。"}],
)

支持的完整模型 ID 列表见 buzzai.cc/models,实时按 token 价格见 buzzai.cc/api/pricing

4. 流式

stream=true 后迭代响应。无论上游是 Anthropic 类型事件还是 OpenAI 类型事件,网关统一以 OpenAI chat.completion.chunk 形状对外发出。

stream = client.chat.completions.create(
    model="claude-sonnet-4-6",
    messages=[{"role": "user", "content": "写一首关于冷存储的俳句。"}],
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)
const stream = await client.chat.completions.create({
  model: "claude-sonnet-4-6",
  messages: [{ role: "user", content: "写一首关于冷存储的俳句。" }],
  stream: true,
});

for await (const chunk of stream) {
  const delta = chunk.choices[0]?.delta?.content;
  if (delta) process.stdout.write(delta);
}

想在流结束时拿到 token 用量,加 stream_options:

stream = client.chat.completions.create(
    model="claude-haiku-4-5-20251001",
    messages=[{"role": "user", "content": "ping"}],
    stream=True,
    stream_options={"include_usage": True},
)

最后一个 chunk 会带非空 usage 对象。当上游是 Claude 时,BUZZ 会在 usage 上额外标记 usage.usage_source = "anthropic" — 在可观测平台里做跨家族成本归因很方便。

5. Tool Use / Function Calling

按 OpenAI 标准格式定义 tools,网关在出口侧把它们映射成 Anthropic tool_use 块(或 Gemini functionDeclarations),响应进入时再把上游的工具选择映射回 tool_calls。原有 OpenAI tool-calling 调用循环不需要改。

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "获取某城市的当前天气。",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {"type": "string"},
                "units": {"type": "string", "enum": ["c", "f"]},
            },
            "required": ["city"],
        },
    },
}]

resp = client.chat.completions.create(
    model="claude-opus-4-7",
    messages=[{"role": "user", "content": "东京现在天气怎么样?"}],
    tools=tools,
    tool_choice="auto",
)

call = resp.choices[0].message.tool_calls[0]
print(call.function.name, call.function.arguments)
# 后续把 assistant 消息追加进对话,再加一条
# {"role": "tool", "tool_call_id": call.id, "content": "..."} 然后再调一次。

6. Claude 路径下被静默丢弃的字段

网关分发到 Claude 上游时,会用你的 chat.completions 请求重建 Messages-API 请求体。在 Anthropic 侧没有对应概念的字段不会出现在上游调用里。它们不会触发 400 — 它们直接消失。下表是已确认的丢弃清单,按这个心智模型设计就行。

chat.completions 入参Claude 路径行为
n(> 1)丢弃。Claude 上游只返回单 choice,n > 1 不可用。
presence_penalty丢弃。Anthropic 没有对应参数。
frequency_penalty丢弃。Anthropic 没有对应参数。
logit_bias丢弃。Anthropic 没有对应参数。
logprobs / top_logprobs丢弃。Claude 响应永远不返回 logprobs。
seed丢弃。Anthropic 没有确定性采样旋钮。
response_format丢弃。JSON 模式 / JSON Schema 约束在 Claude 路径不生效;改用 prompt 引导或 tool-calling。
function_call / functions丢弃(旧 API 形式)。改用 tools + tool_choice — 这条路径已接通。
prediction / modalities / audio丢弃。Anthropic Messages 不暴露这些。
verbosity丢弃。仅 GPT 支持。
user / safety_identifier / prompt_cache_key / metadata / storeClaude 路径丢弃。其中部分字段在 OpenAI 路径上也是通道级开关 — 见下方 callout。
service_tier默认丢弃。可由通道侧 allow_service_tier 开启。
opus-4-7-thinking 后缀的模型 + temperature / top_p / top_k会被强制清空。Extended Thinking 模式下采样参数被刻意忽略,即使你显式传也无效。

反过来,网关也帮你把若干 OpenAI 入参翻译到 Claude 概念:

通道级开关字段。 几个入参在通道未开 allow flag 时会被静默过滤:service_tiersafety_identifierstream_options.include_obfuscation,以及 Claude 侧的 inference_geo / speed。如果业务真的需要这几个端到端透传,联系支持开通对应开关。

7. 什么场景该改用 Anthropic SDK

对于在 chat.completions 里没有标准位置的 Claude 原生特性,改用 Anthropic SDK 调同一个网关 — 同 key、同网关、不同协议。

from anthropic import Anthropic

ant = Anthropic(
    api_key="sk-YOUR_BUZZ_KEY",
    base_url="https://buzzai.cc",
)

msg = ant.messages.create(
    model="claude-opus-4-7",
    max_tokens=1024,
    messages=[{"role": "user", "content": "帮我规划一个模块重构..."}],
    extra_body={"thinking": {"type": "enabled", "budget_tokens": 8000}},
)

8. 框架集成

任何 OpenAI client 包装、且暴露 baseURL 配置的框架都直接可用。三种典型接线:

LangChain(Python)

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="claude-haiku-4-5-20251001",
    api_key="sk-YOUR_BUZZ_KEY",
    base_url="https://buzzai.cc/v1",
    temperature=0.2,
)

print(llm.invoke("一句话总结 BUZZ gateway。").content)

LangGraph

LangGraph 的 node 通常接收一个 chat model 实例。按上面的方式构造 ChatOpenAI,然后传进 graph。Graph 层不需要任何改动 — 路由决策完全靠 model ID 传递。

from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI

model = ChatOpenAI(
    model="claude-sonnet-4-6",
    api_key="sk-YOUR_BUZZ_KEY",
    base_url="https://buzzai.cc/v1",
)

agent = create_react_agent(model, tools=[...])
result = agent.invoke({"messages": [("user", "这次发布做了什么?")]})

Vercel AI SDK

import { createOpenAI } from "@ai-sdk/openai";
import { generateText } from "ai";

const openai = createOpenAI({
  apiKey: process.env.BUZZ_API_KEY,
  baseURL: "https://buzzai.cc/v1",
});

const { text } = await generateText({
  model: openai("claude-haiku-4-5-20251001"),
  prompt: "为缓存改进写一条简短的发布说明。",
});

streamText 的流式、tools 选项的工具调用、Zod schema 的结构化输出都继续可用 — 网关保持的是 @ai-sdk/openai 期望的线协议形状。

9. 可观测性与重试

因为出入两个方向都是 OpenAI 原生形状,所有包装 OpenAI client 的工具都能不修改地继续用:OpenTelemetry GenAI 语义约定、Langfuse / Helicone / Phoenix 这类追踪处理器、429 重试装饰器、请求/响应日志器,都按原配置工作。BUZZ 侧值得在监控里多采一个字段:usage.usage_source,值为 "anthropic" 时表示该响应来自 Claude 上游 — 跨家族成本归因很方便。

10. 错误码

HTTPerror.type典型场景
400invalid_request_error / buzz_errorJSON 格式错误或缺必填字段
401buzz_errorAPI key 缺失或非法
403permission_errorKey 权限不足、IP 不在允许列表
429rate_limit_error命中限流,遵守 retry-after
500api_error内部错误,带退避重试
503buzz_error / model_not_found该 model 在你的 group 下没有可用 channel。换一个别名或调 GET /v1/models 看实时列表。

BUZZ 侧错误返回 {"error": {"type": "buzz_error", "message": "... (request id: ...)"}}。上游透传错误保留上游的包络形状(根据路由模型,可能是 Anthropic 风格或 OpenAI 风格)。

相关链接