Messages API 的 messages 数组里只有两种角色:user 和 assistant。就这两个,没别的。
没有 “system” 角色
系统指令放在顶层的 system 参数里,不是作为 messages 中的一条消息。如果你往 messages 数组里塞一条 role: "system" 的消息,结果不会是你期望的。system prompt 在请求结构里有自己专属的位置。
工具结果用的是 “user” 角色
这个点很容易踩坑。当模型发起工具调用(通过一条包含 tool_use block 的 assistant 消息),你把执行结果用一条 user 消息送回去,里面放 tool_result content block。不是 “tool” 角色,不是 “function” 角色,就是 user。
想通了其实很合理:messages 数组记录的是两方之间的对话——模型那边是 assistant,其余一切都是 user。你的应用在 user 这边,工具执行也发生在你这边,所以工具结果自然是 user 消息。
{
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "Customer order #12345 found: shipped March 15"
}]
}
连续同角色消息会被合并
如果你不小心连发了两条 user 消息,API 不会报错。它会悄悄把它们合成一条。这不是让你故意利用的特性,但说明 API 对结构上的小瑕疵是容忍的。严格的交替模式(user → assistant → user → assistant)是预期的用法,但不是硬性强制的。
system prompt 和 user message:各干各的
系统指令决定模型在整个对话中怎么表现——语气、角色、约束。用户消息提供的是这一轮模型要回应什么。system prompt 像一份岗位说明书,user message 是进来的具体任务。
一句话总结: 只有 user 和 assistant 两种角色——工具结果也是 user 消息,因为你的应用就在 user 那一边。