§05 消息流:从 SDK 里流出来的每一条消息
05.1 消息是一条一条流出来的
你用 for await 接收消息。每转一圈,SDK 就吐出几条消息。
我第一次接的时候,被消息种类搞晕了。其实就 5 种,记住这张表就够。
05.2 五种消息类型
| 类型 | 何时出现 | 关键字段 | 标叔的结论 |
|---|---|---|---|
system |
会话开始 | session_id |
先存好,后面 resume 用 |
assistant |
Claude 回复 | content[] |
看它调了什么工具 |
user |
工具结果回灌 | 工具输出 | 一般不用管 |
result |
全部结束 | subtype、total_cost_usd |
成败看这里 |
streamEvent |
开了流式 | 增量文本 | 做实时打字机用 |
重点看:最后一行
result的total_cost_usd。每次跑完都能看到花了多少钱。我做长期任务时必打这行日志,不然成本会悄悄失控。
05.3 两种 SDK 的写法差异
# Python:用 isinstance 判断类型
from claude_agent_sdk import ResultMessage, AssistantMessage
if isinstance(message, ResultMessage):
if message.subtype == "success":
print(message.result)
// TypeScript:用 type 字符串判断
for await (const msg of q) {
if (msg.type === "result") {
if (msg.subtype === "success") console.log(msg.result);
}
}
这里有个坑:TypeScript 的 assistant 消息,内容在 msg.message.content,不是 msg.content。多套了一层。
注意:
tool_result块也在 assistant 内容里。文档第 10 条坑专门提了:遍历 assistant 内容时,除了
text和tool_use,还要处理tool_result。漏了这一种,解析会出错。
消息看明白了。但 Agent 能调哪些工具、能不能乱调?下一章讲工具和权限。