Claude Code 升级后 DeepSeek API 报错 messages[x].role: unknown variant system 终极解决方案

问题现象

使用 Claude Code(VSCode/Cursor 插件或 CLI)配合 DeepSeek API 时,报错:

text 复制代码
API Error: 400 Failed to deserialize the JSON body into the target type: 
messages[1].role: unknown variant system, expected user or assistant

claude --print 模式正常,但交互模式(IDE 插件)必现。

根本原因

Claude Code v2.1.153+ 在交互模式下,会将某些上下文指令(如 CLAUDE.md 内容、skills 注入等)以 role: "system" 的形式直接放入 messages 数组,而非 Anthropic 规范要求的顶层 system 参数。DeepSeek 的 /anthropic 兼容端点对此做了严格校验,直接拒绝。

本质上是 DeepSeek 的 Anthropic 兼容层对消息格式的容错不如官方 API。

环境变量方案(治标)

~/.claude/settings.jsonenv 中添加:

json 复制代码
{
  "env": {
    "ANTHROPIC_MODEL": "deepseek-v4-pro",
    "CLAUDE_CODE_DISABLE_NON_ESSENTIAL_BETAS": "1",
    "CLAUDE_CODE_BETAS": "",
    "DISABLE_AUTOUPDATER": "1"
  }
}

此方案通过禁用 Beta 功能来减少不兼容性,但实测不一定对所有版本/场景生效

本地代理方案(治本,推荐)

写一个 Python 代理,拦截 Claude Code 发出的请求,自动把 messages 数组中的 system 角色消息移到顶层 system 参数,再转发给 DeepSeek。

创建代理脚本 claude_proxy.py

python 复制代码
import http.server, json, urllib.request

TARGET = "https://api.deepseek.com/anthropic"
API_KEY = "你的DeepSeek-API-Key"
PORT = 9877

class Proxy(http.server.BaseHTTPRequestHandler):
    def do_POST(self):
        length = int(self.headers.get("Content-Length", 0))
        body = self.rfile.read(length)
        try:
            parsed = json.loads(body)
            msgs = parsed.get("messages", [])
            extra, cleaned = [], []
            for m in msgs:
                if m.get("role") == "system":
                    c = m.get("content", "")
                    extra.append(c if isinstance(c, str)
                        else " ".join(x.get("text","") for x in c
                            if x.get("type") == "text"))
                else:
                    cleaned.append(m)
            if extra:
                existing = parsed.get("system", "")
                if isinstance(existing, list):
                    existing = " ".join(
                        x.get("text","") for x in existing
                        if x.get("type") == "text")
                parsed["system"] = (existing + "\n\n" if existing else "") + "\n\n".join(extra)
                parsed["messages"] = cleaned
                body = json.dumps(parsed).encode()
        except:
            pass
        url = TARGET + self.path
        req = urllib.request.Request(url, data=body, method="POST")
        for k, v in self.headers.items():
            if k.lower() not in ("host", "content-length"):
                req.add_header(k, v)
        try:
            resp = urllib.request.urlopen(req, timeout=60)
            rbody = resp.read()
            self.send_response(resp.status)
            for k, v in resp.headers.items():
                if k.lower() not in ("transfer-encoding", "content-length", "connection"):
                    self.send_header(k, v)
            self.end_headers()
            self.wfile.write(rbody)
        except Exception as e:
            self.send_response(502)
            self.end_headers()
            self.wfile.write(str(e).encode())

    def log_message(self, f, *a):
        pass

http.server.HTTPServer(("127.0.0.1", PORT), Proxy).serve_forever()

启动代理

bash 复制代码
python claude_proxy.py

修改配置

修改 ~/.claude/settings.json,将 ANTHROPIC_BASE_URL 指向代理:

json 复制代码
{
  "env": {
    "ANTHROPIC_BASE_URL": "http://localhost:9877",
    "ANTHROPIC_MODEL": "deepseek-v4-pro"
  }
}

重启 Claude Code 即可

开机自启(可选)

代理默认只在当前会话运行,重启电脑后会停。设为开机自启:

Win+R → 输入 shell:startup → 回车,在该文件夹新建 claude_proxy.bat

batch 复制代码
@start /min python "文件路径\claude_proxy.py"

之后每次开机代理都会自动在后台运行,无需手动启动。

如果还不行:例如你装了别的智能体

在 Cursor/VSCode 的 settings.json 中加上:

batch 复制代码
{
  "claudeCode.environmentVariables": [
    { "name": "CLAUDE_CODE_DISABLE_NON_ESSENTIAL_BETAS", "value": "1" },
    { "name": "CLAUDE_CODE_BETAS", "value": "" },
    { "name": "DISABLE_AUTOUPDATER", "value": "1" }
  ]
}

CLAUDE_CODE_DISABLE_NON_ESSENTIAL_BETAS=1 禁掉了 Claude Code 新版本自动启用的 Beta 功能(如 interleaved-thinking、prompt-caching-scope),这些 Beta 会导致请求格式与 DeepSeek 的 Anthropic 兼容代理不兼容。

注意事项

  • 重启电脑后代理会自动停止,需重新启动 python claude_proxy.py
  • 如果 DeepSeek 后续修复了兼容性问题,可去掉代理恢复直连
  • 建议同时设置 DISABLE_AUTOUPDATER=1 防止 Claude Code 自动升级引入新的不兼容

参考

相关推荐
星云穿梭7 小时前
用Python写一个带图形界面的学生管理系统——完整教程
python
金銀銅鐵8 小时前
用 Pygame 实现 15 puzzle
python·数学·游戏
黄忠13 小时前
大模型之LangGraph技术体系
python·llm
hboot1 天前
AI工程师第二课 - 数据处理
人工智能·python·数据分析
用户8356290780511 天前
使用 Python 自动化 PowerPoint 形状布局与格式设置
后端·python
用户8356290780511 天前
用 Python 自动化 PowerPoint 演讲者备注添加
后端·python
黄忠2 天前
01-系统架构设计-LangGraph状态机与多源异构RAG
python
zzzzzz3102 天前
假如我是掘金管理员,我先给评论区装个'代码审查'系统
python·程序员·机器人
砍材农夫2 天前
python环境|conda安装和使用(2)
后端·python
程序员龙叔2 天前
编写高质量 Skill 系列 -- 如何设计需求分析与用例生成的 SKILL
自动化测试·软件测试·python·软件测试工程师·接口测试·性能测试·skill·ai测试