Claude Code 和 Codex 渐渐用得得心应手之后,我本来已经不缺一个能写代码、跑命令、改文件的 Agent。
真正让我再次技痒的,是我陆续在网上看到的另一套工作方式:Claude Cowork 可以接手一整个文件夹、拆分并行工作流,还能使用内置浏览器、操作桌面应用、定时执行任务。相比守着终端和代码仓库,它更像是在接过一整件知识工作。
今晚,研习各种攻略后,我从官网下载并打开了 Claude Desktop App。开启 Developer Mode,一个 Configure third-party inference 页面出现在眼前:Claude Desktop 的界面、Cowork、Projects 和 Artifacts 都可以保留,真正处理请求的模型却可以来自另一套推理网关。看到这里,我还是有点意外——Claude 自家的桌面应用,竟然给“换掉 Claude”留了一扇门。
我自然想到了 CopilotX。一个月前,Claude Code 遇上 GPT-5.6时,它已经搭好了 Anthropic Messages 到 OpenAI Responses API 的桥。看起来,只要把桌面端接到这座现成的桥上就够了。
真正动手后,三扇门依次横在眼前:第一扇写着“App 已损坏”;第二扇只认名字里带 Claude 的模型;第三扇更隐蔽——它只拿 1 个 token 测试连接,而 GPT-5.6 Sol 至少要 16 个。
第一扇门:刚下载就被强制移入废纸篓
Claude Desktop 应从 Anthropic 官方下载页获取。官方帮助中心也给出了 macOS 的标准安装流程:下载 DMG,将 App 安装到 Applications,再启动并登录。
但这次,DMG 能正常打开,Claude.app 一启动,macOS 就弹出提示:
“Claude”已损坏,无法打开。你应该将它移到废纸篓。

我一度怀疑这是 Anthropic 的地区可用性限制。它的 Supported Countries 页面确实没有列出中国大陆,这可能影响下载、登录或服务访问。但截至写作时,官方安装文档没有说明“不支持的地区会触发 macOS 损坏提示”,因此不能把两件事直接画上等号。
更准确的描述是:一次原因不明的本地拦截,让一个刚下载的官方 App 被 macOS 判定为损坏,并要求强制删除。 接下来能做的不是猜它为什么拦,而是验证眼前这个文件到底是否可信。
“已损坏”是一个结论,不是诊断。直接删除重下,只是在重复同一个动作。真正需要回答的是三个问题:
- DMG 的内容是否完整?
- App 是否由 Anthropic 签名并经过 Apple 公证?
- macOS 是否因为下载隔离属性而拒绝启动?
实际检查结果如下:
- DMG 校验和有效;
- macOS 将发布者识别为 Anthropic PBC,并确认已经公证;
- App 的深层代码签名校验通过;
- 文件带有 macOS 的下载隔离标记。
这些结果只能证明两件事:文件本身完整,发布者身份可信。它们无法反推出弹窗究竟由地区策略、下载链路还是 macOS 本地状态触发。已知的是,文件带有下载隔离属性,而移除该 App 的隔离属性后可以正常启动。
处理方式不该是全局关闭 Gatekeeper,而是先验证,再只移除这个 App 的隔离属性:
具体做法分两步:先用 macOS 自带的 hdiutil、spctl 和 codesign 检查镜像与应用签名;三项都通过后,再安装 App,并且只清除 Claude.app 自身的 quarantine 属性,最后重新启动。
# 仅在完整性、发布者和代码签名均验证通过后执行
xattr -dr com.apple.quarantine /Applications/Claude.app
open -a /Applications/Claude.app
如果 App 的签名验证失败,不要执行 xattr,应重新从官方页面下载。也不要为了安装一个 App 而全局禁用 Gatekeeper。安全机制不是障碍;跳过验证才是。
处理完成后,Claude Desktop 正常启动。真正有意思的部分才刚开始。
第二扇门之前:先把 Developer Mode 打开
Claude Desktop 正常启动后,第三方推理配置并不会自动摆在首页。需要先开启 Developer Mode:
- 打开 Claude Desktop;
- 点击 macOS 顶部菜单栏的 Help;
- 进入 Troubleshooting;
- 点击 Enable Developer Mode;
- 在警告框中确认 Enable。

