本页中的监控调用从您的监控或运维工具中运行,并使用您的 Claude API 密钥进行身份验证。worker 辅助工具会处理认领和保活循环,因此您无需直接调用这些端点。

警告

这些端点既接受您的组织 API 密钥,也接受环境密钥。请在 worker 主机之外使用您的组织 API 密钥调用它们。在 worker 主机上设置 ANTHROPIC_API_KEY 会将组织范围的凭据暴露给智能体的工具调用。

读取队列深度

GET /v1/environments/{environment_id}/work/stats (python, typescript, ruby: client.beta.environments.work.stats(); go, csharp: client.Beta.Environments.Work.Stats(); java: client.beta().environments().work().stats(); php: $client->beta->environments->work->stats(); cli: ant beta:environments:work stats) 返回某个环境的队列状态:

字段 含义 用途
depth (csharp, go: Depth) 等待被认领的项目。 扩缩您的 worker 集群,或针对积压发出告警。
pending (csharp, go: Pending) 已被 worker 认领但尚未确认的项目。worker 辅助工具会在处理每个项目之前先确认它,因此在正常运行时该值保持在接近零的水平。 检测在认领和确认之间停滞的 worker:针对持续非零的值发出告警。
oldest_queued_at (java, php: oldestQueuedAt; csharp, go: OldestQueuedAt) 队列中仍存在的最旧项目的时间戳,该项目要么正在等待被认领,要么已被认领但尚未确认。当不存在此类项目时为 null (python: None; ruby: nil; java: Optional.empty(); go: "")。 查看最旧的项目已等待了多长时间。
workers_polling (java, php: workersPolling; csharp, go: WorkersPolling) 在过去 30 秒内进行过轮询的 worker。 针对存活状态发出告警。

cURL

curl -sS "https://api.anthropic.com/v1/environments/$ANTHROPIC_ENVIRONMENT_ID/work/stats" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-beta: managed-agents-2026-04-01" \
  -H "anthropic-version: 2023-06-01"

CLI

ant beta:environments:work stats --environment-id "$ANTHROPIC_ENVIRONMENT_ID"

Python

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}")

TypeScript

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const stats = await client.beta.environments.work.stats(process.env.ANTHROPIC_ENVIRONMENT_ID!);

console.log(`depth=${stats.depth} pending=${stats.pending}`);

C#

using Anthropic;

var client = new AnthropicClient();

var environmentId = Environment.GetEnvironmentVariable("ANTHROPIC_ENVIRONMENT_ID")!;

var stats = await client.Beta.Environments.Work.Stats(environmentId);

Console.WriteLine($"depth={stats.Depth} pending={stats.Pending}");

Go

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/anthropics/anthropic-sdk-go"
)

func main() {
	client := anthropic.NewClient()
	environmentID := os.Getenv("ANTHROPIC_ENVIRONMENT_ID")

	stats, err := client.Beta.Environments.Work.Stats(
		context.Background(),
		environmentID,
		anthropic.BetaEnvironmentWorkStatsParams{},
	)
	if err != nil {
		panic(err)
	}

	fmt.Printf("depth=%d pending=%d\n", stats.Depth, stats.Pending)
}

Java

import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.beta.environments.work.BetaSelfHostedWorkQueueStats;

void main() {
    AnthropicClient client = AnthropicOkHttpClient.fromEnv();

    BetaSelfHostedWorkQueueStats stats = client.beta()
        .environments()
        .work()
        .stats(System.getenv("ANTHROPIC_ENVIRONMENT_ID"));

    IO.println("depth=" + stats.depth() + " pending=" + stats.pending());
}

PHP

<?php

use Anthropic\Client;

$client = new Client();

$stats = $client->beta->environments->work->stats(getenv('ANTHROPIC_ENVIRONMENT_ID'));

printf("depth=%d pending=%d\n", $stats->depth, $stats->pending);

Ruby

require "anthropic"

client = Anthropic::Client.new

stats = client.beta.environments.work.stats(ENV.fetch("ANTHROPIC_ENVIRONMENT_ID"))

puts "depth=#{stats.depth} pending=#{stats.pending}"
{
  "type": "work_queue_stats",
  "depth": 0,
  "pending": 0,
  "oldest_queued_at": null,
  "workers_polling": 0
}

优雅地停止会话

使用 POST /v1/environments/{environment_id}/work/{work_id}/stop (python, typescript, ruby: client.beta.environments.work.stop(); go, csharp: client.Beta.Environments.Work.Stop(); java: client.beta().environments().work().stop(); php: $client->beta->environments->work->stop(); cli: ant beta:environments:work stop) 请求处理特定会话的 worker 关闭该会话。

默认情况下,工作项会进入 stopping 状态。worker 会在下一次租约心跳时察觉到这一点,取消该会话正在进行的工具调用,并确认关闭。随后工作项变为 stopped。而 Python SDK worker 会先让正在进行的工具调用完成,这最多可能需要 2.5 分钟。

传入 force: true (python: force=True; cli: --force) 可立即将工作项标记为 stopped,而无需等待 worker 的确认。强制停止并不会让正在进行的工具调用更早结束,因为 worker 仍然是在下一次心跳时才察觉到停止请求。

由于这些调用是从您的运维工具而非 worker 主机运行的,因此不会自动设置 ANTHROPIC_WORK_ID。在运行以下示例之前,请将其设置为目标工作项的 ID。要查找工作项的 ID,请通过 Environments Work 端点列出该环境的工作项。

cURL

curl -sS "https://api.anthropic.com/v1/environments/$ANTHROPIC_ENVIRONMENT_ID/work/$ANTHROPIC_WORK_ID/stop" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-beta: managed-agents-2026-04-01" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{}'

