Claude API 的响应里,三个字段最重要:content(模型产出了什么)、stop_reason(为什么停了)、usage(消耗了多少 token)。
stop_reason 驱动 agentic 循环
stop_reason 是 agentic 循环的唯一控制信号:
end_turn— 模型自然结束了。它说完了想说的。你的循环应该终止。tool_use— 模型要调用工具。执行它,把结果送回去,继续循环。max_tokens— 响应被截断了,因为撞上了 token 上限。输出可能不完整。
关键区别在这里:end_turn 是模型主动选择停下来,max_tokens 是被强制掐断的。被截断的响应里可能有残缺的 JSON、写到一半的句子、或者缺失的结论。你的代码对这两种情况应该分别处理。
content 是数组,不是字符串
响应的 content 始终是一个类型化 block 数组。一条请求工具调用的响应可能长这样:
{
"content": [
{"type": "text", "text": "Let me look that up for you."},
{"type": "tool_use", "id": "toolu_abc", "name": "search", "input": {"query": "..."}}
],
"stop_reason": "tool_use"
}
text 和 tool_use 共存。你的 agentic 循环看的是 stop_reason,不是有没有 text。
usage 追踪成本
usage 对象包含 input_tokens 和 output_tokens。输入 token 涵盖你发送的所有内容——messages、system prompt、工具定义。输出 token 是模型生成的部分。两者都计入账单。在多轮对话中,输入 token 会逐轮增长,因为每次都要重发完整历史。
一句话总结: stop_reason 是循环控制信号——tool_use 意味着继续,end_turn 意味着停止,max_tokens 意味着响应被截断了。