OpenAI 与 Anthropic API 对比:Chat Completions 与 Messages 接口开发者指南

Apr 22, 2026 at 5:30:00 AM

如果你正在开发一个调用大语言模型的应用,那么你很可能需要对接 OpenAI 的 /v1/chat/completions 或 Anthropic 的 /v1/messages 接口。虽然两者的基本目标相同——将对话发送给 LLM 并获取回复——但它们在认证方式、请求结构、响应格式、工具调用、流式传输等方面存在显著差异。

本文详细梳理了两者的每一个主要区别,帮助你在选择服务商或构建统一抽象层时做出明智的决策。

认证方式

方面OpenAIAnthropic
认证头Authorization: Bearer sk-...x-api-key: sk-ant-...
版本头无需提供anthropic-version: 2023-06-01(必填)
组织/项目头OpenAI-OrganizationOpenAI-Project(可选)

Anthropic 强制要求 anthropic-version 头来锁定 API 行为版本,将 API 版本管理与模型名称解耦。OpenAI 则通过模型名称和接口变更来实现版本控制。

系统提示词

这是两者之间最直观的架构差异之一。

OpenAI 将系统提示词放在 messages 数组内部

{
  "messages": [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Hello"}
  ]
}

Anthropic 使用独立的顶层 system 参数,与消息数组完全分离:

{
  "system": "You are a helpful assistant.",
  "messages": [
    {"role": "user", "content": "Hello"}
  ]
}

Anthropic 的 system 字段还支持内容块数组(不仅仅是字符串),从而可以通过 cache_control 对系统提示词进行缓存。

消息角色与排序

OpenAIAnthropic
system / developer(o 系列模型)无(system 为顶层参数)
useruser
assistantassistant
tool(用于工具结果)无(工具结果放在 user 消息内部)

OpenAI 有 4 种不同角色,Anthropic 只有 2 种(userassistant)。Anthropic 严格要求消息交替排列——不能连续出现两条相同角色的消息。OpenAI 则更灵活,会自动拼接同角色的连续消息。

响应格式

OpenAI 将响应包装在 choices 数组中(支持通过 n 参数生成多个补全):

{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "choices": [{
    "index": 0,
    "message": {"role": "assistant", "content": "Hello!"},
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 13,
    "completion_tokens": 7,
    "total_tokens": 20
  }
}

Anthropic 直接返回类型化的内容块数组:

{
  "id": "msg_abc123",
  "type": "message",
  "role": "assistant",
  "content": [
    {"type": "text", "text": "Hello!"}
  ],
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 13,
    "output_tokens": 7,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 0
  }
}
方面OpenAIAnthropic
内容类型message.content 为字符串content 为类型化块数组
停止标识finish_reason: "stop"stop_reason: "end_turn"
长度停止"length""max_tokens"
工具调用停止"tool_calls""tool_use"
多个补全支持(通过 n 参数)不支持(始终返回 1 个)
总 token 数直接提供需自行计算
缓存统计响应中无内置(cache_creation_input_tokenscache_read_input_tokens

关键参数

参数OpenAIAnthropic
最大输出 tokenmax_completion_tokens(可选)max_tokens必填
温度0–2(默认 1)0–1(默认 1)
Top Ptop_ptop_p
Top K不支持top_k
频率惩罚frequency_penalty(-2 到 2)不支持
存在惩罚presence_penalty(-2 到 2)不支持
停止序列stop(字符串或数组)stop_sequences(数组)
种子(可复现性)seed不支持
对数概率logprobs不支持
用户标识usermetadata.user_id
扩展思考无(o 系列内部推理)thinking 对象,含 budget_tokens

迁移时最容易踩的两个坑:Anthropic 强制要求每个请求都设置 max_tokens(OpenAI 默认使用模型最大值),以及 Anthropic 的温度范围上限为 1.0,而 OpenAI 可达 2.0。

工具调用 / 函数调用

这是两个 API 之间最大的架构分歧之一。

工具定义

OpenAI 使用 type/function 包装结构:

{
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_weather",
      "description": "Get weather for a location",
      "parameters": {
        "type": "object",
        "properties": {"location": {"type": "string"}},
        "required": ["location"]
      }
    }
  }]
}

Anthropic 采用更扁平的结构,使用 input_schema

{
  "tools": [{
    "name": "get_weather",
    "description": "Get weather for a location",
    "input_schema": {
      "type": "object",
      "properties": {"location": {"type": "string"}},
      "required": ["location"]
    }
  }]
}

响应中的工具调用

OpenAI 通过独立的 tool_calls 数组返回工具调用,参数为需要解析的 JSON 字符串

"tool_calls": [{
  "id": "call_abc123",
  "type": "function",
  "function": {
    "name": "get_weather",
    "arguments": "{\"location\":\"Paris\"}"
  }
}]

Anthropic 以内容块形式返回工具调用,input 为已解析的 JSON 对象

"content": [{
  "type": "tool_use",
  "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV",
  "name": "get_weather",
  "input": {"location": "Paris"}
}]

返回工具结果

OpenAI 使用专用的 tool 角色:

{"role": "tool", "tool_call_id": "call_abc123", "content": "Sunny, 22C"}

Anthropic 将工具结果作为内容块放在 user 消息中,并提供显式的 is_error 标志:

{
  "role": "user",
  "content": [{
    "type": "tool_result",
    "tool_use_id": "toolu_01D7...",
    "content": "Sunny, 22C",
    "is_error": false
  }]
}

