Anthropic Messages

POST /v1/messages — Anthropic Messages 原生协议,支持 content blocks、流式事件与 tool_use 工具调用

积木平台提供 Anthropic Messages 原生协议端点。已有 Anthropic SDK 的项目无需重写调用逻辑,只需把 base_url 指向积木、把 API Key 换成积木令牌即可迁移。

本端点对请求参数做透传,并对齐 Anthropic 官方原生格式——不做参数名的中间翻译。因此参数的具体写法(尤其是思考参数)应以你实际调用的模型的官方文档为准;不同模型系列即使走同一个接口,参数形态也可能不同,详见下文「不同模型的思考参数差异」。
同一个积木令牌可同时用于 OpenAI、Anthropic、Gemini 三种协议。协议选择建议: 已有 Anthropic SDK 用本文的 /v1/messages;已有 OpenAI SDK 用 对话补全;已有 Google SDK 用 Gemini 原生协议。

端点与鉴权

POST/v1/messages
POST/v1/messages/count_tokens

鉴权支持两种方式,任选其一(网关统一转换为 Bearer 校验):

Authorization: Bearer <令牌>
x-api-key: <令牌>

x-api-key 是 Anthropic 官方 SDK 的默认鉴权头,原样可用。anthropic-version 请求头可选,网关不强制校验。令牌获取与管理见鉴权与令牌。

请求参数

modelstring必填

模型 ID,如 claude-sonnet-5、claude-opus-5。可用模型以 GET /v2/models 返回为准

messagesarray必填

对话历史,按时间顺序排列。结构见下文「消息结构」

max_tokensinteger

最大生成 token 数。积木网关运行时可选,缺省时按模型设置补默认值。为明确控制输出长度,建议始终显式传入

systemstring | array

系统提示,独立顶层字段,不作为 message 出现。支持纯字符串或 content blocks 数组

streamboolean

为 true 时以 SSE 流式返回,见下文「流式输出」

默认值: false
stop_sequencesarray

停止序列字符串数组,命中即停止生成

temperaturenumber

采样温度,越高越随机

top_pnumber

核采样概率阈值

top_kinteger

Top-K 采样

toolsarray

工具定义数组,见下文「工具调用」

tool_choiceobject

工具选择策略:{"type":"auto"} / {"type":"any"} / {"type":"tool","name":"..."} / {"type":"none"}

thinkingobject

扩展思考配置,参数形态因模型代际而异:Claude 4.5 及更早模型用 {"type":"enabled","budget_tokens":N}(budget_tokens 最小 1024,且必须小于 max_tokens);claude-opus-5/claude-sonnet-5 等 4.7 及更新代际模型改用 {"type":"adaptive"} 配合顶层 effort 控制深度,发送 type:"enabled" 会直接返回 400。完整对照见下文「不同模型的思考参数差异」。推理用量一律以响应返回的 usage 为准

effortstring

控制自适应思考(thinking.type:"adaptive")的推理深度,档位与合法取值因模型而异(如 low/medium/high)。仅新代际模型使用,具体以下文差异表与实际调用结果为准

metadataobject

附加元数据,如 {"user_id":"..."}。该字段可能不被透传,不要依赖它在响应侧回显或用于业务追踪

消息结构

messages 数组中每条消息只有 user 与 assistant 两种角色,没有 system 角色——系统提示通过顶层 system 字段传入:

{
  "model": "claude-sonnet-5",
  "max_tokens": 1024,
  "system": "你是天气播报员,回答控制在 20 字内",
  "messages": [
    { "role": "user", "content": "北京天气?" }
  ]
}

content 支持两种形态:

  • 纯字符串:"content": "你好"
  • content blocks 数组:多模态、工具调用时必须用数组形态

Content blocks

block type用途关键字段
text文本内容text
image图片输入source:{"type":"base64","media_type":"image/png","data":"..."} 或 {"type":"url","url":"https://..."}
tool_use模型发起的工具调用(出现在 assistant 消息)id、name、input
tool_result工具执行结果回传(出现在 user 消息)tool_use_id、content

图片输入示例(base64 已实测透传成功):

{
  "role": "user",
  "content": [
    {
      "type": "image",
      "source": {
        "type": "base64",
        "media_type": "image/png",
        "data": "iVBORw0KGgoAAAANSUhEUgAA..."
      }
    },
    { "type": "text", "text": "这张图里有什么?" }
  ]
}
推荐统一使用 base64 形式传图;source.type 为 url 时存在无法读取的情况。图片输入要求模型具备视觉能力。

多轮对话中 assistant 消息同样用 blocks 数组回传(含模型此前输出的 tool_use block),见下文「工具调用」。

请求示例

curl https://api.jimu.chat/v1/messages \
  -H "Authorization: Bearer $JIMU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 1024,
    "system": "你是简洁的助手",
    "messages": [
      { "role": "user", "content": "你好" }
    ]
  }'

响应结构

以下为生产环境实测的原始响应,text 字段内容由上游模型生成,与平台无关:

