Claude Platform Docs
Managed Agents進階編排

工作階段執行緒

列出、中斷和封存多代理工作階段的執行緒,讀取其事件,並處理跨執行緒的工具權限。

在多代理工作階段中,每個代理都在自己的 session thread(工作階段執行緒)中運作。本頁說明如何列出、中斷和封存執行緒、執行緒傳送的事件,以及工具權限如何在執行緒之間運作。工作流程執行也會建立工作階段執行緒。

主要執行緒與工作階段執行緒

工作階段層級事件串流(/v1/sessions/{session_id}/events/stream)被視為 primary thread(主要執行緒),其中包含所有執行緒中所有活動的精簡檢視。您不會看到子代理的完整活動,但您會看到其工作的開始與結束,以及工具權限請求等阻塞事件。

工作階段執行緒是您深入查看特定代理活動的地方。

工作階段的 status 是所有代理活動的彙總;如果至少有一個執行緒處於 running,則整體工作階段狀態也會是 running。正在執行的工作流程執行也可以讓工作階段保持 running,即使其所有執行緒都沒有在運作。當沒有任何執行緒在運作,且有執行緒正在等待您的用戶端時,工作階段為 idle;請參閱得知工作何時完成。

工作階段預算是工作階段所有執行緒共用的單一上限。當達到上限時,各執行緒會獨立暫停,且每個執行緒的成本會依該執行緒本身所使用的模型計價。

列出執行緒

依下列方式列出與工作階段相關聯的所有執行緒:

for thread in client.beta.sessions.threads.list(session.id):
    agent = thread.agent
    label = agent.type if agent.type == "advisor" else agent.name
    print(f"[{label}] {thread.status}")

完整清單包含主要執行緒。主要執行緒的 parent_thread_id 為 null。其他每個執行緒都是子執行緒。除了執行的執行緒之外,workflow_run_id 皆為 null。

若只要列出具有特定狀態的執行緒,請在請求中加入 statuses[],並重複該參數以指定多個狀態,例如 ?statuses[]=running&statuses[]=idle。省略此參數則會傳回所有狀態的執行緒。

中斷工作階段執行緒

傳送帶有 session_thread_id 的 user.interrupt 以停止特定執行緒。省略 session_thread_id 會中斷工作階段中所有未封存的執行緒,包括主要執行緒。在具有動態工作流程的工作階段中,中斷不會結束任何執行,而指定某個執行之執行緒的中斷則不會停止任何東西。中斷會關閉其他子執行緒的待處理工具呼叫,但請勿依賴它來關閉執行之執行緒的待處理工具呼叫。請參閱在有開啟的執行時中斷工作階段。

client.beta.sessions.events.send(
    session.id,
    events=[{"type": "user.interrupt", "session_thread_id": thread.id}],
)

對於因 requires_action 而阻塞的子代理執行緒,中斷會以錯誤工具結果("Tool execution was interrupted before completion. Please retry.")關閉每個待處理的工具呼叫,並直接重新發出帶有 stop_reason: end_turn 的 session.thread_status_idle;模型不會被取樣。對於以 end_turn 或 budget_reached 處於閒置狀態的子執行緒,中斷不會產生任何作用。指定已終止執行緒的中斷會傳回 400 錯誤。被中斷的子執行緒不會向主要執行緒的代理傳送它在回合結束時會傳送的報告。當該代理正在等待子執行緒時,在有其他東西到達之前(例如 user.message 或另一個執行緒的報告),它不會開始另一個回合。

封存工作階段執行緒

您可以選擇在工作階段執行緒完成工作後將其封存。封存執行緒會釋放其在 25 個子執行緒限制中所佔的名額。伺服器會自行封存工作流程執行的執行緒。您不需要封存它們,而且在執行開啟期間您也無法封存。

archived = client.beta.sessions.threads.archive(thread.id, session_id=session.id)
print(archived.status, archived.archived_at)

只有在執行緒處於 idle 時,封存才會成功。停留在 requires_action 的執行緒視為閒置,可以直接封存;只有正在執行的執行緒必須先中斷:

client.beta.sessions.events.send(
    session.id,
    events=[{"type": "user.interrupt", "session_thread_id": thread.id}],
)
archived = client.beta.sessions.threads.archive(thread.id, session_id=session.id)
print(archived.status, archived.archived_at)

主要執行緒事件

這些事件會在位於 /v1/sessions/{session_id}/events/stream 的主要執行緒上呈現多代理活動。訊息方向事件的命名是相對於其所出現串流的執行緒而言:agent.thread_message_received 表示有訊息從另一個執行緒抵達此執行緒,而 agent.thread_message_sent 表示此執行緒傳送了一則訊息。例如,主要執行緒的代理所委派的任務,會以 agent.thread_message_received 事件的形式抵達子執行緒自己的串流。

類型說明
session.thread_created已建立一個執行緒。包含 session_thread_id 和 agent_name。
session.thread_status_running某個執行緒開始活動。
session.thread_status_idle與該執行緒相關聯的代理正在等待輸入。包含一個 stop_reason,指出代理停止的原因。
session.thread_status_terminated某個執行緒已終止且不再接受任何輸入,例如因為它已被封存或遇到無法復原的錯誤。顧問執行緒也會在其諮詢結束時終止。
agent.thread_message_received在主要執行緒上,子代理向主要執行緒的代理傳送了報告或問題。包含 from_session_thread_id、from_agent_name 和 content。
agent.thread_message_sent在主要執行緒上,主要執行緒的代理向子代理傳送了任務或後續訊息。包含 to_session_thread_id、to_agent_name 和 content。

