Goose 接入统一 API:OPENAI_HOST 的两套写法

最后更新: 2026-07-16

Goose 的 openai 供应商接受一个 host 覆盖。设 GOOSE_PROVIDER=openai,把 OPENAI_HOST 指向 https://api.kkaiapi.com(裸域名),导出一个 Key,整个 Agent 循环连同工具调用都会经一个端点跑,目录里任意模型都能按 ID 寻址。

先说结论:留着 openai 供应商,改 host

Goose 有一条文档记录在案的自定义端点路径:GOOSE_PROVIDER 继续设成 openai,改的是这个供应商指向哪里。OPENAI_HOST 替换掉默认的 api.openai.com,OPENAI_API_KEY 负责鉴权,GOOSE_MODEL 按精确 ID 选模型。请求路径是单独一个变量:OPENAI_BASE_PATH 默认是 v1/chat/completions,通常不用改。 这个形状要仔细看,因为它和这一类工具里多数的约定是反的:OPENAI_HOST 接受裸 host,https://api.kkaiapi.com,不带 /v1 后缀。/v1/chat/completions 这部分活在 OPENAI_BASE_PATH 里。在 host 后面再加一个 /v1,会让路径重复,产生看起来像网关坏了的 404。

export GOOSE_PROVIDER=openai
export OPENAI_HOST=https://api.kkaiapi.com   # 裸 host,不带 /v1
export OPENAI_API_KEY=sk-你的kkaiapi密钥
export GOOSE_MODEL=claude-sonnet-4-6

goose session

Goose 怎么和它的供应商对话

Goose(GitHub 上的 block,约 5.1 万星标)是 Block 出品的自主工程 Agent,能规划任务、改文件、跑 shell 命令、驱动基于 MCP 的扩展。这一切都建立在一个模型对话之上:循环的每一步都是一次带着工具定义的 /v1/chat/completions 请求,所以供应商配置决定了整个 Agent 跑在哪里。 配置是分层的。交互式路径是 goose configure,对 openai 供应商会提示输入 API Key 和一个可选的自定义 host,然后把 GOOSE_PROVIDER、GOOSE_MODEL 这类非敏感设置写进 ~/.config/goose/config.yaml;桌面应用通过界面暴露同样的供应商设置。密钥是分开处理的:Key 走系统钥匙串或环境变量,直接粘贴进 config.yaml 的 Key 会被忽略,不会被读取。 环境变量会覆盖配置文件,这就是为什么上面的环境变量方案能在从笔记本电脑终端到 CI 运行器的任何地方都生效。因为 Goose 把 GOOSE_MODEL 原样传下去,ID 可以是 OPENAI_HOST 背后的端点提供的任意模型:今天是一个 Claude ID,明天换成 Kimi 或 Qwen ID,只差一个变量。

声明式路径:一个自定义供应商文件

除了环境变量覆盖,当前 Goose 文档还描述了声明式的自定义供应商:一个放进 ~/.config/goose/custom_providers/ 目录(Windows 上是对应平台的配置目录)的 JSON 文件,把网关注册成一个和内置供应商并列的、带名字的供应商。文件里声明引擎(chat-completions 端点用 openai)、哪个环境变量存 Key、端点 URL,以及这个供应商提供的模型。 这里的 URL 约定要留意,因为它又反过来了:和 OPENAI_HOST 不一样,自定义供应商的 base_url 是完整的请求 URL,包含路径,https://api.kkaiapi.com/v1/chat/completions。每个 models 条目都带一个 context_limit,让 Goose 知道能打包多大的窗口。 想让网关在 Goose 的供应商列表里以自己的名字出现、有自己的 Key 变量,而不是占用 openai 这个槽位时,声明式文件更合适。环境变量覆盖更适合 CI 和快速切换。两条路最终都到同一个端点;选一个,别叠加着用。

{
  "name": "kkaiapi",
  "display_name": "kkaiapi",
  "engine": "openai",
  "api_key_env": "KKAIAPI_KEY",
  "base_url": "https://api.kkaiapi.com/v1/chat/completions",
  "models": [
    { "name": "claude-sonnet-4-6", "context_limit": 200000 },
    { "name": "claude-opus-4-7",   "context_limit": 200000 },
    { "name": "kimi-k2.7-code",    "context_limit": 256000 }
  ],
  "supports_streaming": true,
  "requires_auth": true
}

给自主 Agent 选模型

实际的工作方式是固定住任务集,让 GOOSE_MODEL 在两三个候选之间轮换,每个跑几轮会话。因为每个候选都经同一个 Key,按 Key 的用量视图会不用你自己记账就给每次实验定价。

  • Goose 会跑一段一段无人值守的过程:规划、改文件、跑命令、读输出、循环。工具调用的可靠性比文笔更重要,这也是 claude-sonnet-4-6 和 claude-opus-4-7 成为主循环默认选择的原因
  • 像 kimi-k2.7-code 这类编程调优过的 ID 值得在重构密集的会话里测一下;经一个网关,这个测试就是改一个 GOOSE_MODEL 变量,不是迁移供应商
  • 长会话会累积上下文。一个通过 context_limit 如实声明真实 20 万窗口的模型,能让 Goose 在需要摘要之前带更多会话历史
  • 脚本或 CI 场景下,一个中端 ID(gpt-5.4、qwen3.7-max)对边界清晰的任务经常够用,成本只是旗舰模型的一小部分;先在自己的任务上测,再决定要不要默认用更贵的

主力模型价格

价格按 kkaiapi 中文区实时价格计算,单位 ¥/1M tokens(输入/输出)。

