GitHub Copilot 看起来像一个简单 provider:登录账号,拿到 token,调用 Copilot API,选择模型,然后开始对话。
但 NousResearch/hermes-agent issue #7731 暴露出一个更真实的情况:Copilot provider 不是“有 token 就能用”的简单 OpenAI-compatible 接口。模型目录、上下文窗口、token exchange、OAuth client ID、Enterprise endpoint,其实是一条连在一起的认证与能力发现链。
只要其中一环按错,用户看到的就可能是:
- 账号里明明有的模型,Hermes 看不到;
claude-opus-4.6-1m这类账号特定模型上下文窗口显示错误;- 企业 Copilot 用户请求打到错误 base URL;
- 交换后的 endpoint 没有被识别,导致 Header 或认证逻辑缺失;
- Individual / Business / Enterprise 账号表现不一致。
这篇不是普通“API Key 错误”文章,而是一次 Copilot provider 能力发现链路复盘。
第一层坑:静态模型库不等于你的账号模型库
issue 里提到,Hermes 的 Copilot provider 会回退到 models.dev 这类静态模型数据。
静态模型库的问题是:它只能告诉你“常见模型大概是什么样”,不能告诉你:
- 当前账号可见哪些模型;
- 某个 preview / internal-only 模型是否开放;
- 当前账号的
max_prompt_tokens; - 企业策略是否隐藏或限制模型;
- 特定模型在 Copilot 里是否有不同 context window。
例如 claude-opus-4.6-1m 在某些 Copilot 计划里可用,但 models.dev 未必列出,或者列出的 context window 不准确。
所以正确的数据源应该优先是 Copilot /models API 返回的 live catalog,而不是静态 fallback。
第二层坑:原始 GitHub token 不等于 Copilot API token
issue 里另一个关键点是 token exchange。
设备流拿到的 ghu_* / gho_* 这类 GitHub token,并不一定就是调用 Copilot API 的最终形态。
完整模型目录、内部模型、企业 endpoint 等能力,需要通过:
/copilot_internal/v2/token
把原始 GitHub token 交换成短期 Copilot API JWT。
这个 JWT 里会携带更关键的信息,例如:
- 可用 endpoint;
proxy-ep;- token 过期时间;
- 与账号/企业策略相关的访问能力。
如果 Hermes 直接把原始 GitHub token 当 Bearer 发给 Copilot API,就可能进入一个“能部分工作,但能力不完整”的状态。
这类 bug 最难查,因为它不是彻底失败,而是半成功。
第三层坑:OAuth Client ID 会影响你看到的世界
issue 里还提到 OAuth client ID。
不同客户端身份可能影响 GitHub 返回的模型目录和权限语义。比如 VS Code、Copilot CLI、第三方工具,可能走不同 client ID / GitHub App / OAuth App 流程。
讨论里也特别谨慎:VS Code 的 client ID 不一定能直接替换,因为 GitHub App 与 OAuth App 的 device flow 权限语义不同。
这说明 provider 不能简单写死一个 client ID 后假设所有账号都一样。
更稳的做法是:
- 明确当前 client ID 的来源和能力边界;
- 用 Individual / Business / Enterprise 做测试矩阵;
- 不要只用个人账号验证后就宣布企业场景可用。
第四层坑:企业账号不一定走 api.githubcopilot.com
普通 Copilot 请求可能打到:
https://api.githubcopilot.com
但企业 Copilot 用户可能需要走交换 token 里给出的 endpoint,例如 proxy-ep 或 endpoints.api。
如果 provider 把 base URL 硬编码成 api.githubcopilot.com,企业用户就可能完全不可用。
评论里还有一个细节:某些代码只判断 URL 是否包含:
api.githubcopilot.com
但 token exchange 后 endpoint 可能是:
api.business.githubcopilot.com
于是本该加的 IDE auth header / Editor-Version header 没有加,最终触发:
HTTP 400: missing Editor-Version header for IDE auth
这类问题不是“Header 忘了加”这么简单,而是 endpoint 识别逻辑太窄。
为什么四个问题要拆成独立 PR?
评论里维护者建议把四个子问题拆成独立 PR,这个判断很专业。
因为它们虽然互相关联,但修复边界不同:
| 子问题 | 修复点 | 风险 |
| live context windows | /models 里的 max_prompt_tokens 接到 resolver | 低,局部清晰 |
| token exchange | 原始 GitHub token 换 Copilot JWT | 中,需要缓存/刷新策略 |
| OAuth client ID | 客户端身份影响模型目录 | 高,需要账号矩阵验证 |
| enterprise endpoint | 从 JWT 推导 base URL / proxy endpoint | 中,需要兼容 override |
如果一次大 PR 全改,review 会很难,也更容易把企业账号、个人账号、本地配置混在一起。
最终修复:#15114 做了什么
维护者后续说明该问题由 #15114 修复,其中关键两点已经落地:
1. Token exchange
exchange_copilot_token()调用api.github.com/copilot_internal/v2/token;- 将原始 GitHub token 换成短期 Copilot API token;
- 来源 PR
#12876; - commit
d7ad07d6f。
2. Live context windows
get_copilot_model_context()查询/modelsendpoint;- 使用账号实际返回的
max_prompt_tokens; - 覆盖
claude-opus-4.6-1m这类 models.dev 没有的账号特定模型; - 来源 PR
#12840; - commit
76329196c。
这比单纯更新一份静态模型表更可靠。
这和上一类“1M 上下文”问题有什么不同?
前一类问题是:Hermes 对模型上下文窗口有硬编码或错误默认。
这篇的 Copilot 场景更复杂:
上下文窗口错误只是表象
真正问题是 Copilot provider 没有完成账号级能力发现
也就是说,不只是“把 128K 改成 1M”这么简单。
Provider 必须先正确登录、交换 token、调用账号级 /models、读取 live max_prompt_tokens,再决定 context window。
企业 Copilot 用户的排查清单
如果你在 Hermes 里接 Copilot,尤其是 Business / Enterprise 账号,建议按下面查。
1. 确认模型目录来自 live /models
不要只看静态 models.dev。重点看当前账号真实返回了哪些模型。
2. 确认是否做了 token exchange
看是否调用过:
/copilot_internal/v2/token
以及后续请求是否使用交换后的 Copilot API token。
3. 确认 endpoint 是否来自 token
如果 JWT 里有 proxy-ep 或 endpoints.api,provider 不应继续硬编码默认 base URL。
4. 检查 endpoint 匹配逻辑
不要只匹配 api.githubcopilot.com。企业或 business endpoint 可能仍属于 githubcopilot.com,但 host 不同。
5. 记录账号类型
排查 Copilot provider bug 时,一定要说明:
- Individual / Business / Enterprise;
- OAuth client ID;
- 是否经过 token exchange;
/models原始返回;- 实际 endpoint;
- 报错 header / status code。
DeepAI API 中转站在这里能做什么?
DeepAI API 中转站适合统一 OpenAI-compatible 模型调用入口:
Base URL: https://api.deepai.wang/v1
API Key: 你的 DeepAI Key
Model: 以 DeepAI 控制台为准
但 Copilot provider 是 GitHub Copilot 自己的一套认证、token exchange、模型目录和企业 endpoint 机制。DeepAI API 中转站不能替 Hermes 完成 Copilot token exchange,也不能让 GitHub 企业 endpoint 自动生效。
更合理的定位是:
- 需要标准 OpenAI-compatible 接入时,用 DeepAI;
- 需要 GitHub Copilot 账号模型时,必须正确实现 Copilot provider 的认证和能力发现;
- 不要把 Copilot 当作普通 OpenAI-compatible base URL。
FAQ
为什么账号里有模型,Hermes 看不到?
可能 Hermes 没有使用账号级 /models live catalog,而是回退到静态模型数据。
为什么 claude-opus-4.6-1m 显示上下文窗口不对?
如果 models.dev 没有该账号特定模型,静态 fallback 就可能给错 context window。应使用 /models 返回的 max_prompt_tokens。
原始 GitHub token 不能直接调用 Copilot API 吗?
可能部分可用,但完整模型目录、企业 endpoint、internal-only 模型通常需要 token exchange。
企业账号为什么更容易出问题?
企业账号可能走不同 endpoint,且 endpoint 信息来自交换后的 JWT。如果 provider 硬编码默认 base URL,就会失败。
DeepAI 能替代 Copilot provider 吗?
不能直接替代 GitHub Copilot 账号体系。DeepAI 是 OpenAI-compatible API 中转站,适合标准模型调用,不负责 GitHub Copilot 的 token exchange 和企业 endpoint。
总结
Copilot provider 的坑不在“某个 URL 写错”这么简单,而是四层假设叠在一起:
静态模型目录 ≠ 账号真实模型目录
原始 GitHub token ≠ Copilot API token
普通 OAuth client ≠ 所有账号能力
默认 base URL ≠ 企业 endpoint
#7731 的修复重点,是把 Copilot 当成一个需要账号级能力发现的 provider,而不是普通 OpenAI-compatible 接口。