Claude Platform Docs
Managed Agents자체 호스팅 Managed Agents

자체 호스팅 서버에서 API 호출하기

공식 SDK, cURL 또는 ant CLI가 자체 호스팅 Claude Managed Agents 서버를 가리키도록 설정하고, 세션을 시작한 다음 에이전트의 응답을 읽습니다. 그런 다음 필요하면 직접 운영하는 워커를 연결합니다.

자체 호스팅 Claude Managed Agents 서버는 Anthropic의 호스팅 Managed Agents 서비스와 동일한 API를 제공합니다. 코드에서는 공식 SDK, cURL 또는 ant CLI로 이 서버를 호출합니다. 달라지는 점은 두 가지입니다. 기본 URL이 사용자 서버의 주소가 되고, API 키가 Claude API 키 대신 서버 API 키가 됩니다.

브라우저에서 에이전트를 생성하고 세션을 실행하려면 사용자 서버의 콘솔 사용하기를 참조하세요.

사전 요구 사항

클라이언트가 서버를 가리키도록 설정하기

SDK와 ant CLI는 ANTHROPIC_BASE_URL에서 서버 주소를, ANTHROPIC_API_KEY에서 API 키를 읽습니다. 이 서버용으로 유지하는 터미널에서 두 변수를 모두 설정하세요.

빠른 시작 스택의 경우 .env 파일이 있는 디렉터리에서 다음 명령을 실행하세요:

export ANTHROPIC_BASE_URL=http://127.0.0.1:8400
export ANTHROPIC_API_KEY=$(grep '^CMA_SERVER__API_KEY=' .env | cut -d= -f2)

Kubernetes에서는 세션 실행에 나온 대로 두 변수를 설정하고, 포트 포워딩을 계속 실행한 상태로 두세요.

해당 터미널에서는 ant beta:agents list와 같은 모든 ant 명령이 사용자의 서버에 연결됩니다. Claude Code와 docker compose는 같은 변수를 읽으므로 그 터미널에서 실행하지 마세요.

세션 시작하기

세션에는 에이전트의 ID와 환경의 ID가 필요합니다:

  • 에이전트: 클라이언트가 서버를 가리키도록 설정한 상태에서 에이전트 생성하기에 나온 대로 에이전트를 생성하세요. 원시 HTTP 요청을 보내는 경우 URL의 https://api.anthropic.com을 $ANTHROPIC_BASE_URL로 바꾸세요.
  • 환경: 빠른 시작 스택은 compose-sandbox라는 환경을 생성하고, Helm 차트는 default라는 환경을 생성합니다. ant beta:environments list가 각 환경의 이름과 ID를 출력합니다. 직접 운영하는 워커의 경우, 자체 워커 실행하기에서 관리자 CLI가 출력한 ID입니다.

다음 예시 ID 대신 두 ID를 셸에 설정하세요:

export AGENT_ID=agent_011CYm1BLqPXpQRk5khsSXrs
export ENVIRONMENT_ID=env_01595EKxaaTTGwwY3kyXdtbs

다음 예제는 세션을 생성하고 같은 요청에서 첫 번째 메시지를 보냅니다:

import os

from anthropic import Anthropic

client = Anthropic()

session = client.beta.sessions.create(
    agent=os.environ["AGENT_ID"],
    environment_id=os.environ["ENVIRONMENT_ID"],
    initial_events=[
        {
            "type": "user.message",
            "content": [
                {"type": "text", "text": "List the files in the working directory."}
            ],
        },
    ],
)
print(session.id)

응답에는 sesn_으로 시작하는 세션 ID가 포함됩니다. 에이전트는 즉시 작업을 시작합니다. bash와 같은 에이전트의 내장 도구는 해당 환경을 처리하는 워커에서 실행됩니다.

세션을 지켜보려면 브라우저에서 사용자 서버의 콘솔을 열고 Sessions를 선택한 다음 해당 세션을 선택하세요. 이 페이지에서처럼 서버 API 키로 시작한 세션은 관리자에게만 표시됩니다.

대신 터미널에서 세션을 따라가려면 세션 ID를 ant beta:sessions connect에 전달하세요:

ant beta:sessions connect sesn_011CZkZAtmR3yMPDzynEDxu7

에이전트 버전 고정 등 세션으로 할 수 있는 그 밖의 작업은 세션 시작하기를 참조하세요.

메시지 보내기 및 응답 읽기

다음 예시 ID 대신 세션 ID를 셸에 설정하세요:

export SESSION_ID=sesn_011CZkZAtmR3yMPDzynEDxu7

