提示生命周期

提示、状态更新和完成如何协同工作

提示启动或贡献会话中的活动工作。Agent 可以继续处理直到报告会话再次空闲,并且它可以在单个提示请求完成之前或之后发出 session/update 通知。活动工作可以涉及与语言模型的多次交换和工具调用。

session/prompt 仅持续到 Agent 接受提示。Agent 通过 session/update 通知报告已接受的用户消息、运行状态、输出和完成。

在发送提示之前,客户端 必须 先完成初始化阶段和会话设置

提示生命周期

典型的提示驱动流程实现了用户、Agent 和任何已连接工具之间的丰富交互。

1. 用户消息

客户端通过 session/prompt 发送用户消息:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "session/prompt",
  "params": {
    "sessionId": "sess_abc123def456",
    "prompt": [
      {
        "type": "text",
        "text": "Can you analyze this code for potential issues?"
      },
      {
        "type": "resource",
        "resource": {
          "uri": "file:///home/user/project/main.py",
          "mimeType": "text/x-python",
          "text": "def process_data(items):\n    for item in items:\n        print(item)"
        }
      }
    ]
  }
}
参数类型描述
sessionIdSessionId要将此消息发送到的会话 ID。
promptContentBlock[]用户消息的内容,例如文本、图像、文件等。

客户端 必须 根据初始化期间建立的提示能力限制内容类型。

2. 提示已接受

收到提示请求后,Agent 必须 在接受提示后响应一次。响应体为空,因为完成通过 state_update 通知报告,而非通过 session/prompt 响应:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {}
}

接受提示后,Agent 必须 报告用户消息在会话历史中的插入位置。它可以发送带有完整内容数组的 user_message 更新或流式 user_message_chunk 更新。此更新是 Agent 拥有的 messageId 的事实来源。

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_abc123def456",
    "update": {
      "sessionUpdate": "user_message",
      "messageId": "msg_user_8f7a1",
      "content": [
        {
          "type": "text",
          "text": "Can you analyze this code for potential issues?"
        }
      ]
    }
  }
}

3. Agent 报告输出

当 Agent 开始或恢复会话的处理工作时,它 必须 发送带有 state: "running"state_update 通知:

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_abc123def456",
    "update": {
      "sessionUpdate": "state_update",
      "state": "running"
    }
  }
}

语言模型可以以文本内容、工具调用或两者兼有来响应。

Agent 通过 session/update 通知向客户端报告模型输出。这可以包括 Agent 完成任务的计划:

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_abc123def456",
    "update": {
      "sessionUpdate": "plan_update",
      "plan": {
        "type": "items",
        "planId": "plan-1",
        "entries": [
          {
            "content": "Check for syntax errors",
            "priority": "high",
            "status": "pending"
          },
          {
            "content": "Identify potential type issues",
            "priority": "medium",
            "status": "pending"
          },
          {
            "content": "Review error handling patterns",
            "priority": "medium",
            "status": "pending"
          },
          {
            "content": "Suggest improvements",
            "priority": "low",
            "status": "pending"
          }
        ]
      }
    }
  }
}

Agent 可以以带有完整 content 数组的 agent_message 更新报告模型的文本响应:

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_abc123def456",
    "update": {
      "sessionUpdate": "agent_message",
      "messageId": "msg_agent_c42b9",
      "content": [
        {
          "type": "text",
          "text": "I'll analyze your code for potential issues. Let me examine it..."
        }
      ]
    }
  }
}

消息 ID

Agent 必须 在消息更新和消息分块上包含不透明的 messageId

用户、Agent 和思考消息可以各自以带有完整 content 数组的消息更新或流式分块的形式报告。user_messageagent_messageagent_thought 更新是以 messageId 为键的 upsert 操作:省略 content 时保留现有消息内容不变,content: null 清除它,具体的 content 数组替换先前内容。具有相同 messageId 的分块更新追加内容;messageId 变化表示新消息。

客户端按每个 messageId 的接收顺序应用消息更新和分块:

  • 不带 content 的消息更新保持当前内容不变,因此 Agent 可以更新其他可选字段而无需重发内容。
  • content 的消息更新替换该消息当前存储的所有内容,包括从先前分块累积的内容。
  • content: []content: null 的消息更新清除消息内容。
  • 分块将其内容追加到该消息当前的内容中,无论该内容来自先前的消息更新还是先前的分块。
  • 分块的 _meta(存在时)是分块作用域的。

例如,如果 Agent 发送 agent_messagecontent: [A],然后发送 agent_message_chunkB,渲染的消息内容是 [A, B]。如果之后发送另一个 agent_messagecontent: [C],渲染内容变为 [C];先前的完整内容和分块被替换。后续分块追加到 [C]

对于流式 Agent 文本,Agent 可以使用 agent_message_chunk 更新:

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_abc123def456",
    "update": {
      "sessionUpdate": "agent_message_chunk",
      "messageId": "msg_agent_c42b9",
      "content": {
        "type": "text",
        "text": " Let me examine it..."
      }
    }
  }
}

Agent 可以使用相同的消息更新或分块模式报告内部推理。agent_thought 更新为同一思考 messageId 修补字段;agent_thought_chunk 更新追加新内容。

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_abc123def456",
    "update": {
      "sessionUpdate": "agent_thought",
      "messageId": "msg_thought_a12",
      "content": [
        {
          "type": "text",
          "text": "Need to inspect the loop body before suggesting a fix."
        }
      ]
    }
  }
}

