Agent SDK 的核心是一个自主执行循环:Claude 评估 prompt → 调用工具 → 接收结果 → 重复,直到任务完成。理解这个循环是构建、调试和优化 Agent 的基础。

核心机制

循环步骤:

  1. 接收 prompt,SDK yield SystemMessage(subtype="init")
  2. Claude 评估并响应,SDK yield AssistantMessage(含文本和工具调用请求)
  3. SDK 执行工具,yield UserMessage(工具结果)
  4. 重复步骤 2-3,直到 Claude 输出无工具调用的纯文本响应
  5. SDK yield 最终 AssistantMessage,然后 yield ResultMessage(含费用、token 用量、session ID)

五种消息类型:

  • SystemMessage:会话生命周期事件(init、compact_boundary)
  • AssistantMessage:每轮 Claude 响应,含文本块和工具调用块
  • UserMessage:工具执行结果,反馈给 Claude
  • StreamEvent:启用 include_partial_messages 时的实时流式事件
  • ResultMessage:循环结束标志,含 subtype(success/error_*)、result、total_cost_usd

ResultMessage subtype:

subtype含义
success正常完成,result 字段有值
error_max_turns达到 maxTurns 限制
error_max_budget_usd达到费用限制
error_during_execution执行中断(API 失败等)

关键细节

循环控制选项:

options=ClaudeAgentOptions(
    max_turns=30,           # 限制工具调用轮次
    max_budget_usd=1.0,     # 限制费用上限
    effort="high",          # 推理深度:low/medium/high/xhigh/max
    model="claude-sonnet-4-6",  # 指定模型
)

并发工具执行:只读工具(Read、Glob、Grep、只读 MCP 工具)可并发执行;修改状态的工具(Edit、Write、Bash)顺序执行。自定义工具默认顺序,设置 readOnlyHint: true 可启用并发。

自动压缩(Compaction):上下文窗口接近上限时,SDK 自动压缩旧历史,保留关键信息。触发时 yield SystemMessage(subtype="compact_boundary")。持久规则应放在 CLAUDE.md 而非初始 prompt,因为 CLAUDE.md 每次请求都会重新注入。

Python vs TypeScript 差异:

  • Python:用 isinstance(message, ResultMessage) 判断类型
  • TypeScript:用 message.type === "result" 判断;AssistantMessage 内容在 message.message.content

与其他概念的关联

实践要点

  • 始终迭代完整消息流,不要在 ResultMessage 后 break,因为后续可能还有 prompt_suggestion 等系统事件
  • 生产 Agent 应设置 max_turns 和 max_budget_usd 防止失控
  • effort 影响每轮 token 消耗,简单任务用 low 可显著降低成本
  • 错误 subtype 的 ResultMessage 也包含 total_cost_usd 和 session_id,可用于恢复