다음 예제를 실행하기 전에 세션이 유휴 상태가 될 때까지 기다리세요. 예제는 턴이 끝나면 읽기를 중지합니다. 이전 턴이 아직 실행 중이면, 그 턴이 끝나면서 메시지에 대한 응답이 도착하기 전에 예제가 중지될 수 있습니다. 세션의 상태는 콘솔과 ant beta:sessions connect 모두에서 확인할 수 있습니다.

다음 예제는 메시지를 보내고 에이전트의 응답을 출력합니다. 스트림은 열린 이후에 발생하는 이벤트만 전달하므로, 예제에서는 먼저 세션의 이벤트 스트림을 엽니다:

import os

from anthropic import Anthropic

client = Anthropic()
session_id = os.environ["SESSION_ID"]

with client.beta.sessions.events.stream(session_id) as stream:
    client.beta.sessions.events.send(
        session_id,
        events=[
            {
                "type": "user.message",
                "content": [
                    {"type": "text", "text": "Summarize what you did in one sentence."}
                ],
            },
        ],
    )

    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.error":
                error_message = event.error.message if event.error else "unknown"
                print(f"\n[Error: {error_message}]")
            case "session.status_idle":
                if event.stop_reason.type != "requires_action":
                    break
            case "session.status_terminated":
                break

루프는 agent.message 텍스트를 출력하는 것 외에 세 가지 이벤트를 처리합니다:

  • session.status_idle: 이벤트의 stop_reason.type이 requires_action이 아니면 루프가 끝납니다.
  • session.status_terminated: 루프가 끝납니다.
  • session.error: 서버가 실패한 모델 호출을 재시도하고 턴을 마칠 수 있으므로 루프는 오류 메시지를 출력하고 계속 읽습니다.

requires_action은 세션이 도구 호출을 위해 일시 중지되었음을 의미합니다. 일시 중지를 끝내는 방법은 호출에 따라 다릅니다:

  • 커스텀 도구 호출 또는 도구 호출 확인 요청: 이에 응답할 수 있는 것은 사용자의 코드뿐입니다. 에이전트가 둘 중 하나를 사용한다면 세션을 일시 중지시키는 도구 호출에 응답하기를 참조하세요.
  • bash와 같이 워커가 실행하는 도구에 대한 호출: 이 호출은 일반적으로 세션을 일시 중지하지 않습니다. 약 3분 동안 어떤 워커도 호출을 가져가지 않으면, 세션은 워커가 결과를 반환할 때까지 일시 중지됩니다. 이 경우 코드에서 응답할 것은 없습니다. 스트림을 열어 두면 워커가 호출을 실행할 때 턴이 재개됩니다.

세션이 보내는 그 밖의 이벤트, 그리고 하나도 놓치지 않고 다시 연결하는 방법은 세션 이벤트 스트림을 참조하세요.

세션 안팎으로 데이터 이동하기

데이터는 워커의 작업 디렉터리를 통해 세션에 전달되고 세션에서 나옵니다.

빠른 시작 스택에서는 각 세션의 컨테이너가 세션 저장소의 클론을 제외하면 빈 /workspace 디렉터리로 시작합니다. 기본적으로 턴이 끝나고 약 1분 후에 컨테이너가 종료되며, Docker가 해당 디렉터리와 함께 컨테이너를 삭제합니다. 세션이 보존해야 하는 모든 것은 그 전에 업로드나 git push와 같은 도구 호출을 통해 밖으로 내보내야 합니다.

컨테이너는 시작된 후 약 1시간이 지나면 턴 도중이라도 종료됩니다. 이는 어떤 설정으로도 바꿀 수 없습니다. 턴은 보통 1~2분 후 새 컨테이너에서 계속되며, 클라이언트는 이 전환에 대한 이벤트를 받지 않습니다. 이 전환에는 두 가지 비용이 따릅니다:

  • 명령: 이전 컨테이너에서 실행 중이던 모든 것이 중지됩니다. 새 컨테이너는 중단된 도구 호출을 처음부터 다시 실행하지만, 에이전트가 백그라운드에서 실행 중으로 남겨 둔 명령은 아무것도 다시 시작하지 않습니다.
  • 파일: 새 컨테이너의 /workspace는 세션 저장소의 새 클론을 제외하면 다시 비어 있습니다.

긴 턴에서는 에이전트가 작업을 진행하면서 결과물을 업로드하거나 푸시하도록 하고, 두 번 실행되면 문제를 일으키는 명령은 피하세요.

