Claude Code 模型封锁终极绕过指南:手写 MITM 代理完整方案与代码实战
直击痛点:为什么以往的好用方法一夜之间全部失效
Anthropic 在最新的 Claude Code(v2.1.126) 中悄然上线了一套极度严格的内生封闭机制,目的非常清楚:阻止用户通过代理工具(如 CC Switch 等)把底层模型替换为 DeepSeek V4 这类既聪明又便宜的第三方大模型。 如果你是一个重度依赖 AI 编程的开发者,某个早上打开终端敲入 claude,大概率会被满屏的 404 Model Not Found、400 Invalid Request,甚至流中断搞得措手不及。为了把这道封锁彻底拆掉,我经历了一整夜的排错,最终手搓了一个“终极中间人代理(MITM Proxy)”,直接让 Anthropic 的防线形同虚设。下面把整个破解过程和可以直接照搬使用的完整代码分享出来。
三重防线:从本地到流式,Anthropic 狠在何处
这次 Anthropic 一共设下了三道防线,一环扣一环,稍有不慎就会触发报错。
第一道防线:本地模型名称白名单校验
过去在代理中直接指名 --model deepseek-v4-flash,Claude Code 就会老老实实把请求外发。升级后,其默认模型被悄悄变更为 claude-sonnet-4-6,并且加上了本地强校验:所有非白名单模型名都会被本地拦截,网络请求根本不会发出去。
绕过思路很简单:顺着它的预期走,客户端依旧发送官方模型名 claude-sonnet-4-6,然后在代理层悄悄替换为真正的目标模型名,客户端完全感知不到底层变化,自然不再报错。
第二道防线:DeepSeek 端的 Catch-22 死循环
突破名称限制后,请求终于到达 DeepSeek,但紧接着就收到了 400 错误。这是因为 Claude Code 默认会携带 output_config: { effort: 'max' },而这个参数会强制触发 DeepSeek 的思考模式(Reasoner)。问题在于,DeepSeek 的 Reasoner 有一个致命缺陷——不支持工具调用(Tool Choice)。
这就形成了一个死锁:
- Claude Code 发出
effort: max→ 触发 Reasoner; - Reasoner 要求历史消息中包含
thinking块; - Reasoner 又不允许工具调用,一旦消息中带有 WebSearch 或 MCP 工具定义就会直接崩溃。
破解方式只能“断臂求生”:在代理层强制删除 output_config 参数,同时遍历所有历史消息,把所有 thinking 块剔除,让 DeepSeek 保持在支持工具调用的 V4 Flash 模式。代价是关闭了思考模式,但完整保留了工具调用的能力。
第三道防线:流式返回的实时校验
这是最隐蔽的一层。即便前两关都完美处理,DeepSeek 也如实返回了 HTTP 200,却会在数据返回中途被 Claude Code 主动掐断连接!深度排查日志发现,Anthropic 还在检查流式数据(Streaming)底部的模型名标记。DeepSeek 返回的流数据里带着 "model": "deepseek-v4-flash" 这样的字段,Claude Code 在接收时一看到不认识的模型名,立刻翻脸中断连接。
破解方法:实时流式篡改。代理拦截 DeepSeek 的返回流,在字节流转过程中把所有 "model":"deepseek-v4-flash" 实时替换为客户端请求的虚假模型名,让 Claude Code 以为一切正常。
反杀时刻:手搓终极流式篡改代理
为了一次性打穿这三道防线,我用 Node.js 写了一个完整代理。它的核心逻辑包括:
- 伪造模型列表:拦截
GET /v1/models请求,返回只包含claude-sonnet-4-6的列表,让客户端自检顺利通过。 - 强制降维:删除
output_config参数,同时剔除历史中的thinking块,彻底避免 Reasoner 模式的触发。 - 流式篡改(绝杀):拦截 DeepSeek 的响应流,把其中所有的模型名实时替换为客户端原本请求的假名字,完美骗过 Claude Code 的最终校验。
开箱即用的部署步骤(直接抄作业即可)
第一步:保存代理脚本
在你的电脑任意位置新建一个文件夹,创建文件 ds_proxy.js,将以下完整代码复制进去:
const http = require('http');
const TARGET_API = 'https://api.deepseek.com/anthropic/v1/messages';
const server = http.createServer(async (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET, POST');
res.setHeader('Access-Control-Allow-Headers', '*');
if (req.method === 'OPTIONS') {
res.writeHead(204);
res.end();
return;
}
// 1. 伪装 models 接口,避免 Claude Code 启动时校验模型列表报错
if (req.method === 'GET' && req.url.includes('models')) {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
data: [
{ type: "model", id: "claude-sonnet-4-6", display_name: "Sonnet 4.6" }
]
}));
return;
}
if (req.method === 'POST') {
let body = '';
req.on('data', chunk => body += chunk);
req.on('end', async () => {
try {
const data = JSON.parse(body);
const requestedModel = data.model || 'claude-sonnet-4-6';
// 2. 强制覆盖发往 DeepSeek 的模型名
data.model = 'deepseek-v4-flash';
// 3. 避免冲突:删除触发思考模式的参数,并剔除历史 thinking 块
delete data.output_config;
delete data.thinking;
if (data.messages && Array.isArray(data.messages)) {
data.messages.forEach(msg => {
if (msg.role === 'assistant' && Array.isArray(msg.content)) {
msg.content = msg.content.filter(block => block.type !== 'thinking');
if (msg.content.length === 0) msg.content.push({ type: 'text', text: '...' });
}
});
}
// 4. 发送请求给 DeepSeek
const fetchOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': req.headers.authorization || '',
'x-api-key': req.headers['x-api-key'] || '',
'anthropic-version': req.headers['anthropic-version'] || '2023-06-01'
},
body: JSON.stringify(data)
};
const apiRes = await fetch(TARGET_API, fetchOptions);
const headers = {};
apiRes.headers.forEach((value, key) => { headers[key] = value; });
res.writeHead(apiRes.status, headers);
// 5. 核心:拦截响应流,把模型名改回客户端请求的名字
if (apiRes.body) {
const reader = apiRes.body.getReader();
const decoder = new TextDecoder();
const encoder = new TextEncoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
let text = decoder.decode(value, { stream: true });
text = text.replace(/"model"\s*:\s*"[^"]+"/g, `"model":"${requestedModel}"`);
res.write(encoder.encode(text));
}
res.end();
} else {
res.end();
}
} catch (err) {
console.error("Proxy error:", err);
res.writeHead(500);
res.end(JSON.stringify({ error: err.message }));
}
});
} else {
res.writeHead(404);
res.end();
}
});
const PORT = 18082;
server.listen(PORT, () => {
console.log(`Ultimate Proxy started on port ${PORT}`);
});
第二步:启动代理
在终端中运行以下命令(请先确认已安装 Node.js):
node ds_proxy.js
保持此终端窗口持续运行。
第三步:设置环境变量并启动 Claude Code
打开一个新的终端(或 VS Code 内置终端),配置直连代理参数并填入你自己的 DeepSeek API Key。
Windows(PowerShell)用户:
$env:ANTHROPIC_BASE_URL="http://127.0.0.1:18082"
$env:ANTHROPIC_API_KEY="sk-你的DeepSeek密钥"
Remove-Item Env:\ANTHROPIC_AUTH_TOKEN -ErrorAction SilentlyContinue
claude
Mac / Linux 用户:
export ANTHROPIC_BASE_URL="http://127.0.0.1:18082"
export ANTHROPIC_API_KEY="sk-你的DeepSeek密钥"
unset ANTHROPIC_AUTH_TOKEN
claude
至此,你已经可以轻松地用 Claude Code 的完整前端,调用 DeepSeek V4 Flash 的推理引擎。
意外之喜:MCP 工具带来的彩蛋
完成所有设置后,你会得到一个意想不到的 bonus。
虽然 Anthropic 原生内置的 web_search 工具因其私有格式在 DeepSeek 兼容层上容易出现解析错误,但如果你在本地挂载了 MCP 工具(例如 Brave Search),这条通路走的是完全标准的 Function Calling 协议。DeepSeek V4 Flash 展现出了极高的智能,它能精准识别标准的 MCP 工具,成功发起调用,并将全网最新信息带回终端。
这意味着:使用 MCP 工具而非官方工具,反而获得了更出色的跨模型兼容性。 这并非事先预期,但在当前架构下成了一份额外的回报。
总结
这场攻防战清楚地展现了 AI 时代的“高墙”与“破壁者”之间的博弈。Anthropic 想通过层层硬编码和强校验将用户锁定在官方 API 生态中,但只要 HTTP 协议还是开放的,只要开发者能掌控网络交互中的每一个字节,生态封锁就终究会被击穿。
三道防线,三次破解。最终的架构非常清晰:Claude Code 前端 + MCP 工具链 + MITM 代理 + DeepSeek V4 Flash 推理引擎。
成本参考:DeepSeek V4 Flash 的定价约为 $0.28/百万 output tokens,仅相当于 Claude Sonnet 4.6 的约 1/30。在实测的日常编码场景中,代码生成和工具调用能力能够覆盖 90% 以上的需求。现在,尽情享受顶级 Claude 前端与高性价比 DeepSeek 算力的完美融合吧!
声明: 本文内容仅供技术研究、学习和内部测试使用。请尊重 Anthropic 与 DeepSeek 的服务条款,在合规范围内使用 API 服务。本文作者不鼓励任何违反服务条款的行为,也不对因使用本方案产生的任何问题承担责任。