Messages 差异
与 Anthropic 官方 /v1/messages 对齐:Anthropic SDK 把 base_url 指向 https://api.model-r.com/v1 即可。差异集中在流式事件的细节、system 字段的写法、缓存标记的处理、思考预算的换算(换算表在总览页)。
支持清单
✅ 按官方语义支持(行为不同处在说明里加注);⊘ 不支持(说明写明实际发生什么)。
| 特性 | 状态 | 说明 |
|---|---|---|
| 顶层字段 | ||
model |
✅ | 填模型名称,以 /v1/models 返回为准 |
max_tokens |
✅ | 输出上限 |
system |
✅ | 字符串或内容块数组;数组只读 text 块,见下文 |
messages |
✅ | 至少一条;role 收 user、assistant、system(与官方一致,其余 role 返回 400)。system 指令两种写法都可用:顶层 system 字段,或 messages[] 里的 system 消息(Claude Code 等客户端的插入式写法)。工具结果用 user 消息里的 tool_result 块 |
temperature / top_p / top_k / stop_sequences |
✅ | 原样发给模型 |
tools / tool_choice |
✅ | tool_choice 四种官方写法都收 |
max_tool_calls |
✅ | 平台扩展:托管工具调用预算,与 Responses 同一种写法,平台自己消费,见下文 |
thinking |
✅ | budget_tokens 换算成档位(见总览页),原值保留、回显时还原,见下文 |
output_config.effort |
✅ | 较新的档位写法;与 enabled / disabled / key 写法的 thinking 同时出现返回 400,与 thinking: adaptive 可并用(此时以 effort 为准) |
metadata / service_tier / truncate |
✅ | 原样发给模型 |
stream_options |
⊘ | 不携带;usage 由平台计量后放在响应里 |
其余顶层字段(如 Claude Code 的 context_management) |
⊘ | 不报错、不转发,静默忽略 |
| 内容块(messages[].content 里) | ||
text |
✅ | 文本 |
image |
✅ | base64 / URL / file_id 三种 source |
tool_use / tool_result |
✅ | 函数调用往返 |
thinking |
✅ | 思考历史(thinking + signature) |
document |
✅ | base64 文档 |
server_tool_use / web_search_tool_result |
✅ | 服务端工具往返 |
file |
✅ | file_id / base64 两种 source |
| 工具类型 | ||
function(custom) |
✅ | name、description、input_schema |
| 托管工具 | ✅ | type 不带日期后缀(写 web_search,不写 web_search_20250305)——平台侧执行,见平台函数页 |
| MCP connector | ⊘ | mcp_servers[] / mcp_toolset 返回 400,见总览页 |
| 响应形态 | ||
| 流式 SSE | ✅ | 不发 ping 事件,见下文 |
| 非流式 JSON | ✅ | 带 content[]、stop_reason、usage 的完整 message 对象 |
与官方的差异
托管工具的 type 不带日期后缀
官方的托管工具 type 带版本日期(web_search_20250305);平台按不带后缀的 type 识别(web_search)。带日期后缀的声明会被丢弃——模型收不到该工具,表现为模型回答没有联网搜索能力。声明、返回与流式形状见平台函数页。
max_tool_calls:托管工具调用预算
官方 Messages 请求结构没有这个字段;平台为两个接口保留同一种写法——顶层 max_tool_calls,与 Responses 一致。平台扩展字段,由平台自己消费,不发给模型;取值须为 ≥ 1 的整数(写 0 返回 400),不写时默认 8。预算按已执行的调用次数计:一轮并行发起的多个调用整批执行,可能一次花掉甚至超出剩余预算;预算用尽后的下一轮由平台强制收尾作答,强制收尾仍发起新调用则请求失败。
请求
{
"model": "your-model",
"messages": [{ "role": "user", "content": "查一下今天北京的天气" }],
"tools": [{ "type": "web_search", "name": "web_search" }],
"max_tool_calls": 5
}
流式不发 ping 事件
官方会周期性发 ping 事件作心跳;平台的流不发。按官方文档解析事件的客户端不受影响——ping 本来就是可忽略的事件。
平台的事件序列(开头)
event: message_start
data: { … }
event: content_block_start
data: { … }
message_start 里没有 model 字段
官方在 message_start 的 message 对象里带 model;平台不带。需要模型名时用请求里发的那一份。
返回(流的第一个事件)
event: message_start
data: {
"type": "message_start",
"message": { "id": "msg_…", "role": "assistant", "content": [], … }
}
tool_use 的参数逐段到达
content_block_start 里 tool_use 块的 input 是空字符串(官方是 {}),参数随后以 input_json_delta 增量到达。
返回(同一个工具调用的两帧)
event: content_block_start
data: {
"type": "content_block_start",
"index": 1,
"content_block": { "type": "tool_use", "id": "toolu_…", "name": "get_weather", "input": "" }
}
event: content_block_delta
data: {
"type": "content_block_delta",
"index": 1,
"delta": { "type": "input_json_delta", "partial_json": "{\"city\":" }
}
把收到的 partial_json 按顺序拼接成完整 JSON;不要依赖 content_block_start 里的 input 值。
cache_control 只在 tools 上有效
官方的缓存标记 cache_control 可以写在 messages、system、tools 上。平台只保留 tools 上的;messages 与 system 上的在解析时丢弃——请求不会失败,只是这些标记不被使用。
请求(messages 上的 cache_control 不生效)
{
"model": "your-model",
"max_tokens": 1024,
"system": [{ "type": "text", "text": "你是一个助手", "cache_control": { "type": "ephemeral" } }],
"messages": [ … ]
}
system 用数组时只读 text 块
system 传内容块数组时只有 text 块生效,其余块被跳过;响应回显时 system 恒为普通字符串。
thinking.budget_tokens 换算成档位
budget_tokens 按总览页的换算表折算成档位发给模型;原始数值保留,响应回显时逐字还原。另外 output_config.effort 与 thinking 是两代写法,同时出现返回 400;唯一例外是 thinking.type 写 adaptive(开与不开交给模型、不指深度,Claude Code 的官方搭配),可与 effort 并存,此时以 effort 为准。
请求
{
"model": "your-model",
"max_tokens": 1024,
"thinking": { "type": "enabled", "budget_tokens": 8000 },
"messages": [{ "role": "user", "content": "想清楚再回答" }]
}
8000 落在 ≤ 10240 一档,按 medium 发给模型;回显的 thinking.budget_tokens 仍是 8000。