跳到主要内容
Router One

用 Claude Code 的两个环境变量,把 Claude Agent SDK 跑在 Router One 上

Claude Agent SDK 把 Claude Code 的 Agent 循环嵌进 Python 和 TypeScript 应用:它拉起随包附带的 Claude Code 引擎,在你的机器上读文件、执行命令、调用工具,每一轮模型调用都是一次 Anthropic Messages 请求。把这个引擎指向 Router One,用的就是 Claude Code 那两个环境变量,写在 shell 里或通过 SDK 的 env 选项传入都行;之后每一轮都会以 POST /v1/messages 的 Trace 出现在 Dashboard → Logs,带 tokens、花费和延迟。本指南安装 Python SDK,用精确的 Claude 系列模型 ID 跑通一次纯文本 query,说明哪些选项决定网关收到什么,以及 max_turns 与按 Key 的 maxSpend 如何约束一次多轮运行。

安装 Python SDK 并设置凭证

使用 Python 3.10 或更新版本,安装 claude-agent-sdk;wheel 包自带原生 Claude Code 可执行文件,不需要单独安装 Claude Code。若 pip 装到的是源码包而不是平台 wheel(官方文档以 ARM64 Windows 为例),按官方方式原生安装 Claude Code,SDK 会从 PATH 找到它。TypeScript 包是 @anthropic-ai/claude-agent-sdk,需要 Node.js 18 或更新版本。下面是 macOS/Linux 的 shell 示例,运行前替换两个占位符:Router One Key,以及当前目录中详情页列出 POST /v1/messages 的 Claude 系列模型的精确 ID。ROUTER_ONE_* 是本示例定义的变量名,代码读取后把 ANTHROPIC_BASE_URL 和 ANTHROPIC_AUTH_TOKEN 交给引擎;像 Claude Code 指南那样直接导出这两个变量同样有效,因为 Python SDK 会把 env 合并到继承的环境之上。SDK 不会自动读取 .env 文件,运行 Python 文件时要沿用同一环境。

terminal
python -m pip install claude-agent-sdk
export ROUTER_ONE_API_KEY="sk-your-router-one-key"
export ROUTER_ONE_MODEL_ID="<exact-model-id-from-/models>"

把 Claude Agent SDK 配置到 Router One base URL

保存为 claude_agent_sdk_router_one.py,运行 python claude_agent_sdk_router_one.py。query() 以子进程方式启动随包附带的 Claude Code 引擎,并逐条产出它的消息。env 选项合并到继承的环境之上:ANTHROPIC_BASE_URL 填不带 /v1 的主机根地址 https://api.router.one,因为引擎会自己拼上 /v1/messages;ANTHROPIC_AUTH_TOKEN 以 Authorization: Bearer 头携带你的 Router One Key,于是每一轮模型调用都是发往网关的 Anthropic Messages 请求。ANTHROPIC_API_KEY 不需要设置,示例刻意没有写它。model= 把目录里的模型 ID 原样传给引擎的 --model 参数;不设 model 时会回退到 Claude Code 的默认别名,别名解析出的是内置默认 ID,未必是目录里的条目。max_turns=3 限制工具调用的往返轮数。permission_mode 保持未设置且没有提供 can_use_tool 回调,模型即便请求工具也会被拒绝而不是执行,所以首次运行只有模型请求。循环打印每条 AssistantMessage 里的 TextBlock,最后打印 ResultMessage 的 subtype 和 num_turns。

claude_agent_sdk_router_one.py
import asyncio
import os

from claude_agent_sdk import (
    AssistantMessage,
    ClaudeAgentOptions,
    ResultMessage,
    TextBlock,
    query,
)

options = ClaudeAgentOptions(
    model=os.environ["ROUTER_ONE_MODEL_ID"],
    env={
        "ANTHROPIC_BASE_URL": "https://api.router.one",
        "ANTHROPIC_AUTH_TOKEN": os.environ["ROUTER_ONE_API_KEY"],
    },
    max_turns=3,
)