非流式响应(实测)200
{
  "id": "msg_51e012b459b442ba9e88a5cdb631a887",
  "type": "message",
  "role": "assistant",
  "model": "claude-sonnet-5",
  "content": [{ "type": "text", "text": "我是 Kiro,一个 AI 开发助手…" }],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": { "input_tokens": 6820, "output_tokens": 1551 }
}

响应字段

idstring

消息 ID。id 的前缀与格式不构成契约,不要解析或依赖其格式

typestring

固定 "message"

rolestring

固定 "assistant"

modelstring

实际提供响应的模型

contentarray

content blocks 数组。纯文本时为 [{"type":"text","text":"..."}];触发工具调用时含 tool_use block

stop_reasonstring

停止原因,取值见下表

stop_sequencestring | null

实际命中的停止序列,未命中为 null

usageobject

token 用量,见下文「usage 字段」

stop_reason 取值

值含义
end_turn模型自然结束本轮回复
stop_sequence命中 stop_sequences 中的某个停止序列
max_tokens达到 max_tokens 上限被截断,需调大后重试
tool_use模型请求调用工具,需回传 tool_result 继续对话
refusal模型拒绝回答(内容安全原因)

usage 字段

Anthropic 协议的 usage 字段与 OpenAI 协议不通用,对照如下:

Anthropic(本文)OpenAI Chat Completions说明
input_tokensprompt_tokens输入 token 数
output_tokenscompletion_tokens输出 token 数
cache_creation_input_tokens—(OpenAI 无对应)写入提示词缓存的 token 数
cache_read_input_tokensprompt_tokens_details.cached_tokens(近似)命中提示词缓存的 token 数

计费以返回的 usage 为准。缓存字段可能为零或不出现,以响应实际返回为准。

流式输出

"stream": true 时以 SSE 返回,事件按固定顺序推送。实测序列:

event: message_start
data: {"type":"message_start","message":{"id":"msg_...","type":"message","role":"assistant","model":"claude-sonnet-5","content":[],"stop_reason":null,"usage":{"input_tokens":388,"output_tokens":0,...}}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"1\n2\n3"}}

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

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"input_tokens":6752,"output_tokens":326,...}}

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

各事件类型:

事件说明
message_start消息开始,message 携带 id/model 与初始 usage(input_tokens 此时已确定)
content_block_start一个 content block 开始,index 标识其在 content 数组中的位置
content_block_delta内容增量。delta.type 常见为 text_delta(文本);工具调用时为 input_json_delta(partial_json 分片,需拼接后解析);思考模型为 thinking_delta / signature_delta
content_block_stop当前 block 结束
message_delta消息级收尾,delta.stop_reason 在此出现,usage 含最终 output_tokens
message_stop整条消息结束
ping保活事件,可忽略
error流中途出错,error 对象携带错误信息

本端点的流式响应以 message_stop 作为结束标志——收到 message_stop 即表示生成结束。不要依赖 data: [DONE](OpenAI Chat Completions 的结束标志)作为通用结束条件,四套协议各有自己的终态事件。

每个文本 block 遵循 content_block_start → 若干 content_block_delta → content_block_stop 的嵌套结构;工具调用 block 同理,先收到 content_block_start(含 id/name),再通过 input_json_delta 逐片接收参数 JSON。

工具调用

工具通过 tools 数组定义,input_schema 为 JSON Schema:

{
  "model": "claude-sonnet-5",
  "max_tokens": 300,
  "messages": [{ "role": "user", "content": "北京现在天气如何?" }],
  "tools": [
    {
      "name": "get_weather",
      "description": "查询城市天气",
      "input_schema": {
        "type": "object",
        "properties": { "city": { "type": "string" } },
        "required": ["city"]
      }
    }
  ]
}

模型决定调用工具时,响应 stop_reason 为 tool_use,content 中包含 tool_use block(实测):

{
  "id": "msg_7b3d38884da84496a8b31e34d76c5cb1",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_bdrk_016jVag6MbzxTnRUmRbudsE8",
      "name": "get_weather",
      "input": { "city": "北京" }
    }
  ],
  "stop_reason": "tool_use",
  "usage": { "input_tokens": 7244, "output_tokens": 1870 }
}

执行工具后,把结果作为新一轮对话发回——assistant 消息原样带回 tool_use block,user 消息携带 tool_result block(实测往返通过):

{
  "model": "claude-sonnet-5",
  "max_tokens": 300,
  "messages": [
    { "role": "user", "content": "北京现在天气如何?" },
    {
      "role": "assistant",
      "content": [
        { "type": "tool_use", "id": "toolu_bdrk_016jVag6MbzxTnRUmRbudsE8", "name": "get_weather", "input": { "city": "北京" } }
      ]
    },
    {
      "role": "user",
      "content": [
        { "type": "tool_result", "tool_use_id": "toolu_bdrk_016jVag6MbzxTnRUmRbudsE8", "content": "晴,25度" }
      ]
    }
  ]
}
tool_result 的 tool_use_id 必须与模型返回的 tool_use.id 完全一致,且 tool_result 必须放在 user 角色消息的 content 数组里——Anthropic 协议没有 OpenAI 的 role: "tool"。

Token 计数

