记一次 AI agent 编排工具 Goose 持续出现 404 的长期未解决 Issue(已修复)
本文最后更新于 2026年3月19日 晚上
AI 真的很强,写文档的功力是我十年也赶不上的,但前提是:需求要说清楚。
这篇文章前后经过了三轮 AI 帮写,我自己再一边声明需求一边润色,面向 Spec 写博客是吧。
本文聚焦一个可复现、可溯源的问题:Goose Desktop / CLI 在执行
goose configure(或 GUI 里配置 Provider)时,Azure OpenAI 会在“拉取模型列表”阶段报 404,进而导致配置流程卡死。相关溯源:
1. 背景描述:无法加载模型
这几天我在 Windows(以及 Linux)上用 Goose Desktop GUI 通过 Other Providers 配置 Azure OpenAI 遇到一个的问题:
GUI 里配置看起来完全正确,但一用就报 404。
GUI 里会提示类似:
1 | |
更离谱的是:同样的 Azure OpenAI 服务
- 用
curl直接调用没问题 - 用 VScode 连该 API 也没问题
- 装了 Goose CLI 之后,Desktop 反而突然好了,甚至还能看到 CLI 刚跑出来的 session
- 换多台机器,不同操作系统验证过
这整件事看起来是:Goose Desktop 本地的 goosed 后端无法正确的加载。
2. 场景还原:排查 404 的试验过程
2.1 Desktop 里“看起来任何 provider 都 404”:先从日志入手
最开始我以为是 Azure 的 endpoint / api-version / deployment_name 填错了;但很快我发现一个更难评的现象:在 Desktop 里,很多 provider 的失败都会被 UI 统一呈现成 404。
GUI 经常出现:
1 | |
继续往下钻,就得看日志。Desktop 的 main.log 经常会把 goosed 后端(Rust)的 stderr 转存进去,因此你会在里面看到类似:
1 | |
这和 issue #3571 的症状非常像:同一套 key/模型用 curl 能通,但 Desktop 里持续 404。
就是下层的 raise 上层没有好好捕获,包起来了之:
Desktop UI 的报错经常只是“统一出口”。它告诉你“某个请求失败了”,但并不保证 404 一定来自真实的上游 API。
2.2 curl / PowerShell 直连 Azure:证明服务端本身没问题
排除“服务真挂了”最直接的方法,就是绕开 Desktop / goosed,直接对 Azure 发请求。
以 Azure OpenAI 为例,我当时的 endpoint(示意)类似:
1 | |
用 curl(或 PowerShell 的 Invoke-RestMethod)直连 chat/completions 能返回 200 并拿到回复。
结论:Azure chat/completions 本身是通的。
2.3 被 404 带偏的 4 小时:典型“错误方向”长什么样
接下来我偷了个懒,让 AI Agent 自己读上下文,读源码,自己编译看 log,就见它反复的把我的 token 烧在:
- API key / 权限 / 订阅
- endpoint / api-version / deployment 名称
- 网络、代理、证书、DNS
现在回头看,这些方向并不是完全不该查,而是当 Desktop 的错误信息无法准确定位“是哪一段请求失败”时,404 会把人强行拉进“外部 API 不通 / 配置不对”的思维定式,导致迟迟看不到“本地配置写入/加载”或“URL 组装逻辑”这类更接近根因的方向。
还有个原因就是我完全不懂 Rust ,这波也没有认真去看代码逻辑,正好想探索一下 AI 的边界,看看它有多少烧,虽然它最后确实也找到了 Bug, 但是它即时给出的 fix 我是没看懂的。
要彻底看懂要等正好我想提交 PR 的时候发现 Master branch 已经修复之后了,而这只是一个简单又常见的请求拼错地址和重构的时候拼地址范围搞错了的问题,要是我的工程中出现这个问题,不说 14mins 找到,总归不会烧 4h 吧。。。
3. Issue 跟进:为什么这个 404 现象长期悬而未决
我遇到问题时,社区里已经有一个很长的讨论串:
从公开讨论能看到几个典型阶段:
- 难以复现:维护者多次表示在“干净安装”环境里无法稳定复现,建议删除本地配置目录后重试。
- 噪声干扰排障:有用户在 DevTools 里看到本地
127.0.0.1:<port>/config/read的 404,于是误以为是“本地服务没启动”。随后贡献者指出这类 404 可能只是“读取了一个不存在的可选配置项”,属于噪声,不应当当作根因。 - 猜测模型/后端不匹配:讨论中一度怀疑是模型名(例如
-latest)或 provider/backend 不匹配导致 404,但缺少稳定复现的最小用例。 - issue 被关闭:根据 issue 元数据,该问题在 2026-02-06 被关闭(state: closed),当时我还以为“这就是用爱发电”,后来才知道可能是已经合并到主分支了只是还没 release。
3.1 我给出的绕过办法(gou7ma7 就是我)
我在 issue 下补充了一个可以绕过的办法(comment 作者 gou7ma7 是我本人):
核心观察是:
Desktop 写入
config.yaml时,只写了 Azure 相关的三项:1
2
3AZURE_OPENAI_ENDPOINT: <...>
AZURE_OPENAI_API_VERSION: <...>
AZURE_OPENAI_DEPLOYMENT_NAME: <...>但当你用 CLI 配置同一个 provider 时,会额外写入两行:
1
2GOOSE_PROVIDER: <...>
GOOSE_MODEL: <...>
然后仅仅是把这两行补进 config.yaml(不改别的),Desktop 就恢复可用。
说明:这一条“Desktop 写入配置不完整 -> 找不到 model -> 选择 model 必须先验证成功 -> 但验证又依赖已选 model -> 形成死循环”的推断,来自上面 comment 的试验观察与总结;它不是 #7034/#6832 PR 里直接声明的根因。
相当于跳过了配置的第一步,绕过这个死循环。
4. 统一报错为何会误导:Desktop UI、goosed(Rust)与 Azure 三段链路
把链路画出来,才知道 404 可能来自哪里:
- Desktop UI 通过
127.0.0.1调本地 goosed(Rust) - goosed 负责真正对外请求(列模型 / 发起对话)
- Azure endpoint 才是最终上游
flowchart LR
UI[Goose Desktop UI] -->|HTTP 127.0.0.1| GOOSed["goosed backend (Rust)"]
subgraph "Actions"
M[List models]
C[Chat completions]
end
GOOSed --> M
GOOSed --> C
M -->|HTTP or HTTPS| Azure[Azure OpenAI Endpoint]
C -->|HTTP or HTTPS| Azure
一旦 UI 把任何一段失败都折叠成“404”,就会陷入:到底是本地配置没生效、还是 goosed 组装 URL 错了、还是 Azure 真返回 404?
喜欢不严格的异常捕获最外包一层是吧。
5. 第一类根因(来自 issue):Desktop 写入配置不完整导致“配置死循环”
这条线来自我在 issue comment 的观察:Desktop 写入配置不完整,导致缺少全局的 GOOSE_PROVIDER 与 GOOSE_MODEL。
如果 Desktop 的 UI 在“选择 model”时强依赖“验证成功”才允许落盘,而验证逻辑又依赖已选 model,那么就可能形成死循环:
- 没有
GOOSE_MODEL-> goosed 不知道该用哪个模型 - UI 要求先验证才能写入
GOOSE_MODEL - 验证又需要模型 -> 验证失败
- 于是永远写不回去
这类问题本质上是“本地配置与状态机设计”的 bug,不一定与某个上游 provider 的 API 兼容性直接相关。
6. 第二类根因(源码解析):重构抽象 OpenAI-compatible Provider 时把 Azure 的 deployment 路径误并入 base URL,导致 GET /models 走错地址返回 404
这条线有明确的 PR 溯源:
- #7034 明确写了:它修复了 Azure OpenAI 在
goose configure时 model listing 404 的问题,并且说明与 #6832 相关。
“Relates to #6832 which broke this”
这里的“功能退化(regression)”含义是:原本能用的功能,因为一次重构/改动被改坏了。
6.1 Azure OpenAI 的两个不同语义路径(决定了为什么会 404)
对 Azure OpenAI 来说:
- 列模型是“全局路径”:
.../openai/models?api-version=... - 对话 completions 才需要绑定 deployment:
.../openai/deployments/<deployment>/chat/completions?api-version=...
如果把 deployment 错误地塞进“host/base path”,就会导致:
- chat/completions 可能仍然通(因为本来就需要 deployment)
- 但 models 会变成
.../deployments/<deployment>/models,Azure 不认 -> 404
6.2 #6832 做了什么:抽象 OpenAI 兼容 provider,但 Azure 的 base URL 选错了
#6832 的目标之一,是抽象出一个可复用的 OpenAiCompatibleProvider:
“OpenAiCompatibleProvider: reusable struct that implements Provider for any OpenAI-compatible API.”
抽象本身没问题,问题在于:Azure provider 把 client 的 host 指到了 .../openai/deployments/<deployment> 这一层,而 OpenAiCompatibleProvider 会去调用 GET models。
于是 models 请求被拼成了(概念示意):
- 错误:
.../openai/deployments/<deployment>/models - 正确:
.../openai/models
6.3 #7034 怎么修:host 回到 /openai,只给 completions 加 prefix
#7034 的 patch 描述写得很直白:
“Move Azure base URL from {endpoint}/openai/deployments/{name} to {endpoint}/openai and add a completions_prefix field so the deployment path is only prepended to chat/completions, not to models.”
你可以直接看两个关键 diff(节选):
azure.rs:host 从/openai/deployments/<name>改为/openai,并传入 completions_prefix
1 | |
openai_compatible.rs:新增completions_prefix,仅对chat/completions拼接
1 | |
6.4 新旧对比(简化图)
flowchart LR
subgraph "Before (broken)"
B1[Base URL includes deployments]
B1 --> Bm[GET models becomes deployments slash models]
Bm --> B404[404]
end
subgraph "After (fixed)"
A1[Base URL is openai]
A1 --> Am[GET models is openai slash models]
Am --> A200[200]
A1 --> Ac[POST completions uses deployments prefix]
end
7. 如何验证修复(基于公开 Release)
- v1.24.0 release notes 中包含:
- “Azure OpenAI model listing 404 during configure #7034”
- https://github.com/block/goose/releases/tag/v1.24.0
因此:如果你使用的是 v1.24.0 之前的版本,且症状是“配置 Azure OpenAI 时拉模型列表 404”,那很可能命中 #7034 修复范围。
8. 教训:同一个 404,可能是两套完全不同的根因
这次最难受的点是:“404”这个表象被复用了太多层。
- 第一类(issue 线):本地配置/状态机/落盘字段缺失,导致“永远选不上模型”
- 第二类(PR 线):provider 代码重构后,Azure 的 base URL 组装错误,导致
models走错路径
要减少这种排障成本,最有效的工程动作通常是:
- 把“哪一段请求失败”暴露出来(UI 不要把所有错误都折叠成 404)
- 为 OpenAI-compatible 抽象补契约测试(至少断言 Azure 的 models 路径不会带 deployment)
附:本文引用与溯源
- Issue:https://github.com/block/goose/issues/3571
- 你的绕过办法 comment(gou7ma7):https://github.com/block/goose/issues/3571#issuecomment-3871651227
- 引入 Azure 404 回归的重构 PR:https://github.com/block/goose/pull/6832
- 修复 PR:https://github.com/block/goose/pull/7034
- 修复 patch:https://github.com/block/goose/pull/7034.patch
- Release:https://github.com/block/goose/releases/tag/v1.24.0