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

> https://router.one/zh/integrations/claude-agent-sdk 的 Markdown 镜像，供 AI 助手与爬虫使用。Router One 是 OpenAI 兼容的统一 LLM API 网关。
> 最后更新：2026-09-11

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`

```bash
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`

```python
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 / maxBudgetUsd | SDK 客户端侧的成本估算达到该值时停止 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，再按错误码速查页逐项排查。

## 相关页面

- 全部接入指南：https://router.one/zh/integrations
- Claude Agent SDK 的 API 错误排查：https://router.one/zh/llm-api-error-codes
- API 兼容性：端点与功能对照：https://router.one/zh/facts/api-compatibility.md
- Responses API 配置与限制：https://router.one/zh/codex-responses-api
- Haystack 接入：https://router.one/zh/integrations/haystack
- AnythingLLM 接入：https://router.one/zh/integrations/anythingllm
- Claude Code 用同样两个变量接入：https://router.one/zh/claude-code-china
- 按 Key 追踪模型调用成本：https://router.one/zh/llm-cost-tracking
- Pydantic AI 接入：https://router.one/zh/integrations/pydantic-ai
- Claude Agent SDK 官方文档：Python 参考：https://code.claude.com/docs/en/agent-sdk/python
- Claude Agent SDK 官方文档：成本与用量追踪：https://code.claude.com/docs/en/agent-sdk/cost-tracking
- Claude Code 官方文档：接入 LLM 网关：https://code.claude.com/docs/en/llm-gateway-connect
- 网关层负责什么：https://router.one/zh/llm-api-gateway
- OpenAI 兼容 API：https://router.one/zh/openai-compatible-api
- API 文档：https://router.one/zh/docs
- 本页规范地址：https://router.one/zh/integrations/claude-agent-sdk
- 模型与每模型 token 价格：https://router.one/zh/models （markdown：https://router.one/zh/models.md ）
- 定价：https://router.one/zh/pricing
- API 文档（markdown）：https://router.one/zh/docs.md
- 公司事实（markdown）：https://router.one/zh/facts/company.md