Kubernetes에서는 세션이 하나의 파드를 최대 약 1시간 동안 유지하며, 턴은 같은 방식으로 계속됩니다. 다른 점은 두 가지입니다. 새 파드는 /workspace에서 세션의 파일을 찾으며, 이전 파드가 중지된 후 약 6분 후에 시작됩니다.

직접 시작하는 워커의 경우, 입력 파일이 필요한 메시지를 보내기 전에 해당 파일을 작업 디렉터리에 넣으세요. 이후 출력 파일을 그곳에서 읽으세요.

세션마다 컨테이너를 직접 시작하는 경우, 세션의 입력 파일이 들어 있는 디렉터리를 컨테이너의 작업 디렉터리로 마운트하세요. 컨테이너가 종료된 후 그 디렉터리에서 출력 파일을 수집하세요. 세션용 파일 준비를 참조하세요.

호스팅 가이드에서 더 많은 예제 찾기

호스팅 서비스의 가이드에서는 API의 핵심 개념을 설명하고 각 기능의 예제를 제공합니다. 이 가이드들의 SDK 및 CLI 예제는 ANTHROPIC_BASE_URL과 ANTHROPIC_API_KEY가 설정된 터미널에서 실행하면 서버를 호출합니다. 이 가이드들의 cURL 예제는 https://api.anthropic.com을 지정하므로, 실행하기 전에 해당 주소를 $ANTHROPIC_BASE_URL로 바꾸세요.

일부 기능은 먼저 서버에 설정이 필요하거나 예제를 변경해야 합니다:

작업호스팅 가이드사용자 서버에서
에이전트의 모델, 시스템 프롬프트 및 버전 설정에이전트 정의하기일부 필드는 추론 공급자에 따라 달라집니다.
내장 도구 선택 또는 커스텀 도구 추가도구웹 도구를 사용하려면 웹 도구에는 서버 설정이 필요합니다에 설명된 대로 먼저 웹 도구를 켜세요. 어떤 웹 도구가 있는지는 추론 공급자에 따라 다릅니다.
MCP 서버 연결 및 토큰 저장MCP 커넥터 및 볼트로 인증하기MCP 서버의 호스트를 MCP 서버 허용 목록에 추가하세요. 토큰은 static_bearer 자격 증명으로 저장하세요.
에이전트에 스킬 부여스킬서버가 zip 아카이브를 거부하므로 각 스킬을 개별 파일로 업로드하세요. 해당 가이드 예제의 사전 빌드된 스킬은 사용할 수 없습니다.
세션 간 메모리 유지에이전트 메모리 사용하기직접 워커를 실행하는 경우 자체 호스팅 샌드박스의 메모리 저장소에 나온 대로 워커에 쓰기 가능한 /mnt/memory 디렉터리를 제공하세요.
다른 에이전트에 작업 넘기기멀티에이전트 오케스트레이션해당 가이드 예제의 multiagent_20261001 블록을 coordinator 블록으로 바꾸세요.
Git 저장소에서 작업하기GitHub 액세스하기Git 저장소에는 허용 목록 항목이 필요합니다에 설명된 대로 서버 설정에 Git 호스트를 등록하세요. 해당 가이드의 예제 에이전트에는 MCP 서버 허용 목록에 api.githubcopilot.com도 필요합니다.
채점자가 루브릭에 따라 작업 확인결과 정의하기루브릭을 텍스트로 보내세요. Files API를 사용할 수 없으므로 작업 디렉터리에서 출력 파일을 수집하세요.
세션 따라가기 및 도구 호출에 응답하기세션 이벤트 스트림해당 가이드의 첫 번째 예제는 일시 중지가 발생하면 스트림을 닫으므로, 대신 메시지 보내기 및 응답 읽기의 루프에서 시작하세요.

호스팅 서비스와의 차이점에 전체 목록이 있습니다. 기존 애플리케이션을 옮기기 전에 확인하세요.

자체 워커 실행하기

빠른 시작 스택은 환경을 생성하고 해당 환경의 워커를 실행합니다. Kubernetes에 배포하기의 Helm 차트도 마찬가지입니다. 이러한 워커만 필요하다면 이 섹션을 건너뛰세요.

워커는 자체 호스팅 샌드박스에서와 같은 방식으로 실행합니다. 즉, 자체 호스팅 워커 배포에 나온 방식대로 동일한 ant beta:worker 명령과 SDK 워커를 사용합니다. 예외는 웹훅으로 트리거되는 워커로, 사용자 서버는 웹훅을 보내지 않기 때문입니다.