当前版本的确认框写得很直接:Developer Mode 会开放开发工具与调试功能,只应在清楚自己正在做什么时启用。开启后,才能进入 Configure third-party inference,选择 Gateway、认证方式和模型列表。
第二扇门:五个输入框背后的协议
打开第三方推理设置页,Connection 选择 Gateway,认证方式选择 Static API key。
CopilotX 的配置如下:
| 字段 | 填写内容 |
|---|---|
| Connection | Gateway |
| Credential kind | Static API key |
| Gateway base URL | 网关根地址,例如 https://your-gateway.example.com |
| Gateway API key | 网关分配的 API Key 原文 |
| Gateway auth scheme | Bearer |
| Artifact preview iframe origin | 留空 |
Base URL 必须是网关根地址,不要额外添加版本路径或具体 API endpoint。Claude Desktop 会自行补全模型发现和推理路径;手动多写一层,地址就会被重复拼接。API Key 也只填原始值,不要自行添加认证前缀。
这些字段全部保存后,Gateway 连接成功了。但 Claude Desktop 随即给出另一个错误:
Gateway returned no usable models.
第一次转折:16 个模型,一个都“不存在”
CopilotX 的模型目录明明返回了多种可用模型。地址正确,API Key 正确,响应格式也没有问题。
答案藏在 Desktop 的模型名称约定里。它要求 Gateway 暴露一个看起来像 Anthropic 模型的路由名,普通 GPT 或 Gemini 模型 ID 会被视为不可用。
这解释了那个看似矛盾的结果:上游模型都存在,却没有一个符合 Desktop 对 Gateway 路由的命名要求。
关闭自动发现、手动填写 gpt-5.6-sol 也不行。配置页会明确警告:Gateway model route 必须看起来像一个 Anthropic 模型;而且校验不只是寻找 claude,名字中出现 gpt 等其他模型家族标识,同样会被拒绝。
这里需要的不是伪装模型能力,而是定义一个网关路由名:Desktop 看到符合其约定的入口,网关再把入口解析到真实上游。
最终采用的名字是:
- Desktop 路由:
claude-copilotx-sol - CopilotX 上游:
gpt-5.6-sol - Desktop 展示名:
GPT-5.6 Sol
CopilotX 中只需加入一条显式路由。用伪代码表示,就是:
Desktop 请求 claude-copilotx-sol
→ Gateway 解析路由
→ 上游选择 gpt-5.6-sol
名字承担的是路由协议,不是假装 GPT 变成了 Claude。模型选择器仍然显示 GPT-5.6 Sol,真实请求进入 CopilotX 后也会在推理前映射回 gpt-5.6-sol,再根据实时模型目录选择 Responses transport。
Claude Desktop 的 Model list 最终配置为:
| 字段 | 值 |
|---|---|
| Model ID | claude-copilotx-sol |
| Display name | GPT-5.6 Sol |
| Offer 1M-context variant | 关闭 |
| Default to 1M context | 关闭 |
| Tier alias | opus |
| Default for tier | 开启 |
1M 开关不能凭感觉打开。它是一项能力声明,不是“越大越好”的显示选项。没有验证上游确实支持 1M context,就应该保持关闭。
模型名终于通过了校验。然后,第三扇门出现了。
第二次转折:连接探针只给 1 个 token
点击 Check again 后,Claude Desktop 仍然报告 HTTP 400。这一次,错误体足够具体:
Invalid
max_output_tokens: integer below minimum value. Expected a value >= 16, but got 1 instead.
这条错误反而证明,前面的配置已经全部正确:请求到达网关,认证已经通过,模型别名也成功映射,失败只发生在最后一个参数约束上。
Claude Desktop 的可用性探针为了节省开销,只请求 1 个输出 token。Anthropic Messages 接受这个值,但 GPT-5.6 Sol 背后的 Responses API 要求 max_output_tokens >= 16。两边都没有错,错位发生在兼容层。
修复应放在 Anthropic→Responses 转换器里:低于 16 的值抬到 16,正常业务请求则保持原值。
实际输出上限 = max(客户端请求值, 上游最低值)
边界测试覆盖了三种情况:1 → 16、16 → 16、17 → 17。这不是把所有请求粗暴改成 16,而是只消除两套 API 之间的下限差异。
修复部署到网关后,用与 Desktop 完全相同的最小探针重新请求,服务正常返回 OK。
再次点击 Check again,橙色错误消失。模型选择器右下角出现了 gpt-5.6-sol。
到这里,GPT-5.6 Sol 才真正住进 Claude Desktop。
兼容不只是“接口能通”
这次最值得留下的,不是 Claude Desktop 又多了一个模型选项,而是三层失败分别揭示了三种不同的兼容面:
| 表面错误 | 真正边界 |
|---|---|
| App 已损坏 | 操作系统信任与下载隔离 |
| No usable models | 模型发现与命名约定 |
max_output_tokens 过小 | 客户端探针与上游参数约束 |
消息接口的 JSON 能被解析,不等于真实客户端就能工作。它还会发现模型、验证名称、探测可用性,并带着自己对默认值和最小响应的假设。最小请求,往往最容易撞上边界。
协议兼容只是起点;行为兼容才决定产品能不能真正亮起来。
CopilotX 版本线:
| 日期 | 里程碑 | 博文 |
|---|---|---|
| 2/9 | v1.0:本地 API | 把 Copilot 变成本地 API |
| 2/9 | v2.0:远程服务 | 从本地工具到远程服务 |
| 2/13 | v2.3:Tool Calling | 让 OpenClaw 终于能动手了 |
| 4/6 | v2.4:可观测性 | 盲飞三个月后,它终于睁开了眼 |
| 6/12 | v2.7:多用户密钥 | 换锁记:当我把钥匙哈希之后 |
| 8/13 | v2.8:Responses 桥 | Claude Code 遇上 GPT-5.6 |
| 9/3 | Claude Desktop Gateway | 本文 |
收束
三次拒绝分别来自三个系统,每一次单看都很合理。真正缺少的,是中间那层愿意理解两边约定、把差异收进去的桥。
现在,Claude Desktop 仍然是熟悉的 Claude Desktop。它有 Cowork,有 Projects,也有 Artifacts。只是模型选择器里,多了一行 gpt-5.6-sol。
这次,换脑没有改变它的脸。


