---
title: 자체 호스팅 워커 모니터링 및 문제 해결
url: https://platform.claude.com/docs/ko/managed-agents/self-hosted-sandboxes-operations
description: 큐 깊이를 확인하고, 작업 손실 없이 세션과 워커를 중지하며, 일반적인 자체 호스팅 샌드박스 오류를 해결합니다.
featureMetadata:
  topic:
    title: Managed Agents
    url: https://platform.claude.com/docs/en/managed-agents/overview
  status: beta
  betaHeader: managed-agents-2026-04-01
---

이 페이지의 모니터링 호출은 Claude API 키로 인증된 모니터링 또는 운영 도구에서 실행됩니다. 워커 헬퍼가 작업 가져오기(claim) 및 keep-alive 루프를 처리하므로 해당 엔드포인트를 직접 호출할 필요가 없습니다.

<Warning>
  이 엔드포인트는 조직 API 키 또는 환경 키를 모두 허용합니다. 워커 호스트 외부에서 조직 API 키로 호출하세요. 워커 호스트에 `ANTHROPIC_API_KEY`를 설정하면 조직 범위의 자격 증명이 에이전트 도구 호출에 노출됩니다.
</Warning>

## 큐 깊이 확인

`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`)                                                  | 워커가 가져가기를 기다리는 항목입니다.                                                                                                                                         | 워커 플릿을 확장하거나 백로그에 대해 알림을 설정합니다.                             |
| `pending` (csharp, go: `Pending`)                                              | 워커가 가져갔지만 아직 확인(acknowledge)하지 않은 항목입니다. 워커 헬퍼는 각 항목을 처리하기 전에 확인하므로, 정상 작동 시 이 값은 0에 가깝게 유지됩니다.                                                               | 작업 항목을 가져온 뒤 확인하기 전에 멈춘 워커를 감지합니다. 0이 아닌 값이 지속되면 알림을 설정하세요. |
| `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초 이내에 폴링한 워커입니다.                                                                                                                                         | 활성 상태(liveness)에 대해 알림을 설정합니다.                              |

<CodeGroup>
  ```bash 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"
  ```

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

  ```python 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 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}`);
  ```

  ```csharp 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 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 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
  <?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 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}"
  ```
</CodeGroup>

```text wrap
{
  "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`)를 사용하여 특정 세션을 처리하는 워커에게 해당 세션을 종료하도록 요청합니다.

기본적으로 작업 항목은 `stopping` 상태로 전환됩니다. 워커는 다음 "lease heartbeat"(리스 하트비트)에서 이를 감지하고, 세션의 진행 중인 도구 호출을 취소한 후 종료를 확인합니다. 그러면 작업 항목은 `stopped` 상태가 됩니다.

워커의 확인을 기다리지 않고 작업 항목을 즉시 `stopped`로 표시하려면 `force: true` (python: `force=True`; cli: `--force`)를 전달하세요.

