Claude Code Provider 指纹调整复盘:JUN 8335 恢复与 x666 8334 边界
JUN 8335 的 channel:client_restricted 不是单纯 User-Agent 问题,而是缺少 Claude Code / Stainless 客户端指纹;补齐 x-stainless-*、收敛 anthropic-beta、固定 Accept: application/json 后,non-stream、stream、tool_calls 均恢复 200。x666 8334 即使本地 adapter 补齐同样指纹仍返回 Go-http-client/1.1,说明被拦的是 x666 服务端出站 client,不是本机请求。
继续把 JUN 8335 作为可用 Claude Code-shaped provider;x666 8334 保留 adapter 与最新指纹补丁,但不接入 Hermes 正式 provider,直到 x666 后端出站层改掉 Go client 指纹或更换 channel。
同一 key、同一模型下,JUN 单换 UA 全 403,但加完整 Stainless headers 后 /v1/messages 与 /v1/chat/completions 均 200;x666 本地 adapter 加同样 headers 后,健康检查和模型列表 200,真实推理仍四路 403,错误仍显示 检测到:Go-http-client/1.1。
已修改 /home/ht/code/jun_claude_code_shim.py 与 /home/ht/code/x666_claude_code_adapter.py,并重启对应 systemd user service。JUN 已验证可用;x666 已验证仍不可用,作为上游后端问题留档。
证据摘要
- 同一 key、同一模型下,JUN 单换 UA 全 403,但加完整 Stainless headers 后
/v1/messages与/v1/chat/completions均 200;x666 本地 adapter 加同样 headers 后,健康检查和模型列表 200,真实推理仍四路 403,错误仍显示检测到:Go-http-client/1.1。
行动清单
边界 / 风险
正文未抽取到明确风险;上线前仍需确认权限、回退路径与运行态影响。
完整记录
Claude Code Provider 指纹调整复盘:JUN 8335 恢复与 x666 8334 边界
背景
2026-06-15,JUN 8335 shim 开始返回:
初始判断容易落到“换 UA”上。但实测显示,JUN 当前策略不是只看 User-Agent,而是看一组更接近 Claude Code Node SDK 的客户端指纹。
同一轮排障还回看了 x666 8334:此前 x666 无论直连、本地 adapter、Axon channel 都返回 channel:client_restricted,且错误显示 Go-http-client/1.1。这次用 JUN 恢复经验再次补齐 x666 adapter headers,确认问题仍在 x666 后端出站层。
当前组件状态
JUN 8335
- service:
jun-claude-code-shim.service - script:
/home/ht/code/jun_claude_code_shim.py - local base_url:
http://127.0.0.1:8335/v1 - upstream:
https://muyuan.do/v1/messages - inbound key:
local-test - models:
claude-opus-4-8claude-opus-4-6claude-sonnet-4-6
x666 8334
- service:
x666-claude-code-adapter.service - script:
/home/ht/code/x666_claude_code_adapter.py - local base_url:
http://127.0.0.1:8334/v1 - upstream:
https://x666.me/v1/messages - inbound key:
local-test - models:
claude-opus-4-8-ccclaude-sonnet-4-6-cc
探测过程
第一轮:只换 User-Agent,JUN 全部失败
对 https://muyuan.do/v1/messages 分别测试:
claude-cli/2.1.176 (external, cli)claude-cli/2.1.176claude-cli/2.1.74 (external, cli)claude-cli/2.1.45 (external, cli)claude-code/1.0.0Claude-Code/2.1.176anthropic-python/0.64.0anthropic-typescript/0.60.0curl/8.5.0node- browser UA
结果:全部 403 或 Cloudflare 拦截。结论:单换 UA 没用。
第二轮:OpenAI endpoint 也不靠单 UA 恢复
对 https://muyuan.do/v1/chat/completions 做同样 UA 探测,结果仍全 403。结论:不是 /messages 单 endpoint 特有,JUN 当前 channel 对 client 指纹做更完整校验。
第三轮:补齐真实 Claude Code / Stainless headers 后 JUN 通过
参考公开抓包线索与实测,加入:
JUN /v1/messages 返回 200;JUN /v1/chat/completions 也返回 200。
第四轮:同样经验应用到 x666,仍失败
将 x666 adapter 改成同样 header 指纹,并加 gzip/deflate 解压。重启 x666-claude-code-adapter.service 后验证:
/health:200/v1/models:200claude-sonnet-4-6-ccnon-stream:403claude-opus-4-8-ccnon-stream:403- stream:403
- tool call:403
错误保持:
这个错误文本说明,被上游检测到的不是本机 adapter 的 Python/Claude headers,而是 x666 服务端出站请求的 Go client。
已落地修改
JUN shim
文件:/home/ht/code/jun_claude_code_shim.py
主要修改:
- 默认
anthropic-beta从多 beta 收敛为:
```text
interleaved-thinking-2025-05-14,oauth-2025-04-20
```
- 增加
x-stainless-*headers。 Accept固定为application/json。Accept-Encoding固定为gzip, deflate。- 增加 gzip/deflate 解压,避免压缩响应进入 JSON 解析时乱码。
- systemd unit 固化:
```ini
Environment="JUN_CC_USER_AGENT=claude-cli/2.1.74 (external, cli)"
```
验证结果:
x666 adapter
文件:/home/ht/code/x666_claude_code_adapter.py
主要修改:
- 默认 UA 改为:
```text
claude-cli/2.1.74 (external, cli)
```
- 增加
anthropic-beta与x-stainless-*headers。 Accept固定为application/json。Accept-Encoding固定为gzip, deflate。- 增加 gzip/deflate 解压。
验证结果:
判断
JUN 的根因
JUN 的 403 是本机 shim 发出的 client 指纹不完整。上游能看到并使用我们发出的 header,所以补齐 Stainless 指纹即可恢复。
对应链路:
x666 的根因
x666 的 403 不是本机 adapter headers 问题。即使本机 adapter 已发送完整 Claude Code / Stainless 指纹,上游错误仍显示 Go-http-client/1.1,说明 x666 服务端再转发到真实上游时使用了 Go 默认 client 或 Go-like 指纹。
对应链路:
本机侧不能改变 x666 后端出站请求的 TLS/HTTP/UA 指纹,因此不能靠 Hermes adapter 解决。
后续建议
短期
- JUN 8335 继续作为可用 Claude Code-shaped provider 使用。
- x666 8334 保留本地 adapter,但不加入 Hermes 正式 provider。
- provider 验证不能只看
/v1/models或/health,必须跑:
- non-stream
- stream
- tool_calls
- 至少两个模型
x666 若要恢复,需要上游后端改造
x666 服务端出站层至少需要:
如果仍失败,说明上游还检查 TLS / HTTP2 / header order / transport 指纹。那时 Go 里改 headers 不够,需要:
- Node/undici sidecar;或
- curl-impersonate / browser-like transport;或
- 真 Claude Code sidecar;或
- 直接换允许 server-to-server 调用的 channel。
Smoke Test 命令
JUN 8335
预期:HTTP 200,content 为 ok。
x666 8334
当前预期:HTTP 403,错误包含 Go-http-client/1.1。若未来变为 200,说明 x666 后端已修复或 channel 已更换。
经验规则
channel:client_restricted不要先假设是 key 或模型名问题,要看错误里的detectedclient。- 如果 detected 是本机发出的 UA,说明本机 adapter 还有机会修。
- 如果 detected 是后端出站 client,如
Go-http-client/1.1,而本机已发送不同 UA,则本机 adapter 无法直接修。 /v1/models200 只能证明模型目录可见,不证明推理链路可用。- Claude Code-shaped provider 的最小验收是:non-stream、stream、tool_calls 三条都 200。
- headers 恢复后要处理压缩响应,否则 gzip/deflate 可能让 JSON 解析失败。