顧問諮詢會以保留名稱 anthropic.advisor 發出這些相同的執行緒事件(在執行緒生命週期事件中作為 agent_name,在建議傳遞中作為 from_agent_name);相關順序請參閱為工作階段提供顧問。

工作流程執行的執行緒在主要串流上的呈現方式如下:

  • 生命週期事件:執行的每個執行緒都會傳送帶有該執行之 workflow_run_id 的 session.thread_created,以及其 session.thread_status_running、session.thread_status_idle 和 session.thread_status_terminated 事件。
  • 訊息事件:執行之執行緒的提示(一個 agent.thread_message_received 事件)會保留在其自己的串流上。
  • 執行事件:workflow_run.* 事件也會抵達此串流;請參閱執行事件。
  • 等待您處理的工具呼叫:執行之執行緒中需要您用戶端處理的工具呼叫,會如同任何子執行緒一樣交叉發布到此串流。請參閱工具權限與自訂工具。

工作階段執行緒事件

關鍵事件會被代理轉送到主要執行緒。不過,您可能仍想調查特定代理的推理和工具呼叫。若要這麼做,請串流或列出相關工作階段執行緒的事件。

每個工作階段執行緒在 /v1/sessions/{session_id}/threads/{thread_id}/stream 都有自己的事件串流,且它接受與工作階段層級串流相同的 event_deltas[] 參數,因此您可以在模型生成子代理的文字時預覽該文字。一個連線只會預覽它正在讀取的執行緒:子執行緒的預覽永遠不會出現在工作階段層級串流上,因此若要即時觀看子代理,請開啟其自己的執行緒串流。關於選擇加入、累積和調和預覽,請參閱預覽工作階段執行緒事件。

在工作流程執行中,伺服器會執行一個工作流程:由主要執行緒的代理所撰寫的程式。在該執行的每個執行緒上,第一個 agent.thread_message_received 是工作流程所撰寫的提示。其 from_session_thread_id 是主要執行緒的 ID,且它沒有 from_agent_name。API 不保證提示的文字內容,因此請勿剖析它。該執行緒的 session.thread_status_terminated 事件(位於主要執行緒的串流上)會告訴您該執行緒已完成。沒有任何事件會記錄它傳回給工作流程的結果。

執行緒的串流不會重播先前的事件。緊接在 session.thread_created 之後,執行之執行緒的事件清單可能是空的,因為伺服器會在其之後才寫入該執行緒的第一個事件。因此,請先開啟執行緒的串流,再列出執行緒的事件,並略過每個 id 已由清單傳回的串流事件。

with client.beta.sessions.threads.events.stream(
    thread.id,
    session_id=session.id,
) as stream:
    for event in stream:
        match event.type:
            case "agent.message":
                for block in event.content:
                    if block.type == "text":
                        print(block.text, end="")
            case "session.thread_status_idle":
                break

工具權限與自訂工具

如果子代理需要您的用戶端提供某些東西,例如執行工具呼叫的權限或自訂工具的結果,該事件會交叉發布到主要執行緒,並以 session_thread_id 識別其來源工作階段執行緒。在 always_ask 下,或在 auto 下伺服器無法做出判定時,工具呼叫需要您的權限。

{
  "type": "session.thread_status_idle",
  "id": "sevt_01ABC...",
  "session_thread_id": "sthr_01DEF...",
  "agent_name": "code-reviewer",
  "stop_reason": {
    "type": "requires_action",
    "event_ids": ["sevt_01XYZ..."]
  }
}

發布 user.tool_confirmation(帶有 tool_use_id)或 user.custom_tool_result(帶有 custom_tool_use_id);伺服器會自動將回應路由到正確的執行緒。該回應可能會以不同的 id 值同時出現在主要執行緒和子代理的執行緒上。若要比對這兩個副本,請比較 type 和 tool_use_id(或 custom_tool_use_id),而不是 id。

只有在沒有任何執行緒處於 running 時,工作階段才會變為 idle,因此 session.status_idle 可能會在子代理的呼叫之後很久才抵達。您不必等待它:一旦交叉發布的 agent.custom_tool_use 事件抵達,就立即傳送 user.custom_tool_result。

在 auto 下,您的 user.message 事件可能會讓伺服器允許原本會拒絕的呼叫。子代理執行緒中的任何內容都不會被視為您的意圖。您的用戶端不會在那裡發布任何訊息,而主要執行緒的代理傳送給子代理的訊息也不算數。當伺服器在 auto 下拒絕某個呼叫時,不會有任何內容被交叉發布:該事件和錯誤工具結果只會出現在子代理自己的執行緒串流上,且子代理會繼續執行。

以下範例位於工具確認處理常式的事件迴圈內。對於 stop_reason.event_ids 中的每個 ID,它會傳送一個允許該呼叫的 user.tool_confirmation。相同的模式也適用於 user.custom_tool_result。

for event_id in stop.event_ids:
    client.beta.sessions.events.send(
        session.id,
        events=[
            {
                "type": "user.tool_confirmation",
                "tool_use_id": event_id,
                "result": "allow",
            }
        ],
    )

上述模式會回應閒置事件所列出的呼叫。在主要串流上,子代理的 session.thread_status_idle 事件可能會在其 stop_reason.event_ids 所列出的 agent.tool_use 或 agent.mcp_tool_use 事件之前抵達。針對事件尚未抵達之呼叫的 user.tool_confirmation 可能會傳回 400。為避免這種情況,請在每個 evaluated_permission 為 ask 的呼叫其自身事件抵達主要串流時,再回應該呼叫。

Was this page helpful?