監控自行託管的 worker 並進行疑難排解
讀取佇列深度、在不遺失工作的情況下停止工作階段與 worker,並修正常見的自行託管沙箱故障。
本頁面上的監控呼叫是從您的監控或維運工具執行,並使用您的 Claude API 金鑰進行驗證。worker 輔助工具會處理認領與保持連線的迴圈,因此您不需要直接呼叫這些端點。
讀取佇列深度
client.beta.environments.work.stats() 會傳回環境的佇列狀態:
| 欄位 | 意義 | 用途 |
|---|---|---|
depth | 等待被認領的項目。 | 擴展您的 worker 叢集,或針對積壓發出警示。 |
pending | 已被 worker 認領但尚未確認的項目。worker 輔助工具會在處理每個項目之前先確認它,因此在正常運作下此值會維持在接近零。 | 偵測在認領與確認之間停滯的 worker:針對持續非零的值發出警示。 |
oldest_queued_at | 仍在佇列中最舊項目的時間戳記,該項目可能正在等待被認領,或已被認領但尚未確認。沒有項目時為 null。 | 查看最舊的項目已等待多久。 |
workers_polling | 在過去 30 秒內進行過輪詢的 worker。 | 針對存活狀態發出警示。 |
import os
import anthropic
client = anthropic.Anthropic()
stats = client.beta.environments.work.stats(os.environ["ANTHROPIC_ENVIRONMENT_ID"])
print(f"depth={stats.depth} pending={stats.pending}"){
"type": "work_queue_stats",
"depth": 0,
"pending": 0,
"oldest_queued_at": null,
"workers_polling": 0
}正常停止工作階段
使用 client.beta.environments.work.stop() 要求處理特定工作階段的 worker 將其關閉。
預設情況下,工作項目會轉為 stopping。worker 會在下一次租約心跳時察覺,取消該工作階段進行中的工具呼叫,並確認關閉。接著工作項目會變為 stopped。
傳入 force=True 可立即將工作項目標記為 stopped,而不等待 worker 的確認。
由於這些呼叫是從您的維運工具而非 worker 主機執行,因此不會自動設定 ANTHROPIC_WORK_ID。在執行以下範例之前,請將其設定為目標工作項目的 ID。若要找出工作項目的 ID,請透過 Environments Work 端點列出環境的工作項目。
import os
import anthropic
client = anthropic.Anthropic()
work = client.beta.environments.work.stop(
os.environ["ANTHROPIC_WORK_ID"],
environment_id=os.environ["ANTHROPIC_ENVIRONMENT_ID"],
)
print(work.state)正常停止 worker
在工作階段執行期間被取消的 worker,會在結束前停止其進行中的工作。如果工作階段附加了記憶體儲存區,worker 會略過最後的同步,但仍會上傳已變更的檔案並移除儲存區目錄。
被強制終止的程序不會執行任何清理作業。若要乾淨地停止 worker:
-
確保 SIGTERM 和 SIGINT 會取消 worker。 做法取決於 worker:
Worker 該怎麼做 antCLI無需任何動作。CLI 會自行處理這兩個訊號:它會取消任何進行中的工具呼叫、發布其錯誤結果,並釋放工作項目。 作為獨立程序的 SDK worker EnvironmentWorker不會安裝任何訊號處理常式。請從訊號處理常式中取消 worker,如同獨立 worker 範例所示。位於 webhook 伺服器內的 SDK worker 請從伺服器本身的關閉掛鉤中取消 worker,如同 webhook 範例所示。worker 不得接管伺服器的訊號。 -
使用 SIGTERM 停止 worker,並在任何強制終止之前預留至少 30 秒。 最後的上傳可能需要這麼久。Docker 預設會在停止訊號發出 10 秒後傳送 SIGKILL。請在
docker run上使用--stop-timeout,或透過您的協調器的終止寬限期來提高此限制。
如果 worker 在執行清理作業之前就被終止,任何尚未同步的記憶編輯都會遺失。在長期運作的主機上,還需在下一個附加該儲存區的工作階段之前,移除 /mnt/memory/ 下殘留的儲存區目錄。僅服務一個工作階段後即被捨棄的沙箱則不需要清理。
疑難排解
worker 無法連線
如果 workers_polling 一直維持在 0,表示 worker 無法連到佇列。請確認 worker 主機上已設定 ANTHROPIC_ENVIRONMENT_KEY 和 ANTHROPIC_ENVIRONMENT_ID。
工作階段一直處於佇列中
沒有 worker 在認領工作。處於佇列中的工作階段會持續等待,而不會失敗。請查看讀取佇列深度中的 workers_polling 和 depth。
記憶體儲存區無法掛載
worker 會將掛載與背景同步失敗記錄到日誌中,而不是回報給工作階段。只有唯讀拒絕會以工具錯誤的形式傳達給代理(請參閱唯讀儲存區與衝突)。
如果 worker 在認領工作階段時無法掛載記憶體儲存區,它會使該工作項目失敗。工作階段不會發出錯誤事件,並維持閒置狀態。
| 症狀 | 原因 | 修正方式 |
|---|---|---|
worker 日誌包含 the work item carried no sessions token(在 Go 中為 ErrSessionMemoryNoToken 錯誤),且工作項目失敗。 | 工作項目的每個工作階段 secret 未傳達到 worker。可能是您的程式碼未轉送它,或是您的組織未啟用自行託管沙箱上的記憶體儲存區。 | 轉送工作項目的密鑰。如果 worker 在同一個程序中輪詢並執行工作階段,卻仍記錄此訊息,請聯絡支援團隊。 |
worker 日誌包含 something already exists at the memory store's path。 | 先前工作階段殘留的目錄,通常是其 worker 在執行清理作業之前就被終止的工作階段。 | 移除日誌行中指出的殘留目錄。其中尚未同步的編輯將會遺失。 |
worker 日誌包含 cannot create the memory store's folder 和 the worker host must make this mount path writable。 | 執行 worker 的使用者無法在 /mnt/memory 下建立目錄。 | 建立 /mnt/memory 並將其 chown 給該使用者。請參閱準備主機。 |
在 worker 認領工作階段後不久,工作階段處於 idle 狀態,停止原因為 requires_action,且沒有錯誤事件。 | worker 因上述其中一個原因無法掛載記憶體儲存區,而使工作項目失敗。 | 在主機上修正原因,然後傳送 user.interrupt 事件。工作階段的工作會重新排入佇列,下一個認領它的 worker 會重試掛載。 |
自訂工具呼叫一直沒有回傳
如果工作階段處於暫停狀態且停止原因為 requires_action,表示沒有任何 worker 或用戶端提供該工具。請參閱提供自訂工具。
包裝的 MCP 工具呼叫停滯
如果 MCP 用戶端沒有設定逾時,對包裝的 MCP 伺服器的停滯呼叫只有在後備機制觸發時才會變成錯誤工具結果:
| SDK | 後備機制 | 觸發時間 |
|---|---|---|
| Python | worker 本身的工具呼叫限制 | 約兩分半鐘 |
| TypeScript | MCP SDK 的預設請求逾時 | 約一分鐘 |
| Go | worker 會取消超過其預設限制的工具呼叫 | 120 秒 |
Was this page helpful?