提示生命周期
提示、状态更新和完成如何协同工作
提示启动或贡献会话中的活动工作。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)"
}
}
]
}
}
| 参数 | 类型 | 描述 |
|---|---|---|
sessionId | SessionId | 要将此消息发送到的会话 ID。 |
prompt | ContentBlock[] | 用户消息的内容,例如文本、图像、文件等。 |
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_message、agent_message 和 agent_thought 更新是以 messageId 为键的 upsert 操作:省略 content 时保留现有消息内容不变,content: null 清除它,具体的 content 数组替换先前内容。具有相同 messageId 的分块更新追加内容;messageId 变化表示新消息。
客户端按每个 messageId 的接收顺序应用消息更新和分块:
- 不带
content的消息更新保持当前内容不变,因此 Agent 可以更新其他可选字段而无需重发内容。 - 带
content的消息更新替换该消息当前存储的所有内容,包括从先前分块累积的内容。 - 带
content: []或content: null的消息更新清除消息内容。 - 分块将其内容追加到该消息当前的内容中,无论该内容来自先前的消息更新还是先前的分块。
- 分块的
_meta(存在时)是分块作用域的。
例如,如果 Agent 发送 agent_message 带 content: [A],然后发送 agent_message_chunk 带 B,渲染的消息内容是 [A, B]。如果之后发送另一个 agent_message 带 content: [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"
}
}
}
}
used 和 size 是当前会话上下文的必需且非 null 的 token 计数。cost 是可选的,如果存在,amount 和 currency 是必需的。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 的当前内容中。后续带 content 的 tool_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 继续对话,在已建立的会话上下文基础上构建。