Claude API 里的消息不是纯字符串。每条消息的 content 字段是一个类型化的 block 数组。一共四种类型,每种都有固定的流向。
四种类型
| Block 类型 | 方向 | 用途 |
|---|---|---|
text | 双向 | 普通文本内容——用户发问题,模型回答案 |
image | 仅 User → Model | 发图片让模型分析(vision) |
tool_use | Model → Developer | 模型请求调用某个工具,附带具体参数 |
tool_result | Developer → Model | 开发者把工具执行结果返回给模型 |
方向不能搞反。你没法往模型那边发一个 tool_use block——那是模型自己生成的。你也收不到模型发来的 image block——它不通过这个机制生成图片。
简单文本的简写形式
纯文本消息可以跳过数组语法,直接写字符串:
{"role": "user", "content": "Hello"}
等价于:
{"role": "user", "content": [{"type": "text", "text": "Hello"}]}
两种都合法。简写适合简单场景,数组形式在一条消息里需要多个 block 时才是必须的。
一条消息里可以有多个 block
一条 assistant 响应可以同时包含 text 和 tool_use block。模型可能先解释它要做什么(text block),然后请求调用工具(tool_use block)——全在同一条响应里。content 数组把它们都装着。
这对 agentic 循环很关键:不要假设 stop_reason: "tool_use" 的响应里只有 tool_use block。旁边可能还有 text block。靠检查有没有文本内容来判断循环是否终止,这是一个典型的反模式——正是因为 text 和 tool_use 可以共存。
一句话总结: 四种内容块(text、image、tool_use、tool_result),各有固定方向——而且一条响应里可以同时包含多种 block 类型。