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扩展思考配置 {"type":"enabled","budget_tokens":N}。注意 budget_tokens 不保证原样生效,推理用量一律以响应返回的 usage 为准
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。错误处理
错误响应结构、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 错误,可用性以实际调用为准。