如果模型请求了工具调用,这些也会立即报告:

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_abc123def456",
    "update": {
      "sessionUpdate": "tool_call_update",
      "toolCallId": "call_001",
      "title": "Analyzing Python code",
      "kind": "other",
      "status": "pending"
    }
  }
}

会话用量更新

Agent 还可以使用 usage_update 报告当前会话上下文和累积成本状态:

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_abc123def456",
    "update": {
      "sessionUpdate": "usage_update",
      "used": 53000,
      "size": 200000,
      "cost": {
        "amount": 0.045,
        "currency": "USD"
      }
    }
  }
}

usedsize 是当前会话上下文的必需且非 null 的 token 计数。cost 是可选的,如果存在,amountcurrency 是必需的。currency 是 ISO 4217 货币代码,如 "USD"

4. 报告完成

如果没有待处理的工作,Agent 必须 通过 state_update 通知报告会话空闲。当空闲转换完成了活动工作时,Agent 必须 包含相应的 StopReason

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_abc123def456",
    "update": {
      "sessionUpdate": "state_update",
      "state": "idle",
      "stopReason": "end_turn"
    }
  }
}

Agent 可以随时通过发送带有相应 StopReason 的空闲 state_update 会话更新来停止活动工作。

5. 工具调用和状态报告

在继续执行之前,Agent 可以 通过 session/request_permission 方法向客户端请求权限。

在等待权限响应或其他用户操作时,Agent 应该 发送带有 state: "requires_action"state_update 通知。当 Agent 恢复处理时,它 应该 发送另一个带有 state: "running"state_update 通知。

一旦权限被授予(如果需要),Agent 应该 调用工具并报告将工具标记为 in_progress 的状态更新:

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_abc123def456",
    "update": {
      "sessionUpdate": "tool_call_update",
      "toolCallId": "call_001",
      "status": "in_progress"
    }
  }
}

工具运行时,Agent 可以 发送额外的更新,提供关于工具执行进度的实时反馈。当工具产生增量内容时,Agent 可以使用 tool_call_content_chunk 流式传输每个项目:

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_abc123def456",
    "update": {
      "sessionUpdate": "tool_call_content_chunk",
      "toolCallId": "call_001",
      "content": {
        "type": "content",
        "content": {
          "type": "text",
          "text": "Checked syntax..."
        }
      }
    }
  }
}

客户端将每个 tool_call_content_chunk 追加到该 toolCallId 的当前内容中。后续带 contenttool_call_update 替换累积的内容。

工具在 Agent 上执行时,可以 利用初始化期间协商的客户端能力。

工具完成时,Agent 发送另一个带有最终状态和任何内容的更新:

{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "sess_abc123def456",
    "update": {
      "sessionUpdate": "tool_call_update",
      "toolCallId": "call_001",
      "status": "completed",
      "content": [
        {
          "type": "content",
          "content": {
            "type": "text",
            "text": "Analysis complete:\n- No syntax errors found\n- Consider adding type hints for better clarity\n- The function could benefit from error handling for empty lists"
          }
        }
      ]
    }
  }
}

6. 继续对话

Agent 将工具结果作为另一个请求发送回语言模型。

循环返回到步骤 3,持续直到语言模型完成响应而不再请求额外的工具调用,或活动工作被 Agent 停止或被客户端取消。

停止原因

当 Agent 停止活动工作时,它必须在空闲 state_update 会话更新上指定相应的 StopReason:

  • end_turn - 语言模型完成响应后没有更多工具请求,Agent 没有更多工作要做
  • max_tokens - 达到最大 token 限制
  • max_turn_requests - 超过活动工作的最大模型请求数
  • refusal - Agent 拒绝继续
  • cancelled - 客户端取消了活动工作

当客户端可以显示通用的停止状态时,可以使用自定义或未来的停止原因。自定义停止原因 必须_ 开头;未知的非下划线停止原因保留给未来的 ACP 变体。

会话状态

  • running - Agent 正在会话中积极处理工作。
  • idle - Agent 当前未在会话中处理工作。
  • requires_action - Agent 正在等待用户操作才能继续。

取消

客户端可以随时通过发送 session/cancel 通知来取消活动会话工作:

{
  "jsonrpc": "2.0",
  "method": "session/cancel",
  "params": {
    "sessionId": "sess_abc123def456"
  }
}

客户端 应该 在发送 session/cancel 通知后,立即将当前活动工作相关的所有未完成工具调用标记为已取消。

客户端 必须cancelled 结果响应所有待处理的 session/request_permission 请求。

当 Agent 收到此通知时,它 应该 尽快停止所有语言模型请求和所有工具调用。

所有正在进行的操作成功中止且待处理更新已发送后,Agent 必须 发送带有 cancelled 停止原因 的空闲 state_update 会话更新。

API 客户端库和工具通常在其操作被中止时抛出异常,这可能以通用失败的形式呈现。客户端通常向用户显示来自 Agent 的未识别错误,这对于取消来说是不可取的,因为取消不被视为错误。Agent 必须 捕获这些错误并在 state_update 通知上报告语义上有意义的 cancelled 停止原因,以便客户端能可靠地确认取消。

Agent 可以 在收到 session/cancel 通知后发送带内容或工具调用更新的 session/update 通知,但 必须 确保在发送报告取消的空闲 state_update 会话更新之前完成。

客户端 应该 仍然接受在发送 session/cancel 后收到的工具调用更新。

Agent 报告会话空闲后,客户端可以发送另一个 session/prompt 继续对话,在已建立的会话上下文基础上构建。