POST /v1/messages/count_tokens 在不消耗生成额度的情况下计算输入 token 数,请求体与 /v1/messages 相同(max_tokens 可省略),计数由端点侧完成:

curl https://api.jimu.chat/v1/messages/count_tokens \
  -H "Authorization: Bearer $JIMU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "messages": [{ "role": "user", "content": "hello world" }]
  }'
Token 计数响应(实测)200
{ "input_tokens": 227 }
计数结果可能与你本地 tokenizer 存在差异,应作为估算而非精确值使用;system 与 tools 也会计入输入 token。

不同模型的思考参数差异

积木在 /v1/messages 上做的是参数透传,并对齐各模型自身的官方原生格式——不会把厂商 A 的思考参数名字翻译成厂商 B 的写法。这意味着即使同样调用 /v1/messages 这一个接口,换一个模型系列,thinking 字段该怎么填可能完全不同,照抄别的模型的示例很容易导致参数被静默忽略,甚至直接报错。下表把已确认的官方差异列出来,方便你按实际调用的模型对号入座。

关于思考档位:thinking.type、budget_tokens、effort 等所有思考参数的档位取值与默认行为因供应商而异,务必查阅你所调用模型的官方参考文档。下表仅收录有官方协议明文支撑的差异,未明文的模型不在此臆造数值,也不代表本端点适配所有供应商。

模型系列思考参数形态合法档位约束条件
Claude(4.5 及更早代际,如 Opus 4.5)手动扩展思考:thinking: {"type":"enabled","budget_tokens":N}budget_tokens 为整数,无固定挡位,按 token 数自由设置budget_tokens 最小 1024,低于该值直接被拒绝;必须严格小于 max_tokens(因为思考 token 计入同一份 max_tokens 额度);官方未给出上限数字,仅建议超过约 32k 时改走 Batch API
Claude Opus 4.6 / Sonnet 4.6(过渡代)两种写法都接受:旧的 type:"enabled"+budget_tokens(已弃用但仍可用);新的 type:"adaptive"同上;或 adaptive 无需 budget_tokens官方建议尽快迁移到 adaptive,旧写法随时可能被下线
claude-opus-5 / claude-sonnet-5 等(4.7 及更新代际)自适应思考:thinking: {"type":"adaptive"},深度改由顶层 effort 参数控制无 budget_tokens 概念;effort 具体合法档位因模型而异发送 type:"enabled" 会直接返回 400,不是被忽略——这是从旧模型迁移过来最容易踩的坑;thinking.type:"disabled" 在 Fable 5 / Mythos 5 上同样不允许(思考始终开启)
DeepSeek 系模型(走 Anthropic 兼容接口时)同样接受 thinking 对象,但深度控制字段不同thinking.budget_tokens 子字段被忽略(不报错,静默失效);实际深度由 output_config.effort 控制如果把 Claude 侧调好的 budget_tokens 数值直接套到 DeepSeek 模型上,看起来请求成功,但该数值根本没有生效

该怎么用:先确认自己调用的模型属于哪一代/哪一系列,再照对应写法传参;不确定时优先看模型名对应厂商的官方最新文档,而不是复用其他模型的历史示例。积木不做参数名的中间翻译,因此换模型即可能需要改 thinking 的写法,这是协议透传设计的直接后果,不是 bug。

上表仅收录有官方文档明文支撑的差异;未在官方文档中找到明确挡位说明的模型,不在此处列出具体数值,请以实际调用返回结果为准。

错误处理

错误响应结构、HTTP 状态码与排查指南统一由错误处理与请求追踪承载,本端点的错误形态与状态码映射以该页为准(含 Anthropic 原生接口的错误变体)。

注意:不要在客户端硬编码固定状态码对照,实际返回的 HTTP 状态码以响应为准。

与 OpenAI 格式的关键差异

从 /v1/chat/completions 迁移到 /v1/messages 时注意:

维度OpenAI Chat CompletionsAnthropic Messages
系统提示messages 中 role: "system" 消息顶层 system 字段,不在 messages 中
最大输出max_tokens 可选运行时可选,缺省时按模型设置补默认值
消息内容字符串或 content parts 数组字符串或 content blocks 数组
图片输入image_url part(URL 或 data URI)image block,source 区分 base64 / url
工具定义tools[].function.{name,parameters}tools[].{name,input_schema}
工具调用回传assistant 消息 tool_calls 数组assistant 消息 content 中的 tool_use block
工具结果独立 role: "tool" 消息user 消息 content 中的 tool_result block
停止原因finish_reason:stop/length/tool_calls/content_filterstop_reason:end_turn/max_tokens/tool_use/stop_sequence/refusal
用量字段prompt_tokens/completion_tokens/total_tokensinput_tokens/output_tokens(+缓存字段)
流式chat.completion.chunk 增量对象事件流:message_start/content_block_delta/message_delta/message_stop
鉴权头Authorization: Bearerx-api-key(积木网关两种都接受)
平台同时提供 OpenAI 兼容端点与本文的 Anthropic 原生端点。注意模型与端点存在协议归属:部分模型仅接受原生协议,跨协议调用会返回 format_not_accepted 错误,可用性以实际调用为准。