Claude Platform Docs
Managed Agents自托管沙箱

监控自托管 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:

  1. 确保 SIGTERM 和 SIGINT 会取消 worker。 具体做法取决于 worker:

    Worker操作
    ant CLI无需任何操作。CLI 会自行处理这两个信号:它会取消任何正在进行的工具调用,发布其错误结果,并释放工作项。
    作为独立进程的 SDK workerEnvironmentWorker 不会安装任何信号处理程序。请像独立 worker 示例那样,从信号处理程序中取消 worker。
    位于 webhook 服务器内的 SDK worker请像 webhook 示例那样,从服务器自身的关闭钩子中取消 worker。worker 不得接管服务器的信号。
  2. 使用 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。要么是您的代码没有转发它,要么是您的组织未启用自托管沙箱上的记忆存储。转发工作项的 secret。如果 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兜底机制触发时间
Pythonworker 自身的工具调用限制约两分半钟
TypeScriptMCP SDK 的默认请求超时约一分钟
Goworker 会取消超出其默认限制的工具调用120 秒

Was this page helpful?