Anthropic Messages
POST /v1/messages — Anthropic Messages 原生协议,支持 content blocks、流式事件与 tool_use 工具调用
积木平台提供 Anthropic Messages 原生协议端点。已有 Anthropic SDK 的项目无需重写调用逻辑,只需把 base_url 指向积木、把 API Key 换成积木令牌即可迁移。
/v1/messages;已有 OpenAI SDK 用 对话补全;已有 Google SDK 用 Gemini 原生协议。端点与鉴权
/v1/messages/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 流式返回,见下文「流式输出」
默认值: falsestop_sequencesarray停止序列字符串数组,命中即停止生成
temperaturenumber采样温度,越高越随机
top_pnumber核采样概率阈值
top_kintegerTop-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 字段内容由上游模型生成,与平台无关:
{
"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实际提供响应的模型
contentarraycontent blocks 数组。纯文本时为 [{"type":"text","text":"..."}];触发工具调用时含 tool_use block
stop_reasonstring停止原因,取值见下表
stop_sequencestring | null实际命中的停止序列,未命中为 null
usageobjecttoken 用量,见下文「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_tokens | prompt_tokens | 输入 token 数 |
output_tokens | completion_tokens | 输出 token 数 |
cache_creation_input_tokens | —(OpenAI 无对应) | 写入提示词缓存的 token 数 |
cache_read_input_tokens | prompt_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" }]
}'
{ "input_tokens": 227 }
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 Completions | Anthropic 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_filter | stop_reason:end_turn/max_tokens/tool_use/stop_sequence/refusal |
| 用量字段 | prompt_tokens/completion_tokens/total_tokens | input_tokens/output_tokens(+缓存字段) |
| 流式 | chat.completion.chunk 增量对象 | 事件流:message_start/content_block_delta/message_delta/message_stop |
| 鉴权头 | Authorization: Bearer | x-api-key(积木网关两种都接受) |
format_not_accepted 错误,可用性以实际调用为准。