# 前言

在使用 claude-code 命令行工具时,系统默认采用的是 Anthropic 原生的 API 格式。为了平衡成本与响应速度,许多开发者(包括我自己在内)选择接入国内的大模型或其他第三方中转 API。这就需要通过工具(如 cc-switch 等)进行模型映射与协议转换。

在实际配置中,我发现由于各大厂商的接口规范存在差异,部分国内模型在对接时频繁报错。为了彻底解决这一问题,看了下当前主流的四大 API 格式,并剖析模型映射的底层逻辑与常见踩坑点。


# 主流大模型 API 格式拆解

当前主流大模型厂商在技术演进与架构设计上各有侧重,其 API 主要分为以下四种形态。

# 1. OpenAI Chat Completions (传统经典格式)

作为大模型领域普及度最高的行业标准,全球绝大多数兼容阵营(如 DeepSeek、智谱 GLM、月之暗面 Kimi 等)均原生支持该格式。

  • 核心理念无状态(Stateless)的文本对话拼接。服务端不保存会话状态,多轮对话必须在客户端自行维护历史上下文,并在每次请求时完整传递 messages 列表。
  • 适用场景:单次问答、常规多轮对话、接入第三方开源模型。

# 🐍 Python SDK 示例

from openai import OpenAI
client = OpenAI(api_key="your_api_key")
response = client.chat.completions.create(
    model="gpt-4o", 
    messages=[
        {"role": "system", "content": "你是一个幽默的助手。"},
        {"role": "user", "content": "为什么程序员喜欢天黑写代码?"}
    ],
    temperature=0.7
)
print(response.choices[0].message.content)

# 2. OpenAI Responses API (全新智能体格式)

这是 OpenAI 针对 “智能体(Agent)” 和 “有状态(Stateful)” 应用推出的全新一代接口规范,旨在替代传统的 Chat Completions。

  • 核心理念有状态会话与内置工具链
  1. 服务端状态托管:客户端可通过传回上一次请求的 previous_response_id 承接上下文,无需每次重复发送冗长的历史数据。
  2. 原生 Agent 能力:内置官方托管的 web_search (联网搜索)、 file_search (文件检索)、 code_interpreter (代码解释器)等工具,服务端自动执行 Agentic 循环。
  3. 细粒度数据单元:数据单元由 Message 演进为更细粒度的 Item ,原生支持中间思考(Commentary)与最终答案(Final Answer)的标记分离。
  • 适用场景:复杂 AI Agent 开发、长对话内存管理、免客户端拼装的联网 / 代码沙盒应用。

# 🐍 Python SDK 示例

from openai import OpenAI
client = OpenAI(api_key="your_api_key")
# 1. 发起第一轮对话,并开启官方的联网搜索工具
response_1 = client.responses.create(
    model="gpt-5.5", 
    input="2026年最新发布的 iPhone 有什么新功能?",
    tools=[{"type": "web_search"}] 
)
print(response_1.output[0].content[0].text)
# 2. 第二轮对话:通过 Response ID 实现服务端记忆无缝承接
response_2 = client.responses.create(
    model="gpt-5.5",
    input="它的售价是多少钱?",
    previous_response_id=response_1.id 
)
print(response_2.output[0].content[0].text)

# 3. Anthropic Messages (Claude 阵营)

Anthropic 遵循极其严格的输入校验规范,在参数结构、安全过滤以及长文本推理(如 Extended Thinking 深度思考流)上做了精细化设计。

  • 核心理念结构绝对分离、角色严格交替
  1. system 提示词属于顶层控制参数,禁止混入 messages 数组中。
  2. messages 列表内的角色必须严格按照 userassistant 顺序交替出现,且首尾角色需符合校验规范。
  • 适用场景:复杂逻辑推理、大规模代码审查、长文本深度分析。

# 🐍 Python SDK 示例

from anthropic import Anthropic
client = Anthropic(api_key="your_api_key")
message = client.messages.create(
    model="claude-3-5-sonnet",
    max_tokens=1024,
    system="你是一个代码审查专家,只指出代码中最严重的 1 个问题。", # 系统提示词外置
    messages=[
        {"role": "user", "content": "这里有一段 Python 代码: `def add(a, b): return a + b`"} # 严格交替
    ]
)
print(message.content[0].text)

# 4. Gemini Native generateContent (Google 阵营)

Google 从底层重构了多模态(Native Multimodal)架构,将非文本模态视为与文本对等的底层原生数据。

  • 核心理念一切皆是 Part(多模态内容块)。一个 contents 对象包含一个 parts 数组,文本、图片二进制、音频流在内部以平等的 Part 形式并列存在,而非将非文本数据作为文本列表的变体。
  • 适用场景:音视频复合多模态理解、百万级超大上下文检索。

# 🐍 Python SDK 示例

