TL;DR — Claude Code 说的是「新派 Anthropic 方言」,基元律动(TokenRhythm)的 DeepSeek 兼容端点只认「古典 Messages API」。鸡同鸭讲 → 400 Bad Request。解法:在 127.0.0.1 架一个约 150 行的 Node 代理,把每个请求「洗」成上游认识的格式再转发。不装依赖、不改环境变量、不留痕迹,双击即用。

脚本地址:GitHub - Ameng052/ClaudeCode-tokenrhythm-DeepSeek: 本地兼容代理驯服 DeepSeek 的 400 报错 · GitHub

 快速上手

  1. 装好 Node 18+ 和 Claude Code(脚本会自检 PATH)
  2. 两个文件放进同一目录
  3. 双击 RunTokenRhythm.cmd,回车确认模型 ID
  4. 用完即焚:代理进程、临时文件、内存里的 key,全部蒸发
  • 可每次调用手动传入APIKEY

  • 可在脚本中写死APIKEY

  • 可在脚本中指定写死模型

病因:400 是怎么炼成的

拆开 Claude Code 发出的请求体,里面全是兼容端点不认识的字段:

违禁品

位置

后果

anthropic-beta

请求头

400

thinking / output_config / context_management / service_tier

顶层字段

400

thinking / redacted_thinking block

messages[]

400

cache_control

散落在每个 block 里

400

role: "system" 混在消息列表里

messages[]

400

tool_use / tool_result 的扩展字段

messages[] / tools[]

400

上游校验器的逻辑很朴素:多一个字段,拒一个请求。这不是 bug,是协议代差。

处方:中间人,但站你这边

Claude Code ──→ http://127.0.0.1:<随机端口> ──→ https://tokenrhythm.studio
                      │
                      └─ proxy.js:只做一件事 —— sanitize

洗请求体:白名单制

const allowedTopLevel = new Set([
  "model", "max_tokens", "messages", "system", "stream",
  "stop_sequences", "temperature", "top_p", "top_k",
  "tools", "tool_choice", "metadata"
]);
// 不在名单里?delete。

洗 blocks:能丢的丢,能砍的砍

// thinking / redacted_thinking?丢。空 text?丢。
// tool_use 只留四件套:
kept.push({ type: "tool_use", id: block.id, name: block.name, input: block.input || {} });
// cache_control?递归剥光,一片不留。

洗角色:system 归位

role: "system" 不许躺在 messages[] 里 —— 提取文本,合并进顶层 system 字段,一条不剩。DeepSeek 兼容端点的第一条铁律。

洗请求头:beta 是重灾区

delete headers["anthropic-beta"];   // 最大的 400 来源,先斩后奏
delete headers["host"];             // hop-by-hop 头一并清理
headers["host"] = UPSTREAM.host;    // Host 重写到上游

留后手:可观测性

上游再返回 ≥400,代理把响应体原文打到控制台;?beta= 查询参数顺手抹掉;10 分钟超时兜底。下次再 400,至少有据可查。

启动器:一次性会话的工程美学

外面那层 15 KB 的 PowerShell 不是赘肉,全是细节:

  • 随机端口TcpListener(Loopback, 0) 让操作系统分配空闲端口,零配置、零冲突
  • 临时王国:所有状态塞进 %TEMP%\clawgod-tokenrhythm-<guid>\finally 块连锅端掉
  • 零环境污染ANTHROPIC_BASE_URL 只写进临时 settings.json,靠 --settings 传入 —— 用户级配置一个字节都没动
  • 模型大一统:OPUS / SONNET / HAIKU / subagent 全部指向 deepseek-v4-flash-0731,Claude Code 内部怎么调度都逃不出 DeepSeek 的手心
  • 顺手阉割:实验性 beta、交错思考、非必要流量全部关闭 —— 少发一个字段,就少一个 400 的理由
  • 看门狗:代理每秒探测一次父进程,PowerShell 一死它立刻陪葬,不留孤儿进程
  • 健康检查/__health 确认就绪后才启动 CLI,竞态不存在
  • .cmd 壳ExecutionPolicy Bypass + 退出码透传,双击即用;失败时 pause 把错误留在你眼前

结语:这不是补丁,是模式

「新客户端 × 旧兼容端点」的矛盾会永远存在。这套三层清洗可以原样套到任何同类场景:

  1. 顶层字段白名单
  2. block 级规范化(剥 cache_control、删 thinking)
  3. 请求头去 beta 化

代理不生产 token,它只是协议的搬运工。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