async def main() -> None:
    prompt = "Reply with one short greeting."
    async for message in query(prompt=prompt, options=options):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, TextBlock):
                    print(block.text)
        elif isinstance(message, ResultMessage):
            print(f"{message.subtype}: {message.num_turns} turn(s)")


asyncio.run(main())

哪些选项决定网关收到什么

ClaudeAgentOptions 的大多数字段只影响引擎在本地做什么,下表是会改变 Router One 收到的请求的几个;TypeScript 侧是 Options 对象上同名的驼峰字段,其中一个在两套 SDK 里行为不同。

选项(Python / TypeScript)作用在 Router One 上要核对什么
env / env传给 Claude Code 子进程的环境变量。Python 合并到继承的环境之上;TypeScript 会整个替换环境,需要把 process.env 展开进去ANTHROPIC_BASE_URL 填不带 /v1 的主机根地址,ANTHROPIC_AUTH_TOKEN 填 Router One Key;Claude Code 设置文件里的 env 块会覆盖这两者(见常见问题)
model / model别名或完整模型名,以 --model 交给引擎;不设则用 Claude Code 默认值,别名解析为内置默认 ID填 /models 里详情页列出 POST /v1/messages 的精确 ID;GPT 系列 ID 会在调用任何模型之前被 400 must be called via 拒绝
max_turns / maxTurns工具调用往返的最大轮数;到达后 ResultMessage 的 subtype 为 error_max_turns每一轮至少一次 Messages 请求,一次 query() 在 Logs 里会有多条 Trace,有 subagent 时更多
max_budget_usd / maxBudgetUsdSDK 客户端侧的成本估算达到该值时停止 query(subtype 为 error_max_budget_usd)估算来自 SDK 内置的价格表,不是你的 Router One 费率;真正能止损的是 Key 上的 maxSpend
permission_mode / permissionMode 与 allowed_tools / allowedTools哪些工具调用无需确认即可执行;default 模式且没有回调时一律拒绝网关侧没有可核对的东西:工具在你的机器上运行,Router One 只记录前后的 Messages 请求

给一次 query 设预算,并在 Logs 里逐轮核账

一次 query() 调用是一串 Messages 请求:每轮至少一次,引擎拉起 subagent 时更多,再加上 Claude Code 引擎文档里写明的后台请求。max_turns 限制的是工具调用轮数而不是花费;max_budget_usd 比较的是按公示价算出的估算值,官方文档明确说它可能与实际账单偏离,不能据此做财务决策。给这个 Agent 单独建一把设了 maxSpend 的 Router One Key,然后到 Dashboard → Logs 看这次运行:按该 Key 和精确模型过滤,把 Trace 对到运行的时间窗和 ResultMessage 的 num_turns,失败的 Trace 保留 request_id。结果里的 total_cost_usd 是 SDK 的估算,网关每条 Trace 记录的费用才是实际扣费。Router One 只提供并记录模型请求:工具执行、hooks、权限检查、会话和 subagent 都在 SDK 里、在你的机器或容器上运行。

Claude Agent SDK 该填哪个模型 ID?

从 /models 页复制精确的模型 ID,保留大小写、连字符和版本后缀,不要用展示名称代替。打开该模型的详情页,核对支持的 API 端点、上下文窗口和工具调用等能力,再与 Claude Agent SDK 当前选择的 provider 和功能对应。模型出现在目录里,不等于当前客户端能调用它的所有功能。建议为每个工具单独建 API Key,并设置 maxSpend 消费上限。

Claude Agent SDK 用的是哪种 API 协议?

OpenAI 兼容描述的是接口格式,不能据此推断 Chat Completions(/v1/chat/completions)、Responses(/v1/responses)和 Anthropic Messages(/v1/messages)可以互换。先核对工具当前版本、provider 配置和实际请求路径,再查模型详情与 API 兼容性事实页。一次普通对话成功,也不能证明服务端工具、历史状态或文件编辑功能都受支持。

在 trace 里验证 Claude Agent SDK 的调用

先在 Claude Agent SDK 发出一次简单文本请求,再到 Dashboard → Logs 按时间、模型和 request_id 核对 trace:tokens、花费、延迟和状态码。成功后再分别验证流式输出、工具调用和多轮历史。失败时保留实际请求路径、完整错误消息及 request_id;没有对应日志时,先查客户端配置和网络,不能仅凭客户端报错认定是网关或上游故障。