CLI

ant beta:environments:work stop \
  --environment-id "$ANTHROPIC_ENVIRONMENT_ID" \
  --work-id "$ANTHROPIC_WORK_ID"

Python

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)

TypeScript

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const work = await client.beta.environments.work.stop(process.env.ANTHROPIC_WORK_ID!, {
  environment_id: process.env.ANTHROPIC_ENVIRONMENT_ID!
});

console.log(work.state);

C#

using Anthropic;

var client = new AnthropicClient();

var work = await client.Beta.Environments.Work.Stop(
    Environment.GetEnvironmentVariable("ANTHROPIC_WORK_ID")!,
    new()
    {
        EnvironmentID = Environment.GetEnvironmentVariable("ANTHROPIC_ENVIRONMENT_ID")!
    }
);

Console.WriteLine(work.State);

Go

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/anthropics/anthropic-sdk-go"
)

func main() {
	client := anthropic.NewClient()

	work, err := client.Beta.Environments.Work.Stop(
		context.Background(),
		os.Getenv("ANTHROPIC_WORK_ID"),
		anthropic.BetaEnvironmentWorkStopParams{
			EnvironmentID: os.Getenv("ANTHROPIC_ENVIRONMENT_ID"),
		},
	)
	if err != nil {
		panic(err)
	}
	fmt.Println(work.State)
}

Java

import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.beta.environments.work.BetaSelfHostedWork;
import com.anthropic.models.beta.environments.work.BetaSelfHostedWorkStopRequest;
import com.anthropic.models.beta.environments.work.WorkStopParams;

void main() {
    AnthropicClient client = AnthropicOkHttpClient.fromEnv();

    BetaSelfHostedWork work = client.beta().environments().work().stop(
        WorkStopParams.builder()
            .environmentId(System.getenv("ANTHROPIC_ENVIRONMENT_ID"))
            .workId(System.getenv("ANTHROPIC_WORK_ID"))
            .betaSelfHostedWorkStopRequest(BetaSelfHostedWorkStopRequest.builder().build())
            .build()
    );

    IO.println(work.state());
}

PHP

<?php

use Anthropic\Client;

$client = new Client();

$work = $client->beta->environments->work->stop(
    getenv('ANTHROPIC_WORK_ID'),
    environmentID: getenv('ANTHROPIC_ENVIRONMENT_ID'),
);

echo $work->state . "\n";

Ruby

require "anthropic"

client = Anthropic::Client.new

work = client.beta.environments.work.stop(
  ENV.fetch("ANTHROPIC_WORK_ID"),
  environment_id: ENV.fetch("ANTHROPIC_ENVIRONMENT_ID")
)

puts work.state

优雅地停止 worker

在会话运行期间被取消的 worker 会在退出前关闭该会话,就像您停止会话时一样。如果会话附加了记忆存储,worker 会跳过最终同步,但仍会上传已更改的文件并删除存储目录。

被强制终止的进程不会执行任何清理。要干净地停止 worker:

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

    Worker 操作
    ant CLI 无需任何操作。CLI 会自行处理这两个信号:它会取消任何正在进行的工具调用,发布其错误结果,并将工作项标记为 stopped。
    作为独立进程的 SDK worker EnvironmentWorker 不会安装任何信号处理程序。请像独立 worker 示例那样,从信号处理程序中取消 worker。
    位于 webhook 服务器内的 SDK worker 请像 webhook 示例那样,从服务器自身的关闭钩子中取消 worker。worker 不得接管服务器的信号。
  2. 使用 SIGTERM 停止 worker,并在任何强制终止之前至少留出 30 秒(Python SDK worker 为 3 分钟)。 将已更改的文件上传到记忆存储最多可能需要 30 秒,而 Python SDK worker 会先让正在进行的工具调用完成。默认情况下,Docker 会在发送停止信号 10 秒后发送 SIGKILL。可以通过 docker run 上的 --stop-timeout,或通过您的编排器的终止宽限期来提高该限制。

如果 worker 在执行清理之前被终止,任何尚未同步的记忆编辑都会丢失。在长期运行的主机上,还需要在下一个附加该存储的会话之前,删除 /mnt/memory/ 下残留的存储目录。仅服务一个会话随后即被丢弃的沙箱无需清理。

故障排除

worker 无法连接

如果 workers_polling (java, php: workersPolling; csharp, go: WorkersPolling) 一直为 0,说明 worker 未能访问到队列。请确认 worker 主机上已设置 ANTHROPIC_ENVIRONMENT_KEY 和 ANTHROPIC_ENVIRONMENT_ID。

会话一直处于排队状态

没有 worker 在认领工作。排队中的会话会一直等待,而不会失败。请在读取队列深度中检查 workers_polling (java, php: workersPolling; csharp, go: WorkersPolling) 和 depth (csharp, go: Depth)。

记忆存储挂载失败

worker 会将挂载失败和后台同步失败记录到日志中,而不是报告给会话。只有只读拒绝会以工具错误的形式传达给智能体(请参阅只读存储和冲突)。

如果 worker 在认领会话时无法挂载记忆存储,它会使该工作项失败。会话不会发出错误事件,并保持空闲状态。

症状 原因 解决方法
worker 日志中包含 the work item carried no sessions token(在 Go 中为 ErrSessionMemoryNoToken 错误),且工作项失败。 工作项的每会话 secret (csharp, go: 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 兜底机制 触发时间
Python worker 自身的工具调用限制 约两分半钟
TypeScript MCP SDK 的默认请求超时 约一分钟
Go worker 会取消超出其默认限制的工具调用 120 秒