用 OPENAI_HOST 和精确模型 ID 让 Goose 跑在 Router One 上
Goose 是开源 AI agent,隶属 Linux 基金会下的 Agentic AI Foundation,Homebrew 上仍以 block-goose 的名字发布;它有桌面版和 CLI 两种形态,工具通过扩展在你的机器上执行。它内置的 OpenAI provider 接受任何 OpenAI 兼容端点:OPENAI_HOST 是主机根地址,OPENAI_BASE_PATH(默认 v1/chat/completions)会拼接在后面。把主机指向 Router One 之后,每一轮模型调用都是网关上的一次请求,带成本、延迟和状态 Trace;GOOSE_MODEL 用精确 ID 选择目录里的任意聊天模型。本指南讲环境变量配置、与之对应的 goose configure 提示和桌面版字段、自定义 provider JSON 的替代方案、gpt-5 系列名称被送往 /v1/responses 的规则,以及如何把一次带工具调用的会话与 Dashboard → Logs 对账。
安装 Goose,并单独建一把 Key
CLI 用官方安装脚本或 Homebrew(brew install block-goose-cli)安装;桌面版可直接下载,或 brew install --cask block-goose。安装脚本默认会在结尾进入交互式的 goose configure,加 CONFIGURE=false 可以跳过这一步,正适合本指南:provider 通过下面的环境变量配置,之后再用 goose configure 把同样的值持久化也可以。然后为这台机器单独创建一把设了 maxSpend 上限的 Router One Key,并从 /models 复制一个聊天模型的精确 ID;Goose 会把这个字符串原样放进请求的 model 字段。goose --version 可确认安装成功。下文的路径和默认值都对照 goose-docs.ai 页面和 v1.50.1 源码核对过。
# macOS/Linux 上安装 CLI:官方脚本;CONFIGURE=false 跳过交互式配置 curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash goose --version # 或用 Homebrew:brew install block-goose-cli(桌面版:brew install --cask block-goose)
把 Goose 配置到 Router One base URL
把代码块保存为 goose-env.sh,替换两个占位符,执行 source goose-env.sh,再运行 goose session。GOOSE_PROVIDER=openai 选中内置的 OpenAI provider,它的 id 就是 openai。GOOSE_MODEL 填目录里的模型 ID,逐字复制。OPENAI_API_KEY 会作为 Bearer token 发送;环境变量里的 Key 优先于 goose configure 保存的 Key,而写进 config.yaml 的 Key 会被忽略,表现为认证失败。OPENAI_HOST 是不带 /v1 的主机根地址:provider 会在它后面用一个斜杠拼上 OPENAI_BASE_PATH,所以按默认路径 v1/chat/completions,请求发往 https://api.router.one/v1/chat/completions;主机末尾多一个斜杠没有影响,但主机已经以 /v1 结尾就会变成 /v1/v1/chat/completions。因此 OPENAI_BASE_PATH 保持不设。选模型时要记住 provider 源码里的一条规则:base path 为默认值时,Goose 按模型名称决定端点。看起来像 OpenAI 的 gpt-5、gpt-6 或 o 系列的名称(在 ID 开头、或紧跟在 / 或连字符之后匹配,所以 openai/gpt-5.5 也算)会被送往 /v1/responses,其他名称都走 /v1/chat/completions。Router One 对目录中列出的 GPT 系列 ID 原生提供 /v1/responses,所以两条路径都能走通;Claude、Gemini、Grok 和 DeepSeek 的 ID 则留在 Chat Completions 上。发第一个请求前,用 goose info -v 打印实际生效的 provider、模型和主机:
# Goose built-in OpenAI provider -> Router One (macOS/Linux). source this file, then run: goose session export GOOSE_PROVIDER="openai" export GOOSE_MODEL="<exact-model-id-from-/models>" export OPENAI_API_KEY="sk-your-router-one-key" export OPENAI_HOST="https://api.router.one" # host root only: no /v1, no path # OPENAI_BASE_PATH stays at its default, v1/chat/completions. # Goose joins it to OPENAI_HOST -> POST /v1/chat/completions # (gpt-5, gpt-6 and o-series names are sent to /v1/responses instead).
每个值填在哪里,怎么验证
同样这几个值也可以通过 goose configure 输入(Configure Providers → OpenAI 会先问 Key,再问 OPENAI_HOST,默认值 https://api.openai.com,然后问 OPENAI_BASE_PATH,默认值 v1/chat/completions),或在 goose 桌面版填写(Settings → Models → Configure providers → OpenAI:API Key 和 Host URL)。不管走哪个界面,到达网关的请求都一样:
| Goose 字段 | 填什么 | 怎么验证 |
|---|---|---|
| GOOSE_PROVIDER(环境变量)、config.yaml 里的 active_provider,或 goose configure / 桌面版里选的 provider | openai | goose info -v 列出该 provider;自定义 provider 用它自己的 name(见下文 custom_…) |
| GOOSE_MODEL(环境变量)、config.yaml 里的 providers.openai.model,或桌面版 Switch models → Use custom model | <exact-model-id-from-/models> | Logs 里每条 Trace 的模型与 /models 逐字一致;goose configure 的模型列表来自网关的 GET /v1/models,列表里没有的 ID 直接设 GOOSE_MODEL 即可 |
| OPENAI_HOST(环境变量或 goose configure 提示)、桌面版 Host URL | https://api.router.one | 不带 /v1、不带任何路径;第一轮就 404 说明路径叠成了 /v1/v1/chat/completions |
| OPENAI_BASE_PATH | 不设,沿用默认的 v1/chat/completions | Logs 的 Trace 显示 POST /v1/chat/completions,gpt-5、gpt-6 和 o 系列名称则显示 POST /v1/responses;值里含 responses 会把所有模型都强制送到 /v1/responses |
| OPENAI_API_KEY(环境变量,或由 goose configure 存进系统 keyring) | 为这台机器单独创建、设了 maxSpend 的 Router One Key | goose configure 会提示 OPENAI_API_KEY is set via environment variable;第一条 Trace 出现在 Logs 里这把 Key 名下;贴进 config.yaml 的 Key 会被忽略 |
| OPENAI_ORGANIZATION、OPENAI_PROJECT、OPENAI_CUSTOM_HEADERS、OPENAI_TIMEOUT | 不设(超时默认 600 秒) | 网关只靠 Bearer Key 认证;这几项只会增加请求头或改超时,不影响路径和模型 |
| GOOSE_CONTEXT_LIMIT | 模型详情页上的上下文窗口,按 token 数填 | Goose 对不认识的名称一律按 128,000 处理;这个值影响它的 token 用量显示和压缩时机,不影响网关接受什么 |
替代方案:自定义 provider 的 JSON 文件
如果想让 Router One 与 OpenAI provider 分开——在选择器里有自己的名字、单独的 Key 和固定的模型列表——就定义一个自定义 provider。goose configure → Custom Providers → Add A Custom Provider,以及桌面版的 Add Custom Provider(Provider Type 选 OpenAI Compatible,填 Display Name、API URL、API Key、Available Models、Streaming Support),写出的都是同一个 JSON 文件,放在 custom_providers 目录:macOS 和 Linux 是 ~/.config/goose/custom_providers/,Windows 是 %APPDATA%\Block\goose\config\custom_providers\,每个 provider 一个 <name>.json。base_url 按官方示例填完整的 Chat Completions 地址;Goose 会把它拆成主机和请求路径,所以每一轮仍是 POST /v1/chat/completions,同样的模型名称规则也会把 gpt-5、gpt-6 和 o 系列 ID 送到 /v1/responses。models 列出你想在选择器里看到的 ID,每个的 context_limit 填模型详情页上的上下文窗口,绝不能填输出 token 上限;Goose 还会向网关请求 GET /v1/models 并列出返回的模型。api_key_env 指定存放 Key 的环境变量名:启动 Goose 前先 export,或者在桌面版里输入 Key 存进系统 keyring。把 GOOSE_PROVIDER 设成 name 字段的值即可选中它:
{
"name": "custom_router_one",
"engine": "openai",
"display_name": "Router One",
"description": "Router One unified LLM API gateway",
"api_key_env": "CUSTOM_ROUTER_ONE_API_KEY",
"base_url": "https://api.router.one/v1/chat/completions",
"models": [
{ "name": "<exact-model-id-from-/models>", "context_limit": <context-window-from-the-model-page> }
],
"supports_streaming": true,
"requires_auth": true
}给一次会话定预算,并逐轮对账
一次 agent 会话是很多次模型请求。Goose 每一轮调用一次模型,每拿到一个工具结果又调用一次,它的 provider 层还会对限流、服务端错误和网络错误重试最多三次,采用指数退避(1 秒起,每次翻倍,最长 30 秒),所以每一次真正到达网关的尝试在 Dashboard → Logs 里都是独立请求,有各自的 request_id、tokens、费用和状态。给每台运行 Goose 的机器单独一把设了 maxSpend 的 Key:会话触到上限后,下一轮会收到 HTTP 402,钱包和其他 Key 不受影响。Goose 内部也要限制循环:GOOSE_MAX_TURNS(默认 1000),或 goose session 和 goose run 的 --max-turns,以及针对完全相同的重复调用的 --max-tool-repetitions。这里有三份记录,只有一份是钱。Logs 是逐请求的费用。Goose 自己的 llm_request.*.jsonl 文件(~/.local/state/goose/logs/ 下最近的十条)保存模型配置、请求体、响应和 token 用量,是查看离开本机的 model 字符串最快的办法。GOOSE_CLI_SHOW_COST(默认 false)打印的是估算成本,不是网关的实际扣费。按时间、模型和 token 数对账,报障时保留 Logs 里的 request_id。developer 扩展、MCP 服务器、会话、权限(GOOSE_MODE)和上下文压缩都在 Goose 里运行;Router One 只记录模型调用,别的都不记。
Goose 该填哪个模型 ID?
从 /models 页复制精确的模型 ID,保留大小写、连字符和版本后缀,不要用展示名称代替。打开该模型的详情页,核对支持的 API 端点、上下文窗口和工具调用等能力,再与 Goose 当前选择的 provider 和功能对应。模型出现在目录里,不等于当前客户端能调用它的所有功能。建议为每个工具单独建 API Key,并设置 maxSpend 消费上限。
Goose 用的是哪种 API 协议?
OpenAI 兼容描述的是接口格式,不能据此推断 Chat Completions(/v1/chat/completions)、Responses(/v1/responses)和 Anthropic Messages(/v1/messages)可以互换。先核对工具当前版本、provider 配置和实际请求路径,再查模型详情与 API 兼容性事实页。一次普通对话成功,也不能证明服务端工具、历史状态或文件编辑功能都受支持。
在 trace 里验证 Goose 的调用
先在 Goose 发出一次简单文本请求,再到 Dashboard → Logs 按时间、模型和 request_id 核对 trace:tokens、花费、延迟和状态码。成功后再分别验证流式输出、工具调用和多轮历史。失败时保留实际请求路径、完整错误消息及 request_id;没有对应日志时,先查客户端配置和网络,不能仅凭客户端报错认定是网关或上游故障。
常见问题
设置好 OPENAI_HOST 之后,Goose 第一轮就返回 404,问题在哪?
多半是路径叠了。OPENAI_HOST 必须是主机根地址 https://api.router.one,因为 Goose 会在它后面用一个斜杠接上 OPENAI_BASE_PATH(默认 v1/chat/completions)。主机填 https://api.router.one/v1 就会请求 /v1/v1/chat/completions,把完整端点地址填进去路径更长;两种情况都会在调用任何模型之前收到 404 not_found。Goose 文档对代理的说法也一样:OPENAI_HOST 填根地址、末尾不带路径,遇到 404 先查 base path。在 Router One 上默认 base path 本来就是对的,所以只改主机,OPENAI_BASE_PATH 保持不设;值里含 responses 会把所有模型(包括 Claude 和 Gemini 的 ID)都送到 /v1/responses,GPT 和 DeepSeek 系列之外的 ID 在那里会在模型运行前收到 400 model '<id>' must be called via …。再查一下有没有遗留的 export:环境变量里的 OPENAI_HOST 会覆盖 goose configure 保存的值和 OPENAI_BASE_URL,goose info -v 显示的主机才是真正生效的。走自定义 provider 时,Goose 会从 base_url 推导请求路径,只填主机或以 /v1 结尾的地址都会被补全成 /v1/chat/completions,所以那里的 404 通常是地址本身写错了。
goose configure、config.yaml 和环境变量,到底以谁为准?
先环境变量,再配置文件,最后默认值,这是文档写明的顺序。shell 里 export 的 GOOSE_PROVIDER 和 GOOSE_MODEL 会在当前进程里覆盖 config.yaml 的 active_provider 和 providers.<id>.model;goose run 的 --provider 和 --model 只对这一次运行覆盖环境变量;会话中用 /model 可以切换模型。主机地址方面,provider 源码依次读取环境变量 OPENAI_HOST、OPENAI_BASE_URL(环境变量或配置,末尾的 /v1 会被去掉)、goose configure 保存的 OPENAI_HOST,最后才是 https://api.openai.com。Key 是配置文件的例外:Goose 不从 config.yaml 读取 provider 的 API Key;goose configure 把 Key 存进系统 keyring,没有 keyring 的环境则存进 secrets.yaml,而环境变量里的 OPENAI_API_KEY 优先于存储的值。goose 桌面版请在 Settings → Models → Configure providers → OpenAI 里填同样的值(API Key、Host URL);文档给桌面版的配置入口是这个页面,不是 shell 变量。配置文件在 ~/.config/goose/config.yaml(Windows:%APPDATA%\Block\goose\config\config.yaml),goose info -v 显示实际生效的值。
我没有改 base path,为什么 Goose 把 GPT 模型发到了 /v1/responses?
因为只要 base path 是默认值,OpenAI provider 就按模型名称选端点。它的源码匹配看起来像 OpenAI 推理模型的名称:gpt-5、gpt-6 后面跟一个点、连字符或名称结尾,以及 o3 这类 o 系列名称,匹配位置是 ID 开头或紧跟在 / 或连字符之后,所以 openai/gpt-5.5 也符合。这些轮次会被组装成 Responses 请求发往 /v1/responses,store 为 false。其他名称,包括 gpt-4o 以及 Claude、Gemini、Grok 和 DeepSeek 的 ID,都走 /v1/chat/completions。Router One 对目前列出的 GPT 系列和 DeepSeek ID 原生提供 /v1/responses,所以不用改什么:到 Dashboard → Logs 确认第一轮的路径和状态,在依赖 Responses 专属功能之前,先核对模型详情页列出了 POST /v1/responses。自定义 OPENAI_BASE_PATH 会改变这条规则:含 chat/completions 但不等于默认值的路径会让所有模型都走 Chat Completions,含 responses 的路径会让所有模型都走 Responses,所以除非你要的就是这种覆盖,否则不要设它。
Goose 能通过网关用哪些模型?
选用当前目录中同时支持 Goose 所用端点和所需功能的模型。精确 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,再按错误码速查页逐项排查。