提供程序配置
每个模型提供方都位于 [providers.models.<type>.<alias>]。<type> 是规范的系列槽位(参见 Catalog 查看每个槽位及其端点)。<alias> 是你作为运维人员指定的实例名称,可以选择任意具有描述性的名称(home、work、cn、gpt5……)。
最小可运行示例
加载无误的最小配置包含四个节标题:一个 provider 条目、一个引用该条目的 agent,以及一个 agent 据以进行门控的风险配置。可通过 gateway、zerocode 或 zeroclaw config set 进行配置;配置参考中有完整的字段索引。
字段参考:提供程序条目
几乎每个 family 也会从 ModelProviderConfig 中获取共享字段:
api_key:用于使用 bearer 或订阅式 API 密钥的提供方的凭据。uri:完整端点覆盖。保持未设置以使用该 family 的端点解析器。model:发送给提供方的模型标识符。temperature:可选的采样温度。timeout_secs:HTTP 请求超时时间(秒)。将其设置为大于 300 的值时,还会提高提供方的流式空闲上限(即两次流读取之间允许的最长间隔,默认上限为 300 秒),适用于 OpenAI Responses 及 OpenAI 兼容提供方。max_tokens:可选的响应长度上限。extra_headers:用于自定义网关或认证桥接的额外 HTTP 标头。fallback_models:同一提供程序别名上的备用模型 ID。fallback:在此别名失败后要尝试的其他带点的 provider 别名有序列表。wire_api、native_tools、provider_extra、think、thinking_passthrough和chat_template_kwargs:高级协议与请求体覆盖项。vision:覆盖提供方的图像输入(vision)能力。未设置时使用该系列的内置默认值。对于由支持视觉的系列提供服务的纯文本模型(例如通过 llama.cpp 提供的文本模型),设置false,使图像消息路由到已配置的[multimodal] vision_model_provider,而不是报错;设置true则强制启用。未配置视觉提供方时,若最新用户消息中的所有图像引用均未通过存在性、data URI 结构或远程获取策略检查(即文件缺失、data URI 格式错误,或在multimodal.allow_remote_fetch关闭时使用远程 URL),非视觉轮次会继续执行,并将媒体标记替换为占位符。本地路径仅在满足以下条件时才被视为有效:为绝对路径、被智能体的文件系统策略允许(与文件工具所应用的检查相同),且作为文件存在;被策略拒绝的路径永远不会被探测。若任一引用通过检查,该轮次仍会因视觉能力错误而失败。可解析性检查每轮最多评估 16 个绝对本地路径标记;对于这些标记,策略检查与存在性探测会在阻塞线程上一并执行,而不占用异步执行器。消息中超出此数量的标记将被视为可解析,且不做任何检查,因此超大消息会以视觉能力错误失败,而不是静默降级。tool_result_image_policy:用于发送给兼容 chat-completions 提供方的原生role = "tool"结果所附图片的处理方式。工具结果的图片在工具结果载体中、结果文本旁边的attachments数组里声明,从不从结果文本本身中恢复,因此工具输出中的字面标记语法只是普通文本。默认值为"image_url"(将声明的图片作为image_url部分发送);设为"omit"则丢弃这些图片并追加一条固定提示。该策略仅读取原生载体的attachments数组;旧版工具结果(没有该数组键)在两种设置下都原样传递,因为它不声明任何内容,其正文即为文本。此设置不影响直接的用户图片或 OpenAI Responses 提供方。cache_passthrough:选择启用 Anthropic 提示词缓存,适用于转换为 Anthropic Messages API 的 chat-completions 网关。每个请求最多添加两个cache_control断点,并在 token 用量中呈现网关报告的缓存读取量。默认为false,请求保持不变。在生产环境使用前需要先完成路由验证;参见 Prompt cache passthrough。cache_ttl:为 Anthropic 提示缓存标记请求的缓存条目生存时间。可选值为"5m"(默认)或"1h"。它直接作用于原生 Anthropic 提供方,以及通过cache_passthrough接入的 chat-completions 网关;未启用 passthrough 时该设置不生效。通过其他方式生成自身缓存标记的提供方(openrouter)会忽略此设置。参见 Choosing a 1h cache lifetime。tls_ca_cert_path:用于与此提供程序建立 TLS 连接的 PEM 编码 CA 证书的绝对路径(按提供程序的信任覆盖,区别于网关 TLS 的ca_cert_path)。不会执行诸如~之类的 Shell 展开;留空则使用系统信任存储。
特定 family 的条目会在这些共享字段之上添加它们自己的类型化字段。
Anthropic 思考透传
thinking_passthrough = true 在 OpenAI 兼容的 provider 条目上启用 Anthropic 扩展思考透传:运行时的思考预算会被转发到网关,网关返回的思考内容会被规范化为可重放的签名块,并且这些签名块会在后续出站历史消息中被重放。
在使用此标志之前,请先检查网关是否还提供 Anthropic Messages 端点。如果提供,请使用 uri 将 [providers.models.anthropic.<alias>] 条目指向该端点;原生提供方无需转换即可处理 thinking、签名块重放和提示词缓存。thinking_passthrough 适用于仅提供 Chat Completions 接口的网关。
[providers.models.custom.my-gateway]
uri = "https://your-gateway.example.com"
model = "claude-group/claude-fable-5"
api_key = "..."
wire_api = "chat_completions"
thinking_passthrough = true
它的作用
- 请求侧:当运行时提供原生 thinking 参数时,请求体顶层会增加一个 Anthropic 格式的对象:
{"thinking": {"type": "enabled", "budget_tokens": N}}。显式指定的provider_extra键始终优先于注入的对象,因此你可以通过该逃生口(escape hatch)固定自定义格式。temperature 与max_tokens的规范化依据的是实际发送的对象:因此显式的{type = "off"}会保留你设置的 temperature 与上限;而带有自身budget_tokens的显式enabled对象会将max_tokens提高到该预算之上。注入 thinking 对象时,请求的 temperature 会被设为 1.0,这是 Anthropic 的要求;只有在 thinking 关闭时,显式设置的 temperature 才会生效。当注入固定的 thinking 预算时,如果配置的上限不高于该预算,max_tokens也会被提高到budget_tokens + 1,这同样是 Anthropic 的要求。 - Capture:网关的思考响应会被规范化为与原生 Anthropic 提供方在
reasoning_content中存储的格式相同的换行分隔签名 JSON,即每个思考块对应一行{"thinking": ..., "signature": ...}。仅含签名的块(文本为空、签名有效,即 TrueFoundry 输出的格式)同样会被保留。关闭该标志时,网关的reasoning_content/thinking_blocks响应保持原有流转方式不变,因此 DeepSeek/GLM/Qwen 的推理行为不受影响。 - 重放:带签名的历史记录会在发出的助手消息上重建
thinking_blocks数组,并抑制字符串字段。该重建是全有或全无的;参见下方的限制说明。replay_assistant_reasoning = false覆盖设置仍然优先生效:拒绝推理输入的提供方在任何标志组合下都不会收到任何内容。
需求与限制
- 需要翻译网关。 该标志仅对 OpenAI 兼容端点有意义,这类端点需要在 OpenAI Chat Completions 与 Anthropic Messages API 之间进行转换(LiteLLM 记录了这一转换;该格式已通过实际运行的 TrueFoundry 网关验证)。若指向不做转换的上游,注入的
thinking对象会成为未知参数,请求将以 HTTP 400 失败。这是设计好的故障模式:在第一次请求时即明确报错,而非静默失败。 - 未签名的思考内容会使重放失效。 Anthropic 在输入中接受的
thinking思考块必须带有有效签名。若历史记录中的推理内容未签名(流式文本,或剥离了签名的网关),则不发送任何推理内容,而不是伪造网关可能拒绝的块:任何无法解析的行,或缺少签名的thinking行,都会使整条消息的重放失效(不保留部分序列)。结构无效的redacted_thinking块(缺少 data 载荷)会被单独省略,其有效的同级块仍会重放。捕获白名单严格限定为:thinking(要求 text 和/或 signature)与redacted_thinking(要求不透明的data,按原样重放,且按设计不带签名);网关发出的任何其他块类型在捕获时跳过,且绝不在重放时转发。提示引导的回退路径会重放同样经过验证的块,因此第二次 schema 回退不会丢弃已签名的推理轨迹。 - 嵌套内容块未被捕获。 仅读取顶层的
reasoning_content、reasoning和thinking_blocks字段。嵌套在content数组中的 Anthropic 格式块不会被捕获;如果你的网关会输出这类块,请附上线路样本提交 issue。 - 透传会禁用叶子节点上的流式传输。 能力归一化只作用于非流式响应,而网关 SSE 的思考帧尚未经过验证,因此该提供方会将自身报告为非流式:当它作为实际服务提供方时,整个工具循环都在非流式通道上运行,签名捕获与重放在此通道上能够保持正确。有两种边界情况:解析到该提供方的 Router 会调用其非流式路径,并合成标准流式事件;包含支持流式传输的备用提供方的可靠性域,可能会由该备用提供方处理该轮对话(并显示标准的备用通知)。因此,若运维人员要求每一轮都在已启用选项的提供方上运行,应配置一个全部为非流式的可靠性域。在支持优先线级流式传输的功能落地之前,叶子节点上的逐轮流式传输不会恢复。
- **思考形态跟随模型。**注入的对象与原生提供商的解析规则保持一致:固定预算模型使用
{"type": "enabled", "budget_tokens": N},仅支持自适应的模型(Opus 4.7 及整个 Fable 5 系列)使用{"type": "adaptive"},且不包含预算键。网关模型 ID 可能带有路由前缀(claude-group/...);解析基于子串匹配,因此带前缀的 ID 与裸名解析为相同的形态。当运行时请求显示模式时,蛇形命名的display键会同时附加在两种形态上(omitted、updates、summarized);未请求显示模式时,该键被完全省略。 - 逃生通道:对于本功能未覆盖的结构,
provider_extra仍会将任意顶层 JSON 合并到每个请求体中,包括静态的thinking对象,风险自负,且不做任何响应处理。
另见
- Anthropic 提供商的原生扩展思考:#10542。
- 请求体逃生口:上方的
provider_extra;参考。
字段解析顺序
对于大多数系列,URL 按以下顺序解析:
- 运算符覆盖:别名条目上的
uri字段(如果已设置)。 - Family 端点:该 family 的
*Endpoint枚举提供 URL(例如OpenAIEndpoint::Default->https://api.openai.com/v1)。多区域 family 在别名条目上有一个endpoint字段,用于选择变体(例如 Moonshot 的endpoint = "cn")。 - 模板化家族:Azure 接受类型化输入(
resource、deployment、api_version),并将其替换到家族的 URI 模板中。缺少字段时,运行时会立即报错。
Bedrock 是个例外:其端点主机名会在请求时根据通过 AWS 凭证链解析出的签名区域构造(该区域来自 AWS_REGION、AWS_DEFAULT_REGION,或活动 credential_process 或 IMDS 配置文件中的 region)。uri 别名字段以及 schema 级别的 providers.models.bedrock.<alias>.region 字段在当前实现中不起作用。
家庭席位
每个槽位、其默认端点以及是否在本地运行均记录在目录中。每个供应商只有一个规范键名:不设同义词。
凭证
支持的凭据输入和存储形式:
- 内联
api_key = "...",置于别名条目中(开发时尚可,但对于提交到版本库的配置存在风险)。 - 1Password 引用:将密钥字段设置为
op://vault/item/field。ZeroClaw 会在配置中保留该引用,并在运行时通过op read解析它,因此必须安装并登录 1Password CLI。 - 配置级密钥存储:通过本地密钥文件在
~/.zeroclaw/secrets中加密存储。 - 通用环境变量覆盖:
ZEROCLAW_providers__models__<type>__<alias>__api_key=...会在启动时设置providers.models.<type>.<alias>.api_key。完整的语法规则请参阅环境变量。
架构镜像环境变量覆盖在启动时优先生效。它们会替换该进程的内存凭据,而不会重写磁盘上存储的内联、加密或 op:// 值。
zeroclaw quickstart 默认将凭据写入密钥存储。你提交的配置不应包含内联密钥。对于你已在 shell 中导出的生态系统默认名称($ANTHROPIC_API_KEY、$OPENROUTER_API_KEY 等),env-vars 参考文档展示了将 schema-mirror 名称指向现有值的单行 bash 展开式。
OAuth 和订阅认证
一些提供商接受 OAuth 或订阅式令牌,而非原始 API 密钥。请从供应商自己的仪表板或 CLI 流程中获取令牌,然后像填写 API 密钥那样将其填入别名条目:
- Anthropic / Claude: 由
claude setup-token为 Claude Max 生成的控制台 API 密钥和令牌应填写到[providers.models.anthropic.<alias>]中的api_key。在 Quickstart 中,选择api_key或setup_token;已保存的提供商条目仍然是规范的anthropic插槽。 - OpenAI Codex 订阅:运行
zeroclaw auth login --model-provider openai-codex(或使用--import ~/.codex/auth.json导入现有的 Codex CLI 登录),然后将requires_openai_auth = true设为启用,并在[providers.models.openai.<alias>]上保持api_key未设置;运行时会读取 ZeroClaw 存储的openai-codex认证配置文件。 - Gemini CLI:
[providers.models.gemini_cli.<alias>]会调用geminiCLI;请使用该 CLI 自带的认证流程。 - Grok Build CLI:
[providers.models.grok_cli.<alias>]会通过文档所述的grok agent stdioACP 接口调用外部进程。组装后的提示词以 JSON-RPC 形式通过 stdin 传入,绝不会通过 argv 或提示词文件传递。默认情况下,身份验证使用 CLI 登录缓存。对于 API 密钥身份验证,请将XAI_API_KEY导出到守护进程环境中,并将env_passthrough = ["XAI_API_KEY"]明确添加到别名配置中;类型化别名api_key仍不受支持。必须指定一个已存在的绝对working_directory,它同时定义子进程 cwd 和 ACP 会话边界。子进程启动前会清空其环境,env_passthrough默认为空。其他提供商自有的XAI_*名称以及所有GROK_*名称都会被拒绝。ZeroClaw 默认使用--sandbox strict、--permission-mode dontAsk、空的内置工具集以及失败关闭的 ACP 权限响应。extra_args是按别名显式选择放宽这些控制的方式。绕过标志--always-approve、--dangerously-skip-permissions、--yolo和--permission-mode=bypassPermissions会使无头 ACP 客户端选择allow_once;其他权限模式仍选择reject_once。ACP 传输、模型、会话和 cwd 标志,以及位置参数和短参数均为保留项;未知的取值型长选项使用--flag=value。别名vision = true仅会让 ZeroClaw 选择发送 ACP 图像块;截至 0.2.118,Grok 仍宣称promptCapabilities.image = false,并且无法可靠地使用图像内容 - 生产环境请勿设置;请参阅 ACP 视觉 / 图像输入。 - Qwen / MiniMax:在别名条目中设置
auth_mode = "o_auth",并添加相关的oauth_*字段(参见 env-vars → OAuth 和 CLI 路径字段)。
OpenAI Astra 设置
OpenAI 的公共 API 模型 ID 为 gpt-6-astra。模型指南要求工具调用使用 Responses API,并且在不支持的参数列表中包含 temperature。请为 openai 别名配置公共 API 路由,使用 API 密钥并显式指定 Responses wire:
[providers.models.openai.astra_api]
api_key = "op://platform/openai/api-key"
model = "gpt-6-astra"
wire_api = "responses"
vision = true
context_window = 1050000
max_tokens = 32000
[runtime]
reasoning_effort = "high"
[runtime_profiles.astra]
agentic = true
max_tool_iterations = 12
max_history_messages = 80
max_context_tokens = 200000
[agents.astra]
model_provider = "openai.astra_api"
runtime_profile = "astra"
risk_profile = "supervised"
这些数值是有意设置的本地预算,并非建议将模型宣传的上下文窗口全部用满。提供方条目记录端点能力和输出上限,而运行时配置文件则保留较小的估算输入预算,并限制工具循环的次数。请根据工作负载进行调整,并保留足够的输出余量。这些字段分别由不同的负责方维护:
providers.models.openai.astra_api.context_window记录供服务商感知预算计算使用的模型输入窗口。providers.models.openai.astra_api.max_tokens用于限制生成输出的长度上限;它不是输入历史的限制。runtime_profiles.astra.max_context_tokens是 ZeroClaw 估算的本地裁剪阈值。它可能小于context_window。runtime_profiles.astra.max_tool_iterations限制智能体工具循环的次数,而max_history_messages则单独限定保留的完整用户轮次数(包括其中的工具交互)。通道发送者缓存保留其独立的基于行数的上限。runtime.reasoning_effort是面向提供商的全局推理级别。ZeroClaw 当前接受minimal、low、medium、high和xhigh。Astra 的公共 API 接受low、medium、high、xhigh和max,因此在 max 推理支持 合入之前,请使用共享值。
不要为 Astra 设置提供方的 temperature。Responses 适配器会原样转发已配置的值,不会修复不受支持的采样参数。请将 API 验证错误与账户、用量等级、地域或后端访问限制区分开来。
vision = true 表示运维人员确认此特定模型和端点支持图像输入。公开的 Astra 模型规范 目前列出了图像输入,但在启用之前,请验证已配置的账户和端点。工具结果的图像序列化是一个单独的适配器边界,跟踪于 #9599。
The Codex 订阅路由使用 requires_openai_auth = true 而不是 API 密钥,并且必须使用该后端提供的精确模型 ID。公共 API 可用并不代表 Codex 后端可用;请遵循 Codex 订阅指南,并在将生产流量路由到该路径之前测试账户。
公共 API 可能支持一些 ZeroClaw 尚未为此适配器开放的能力。推理状态连续性请跟踪 #10706,异步函数工具请跟踪 #10704,主动响应转向请跟踪 #10708,程序化工具调用请跟踪 #10707。在其 ZeroClaw 实现和提供方路由得到验证之前,这些均属于提案。
容器友好的覆盖
当 ZeroClaw 在容器内运行而提供商位于主机上(例如 Ollama)时,请将 uri 设置为主机可访问的地址。通用的环境变量覆盖机制(ZEROCLAW_<dotted_path_with_double_underscores>=<value>)可以在运行时设置同一字段,而无需编辑配置:
sh
ZEROCLAW_providers__models__ollama__home__uri=http://ollama:11434 zeroclaw agent -a assistant
__ 是路径分隔符;上面的示例设置了 providers.models.ollama.home.uri。完整语法请参阅环境变量。
每个模型的视觉能力
当某个提供商系列可以同时支持多模态和纯文本模型时,请使用 vision。该值属于提供商别名,因此路由和回退路径会将其与该别名的端点、凭据和模型一起解析:
[providers.models.openai.vision]
model = "gpt-4o"
wire_api = "responses"
vision = true
[providers.models.llamacpp.text]
model = "qwen3-4b"
vision = false
不设置 vision 会保留提供商系列内置的默认值。对于 OpenAI Responses 别名,请为接受图像输入的模型设置 vision = true;此显式启用可避免仅支持文本的 Responses 模型意外接收图像负载。
设置 vision = true 表示操作员明确声明所选别名接受图像输入。它会改变图像路由:ZeroClaw 会将图像附件保留在该别名上,而不是将其视为纯文本,或将其路由到 multimodal.vision_model_provider。仅在经过测试的 provider 和模型组合上设置此项。对于 grok_cli,同一字段仅控制 ZeroClaw 是否 发送 ACP 图像块;它不会重写 Grok 的 promptCapabilities.image 声明(截至 0.2.118 仍为 false),也不会让 CLI 可靠地描述图像。请参阅 ACP 视觉 / 图像输入。
当 [multimodal] vision_model_provider 指定带点号的提供方别名时,会自动使用其 model。显式设置的 [multimodal] vision_model 优先级高于别名中的模型;若两者均未设置,则使用主对话轮次模型以保持向后兼容。
原生思考显示(Anthropic)
agent.thinking.display 控制启用原生思考时 Anthropic 扩展思考的传递方式(agent.thinking.native_thinking = true)。可接受的值:
off(默认):不发送display字段;请求与早期 ZeroClaw 版本逐字节一致,思考请求使用非流式回退。omitted:Anthropic 会从响应中省略思考文本;块仅包含签名(thinking为空,但包含必需的 signature),在保持回放完整性的同时,尽量减少可见的推理内容。updates:请求携带thinking-display-updates-2026-08-18beta,并使用流式响应路径。模型工作时,可读的思考进度会实时呈现;已签名的推理载荷会单独保留,用于历史记录重放,且绝不会显示。summarized:相同的流式传输行为,请求摘要形式的思考。
[agent.thinking]
native_thinking = true
display = "updates"
此设置要求使用已加入 thinking-display-updates beta 的 Anthropic 账户;未加入时,API 会拒绝请求。将 display = "off"(或移除该字段)即可恢复之前的线路行为。
Prompt 缓存透传(chat-completions 网关)
cache_passthrough = true 用在 chat-completions provider 别名上时,会让该 provider 的请求启用 Anthropic 提示词缓存。对于将 Chat Completions 转换为 Anthropic Messages API 的网关(如 LiteLLM、TrueFoundry 等类似产品),请使用此设置;原生 Anthropic 系列默认已启用缓存,并会忽略该字段。
在使用此标志之前,请先确认该网关是否同时提供 Anthropic Messages 端点。如果提供,请将 [providers.models.anthropic.<alias>] 条目通过 uri 指向该端点,并完全跳过透传;原生 provider 会自行放置缓存断点。cache_passthrough 仅适用于只提供 Chat Completions 接口的网关。
With the flag on, requests gain at most two cache_control breakpoints: one on the system prompt, and one rolling breakpoint on the last message once the conversation has more than one non-system message, the same gate the native Anthropic provider applies. On a message that ends with an image, the rolling breakpoint sits on the message’s last text block; the image is covered by the following turn. With merge_system_into_user the system role never reaches the wire, so the merged first user message (or the synthetic user carrying the system text) carries the system-equivalent breakpoint instead. Only breakpoint-carrying messages change serialization.
Wait, I need to correct that. Here is the translation:
带有该标志开启时,请求最多会新增两个 cache_control 断点:一个位于系统提示词上,另一个滚动断点位于对话中非系统消息超过一条后的最后一条消息上,这与原生 Anthropic 提供方采用的门控条件一致。若消息以图片结尾,滚动断点位于该消息的最后一个文本块上;图片由后续轮次覆盖。启用 merge_system_into_user 时,系统角色永远不会出现在传输线路上,因此合并后的第一条用户消息(或承载系统文本的合成用户消息)会改为承载与系统等效的断点。只有携带断点的消息会改变序列化方式。
该标志也适用于结构化请求路径:代理轮次、工具调用和结构化流式传输。纯文本辅助函数(chat_with_system、chat_with_history,以及旧版分块流式 API)即使开启该标志也不会生成缓存断点,因为它们的响应不返回 token 用量,因此触发的高级缓存写入永远无法体现在计费统计中。对于这些辅助函数,该标志不生效,这也意味着通过它们进行的回退重入会发送未标记的请求。标志关闭时(默认值),请求体与之前的版本字节级一致。
[providers.models.custom.claude-via-gateway]
uri = "https://<gateway-host>/v1"
model = "<anthropic-routed model>"
api_key = "op://platform/gateway/api-key"
cache_passthrough = true
要求与注意事项:
- 需要网关支持。 只有当网关将带有
cache_control的块格式内容转发到原生 Messages API 时,缓存断点才会到达 Anthropic。直接代理 OpenAI API 的路由会忽略该字段。同一网关后面的非 Anthropic 路由模型不会明确报错:该字段会被接受并丢弃,网关仍可能在其自身的用量统计中对该路由计入缓存写入 token。请为 Anthropic 路由的模型设置专用别名,而不是在混合配置条目上启用该标志。 - 大小与 TTL。 Anthropic 仅缓存长度至少为 1024 个 token 的前缀(在部分较小的模型上为 2048 个 token),缓存条目大约在五分钟后过期,每次读取时都会刷新。简短或不频繁的对话无法从中受益。可以通过
cache_ttl为每个提供商单独配置缓存时长;参见 选择 1 小时缓存时长。 - 写入按溢价计费。 写入缓存的 token 按高于输入价格的溢价计费,所观察的路由对 5 分钟默认缓存的写入按 1.25x 计费。1 小时生命周期内的写入可能按其他费率计费,规划所用的数值参见选择 1h 缓存生命周期。读取享受大幅折扣。如果某个路由每次请求都写入缓存却从不读取,其成本反而高于完全不使用缓存。
- 先确认确切的路由。 网关会将多个模型别名暴露给同一个上游账户,而某个别名即使接受并计费缓存写入,也可能永远无法提供缓存读取。在生产环境中依赖该标志之前,先发送一个带标志的请求,并检查用量报告中
cache_creation_input_tokens > 0;然后立即重复发送逐字节相同的请求,并检查cache_read_input_tokens > 0。仅有缓存创建并不能证明缓存生效。每次更改模型别名或网关路由后,都要重新运行这一对请求。 - 用量报告。 当网关转发 Anthropic 格式的用量计数器时,
cache_read_input_tokens会填充 token 用量和成本报告中的缓存输入数值,cache_creation_input_tokens仅以计数形式写入调试日志。若响应报告的缓存读取为零,则缓存数值保持为零,而不会改用 OpenAI 格式的计数器替代。该统计仅覆盖结构化路径,这正是上文中没有用量采集的辅助函数保持惰性的原因。 - 工具定义不会被单独标记。 原生 Anthropic 提供方还会标记最后一个工具定义,这样在不存在系统提示词时,也能覆盖工具 schema 的 token。此标志不会标记工具定义;对于带有工具但没有系统提示词的请求,只会缓存滚动的消息断点。实时网关鉴定显示,当存在系统提示词时,工具 schema 的 token 本身就位于缓存前缀之内。
选择 1 小时缓存时长
cache_ttl = "1h" 表示该提供方的缓存标记所创建的缓存条目采用一小时的有效期,而非默认的五分钟。当对话经常在上一次请求五分钟之后才恢复时可以使用它:否则,每次恢复的轮次都要以全价重写缓存前缀,而更长的有效期本可以让该前缀保持有效。
盈亏平衡的计算方式如下,其中 P 为前缀的基础输入价格:5 分钟缓存写入的成本为 1.25P,1 小时写入的成本为 2P,因此选择 1 小时有效期每次缓存写入多花费 0.75P(命中会刷新缓存条目,因此该溢价按每次写入支付,而非按小时计算)。长有效期每避免一次过期,可节省 1.25P 减去 0.1P 读取费用,约 1.15P。对于输入价格为每百万 token 10 美元、前缀为 14 万 token 的情况,P 为 1.40 美元:每次 1 小时写入约多花费 1.05 美元的写入溢价,每避免一次过期约节省 1.61 美元,因此第一次避免的暂停净收益约为 0.56 美元,之后每次暂停净收益为完整的 1.61 美元。节省是有上限的:仅当前缀在超过 5 分钟、但不足 1 小时的间隔后被复用时才存在节省;若间隔超过 1 小时,则需再次支付 2 倍写入费用,且无任何节省。除写入溢价外,1 小时有效期还会对每个追加的尾部内容产生少量额外成本:即数千 token 乘以 0.75 再乘以输入价格,在该价格下,每轮对话的数千 token 尾部约需 2 到 3 美分。(0.1 倍的读取费率是常见数值,部分模型有所不同,因此请查阅 Anthropic 针对相应模型的提示词缓存定价表。)暂停时长介于 5 分钟到 1 小时之间的对话适合使用 "1h";持续活跃、快速结束或暂停超过 1 小时的对话则适合使用默认设置。
按 Anthropic 名义上的 2 倍缓存写入价格进行规划。API 前置的网关可能会按其自身费率对 1 小时写入计费。账本在存在配置或实时的 cache_write_per_mtok 费率时,按该费率计算缓存写入费用;当仅适用目录回退(目录中不包含写入费率)时,则按普通输入费率计算。cache_ttl 不会选择写入费率:如果运维人员将某条目改为 "1h",应将提供商的写入费率设置为与该路由实际收取的费用一致。
两项限制来自实时路由验证:超过五分钟的存活已在两次测试中得到证实,分别为六分钟和四十九分钟;完整的一小时生命周期未经测量。此外,本实现生成的每个标记都适用同一个 TTL:原生 Anthropic 提供方的 system、tool 和滚动消息标记,以及兼容透传的断点,均采用已配置的生命周期。运营方提供的 cache_control(通过 provider_extra 请求体字段或原始 tool JSON 传入)不在此保证范围内。同一请求中若存在混合生命周期,必须满足 Anthropic 的排序规则(1h 标记须位于 5m 标记之前)。
[providers.models.custom.claude-via-gateway]
uri = "https://<gateway-host>/v1"
model = "<anthropic-routed model>"
api_key = "op://platform/gateway/api-key"
cache_passthrough = true
cache_ttl = "1h"
在原生 Anthropic 入口上,同一密钥无需 cache_passthrough 也可使用:
[providers.models.anthropic.direct]
model = "claude-sonnet-4-5"
cache_ttl = "1h"
图片输入限制
[multimodal] 会限制进入请求管道的每一张图片,无论其来源是什么:渠道附件、工具声明的附件,还是 Web 控制台的上传内容。
[multimodal]
max_image_size_mb = 20 # per image, decoded bytes (default: 20, clamped to 1-20)
max_images = 4 # most images kept per request (default: 4, clamped to 1-16)
max_image_size_mb 在 base64 编码之前计量,因此实际发送给提供商的负载约大三分之一。20 MiB 的上限是各受支持视觉 API 中最低的单图或单请求限制,并且图片会被整体缓存,因此它也限制了每次上传占用的网关内存。若要限制每轮对话的上传成本,请降低该值。
Provider 会在此设置之上再施加各自的限制。Anthropic 会拒绝 base64 编码后超过 10 MB(解码后约 7.5 MiB)的单张图片,其客户端无论 max_image_size_mb 允许多大都会强制执行该限制。模型的上下文开销并不与字节数成正比:provider 会对图片进行栅格化,并按像素尺寸计费,因此体积大与体积小的文件,只要分辨率相同,成本大致相当。
max_images 统计对话中仍然存在的所有图片,而不仅仅是新增的图片,因此长会话会达到该上限。超过上限后,最旧的图片会被一次性批量移除,直到数量降至上限的一半(向上取整,即 4 降至 2,16 降至 8),然后数量会再增长到上限,之后才会进行下一批移除。移除图片会改变较早的消息,因此服务商的提示缓存会从该消息开始重建;采用批量移除意味着每新增 max_images / 2 + 1 张图片才发生一次,而不是每新增一张都发生。批量移除之后,模型看到的较早图片数量会少于上限允许的数量。对于截图较多的会话,请提高该上限。
各系列调节项:实例演示
Ollama
Ollama 默认使用本地端点,因此本地别名只需要模型名称:
[providers.models.ollama.local]
model = "llama3.1"
当 ZeroClaw 不是运行在与 Ollama 相同的主机上时,请设置 uri:
[providers.models.ollama.host]
model = "llama3.1"
uri = "http://host.docker.internal:11434"
Ollama 特定的可选字段是 num_ctx、num_predict 和 temperature_override。
Hailo-Ollama
Hailo-Ollama 使用单独的 hailo_ollama 插槽,因为其原生 API 对请求格式的要求比普通 Ollama 更严格。本地实例默认为 http://localhost:8000;模型发现会读取其实时的 /api/tags 响应。
[providers.models.hailo_ollama.edge]
model = "qwen3:1.7b"
context_window = 2048
max_tokens = 256
timeout_secs = 90
queue_timeout_secs = 30
将 uri 设置为 Hailo-Ollama 的基础 URL(当其运行在其他主机上时)。该 URL 必须使用 http 或 https,且不得包含凭据、查询参数或片段。别名 api_key 会以 Bearer Authorization 请求头的形式发送,extra_headers 会同时转发到原生聊天请求和模型目录请求。请勿同时配置 api_key 和显式的 Authorization 额外请求头:ZeroClaw 会拒绝这种含糊的凭据组合。对于每个规范化后的端点,生成请求会被串行化,同一时间仅允许一个活动请求,即使有多个别名指向该端点也是如此;排队中的任务若超过 queue_timeout_secs,将被拒绝。
对于非回环(non-loopback)端点,明文 http 会在没有传输加密或身份验证的情况下发送提示词和响应;当网络不是可信的隔离链路时,请使用 https。该提供方允许在本地和明确受信任的局域网部署中使用明文 HTTP,因为 Hailo-Ollama 的原生端点没有身份验证约定。
Hailo-Ollama 会拒绝无法实现的传输选项,而不是静默忽略它们。具体来说,tls_ca_cert_path、think=true、vision=true、调用级原生 thinking、provider_extra、api_path、wire_api 和 chat_template_kwargs 均不受支持。请设置 native_tools = false(或保持未设置)。
如果已接受的请求达到 HTTP 超时,或以其他连接建立后的传输失败结束,ZeroClaw 会将该端点隔离至进程剩余运行期间,因为客户端断开后 Hailo 可能仍在生成内容。请确认后端已空闲(必要时重启后端),然后重启 ZeroClaw 以清除隔离状态。连接建立失败不会隔离该端点。
为保证原生后端兼容性,ZeroClaw 会省略不受支持的 think 和 num_ctx 线路字段,而不是声称能够控制它们。原生服务会对每条解码后的消息再次将其解析为结构化提示词 JSON,因此 ZeroClaw 会对 API 值中的字面反斜杠以及 CR/LF/制表符控制字符进行转义,以便在该次解析过程中保留其原始含义。context_window 用于控制 ZeroClaw 尽力而为的本地历史记录预算。若要避免对整个提供方做出上下文假设,请省略该字段;配置一个正值即可启用本地预算。显式设置为零会被共享配置检查工具(shared configuration doctor)拒绝。它被有意不发送给 Hailo-Ollama。调用级别的原生思考(thinking)请求会在发送任何后端请求之前被拒绝。响应必须是已完成的非流式响应(done=true),空的已完成响应将被视为错误。当 context_window 较小时,会依据已配置的尽力而为的总预算,丢弃较早的、以用户为起点的完整对话轮次。在进行该检查之前,系统指令会先并入第一条保留下来的用户消息中。配置非零的 context_window 后,如果仅最新的完整对话轮次就超出已配置的预算,请求将在网络传输之前在本地失败,而不会丢弃该轮次,也不会替换为合成提示词。省略 context_window 时,不会应用提供方级别的本地预算。不存在提供方级别的字符数或消息数上限;实际支持的上下文容量仍以原生 HEF/运行时为准。
如果原生响应没有可见内容,但包含非空的内部推理字段,则提供方会将该字段用作最后手段的普通文本回退,以兼容那些只把输出放在该字段中的模型。它不会暴露单独的推理通道,调用方也不应将此回退视为支持扩展思考的证据。
原生工具调用、流式输出和视觉功能均不对外声明。由于 Hailo-Ollama 0.5.1 的聊天 DTO 中没有图像字段,vision=true 会被拒绝,而不会覆盖这一纯文本能力;请改为配置单独的支持视觉的提供方。当注入的完整工具协议能放入有界的第一条消息时,提示引导的工具调用及其结果仍会以纯文本历史的形式保留;若协议过长,ZeroClaw 会直接拒绝,而不会发送被截断的工具指令。
Azure OpenAI
Azure OpenAI 根据输入的 Azure 字段计算其 endpoint:
[providers.models.azure.work]
api_key = "op://platform/azure-openai/api-key"
model = "gpt-4o"
resource = "example-resource"
deployment = "gpt-4o-prod"
api_version = "2024-10-21"
resource、deployment 和 api_version 值保存在这个类型化配置中,不会从 Azure 特定的环境变量中读取。仅在需要完全覆盖计算出的端点时才使用 uri。
Amazon Bedrock
Bedrock 需要一个带有模型的别名;终端节点区域当前来自 Bedrock 身份验证环境/配置文件路径:
[providers.models.bedrock.work]
model = "anthropic.claude-sonnet-4-6"
Bedrock 提供程序使用 crates/zeroclaw-providers/src/bedrock.rs 中实现的凭证路径:
- Bedrock 别名上的
api_key,或BEDROCK_API_KEY,使用 Bedrock bearer-token 认证,并优先于 SigV4 凭据。 AWS_ACCESS_KEY_ID加上AWS_SECRET_ACCESS_KEY使用 SigV4。AWS_SESSION_TOKEN为可选项。AWS_REGION或AWS_DEFAULT_REGION用于选择签名区域,默认回退到us-east-1。- 来自
~/.aws/config或AWS_CONFIG_FILE的活动配置文件中的credential_process使用 SigV4。AWS_PROFILE用于选择配置文件,默认为default。 - EC2 IMDSv2 实例凭证是 SigV4 的最后回退方案。
配置架构还定义了一个 providers.models.bedrock.<alias>.region 字段,但当前实现不会读取该字段。端点区域始终从 AWS 凭证链(环境变量、credential_process 或 IMDS)中解析,如上所述。
当前 Bedrock 实现不会读取 ~/.aws/credentials 中的普通静态配置文件。~/.zeroclaw/secrets 仅存储 ZeroClaw 配置密钥(例如别名 api_key),不会为该提供程序导出 AWS_* 变量。
要通过已实现的配置文件路径复用 AWS CLI 配置文件,请在 ~/.aws/config 中放置一个 credential_process:
[profile zeroclaw-bedrock]
credential_process = /usr/bin/aws configure export-credentials --profile my-existing-profile
region = us-east-1
/usr/bin/aws 是 Debian 和 Ubuntu 上的默认路径。在其他系统上,请使用 command -v aws 得到的绝对路径。
然后使用 AWS_PROFILE=zeroclaw-bedrock 运行 ZeroClaw。有关 systemd 用户服务,请参阅服务管理。
多区域(Moonshot / Qwen / GLM / MiniMax / …)
每个系列一种类型;通过别名条目上类型化的 endpoint 字段选择区域。
自定义 OpenAI 兼容端点
custom 插槽需要 uri。请参阅自定义提供程序。
为代理选择使用哪个提供商
智能体通过点分隔的别名引用提供方。提供方条目本身不会执行任何操作。
risk_profile 和 runtime_profile 引用各自独立的别名映射,因此它们的名称不必匹配(runtime_profile 同样是可选的)。如果 model_provider 无法解析到已配置的 [providers.models.<type>.<alias>] 条目,或者 risk_profile 无法解析到已配置的 [risk_profiles.<alias>] 条目,Config::validate() 会在启动时直接报错失败。
关于将多个 agent 指向不同提供方的方法,请参阅 Routing。
单工具轮次支持
智能体运行时配置文件中的 single_tool_rounds 设置默认关闭。有关配置、用量统计和回滚行为,请参阅 单工具轮次。仅当实际使用的模型路由及所有可达的回退路由都支持原生控制参数时,该设置才会请求每次响应只调用一个工具。
| 已配置的提供商路径 | Native 控制 | 支持 |
|---|---|---|
openai、API 密钥认证、官方 OpenAI 端点、chat-completions 或 Responses 传输协议 | parallel_tool_calls: false | 已支持 |
anthropic,官方 Anthropic 端点 | tool_choice.disable_parallel_tool_use: true | 已支持 |
| 自定义或兼容端点、OVH、Codex 订阅认证以及其他适配器 | 无已验证的控制 | 批量处理,并附带可见的限制说明 |
Responses 和 Anthropic 在流式和非流式请求中都会发送该控制参数。OpenAI chat-completions 使用其现有的非流式实现,即使路由器将该响应转换为流式事件也是如此。不包含工具的请求保持其现有的请求结构。与受支持的提供商共享适配器,并不意味着支持另一个端点。混合回退链即使其主提供商支持该控制参数,仍保持批处理模式。
失败时回退
当对某个提供方的请求在用尽重试次数后仍然失败时(提供方宕机、密钥受到速率限制、模型不可用),别名可以回退到你在别名条目中声明的备选方案。两个独立、有序的维度:
fallback_models:在 此 提供方上尝试的备用模型 ID,使用相同的端点、密钥和请求头。仅模型标识符会发生变化。当某个提供方提供备用模型(更小或更旧的变体)且应在完全离开该提供方之前先行尝试时,可使用此项。fallback:一个由_其他_提供方别名组成的有序列表(采用点号分隔的<type>.<alias>形式引用[providers.models])。每个回退别名都会使用其自身的凭据、端点和模型进行解析,回退绝不会继承发生故障的别名所使用的密钥。
尝试顺序
遍历采用深度优先方式:在离开某个别名之前,会先穷尽该别名的整个模型列表,然后依次进入每个 fallback 别名,并递归应用该别名自身的 fallback_models 和 fallback。假设 anthropic.prod 提供 claude-sonnet-4-5,在其 fallback_models 中列出了 claude-haiku-4-5,并在其 fallback 中指定了 openai.backup(提供 gpt-4.1)。那么尝试顺序为:
anthropic.prod/claude-sonnet-4-5
-> anthropic.prod/claude-haiku-4-5
-> openai.backup/gpt-4.1
-> (request fails)
后备别名本身也可以声明 fallback,因此整条链的长度取决于你的配置,最大深度为 3 个别名。如果某条链形成自循环(a -> b -> a),系统会检测到并裁剪掉形成环的那条边;如果非环链的深度超过限制,则会裁剪掉多余的链接。无论哪种情况,都不会出现死循环、卡死或栈溢出。
配置错误
一个 fallback 条目若指向未配置的别名、形成循环引用,或导致链路超过最大深度,均属于非致命情况:Config::validate() 仍会成功,运行时会跳过有问题的边,并将该问题作为验证警告(dangling_fallback_ref / fallback_cycle / max_fallback_depth_exceeded)在 CLI 和仪表板中显示。一个 fallback_models 条目若为空白或与该别名的主 model 重复,同样会在运行时被跳过并予以显示(empty_fallback_model / fallback_model_duplicates_primary)。错误的回退链接会优雅降级,绝不会阻止 agent 运行。
Anthropic 拒绝与回退
Native Anthropic 请求可能返回一种 refusal(拒绝):HTTP 200 响应,其 stop_reason 为 "refusal",由 Fable 的安全分类器发出,而非正常完成。ZeroClaw 将拒绝视为类型化错误,以便回退机制通过两种方式进行恢复:
- 客户端(上文的
fallback_models):拒绝会以错误的形式出现,ZeroClaw 会像处理其他任何提供商故障一样切换到下一个模型或别名,因此回复将来自另一个模型。 - 服务端(在
[providers.models.anthropic.<alias>]中配置server_fallback_models):Anthropic 会在其服务端,以单次非流式调用的方式,对被拒绝的请求重试列出的模型。条目必须指定允许的回退目标,例如将claude-fable-5映射到claude-opus-4-8。
无论哪种情况,交付的回复都会带有一个简短的页脚,标明请求的模型和实际服务的模型,以便用户看到模型已切换。在 Web 控制台聊天中,同样的切换会在回答之前以内联提示的形式显示,且仅显示请求的模型名称和实际服务的模型名称。当一次普通的提供方故障已在 Anthropic 于其一侧切换模型之前,将请求转移到了客户端回退方案时,回复会同时保留普通的回退提示,从而让最初请求的模型保持可见,并且两种原因不会被混为一谈。
流式输出存在一项限制:如果拒绝响应是在流式输出已经开始之后才到达的,则保持现有的回复中断行为;回退机制仅适用于在输出开始之前检测到的拒绝。
OpenAI 兼容协议和 Responses 协议无法承载 Anthropic 原生的拒绝/回退元数据;若要获得此行为,请通过 [providers.models.anthropic.<alias>] 路由 Anthropic 模型。