환경 및 환경 키 생성하기

Claude Console이 아닌 관리자 CLI로 환경과 환경 키를 생성하세요. CLI인 cma-server-admin은 릴리스 아카이브의 최상위에 있으므로, 그 위치에서 명령을 실행하세요. -base-url에는 워커가 서버에 접근할 주소를 전달하세요:

관리자 CLI는 같은 주소로 서버를 호출하므로, 해당 주소에 접근할 수 있는 머신에서 실행하세요.

echo "$ANTHROPIC_API_KEY" | ./cma-server-admin bootstrap \
  -base-url http://127.0.0.1:8400 -name my-env -key-file -

이 명령은 워커 설정, 워커를 시작하는 명령, 그리고 키의 ID와 만료일을 출력합니다:

export ANTHROPIC_BASE_URL='http://127.0.0.1:8400'
export ANTHROPIC_ENVIRONMENT_ID='env_...'
export ANTHROPIC_ENVIRONMENT_KEY='sk-ant-oat01-...'
# then: histchars= HISTFILE=/dev/null ant beta:worker poll --workdir /workspace
# key id: 'etok_...'  expires: '...'

이 명령은 키를 한 번만 표시하므로 키와 키 ID, 만료일을 시크릿 매니저에 저장하세요. 키는 365일이 지나면 작동을 멈춥니다. 그 전에 자체 워커의 환경 키 교체하기를 따르세요.

워커를 실행하는 머신에는 서버 API 키를 두지 마세요. 보호해야 할 것이 전혀 없는 컨테이너나 VM에서 워커를 실행하세요. 그 밖의 보안 책임은 사용자의 보안 책임을 참조하세요.

로컬 실험 실행하기

워커를 시작하는 셸에서 세 개의 export 줄을 실행하세요. 그런 다음 출력된 명령이 아닌 다음 명령으로 워커를 시작하세요. 워커는 작업 디렉터리를 생성하지 않으므로 첫 번째 명령이 워커의 작업 디렉터리를 생성합니다:

mkdir -p "$HOME/cma-workspace" "$HOME/.config/cma"
cat > "$HOME/.config/cma/worker.inputrc" <<'EOF'
$include /etc/inputrc
set disable-completion on
EOF
histchars= HISTFILE=/dev/null INPUTRC="$HOME/.config/cma/worker.inputrc" \
  ant beta:worker poll --workdir "$HOME/cma-workspace"

histchars, INPUTRC, HISTFILE은 워커의 bash 도구 뒤에서 동작하는 셸을 설정하여, 셸이 각 명령을 에이전트가 작성한 그대로 실행하도록 합니다:

  • histchars=: 셸이 !를 명령 기록에 대한 참조로 취급하지 않습니다.
  • INPUTRC: 이 파일은 자동 완성을 끕니다. 그렇지 않으면 자동 완성이 명령의 각 탭 문자를 소비합니다. 에이전트의 파일 도구가 이 파일을 다시 쓸 수 있으므로, 파일을 작업 디렉터리 밖에 두세요.
  • HISTFILE=/dev/null: 셸이 기록 파일을 읽지도 쓰지도 않습니다.

이 워커는 다른 용도로 사용하지 마세요. 이 워커는 환경 키를 보유하고 모든 세션의 도구를 하나의 프로세스에서 실행합니다. 또한 세션의 저장소를 클론하지도 않습니다. 세션은 저장소 없이 실행되며, 클라이언트에는 오류가 전달되지 않습니다.

프로덕션에서 워커 실행하기

로컬 실험 외의 경우에는 세션당 샌드박스 하나 실행하기에 나온 대로 세션마다 컨테이너를 하나씩 시작하고 그 안에서 ant beta:worker run을 실행하세요. 컨테이너 이미지에는 자체 샌드박스 이미지 빌드하기에 나열된 항목을 갖추고, 해당 설정에서 다음 세 가지를 변경하세요:

  • 환경 키: 세션의 컨테이너에 ANTHROPIC_ENVIRONMENT_KEY를 전달하지 마세요. 서버는 이 키를 환경의 모든 세션에 대해 허용하지만, 컨테이너에는 한 세션에 대한 접근 권한만 필요합니다.
  • 작업 항목의 시크릿: 서버는 이 시크릿을 해당 한 세션에 대해서만 허용하므로, 키 대신 이 시크릿을 전달하세요. 작업 항목의 시크릿 전달에 코드가 시크릿을 받는 위치가 나와 있습니다. 해당 섹션에서 ANTHROPIC_WORK_SECRET을 설정하는 곳에서, 컨테이너의 사용자만 읽을 수 있는 파일에 시크릿을 넣으세요. 예를 들어 시크릿을 컨테이너의 표준 입력으로 파이프하고, 컨테이너가 워커를 시작하기 전에 파일을 쓰도록 하세요. 그런 다음 ANTHROPIC_WORK_SECRET_FILE을 해당 파일의 경로로 설정하세요.
  • 서버 주소: ANTHROPIC_BASE_URL을 컨테이너가 접근할 수 있는 주소로 설정하세요. http://127.0.0.1:8400은 그런 주소가 아닙니다.