import google.generativeai as genai
genai.configure(api_key="your_api_key")
model = genai.GenerativeModel(
    model_name="gemini-1.5-pro",
    system_instruction="你是一个视觉艺术评论家。" # 系统提示词外置
)
with open("painting.jpg", "rb") as f:
    img_data = f.read()
# 发起原生多模态调用,文本与图片数据是平等的 Part
response = model.generate_content([
    "请结合这幅画的色彩,分析作者表达的情感:",
    {"mime_type": "image/jpeg", "data": img_data} 
])
print(response.text)

# 模型映射的底层原理

Claude Code 会默认调用 Anthropic 的 Messages API 。如果我们希望将其替换为 DeepSeek-V3 等高性价比模型,就必须引入模型映射。

# 1. 为什么需要映射?

Claude Code 内部硬编码了对 Anthropic 格式的解析逻辑。如果直接将请求发送给支持 OpenAI 规范的 DeepSeek 服务器,会由于参数结构不匹配(如 system 字段位置错误、角色交替校验失败)直接导致接口报错。

因此,映射的核心目的是实现协议翻译与端点伪装

  • 对内:承接 Claude Code 发出的 Anthropic 格式请求。
  • 对外:翻译为目标模型(如 OpenAI 规范)可读的格式并发送。

# 2. 映射的两种实现方式

# 原理 A:中转代理层(软映射)

通过在本地或服务器部署中转工具(如 cc-switch 、OneAPI、LiteLLM),在流量中间进行协议重写。

[Claude Code] 
     │  (Anthropic 格式: model="claude-3-5-sonnet")
     ▼
[中转代理 (如 cc-switch / OneAPI)] ── 字典映射: 将模型字段改写为 "deepseek-chat"
     │  (翻译为 OpenAI 格式)
     ▼
[目标模型官方服务器]

# 原理 B:服务端原生伪装(硬映射)

部分厂商(如 DeepSeek)为了方便开发者迁移,在服务端原生提供了 Anthropic 兼容端点。我们只需通过修改环境变量,重定向请求的目标地址即可。


# DeepSeek 的双重 API 格式对比

在实际配置映射时,DeepSeek 提供了两种不同的端点以应对不同的接入场景:

# 格式一:DeepSeek 标准 API(OpenAI 兼容规范)

常规客户端调用或标准中转工具对接时使用的标准格式:

POST [https://api.deepseek.com/chat/completions](https://api.deepseek.com/chat/completions)
{
  "model": "deepseek-chat", 
  "messages": [
    {"role": "system", "content": "你是一个疯狂的程序员。"},
    {"role": "user", "content": "帮我重构这段代码。"}
  ],
  "stream": true
}

# 格式二:DeepSeek 的 Anthropic 兼容 API(专供 Claude Code)

该端点完全模拟了 Anthropic 的接口规范。此时即便模型名称传入 claude-3-5-sonnet ,DeepSeek 服务端也会自动接收并透明转换为内部模型运行:

POST [https://api.deepseek.com/anthropic/v1/messages](https://api.deepseek.com/anthropic/v1/messages)
{
  "model": "claude-3-5-sonnet", 
  "system": "你是一个疯狂的程序员。", 
  "messages": [
    {"role": "user", "content": "帮我重构这段代码。"}
  ]
}

# 🛠️ 实战配置:在 Claude Code 中落地映射

基于上述原理,我们无需修改任何源码,只需在终端配置两个核心环境变量,即可将 Claude Code 的后端无缝替换为 DeepSeek 的兼容接口:

# 1. 将 Claude Code 的请求目的地重定向至 DeepSeek 的 Anthropic 兼容端点
export ANTHROPIC_BASE_URL="https://api.deepseek.com/anthropic"
# 2. 将 API Key 替换为你的 DeepSeek 官方 API Key
export ANTHROPIC_API_KEY="sk-xxxxxxxxxx"
# 3. 启动 Claude Code
claude

运行机制:启动后,Claude Code 会正常封装 Anthropic Messages 格式的数据包并发送至 api.deepseek.com/anthropic 。DeepSeek 服务端接收后解析并执行编码任务,随后再将结果封装为 Anthropic 响应格式返回给客户端,实现无缝替换。


# ⚠️ 常见踩坑点与局限性

在配置过程中,如果遇到配置正确但接口依然报错死活无法使用的情况,需要重点排查模型类型

目前,该兼容端点暂时无法直接接入深度推理模型(如 DeepSeek-R1)。由于推理模型在输出时会包含特定结构的思考链路( <think> 标签),这种长推理流与 Claude Code 的 Agent 状态机解析存在冲突,会导致客户端流式解析崩溃。因此,在做映射时,请务必确保后端使用的是常规通用对话模型(如 deepseek-chat / DeepSeek-V3 ),切勿直接挂载推理模型。