與 Claude Managed Agents 的通訊是基於事件的。您向代理程式傳送使用者事件,並接收代理程式和工作階段事件以追蹤狀態。
所有 Managed Agents API 請求都需要 managed-agents-2026-04-01 beta 標頭。SDK 會自動設定此 beta 標頭。
事件以兩個方向流動。
user.* 事件啟動工作階段並在其進行過程中引導它;system.message 在回合之間更新代理程式的系統提示。工作階段、span、代理程式、使用者和系統事件類型字串遵循 {domain}.{action} 命名慣例。僅限串流的增量預覽事件(event_start、event_delta)是例外。請參閱參考文件中的事件類型以取得完整目錄。
每個持久化的事件都包含一個 processed_at 時間戳記,表示該事件在伺服器端被記錄的時間。如果 processed_at 為 null,表示該事件已被 harness 排入佇列,並在前面的事件處理完成後才會被處理。
預設情況下,代理程式的回應文字會以緩衝的 agent.message 事件形式到達串流,每個事件僅在產生它的模型請求完成後才會發出。「Event deltas」(事件增量)讓您能夠在模型仍在生成時,以即時預覽的方式逐步呈現該文字。預覽不是回應本身:預覽是盡力而為的顯示輔助工具,而緩衝的 agent.message 始終是權威記錄。忽略預覽的用戶端仍會收到完整、正確的串流。
預覽是每個串流連線各自選擇加入的。將 event_deltas[] 查詢參數新增至 GET /v1/sessions/{session_id}/events/stream,為您想要預覽的每個事件類型重複一次。可接受的值為 agent.message 和 agent.thinking;任何其他值都會回傳 400 錯誤。只有工作階段層級的事件串流支援此參數。工作階段執行緒事件串流會拒絕它。
當預覽的事件開始時,串流會發出一個 event_start,其中包含即將到來的事件的類型和 id:
{
"type": "event_start",
"event": {
"type": "agent.message",
"id": "sevt_01abc..."
}
}對於 agent.message,開始事件之後會接著包含增量文字的 event_delta 事件。每個增量在 event_id 中指明它所擴展的事件,並在 delta.index 中指明它所擴展的內容區塊:
{
"type": "event_delta",
"event_id": "sevt_01abc...",
"delta": {
"type": "content_delta",
"index": 0,
"content": {
"type": "text",
"text": "Here is the summary"
}
}
}當預覽 agent.thinking 事件時,只會發出 event_start。不會有後續的 event_delta 事件,內容會如常在緩衝的 agent.thinking 事件中到達。
與持久化的事件不同,event_start 和 event_delta 本身沒有 id 或 processed_at。它們攜帶的唯一識別碼是它們所預覽的事件的 id。
事件增量使用與串流訊息不同的傳輸格式,這種差異是刻意為之的。預覽的 agent.message 會得到單一的 event_start,之後僅接著 event_delta 事件。沒有每個內容區塊的開始或停止事件,也沒有預覽事件本身的停止事件。增量類型是 content_delta,而非 content_block_delta。為 Messages API 編寫的累加器程式碼無法原封不動地沿用。
Python、TypeScript 和 Go SDK 包含一個累加器輔助工具,它以事件的 id 作為預覽的索引鍵,並為您處理 index 的記錄工作。手動模式適用於所有語言:在其他 SDK 中,將其套用至產生的事件類型。
在手動模式中,將預覽視為暫存緩衝區,將緩衝的事件視為記錄。以 (event_id, index) 作為緩衝區的索引鍵。按每個模型請求進行調和:一個回合以單一的 session.status_running 事件開始,然後在正常完成的回合中,每個模型請求會依序產生 span.model_request_start、event_start、event_delta 事件、緩衝的 agent.message,最後是 span.model_request_end(在 Span 事件分頁中)。在每個事件到達時處理它:
event_start 時,記下宣告的 id。識別碼始終一致:event_start.event.id、每個 event_delta.event_id 以及緩衝的 agent.message 的 id 都是相同的值。event_delta 時,將 delta.content.text 附加到 (event_id, delta.index) 的項目中,並呈現累積中的文字。某個 index 的第一個增量會建立該項目。agent.message 到達時,透過 id 進行比對,捨棄累積的預覽,改為呈現訊息的內容。span.model_request_end 時,關閉任何尚未被其緩衝事件調和的預覽。不會再有更多增量傳來。如果回合發生錯誤或被中斷,緩衝的事件可能永遠不會到達;但 span.model_request_end 仍會到達。# 預覽快照,以事件 ID 為鍵。accumulate_managed_agents_event 會將每個
# event_start / event_delta 摺疊成 agent.message 快照;緩衝的
# agent.message 會取代它。
previews: dict[str, BetaManagedAgentsAgentMessageEvent] = {}
# 在此連線上選擇啟用 agent.message 預覽
with client.beta.sessions.events.stream(
session.id, event_deltas=["agent.message"]
) as stream:
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.message",
"content": [{"type": "text", "text": "Describe the repo in one sentence."}],
},
],
)
for event in stream:
match event.type:
case "event_start":
snapshot = accumulate_managed_agents_event(None, event)
if snapshot is not None:
previews[event.event.id] = snapshot
print(f"event_start {event.event.type} {event.event.id}")
case "event_delta":
preview = accumulate_managed_agents_event(previews.get(event.event_id), event)
if preview is not None:
previews[event.event_id] = preview
text = "".join(block.text for block in preview.content)
print(f"event_delta preview: {text!r}")
case "agent.message":
# 緩衝的事件即為正式記錄:它會取代並關閉預覽
preview = accumulate_managed_agents_event(previews.pop(event.id, None), event)
text = "".join(block.text for block in preview.content)
print(f"agent.message {event.id} {text!r}")
case "span.model_request_end":
# 不會再有差異傳入。關閉任何其緩衝事件
# 始終未送達的預覽。
for event_id in previews:
print(f"span.model_request_end closing preview for {event_id}")
previews.clear()
case "session.status_idle":
break預覽是為回應速度而調校的。請依據以下限制進行建置:
agent.message 仍會完整到達。切勿將累積的預覽視為最終結果。agent.message。沒有辦法重新請求遺漏的增量。agent.thinking 僅有開始事件: agent.thinking 預覽僅發出 event_start 作為思考區塊已開始的訊號;不會有後續的 event_delta 事件。event_start 和 event_delta 僅存在於即時串流中。它們不會出現在工作階段的事件歷史記錄中(GET /v1/sessions/{session_id}/events)。當代理程式呼叫自訂工具時:
agent.custom_tool_use 事件。stop_reason: requires_action 的 session.status_idle 事件。阻塞的事件 ID 位於 stop_reason.event_ids 陣列中。user.custom_tool_result 事件,在 custom_tool_use_id 參數中傳遞事件 ID 以及結果內容。running 狀態。with client.beta.sessions.events.stream(session.id) as stream:
for event in stream:
if event.type == "session.status_idle" and (stop_reason := event.stop_reason):
match stop_reason.type:
case "requires_action":
for event_id in stop_reason.event_ids:
# 查詢該自訂工具使用事件並執行它
tool_event = events_by_id[event_id]
result = call_tool(tool_event.name, tool_event.input)
# 將結果回傳
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.custom_tool_result",
"custom_tool_use_id": event_id,
"content": [{"type": "text", "text": result}],
},
],
)
case "end_turn":
break當權限政策要求在工具執行前進行確認時:
agent.tool_use 或 agent.mcp_tool_use 事件。stop_reason: requires_action 的 session.status_idle 事件。阻塞的事件 ID 位於 stop_reason.event_ids 陣列中。user.tool_confirmation 事件,在 tool_use_id 參數中傳遞事件 ID。將 result 設為 "allow" 或 "deny"。使用 deny_message 來說明拒絕的原因。running 狀態。with client.beta.sessions.events.stream(session.id) as stream:
for event in stream:
if event.type == "session.status_idle" and (stop_reason := event.stop_reason):
match stop_reason.type:
case "requires_action":
for event_id in stop_reason.event_ids:
# 核准待處理的工具呼叫
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.tool_confirmation",
"tool_use_id": event_id,
"result": "allow",
},
],
)
case "end_turn":
break工作階段在互動之間會持續存在。除非明確刪除工作階段,否則對話歷史記錄會被保留。當工作階段進入閒置狀態時,其沙箱會被建立檢查點,保留完整的沙箱狀態,包括檔案系統、已安裝的套件以及代理程式建立的任何檔案。這讓您能夠從非活動狀態乾淨地恢復。
雖然工作階段歷史記錄會持久保存直到被刪除,但檢查點僅在工作階段最後一次活動後保留 30 天。如果您的工作流程需要完整的沙箱狀態(檔案、已安裝的工具等)持續保存超過 30 天,請在檢查點過期前定期傳送 user.message 事件以重設非活動計時器。
若要恢復工作階段,請如常向其傳送 user.message 事件:
# 在正式環境中,請傳入您要恢復之 session 的已儲存 ID。
ant beta:sessions:events send --session-id "$SESSION_ID" <<'YAML'
events:
- type: user.message
content:
- type: text
text: Now run the tests against the changes you made earlier.
YAMLsystem.message 目前僅由 Claude Opus 4.8 支援。如果代理程式上設定的任何模型不支援對話中途的系統注入,該事件會被拒絕並回傳 model_does_not_support_mid_conversation_system 驗證錯誤。
傳送 system.message 事件以在回合之間更新代理程式的系統提示。與代理程式定義上的 system 欄位(在工作階段建立時即固定)不同,system.message 讓您能夠在工作階段進行過程中變更系統提示。當代理程式在工作階段中途需要更新的系統層級指引時使用它:不同的角色設定、修訂的限制條件,或在執行時擷取的、應該影響模型後續行為的上下文。
ant beta:sessions:events send --session-id "$SESSION_ID" <<'YAML'
events:
- type: system.message
content:
- type: text
text: "The user's current timezone is America/New_York."
YAML當工作階段處於閒置狀態且 stop_reason: requires_action 時,無法傳送 system.message。content 接受 1–1000 個文字項目。
工作階段物件包含一個 usage 欄位,其中有累積的 token 統計資料。在工作階段進入閒置狀態後擷取工作階段以讀取最新的總計,並使用它們來追蹤成本、強制執行預算或監控消耗量。
{
"id": "sesn_01...",
"status": "idle",
"usage": {
"input_tokens": 5000,
"output_tokens": 3200,
"cache_creation_input_tokens": 2000,
"cache_read_input_tokens": 20000
}
}input_tokens 報告未快取的輸入 token,output_tokens 報告工作階段中所有模型呼叫的總輸出 token。cache_creation_input_tokens 和 cache_read_input_tokens 欄位反映提示快取活動。快取項目使用 5 分鐘的 TTL,因此在該時間範圍內的連續回合可受益於快取讀取,從而降低每個 token 的成本。
Console 提供您的代理程式工作階段的視覺化時間軸檢視。導覽至 Console 中的 Claude Managed Agents 區段以查看:
session.error 事件傳達Was this page helpful?