SDK 워커의 경우 두 가지 사항이 추가로 적용됩니다:

  • 버전: SDK, CLI 및 라이브러리에 설명된 대로 최신 버전의 SDK로 워커를 빌드하세요. 이 버전의 워커는 승인이 필요한 도구 호출을 실행하기 전에 승인을 기다리며, 정책이 거부하는 호출은 절대 실행하지 않습니다. 이전 버전으로 빌드한 워커는 모든 도구 호출을 도착하는 즉시 실행합니다.
  • 샘플: 샌드박스 내부에서 SDK 워커 실행의 샘플은 환경 키를 읽으므로, 여기서는 그대로 작동하지 않습니다.

자체 샌드박스 이미지 빌드하기

자체 이미지에는 다음 패키지와 설정이 필요합니다:

  • 패키지: Git 2.38 이상, curl, jq, 그리고 워커의 grep 도구가 검색에 사용하는 ripgrep.

  • 셸 설정: 로컬 실험에서와 같은 histchars, HISTFILE, INPUTRC, 그리고 TERMINFO. Dockerfile에서 USER 줄보다 앞에 다음 줄을 넣으세요:

    ENV histchars=
    RUN printf '\nset disable-completion on\n' >> /etc/inputrc
    ENV INPUTRC=/etc/inputrc TERMINFO=/etc/terminfo HISTFILE=/dev/null
    RUN test -r /etc/terminfo/d/dumb

    TERMINFO에는 워커의 bash가 읽는 터미널 설명인 d/dumb가 들어 있는 디렉터리를 지정해야 합니다. bash가 설치된 Alpine에서는 표시된 대로 /etc/terminfo입니다. Debian 또는 Ubuntu 등 다른 기본 이미지에서는 /lib/terminfo 또는 /usr/share/terminfo 중 d/dumb가 있는 쪽입니다. 해당 디렉터리를 TERMINFO 설정과 RUN test 줄에 작성하세요. RUN test 줄은 파일이 없으면 빌드를 중지합니다.

이미지에는 워커가 시작되기 전에 실행되는 아카이브의 스크립트 두 개도 필요합니다:

  1. image-build/with-repositories.sh를 /usr/local/bin/cma-with-repositories로 복사하세요. 이 스크립트는 한 세션의 저장소를 클론합니다.
  2. image-build/with-egress.sh를 /usr/local/bin/cma-with-egress로 복사하세요. 서버에서 “egress gateway”(이그레스 게이트웨이)를 실행하는 경우, 이 스크립트는 세션의 도구가 이그레스 게이트웨이를 가리키도록 합니다.
  3. 두 파일을 모두 실행 가능하게 만드세요.
  4. cma-with-egress cma-with-repositories ant beta:worker run ...처럼 워커 명령 앞에 두 스크립트를 붙이세요. 이미지가 아카이브의 kubernetes/sandbox/worker.sh를 실행한다면 이 단계를 건너뛰세요. 해당 스크립트가 이 방식으로 워커를 시작하기 때문입니다.

cma-with-repositories 없이 시작한 워커는 저장소 없이 세션을 실행합니다. 클라이언트에는 오류가 전달되지 않습니다.

호스팅 서비스에서 워커 옮기기

이미 Anthropic의 호스팅 서비스용 워커를 실행하고 있다면, 같은 워커가 대신 사용자 서버를 처리하도록 할 수 있습니다. 다음 세 가지를 수행하세요:

  • 작업을 폴링하는 프로세스에 관리자 CLI가 출력한 세 가지 export 값을 전달하세요.
  • 로컬 실험에서처럼 histchars, HISTFILE, INPUTRC를 설정한 상태로 해당 프로세스를 시작하세요.
  • 프로덕션에서 워커 실행하기에 설명된 변경 사항을 적용하고, 각 세션의 이미지를 자체 샌드박스 이미지 빌드하기와 대조해 확인하세요.

다음 단계

이 페이지가 도움이 되었나요?