工具选择

行为OpenAIAnthropic
模型自行决定"auto"{"type": "auto"}
必须使用工具"required"{"type": "any"}
指定工具{"type": "function", "name": "X"}{"type": "tool", "name": "X"}
不使用工具"none"{"type": "none"}

视觉 / 多模态

OpenAI 使用 data URL 方案编码 base64 图片:

{
  "type": "image_url",
  "image_url": {
    "url": "data:image/jpeg;base64,{BASE64_DATA}",
    "detail": "high"
  }
}

Anthropic 使用独立字段分别指定媒体类型和数据:

{
  "type": "image",
  "source": {
    "type": "base64",
    "media_type": "image/jpeg",
    "data": "BASE64_DATA"
  }
}
方面OpenAIAnthropic
清晰度控制detail: "high"/"low"/"auto"
PDF 支持Chat Completions 中不支持原生 document 内容块
音频支持支持不支持

Anthropic 拥有独特的一等公民 document 块类型,支持 PDF 和文本文件,并可选启用引用功能——这是 OpenAI Chat Completions 接口所不具备的。

流式传输

两个 API 都使用 Server-Sent Events,但事件结构截然不同。

OpenAI 使用扁平的无名称 data: 行流,以 data: [DONE] 结束:

data: {"choices":[{"delta":{"content":"Hello"}}]}
data: {"choices":[{"delta":{},"finish_reason":"stop"}]}
data: [DONE]

Anthropic 使用命名事件类型,具有结构化的生命周期:

event: message_start
data: {"type":"message_start","message":{...}}

event: content_block_start
data: {"type":"content_block_start","index":0,...}

event: content_block_delta
data: {"type":"content_block_delta","delta":{"type":"text_delta","text":"Hello"}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: message_stop
data: {"type":"message_stop"}

Anthropic 的流式传输更为精细,包含 6 种以上的命名事件类型,覆盖完整的消息生命周期。这使得处理混合内容(文本与工具调用交织)更加方便,但增加了解析复杂度。OpenAI 的方式更简洁——本质上只有一种事件类型加一个终止标记。

错误处理

OpenAI 包含 param 字段,指明是哪个参数导致了错误:

{
  "error": {
    "message": "Incorrect API key",
    "type": "invalid_request_error",
    "param": null,
    "code": "invalid_api_key"
  }
}

Anthropic 使用基于 type 的辨别模式:

{
  "type": "error",
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key"
  }
}

Anthropic 将 overloaded_errorapi_error 区分开来,使得针对容量问题实现退避逻辑更加容易。

速率限制

方面OpenAIAnthropic
头部前缀x-ratelimit-(小写)RateLimit-(IETF 草案格式)
重置格式相对时长(1s6m0sISO 8601 时间戳
重试头非标准Retry-After

两者在遇到速率限制时都返回 HTTP 429,并建议使用指数退避加随机抖动。

各自独有的功能

OpenAI 独有

  • 多个补全——n 参数可在单次请求中生成 N 个替代回复
  • 对数概率——logprobs 返回 token 级别的概率信息
  • 结构化输出——response_format 配合 json_schema 保证 JSON 结构
  • 频率/存在惩罚用于控制重复
  • 音频输入/输出多模态消息支持
  • 种子参数用于可复现输出

Anthropic 独有

  • 扩展思考——显式 thinking 参数配合 budget_tokens,返回可见的思考块
  • 提示缓存——内容块上的 cache_control 支持 TTL 选项,使用量数据中包含缓存命中/未命中统计
  • PDF/文档处理——原生 document 内容块,支持引用
  • Top K 采样——top_k 参数控制 token 选择
  • 内置服务端工具——web_searchcode_executiontext_editor 等运行在 Anthropic 基础设施上
  • 工具错误标志——工具结果上的 is_error 字段

SDK 快速参考

# OpenAI
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello"}]
)
print(response.choices[0].message.content)

# Anthropic
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
    model="claude-sonnet-4-5-20250514",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}]
)
print(response.content[0].text)

迁移清单

如果你正在两者之间切换,或者构建统一的抽象层,以下是需要注意的关键事项:

  1. 移动系统提示词——从 messages 内部(OpenAI)移到顶层 system 字段(Anthropic),反之亦然
  2. 设置 max_tokens——在 Anthropic 中为必填,在 OpenAI 中为可选
  3. 限制温度范围——Anthropic 上限为 1.0;OpenAI 允许到 2.0
  4. 重构工具定义——parameters vs input_schema,包装对象差异
  5. 处理工具结果的方式不同——tool 角色(OpenAI)vs user 消息中的内容块(Anthropic)
  6. 解析工具调用参数——JSON 字符串(OpenAI)vs 已解析对象(Anthropic)
  7. 消息交替排列——Anthropic 强制要求,OpenAI 灵活处理
  8. 更新认证头——Authorization: Bearer vs x-api-key + anthropic-version
  9. 适配流式解析器——扁平数据块 vs 命名生命周期事件
  10. 解包响应——choices[0].message.content vs content[0].text

两个 API 都很强大且设计精良,但它们体现了不同的设计哲学。OpenAI 的 Chat Completions API 倾向于灵活性和向后兼容,而 Anthropic 的 Messages API 则更注重显式性和结构化数据。理解这些差异将帮助你无论选择哪家服务商都能构建出稳健的集成方案。