实时价格以 /pricing 为准
模型模型 IDkkaiapi 价格(输入/输出)适合场景
Claude Sonnet 4.6claude-sonnet-4-6¥3 / ¥15主循环默认
Claude Opus 4.7claude-opus-4-7¥5 / ¥25疑难任务升级
GPT-5.4gpt-5.4¥2 / ¥12中端对比
Kimi K2.7 Codekimi-k2.7-code¥5.85 / ¥24.3重构密集会话
Qwen 3.7 Maxqwen3.7-max¥10.8 / ¥32.4CI 与边界清晰任务

Goose 专属的翻车点

在 OPENAI_HOST 后面加了 /v1。这个变量接受裸 host,路径活在已经默认是 v1/chat/completions 的 OPENAI_BASE_PATH 里。把 https://api.kkaiapi.com/v1 填成 host,会产生 /v1/v1/... 这样的请求和 404。这是最常见的一个错误,恰恰因为这一类工具里其它每一个都要求带 /v1 后缀。 自定义供应商文件里的完整 URL 约定。声明式的 base_url 是完整请求 URL,包含 /v1/chat/completions,和 OPENAI_HOST 正好相反的约定。把一个裸 host 拷进自定义供应商文件,和把一个完整 URL 拷进 OPENAI_HOST 一样会坏得很彻底。 config.yaml 里的 Key 不参与鉴权。Goose 从钥匙串或环境变量读密钥,放在 config.yaml 里的 Key 值会被忽略。如果改完文件之后 401 依然存在,原因就在这;导出这个变量,或者重新跑 goose configure 在提示时输入 Key。 桌面会话看不到 shell 导出的变量。桌面应用不会继承终端配置里的任何东西。通过桌面设置界面配置供应商,或者从已经设好变量的 shell 启动。 配置来源叠加。一个旧的 OPENAI_HOST 导出可能覆盖掉刚在 config.yaml 里设的值,因为环境变量优先于文件。路由看起来不对时,在启动 Goose 的同一个 shell 里打印相关变量,再去怪任何一层。

谁会把 Goose 接到一个网关上

  • 把 Goose 当日常主力用的工程师,想让 Claude、GPT、Kimi、Qwen 都在一个 Key 背后,而不是每家厂商各一套凭证
  • 把 Goose 放进 CI 或定时任务的团队。纯环境变量路径意味着运行器只需要两个路由变量和一个密钥,注入和轮换都容易
  • 在真实任务上对比 Agent 模型的开发者,每个候选是对着同一个端点改一次 GOOSE_MODEL,按 Key 的用量自动定价
  • 想让 Agent 花费按 Key 和按模型可见、不用去对几个厂商仪表盘的平台团队
  • 手头没有某家厂商官方支付渠道的开发者,充值即用不需要海外卡

验证接入与排查首次会话

开一个会话之前先确认网关提供了 GOOSE_MODEL 里的那个 ID;/v1/models 的列表是权威拼写,版本后缀也算。 第一次会话的失败是有规律的。404 说明 host 和路径拼出了问题,几乎总是 OPENAI_HOST 里带了 /v1。401 说明 Key 不在 Goose 会去找的地方:没有在启动它的 shell 里导出、不在钥匙串里、或者只是没用地躺在 config.yaml 里。网关返回模型不存在,是 GOOSE_MODEL 里的 ID 拼错了。如果会话能起来但工具调用表现异常,先确认用的是真正支持工具调用的模型;上面表里的 ID 都支持。 循环跑起来之后,kkaiapi 控制台会显示每次请求的模型、token 数和花费。自主 Agent 是这一点最要紧的场景:会话长、工具调用轮次多,用量视图是唯一能看清一下午的 Goose 到底花了多少的地方。

curl -s https://api.kkaiapi.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY" | head -50

常见问题

Goose 能通过 openai 供应商跑 Claude 或 Kimi 模型吗?

能。openai 供应商是一个协议客户端,不锁定厂商:OPENAI_HOST 指向一个多厂商端点之后,GOOSE_MODEL 可以是端点提供的任意 ID,Claude、Kimi、Qwen 都算在内,工具调用的 Agent 循环不用改。

OPENAI_HOST 需要带 /v1 后缀吗?

不需要,加了反而会坏。OPENAI_HOST 接受裸 host(https://api.kkaiapi.com);请求路径活在默认就是 v1/chat/completions 的 OPENAI_BASE_PATH 里。这和多数工具的约定正相反。

环境变量覆盖和自定义供应商文件有什么区别?

环境变量覆盖直接改写内置的 openai 供应商:设置最快,适合 CI。~/.config/goose/custom_providers/ 里的自定义供应商 JSON 会把网关注册成一个带自己的 Key 变量和模型列表的独立供应商。两者最终都到同一个端点;选一个用。

为什么 Goose 会忽略我填进 config.yaml 的 API Key?

这是设计如此。Goose 从系统钥匙串或环境变量读密钥,忽略 config.yaml 里的 Key。导出 OPENAI_API_KEY(或者你声明的 api_key_env 变量),或者通过 goose configure 或桌面设置界面输入 Key,让它落进钥匙串。

CLI 和桌面应用共用这份配置吗?

共用 config.yaml 和钥匙串,但不共用 shell 环境:终端里导出的变量只对从那个终端启动的 CLI 会话生效,不会传到桌面应用。通过桌面应用自己的设置界面配置,或者依赖共享的配置文件加钥匙串。

Agent 任务该给 GOOSE_MODEL 填哪个模型?

主循环先从 claude-sonnet-4-6 开始;它在多步工具调用上表现稳。重构密集的会话可以测 kimi-k2.7-code,边界清晰的 CI 任务测一个中端 ID。经一个端点,每次测试都只是改一个变量。