이러한 호출은 워커 호스트가 아닌 운영 도구에서 실행되므로 `ANTHROPIC_WORK_ID`가 자동으로 설정되지 않습니다. 다음 예제를 실행하기 전에 대상 작업 항목의 ID로 설정하세요. 작업 항목의 ID를 찾으려면 [Environments Work 엔드포인트](https://platform.claude.com/docs/ko/api/beta/environments/work)를 통해 환경의 작업 항목을 나열하세요.

<CodeGroup>
  ```bash 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 '{}'
  ```

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

  ```python 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 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);
  ```

  ```csharp 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 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 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
  <?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 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
  ```
</CodeGroup>

## 워커를 정상적으로 중지하기

세션이 실행되는 동안 취소된 워커는 종료하기 전에 진행 중인 작업을 중지합니다. 세션에 [메모리 스토어](https://platform.claude.com/docs/ko/managed-agents/self-hosted-sandboxes-memory)가 연결되어 있으면 워커는 최종 동기화를 건너뛰지만 변경된 파일은 여전히 업로드하고 스토어 디렉터리를 제거합니다.

강제 종료된 프로세스는 정리(teardown) 작업을 실행하지 않습니다. 워커를 깔끔하게 중지하려면:

1. **SIGTERM과 SIGINT가 워커를 취소하도록 하세요.** 방법은 워커에 따라 다릅니다:

   | 워커                   | 해야 할 일                                                                              |
   | -------------------- | ----------------------------------------------------------------------------------- |
   | `ant` CLI            | 아무것도 할 필요가 없습니다. CLI가 두 신호를 직접 처리합니다: 진행 중인 도구 호출을 취소하고, 오류 결과를 게시하며, 작업 항목을 해제합니다. |
   | 자체 프로세스로 실행되는 SDK 워커 | `EnvironmentWorker`는 신호 핸들러를 설치하지 않습니다. 독립 실행형 워커 예제처럼 신호 핸들러에서 워커를 취소하세요.          |
   | 웹훅 서버 내부의 SDK 워커     | 웹훅 예제처럼 서버 자체의 종료 훅에서 워커를 취소하세요. 워커가 서버의 신호를 가로채서는 안 됩니다.                           |

2. **SIGTERM으로 워커를 중지하고, 강제 종료 전에 최소 30초를 허용하세요.** 최종 업로드에 그만큼 시간이 걸릴 수 있습니다. Docker는 기본적으로 중지 신호 후 10초가 지나면 SIGKILL을 보냅니다. `docker run`의 `--stop-timeout` 또는 오케스트레이터의 종료 유예 기간으로 이 제한을 늘리세요.

정리 작업이 실행되기 전에 워커가 강제 종료되면 동기화되지 않은 메모리 편집 내용은 손실됩니다. 장기 실행 호스트에서는 해당 스토어를 연결하는 다음 세션 전에 `/mnt/memory/` 아래에 남아 있는 스토어 디렉터리도 제거하세요. 하나의 세션만 처리한 후 폐기되는 샌드박스는 정리가 필요하지 않습니다.

## 문제 해결

### 워커가 연결되지 않음

`workers_polling` (java, php: `workersPolling`; csharp, go: `WorkersPolling`)이 0으로 유지되면 워커가 큐에 도달하지 못하고 있는 것입니다. 워커 호스트에 `ANTHROPIC_ENVIRONMENT_KEY`와 `ANTHROPIC_ENVIRONMENT_ID`가 설정되어 있는지 확인하세요.

### 세션이 대기 상태로 유지됨

작업을 가져가는 워커가 없습니다. 대기 중인 세션은 실패하지 않고 계속 대기합니다. [큐 깊이 확인](https://platform.claude.com/docs/ko/managed-agents/self-hosted-sandboxes-operations#read-queue-depth)에서 `workers_polling` (java, php: `workersPolling`; csharp, go: `WorkersPolling`)과 `depth` (csharp, go: `Depth`)를 확인하세요.

### 메모리 스토어 마운트 실패

워커는 마운트 및 백그라운드 동기화 실패를 세션에 보고하지 않고 로그에 기록합니다. 읽기 전용 거부만 도구 오류로 에이전트에 전달됩니다([읽기 전용 스토어와 충돌](https://platform.claude.com/docs/ko/managed-agents/self-hosted-sandboxes-memory#read-only-stores-and-conflicts) 참조).

워커가 세션을 가져올 때 메모리 스토어를 마운트할 수 없으면 작업 항목을 실패 처리합니다. 세션은 오류 이벤트를 발생시키지 않고 유휴 상태로 유지됩니다.

| 증상                                                                                                             | 원인                                                                                                                     | 해결 방법                                                                                                                                                                                           |
| -------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 워커 로그에 `the work item carried no sessions token`(Go에서는 `ErrSessionMemoryNoToken` 오류)이 포함되고 작업 항목이 실패합니다.       | 작업 항목의 세션별 `secret` (csharp, go: `Secret`)이 워커에 도달하지 않았습니다. 코드에서 이를 전달하지 않았거나, 조직에서 자체 호스팅 샌드박스의 메모리 스토어가 활성화되지 않았습니다. | [작업 항목의 시크릿을 전달하세요](https://platform.claude.com/docs/ko/managed-agents/self-hosted-sandboxes-workers#forward-the-work-items-secret). 워커가 하나의 프로세스에서 폴링과 세션 실행을 모두 수행하는데도 이 로그가 기록되면 지원팀에 문의하세요. |
| 워커 로그에 `something already exists at the memory store's path`가 포함됩니다.                                           | 이전 세션에서 남은 디렉터리로, 일반적으로 정리 작업이 실행되기 전에 워커가 강제 종료된 세션의 것입니다.                                                            | 로그 줄에 명시된 남은 디렉터리를 제거하세요. 그 안에서 동기화되지 않은 편집 내용은 손실됩니다.                                                                                                                                          |
| 워커 로그에 `cannot create the memory store's folder`와 `the worker host must make this mount path writable`이 포함됩니다. | 워커를 실행하는 사용자가 `/mnt/memory` 아래에 디렉터리를 생성할 수 없습니다.                                                                      | `/mnt/memory`를 생성하고 해당 사용자에게 `chown`하세요. [호스트 준비하기](https://platform.claude.com/docs/ko/managed-agents/self-hosted-sandboxes-memory#prepare-the-host)를 참조하세요.                                   |
| 워커가 세션을 가져온 직후 세션이 `requires_action` 중지 사유와 함께 오류 이벤트 없이 `idle` 상태로 유지됩니다.                                     | 앞서 설명한 이유 중 하나로 메모리 스토어를 마운트할 수 없어 워커가 작업 항목을 실패 처리했습니다.                                                               | 호스트에서 원인을 해결한 다음 [`user.interrupt`](https://platform.claude.com/docs/ko/managed-agents/events-and-streaming#interrupt-the-agent) 이벤트를 보내세요. 세션의 작업이 다시 큐에 추가되고, 이를 가져가는 다음 워커가 마운트를 재시도합니다.     |

### 사용자 정의 도구 호출이 반환되지 않음

세션이 `requires_action` 중지 사유와 함께 일시 중지된 상태로 머물러 있다면 해당 도구를 제공하는 워커나 클라이언트가 없는 것입니다. [사용자 정의 도구 제공하기](https://platform.claude.com/docs/ko/managed-agents/self-hosted-sandboxes-custom-tools#serve-a-custom-tool)를 참조하세요.

### 래핑된 MCP 도구 호출이 멈춤

MCP 클라이언트에 타임아웃이 없으면 [래핑된 MCP 서버](https://platform.claude.com/docs/ko/managed-agents/self-hosted-sandboxes-custom-tools#wrap-an-mcp-server-as-custom-tools)에 대한 멈춘 호출은 백스톱이 작동할 때에만 오류 도구 결과가 됩니다:

| SDK        | 백스톱                      | 작동 시점      |
| ---------- | ------------------------ | ---------- |
| Python     | 워커 자체의 도구 호출 제한          | 약 2분 30초 후 |
| TypeScript | MCP SDK의 기본 요청 타임아웃      | 약 1분 후     |
| Go         | 워커가 기본 제한을 초과한 도구 호출을 취소 | 120초 후     |