常见问题

SDK 通过 Router One 能发哪些模型 ID?400 must be called via 是什么意思?

引擎说的是 Anthropic Messages 格式,每一轮都发往 POST /v1/messages,这个端点服务当前目录里的 Claude 系列 ID;/models 下每个模型的详情页都列出了它支持的端点。model 里要填这样的精确 ID,不要填展示名,也不要填 sonnet 之类的别名——别名在客户端解析成 Anthropic 内置的默认 ID。这个端点也可能列出其他系列,但 Claude Code 的网关文档写明 Anthropic 不支持把它路由到非 Claude 模型,所以 SDK 请保持使用 Claude 系列 ID。如果填了 GPT 系列 ID,网关会在调用任何模型之前返回 400 invalid_request_error,消息为 model '<id>' must be called via …;这时换模型 ID,不要去改 base URL。

我已经用 claude.ai 登录或官方 API Key 在跑 Claude Code,这些变量之间怎么相互影响?

Claude Code 的网关文档写明,网关凭证变量优先于已保存的 claude.ai 登录:设置了 ANTHROPIC_AUTH_TOKEN 后,该进程不再使用登录态,订阅的用量限制和计费也不适用。只设 ANTHROPIC_BASE_URL 不会替换登录态:请求仍会发到网关,但不携带你的 Router One Key,首个请求报 401 时先查这一点。ANTHROPIC_API_KEY 不需要设置;之前为官方 API 导出的残留值会作为第二个请求头(x-api-key)与 Bearer token 一起发送,请 unset 它,或不要放进 env。还有一个冲突来源:Claude Code 设置文件里的 env 块会覆盖从 shell 继承的值,而 query() 的默认选项会加载 user、project、local 三级设置,所以要么删掉那里旧的 ANTHROPIC_BASE_URL 条目,要么给这个 Agent 传 setting_sources=[]。

Logs 里出现了我没设置过的模型 ID 的请求,是哪来的?

引擎有两类功能会自己发请求。Claude Code 文档写明,haiku 别名对应的模型也用于后台功能,例如为 resume 做对话摘要,而别名解析出的是内置默认 ID;经过 Router One 时这条请求带的就是那个默认 ID,未必在目录里。在 env 里把 ANTHROPIC_DEFAULT_HAIKU_MODEL 设为当前目录中 /v1/messages 支持的 Claude 系列 ID,后台请求就会用目录模型,和其余请求一样被记录和计费。subagent 同样会以分配给它的模型或 CLAUDE_CODE_SUBAGENT_MODEL 默认值发出自己的请求。若某条意外 ID 的 Trace 失败了,保留它的 request_id 和错误消息,然后固定这个变量,不要去改 base URL。

Claude Agent SDK 能通过网关用哪些模型?

选用当前目录中同时支持 Claude Agent SDK 所用端点和所需功能的模型。精确 ID、当前单价与能力以 /models 及模型详情为准;不要仅按 GPT、Claude 等系列名判断兼容性。客户端能列出模型,只证明模型发现成功,仍需验证实际调用。

能列出模型,但调用报 400 或 404,怎么办?

先记录实际请求路径和错误消息,再核对精确模型 ID。400 可能是参数、工具类型或模型与端点不匹配;404 可能是请求路径或资源不存在,不能直接判定模型下线。若错误提示 must be called via,按它指明的端点调整客户端 provider,或换用支持当前端点的模型。不要在所有工具里统一增删 /v1 或 /chat/completions。

中国大陆能直连吗?

能。网关在大陆可直连、无需 VPN,配置与全球环境完全一致。

报 401/402/403/429 怎么排查?

先到 Dashboard → Logs 核对请求及错误消息。401 查 Key 是否传入和有效;402 查钱包余额与 maxSpend;403 查 Key 权限和访问限制;429 查请求频率、token 限额及上游限流,按错误来源处理。保留 request_id,再按错误码速查页逐项排查。