SSD Nodes Learn Hosting plans →
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-28

SandBase Harness v0.3.2 직접 호스팅 및 설정 방법

SandBase Harness v0.3.2를 VPS에 직접 설치하여 에이전트 런타임을 운영하는 방법을 안내합니다. Node.js 22 환경 구성부터 Anthropic SDK 연동, SQLite 데이터 관리 및 Docker 샌드박스 설정까지 전체 과정을 상세히 설명합니다.

SandBase 에이전트 런타임을 직접 호스팅할 때 얻는 이점

SandBase 에이전트 런타임을 직접 호스팅한다는 것은 사용자가 소유한 서버에서 SandBase Harness를 실행한다는 의미입니다. 따라서 세션, 자격 증명, 메모리 및 감사 추적 데이터가 타사의 서버가 아닌 사용자의 디스크에 저장됩니다. 이 서비스는 Node 기반으로 동작합니다. 127.0.0.1:3000에서 수신 대기하며 /v1 HTTP API와 웹 콘솔을 제공하고, 에이전트 파일 옆의 SQLite에 상태를 유지합니다.

/v1 API는 호스팅형 관리 에이전트 API인 Claude Managed Agents(CMA)를 모델로 설계되었습니다. 바로 이 점이 이 런타임을 양방향으로 유용하게 만듭니다. Anthropic SDK를 사용하여 코드를 작성하고 해당 baseURL를 사용자의 서버로 지정한 뒤, 나중에 동일한 코드를 호스팅 환경으로 이전할 수 있습니다.

SandBase Harness는 모델을 자체적으로 포함하지 않으며, 외부 모델을 호출합니다. 2026년 8월 기준으로 OpenAI, Anthropic 및 OpenAI 호환 엔드포인트를 지원하며, 여기에는 자체 호스팅 게이트웨이와 DeepSeek V4와 같은 제공업체가 포함됩니다. 사용자는 API 키를 직접 준비하거나 OpenAI API를 지원하는 로컬 서버를 사용해야 합니다.

시작하기 전에 필요한 것

  • 최소 2 GB RAM을 갖춘 Ubuntu 24.04 기반 VPS가 필요합니다. TypeScript 빌드는 설치 과정 중 가장 많은 자원을 소모하는 단계입니다.
  • Node.js 22 이상 및 npm 10 이상이 필요합니다. 이는 프로젝트에서 명시한 필수 최소 사양입니다.
  • git, 그리고 사용할 모델 제공업체의 API 키가 필요합니다.
  • 세션별 컨테이너 샌드박스를 사용하려는 경우에만 Docker가 필요합니다.

Ubuntu 24.04는 자체 저장소에서 Node 18.19를 제공하는데, 이는 최소 사양보다 낮으므로 NodeSource에서 Node를 설치하십시오.

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs git
node -v
npm -v

node -v 명령은 v22 이상의 버전을 출력해야 하며, npm -v 명령은 10 이상의 버전을 출력해야 합니다. 만약 node -v 명령이 여전히 v18.19.1를 출력한다면, 배포판 패키지가 여전히 설치되어 있고 PATH에서 우선순위를 점유하고 있는 상태입니다. 빌드는 셸이 먼저 발견한 node를 기준으로 실행되므로, 계속 진행하기 전에 해당 패키지를 삭제하십시오.

v0.3.2 태그에서 SandBase 설치하기

항상 태그를 사용하여 설치하십시오. 변경이 잦은 브랜치를 사용해서는 안 됩니다. main를 사용하여 베어 클론(bare clone)을 수행하면 한 시간 전에 커밋된 코드를 가져오게 되며, 아래의 설정 키가 일치하지 않을 수 있습니다. 2026년 8월 16일 기준으로 현재 태그는 v0.3.2입니다.

sudo install -d -o "$USER" -g "$USER" /opt/sandbase
cd /opt/sandbase
git clone --branch v0.3.2 --depth 1 https://github.com/sandbaseai/sandbase-harness.git
cd sandbase-harness
npm ci
npm run build

npm install 대신 npm ci을 사용하십시오. ci는 커밋된 락파일(lockfile)에 기록된 정확한 버전을 설치하므로, 관리자가 테스트한 트리와 동일한 환경이 구성됩니다. npm install은 더 최신 버전을 확인하여 설치할 수 있으며, 이 경우 고정된 태그의 의미가 사라질 수 있습니다.

이제 워크스페이스를 생성하십시오. 워크스페이스는 에이전트 파일과 모든 런타임 상태를 보관하는 별도의 디렉터리입니다. 소스 체크아웃 외부에서 워크스페이스를 관리하면 데이터를 건드리지 않고도 더 최신 태그를 가져올 수 있습니다.

mkdir -p /opt/sandbase/workspace
cd /opt/sandbase/workspace
node /opt/sandbase/sandbase-harness/dist/index.js init
node /opt/sandbase/sandbase-harness/dist/index.js start

init은 워크스페이스 내에 .managed-agents/ 디렉터리를 생성합니다. start를 실행하면 http://127.0.0.1:3000/dashboard에서 콘솔이, http://127.0.0.1:3000/v1에서 API가 시작됩니다. 아직 노트북에서 이 주소들에 접근할 수 없으며, 이는 정상적인 상태입니다. 자세한 내용은 아래에서 다룹니다. 현재는 SSH를 통해 콘솔에 접근하십시오.

ssh -N -L 3000:127.0.0.1:3000 you@your-server

긴 node .../dist/index.js 경로는 입력하기 번거로우므로 이름을 지정하십시오.

alias sandbase='node /opt/sandbase/sandbase-harness/dist/index.js'

아래의 명령어들은 이를 기준으로 sandbase <command>으로 작성되었습니다.

npm을 통해 설치하지 마십시오

해당 프로젝트의 자체 설치 문서에는 다음과 같은 내용이 명시되어 있습니다. npm에 공개된 스코프가 없는 managed-agents 패키지는 이 프로젝트와 무관합니다. 따라서 npx managed-agents 및 npm install -g managed-agents 명령을 실행하면 사용자가 원하는 런타임과 관계없는 패키지가 설치됩니다. 관리자가 공식 스코프 패키지를 발표하기 전까지는 태그가 지정된 GitHub 소스에서 직접 설치하십시오. 이는 프로젝트 역사에서 가볍게 넘길 수 있는 각주가 아닙니다. v0.3.1 버전이 존재하는 주된 이유는 기존의 npm 퀵 스타트 방식을 고정된 태그 소스 경로로 대체하기 위함입니다.

워크스페이스를 모델 제공자에 연결하기

init은 .managed-agents/config.yaml을 작성합니다. 워크스페이스 전체에 하나의 제공자가 설정되며, 개별 에이전트는 구체적인 모델 ID를 선택합니다.

model:
  provider: openai
  api_key: ${OPENAI_API_KEY}
storage:
  metadata:
    provider: sqlite
    options: {}
  artifacts:
    provider: local
    options:
      base_path: files

${OPENAI_API_KEY} 폼은 프로세스 환경에서 값을 가져오므로, 키가 설정 파일에 남지 않으며 해당 파일의 모든 백업본에서도 제외됩니다. systemd는 권한을 낮추기 전에 EnvironmentFile=을 root로 읽으므로, root만 읽을 수 있는 환경 파일에 해당 값을 넣으십시오.

sudo install -d -m 750 /etc/sandbase
sudo touch /etc/sandbase/runtime.env
sudo chmod 600 /etc/sandbase/runtime.env

해당 파일을 편집기로 열고 OPENAI_API_KEY=sk-... 한 줄을 추가하십시오. 제공자 키는 이곳에 보관합니다. 에이전트가 세션 중에 사용하는 비밀 정보는 런타임의 자격 증명 보관소(credential vault)에 넣어야 합니다. 이는 영향 범위가 다른 별개의 문제이므로, 운영 환경의 토큰을 어느 곳에든 붙여넣기 전에 AI 에이전트에서 비밀 정보 제외하기를 읽어보는 것이 좋습니다.

에이전트 YAML: mcp_servers, 도구 및 권한 정책

에이전트는 워크스페이스의 agents/ 디렉터리에 있는 YAML 파일로 정의합니다. 이곳은 런타임에서 실제로 가장 많은 시간을 보내게 될 영역입니다. 직접 작은 에이전트 루프를 작성해 보면 각 키의 의미가 더 명확해집니다. 각 키는 시스템 프롬프트, 도구 목록, 도구 실행 전 검사 등 직접 코딩해야 할 기능들을 제어하는 설정값입니다.

name: Incident commander
description: Triages alerts and coordinates response.
model: gpt-4o
system: |-
  You are an on-call incident commander.
mcp_servers:
  - name: sentry
    type: url
    url: https://mcp.sentry.dev/mcp
tools:
  - type: agent_toolset_20260401
    default_config:
      permission_policy: { type: always_ask }
    configs:
      - name: bash
        permission_policy: { type: always_ask }
  - type: mcp_toolset
    mcp_server_name: sentry
metadata:
  template: incident-commander

파일을 로드하고 정상적으로 반영되었는지 확인합니다.

sandbase reload
sandbase list
sandbase chat agent_assistant --message "hello"

reload은 시드 YAML을 SQLite로 가져옵니다. 이제 list를 실행하면 ID가 포함된 에이전트 정보가 출력되어야 합니다. 만약 list에 아무것도 나타나지 않는다면 파일이 파싱되지 않은 것이며, 그 이유는 .managed-agents/logs/runtime.log에서 확인할 수 있습니다.

mcp_servers는 MCP(model context protocol) 엔드포인트를 선언한다. type: url은 런타임이 다른 곳에서 실행 중인 서버와 HTTP로 통신한다는 뜻이다. 따라서 이미 운영 중인 것은 무엇이든 여기서 사용할 수 있으며, 여기에는 런타임과 동일한 VPS에서 호스팅하는 MCP 서버도 포함된다. 웹 검색은 보통 사람들이 가장 먼저 사용하는 도구다. 하지만 웹 검색 도구를 연결하기 전에 에이전트에 자체 SearXNG 인스턴스 연결하기를 먼저 읽어 보는 것이 좋다. 낯선 사람이 작성한 페이지를 반환하는 도구는 신뢰할 수 없는 텍스트를 모델의 컨텍스트에 직접 넣기 때문이다. 처음 연결할 때는 이미 소유한 데이터에 대한 읽기 전용 엔드포인트를 제공하는 반대 형태가 더 안전하다. openGym은 운동 기록 추적기 자체 옆에 이 기능을 노출한다. 따라서 에이전트가 운동 기록에 관한 질문에는 답할 수 있지만 기록 자체를 다시 작성할 수는 없다.

서버를 선언한다고 해서 해당 도구가 에이전트에 자동으로 제공되지는 않습니다. tools 목록을 통해 도구를 할당하며, 이때 mcp_toolset 항목의 mcp_server_name 값이 위에서 정의한 name와 일치해야 합니다. 에이전트가 MCP 도구를 인식하지 못하는 것처럼 동작한다면, 다른 곳을 확인하기 전에 두 문자열이 한 글자도 틀리지 않고 일치하는지 먼저 비교하십시오.

agent_toolset_20260401은 내장 도구 세트입니다. 날짜가 포함된 접미사는 스키마 버전이므로, 특정 버전에 고정된 에이전트는 작성 당시의 도구 정의를 그대로 유지합니다. default_config는 해당 세트 내 모든 도구에 대한 정책을 설정하며, configs 하위의 각 항목은 예시의 bash과 같이 도구 이름별로 설정을 재정의합니다.

permission_policy은 런타임이 단순 모델 호출보다 우위에 있는 이유를 보여주는 부분입니다. always_ask은 세션을 일시 중지하고 도구 호출이 실행되기 전에 사람이 승인할 때까지 대기합니다. always_allow는 호출을 허용합니다. bash을 always_ask로 설정하면 에이전트가 셸 명령을 실행하기 전에 사용자가 정확한 명령을 먼저 확인해야 합니다. 이는 VPS에서 Claude Code를 안전하게 실행할 때 사용하는 제어 방식과 동일합니다. DeepSeek Harness를 사용하는 경우에도 동일한 제어 기능이 YAML 키가 아닌 애드온 형태로 제공되며, 예산을 제한하고 도구 호출을 차단하는 플러그인이 이 블록과 가장 유사한 기능을 수행합니다.

세 가지 샌드박스 모드와 각 모드의 적합한 사용 사례

코드를 실행하는 도구 호출은 샌드박스 내부에서 수행됩니다. 백엔드는 환경별로 선택하며, 환경의 config 객체 내 sandbox_provider를 통하거나 콘솔의 Settings 내 Sandbox 메뉴에서 설정할 수 있습니다. 환경은 POST /v1/environments API를 통해 생성됩니다.

local 모드는 런타임의 자식 프로세스로서 호스트에서 런타임 사용자 권한으로 코드를 실행합니다. 기본값이며, 사용자가 본인뿐이고 에이전트가 본인 소유의 파일만 읽는 경우에 적합합니다. 이는 격리된 환경이 아닙니다. 파일을 삭제하는 도구 호출은 사용자의 파일을 삭제하며, /etc/sandbase/runtime.env를 읽는 도구 호출은 사용자의 공급자 키를 읽습니다.

docker 모드는 세션당 하나의 컨테이너를 시작합니다.

{
  "sandbox_provider": "docker",
  "image": "node:22-slim",
  "resources": { "memory": "1g", "cpu": 1 }
}

각 세션은 고유한 파일 시스템, 메모리 제한, CPU 점유율을 가지며 세션이 종료되면 컨테이너도 제거됩니다. 에이전트가 본인이 작성하지 않은 코드를 실행하는 즉시 이 모드로 전환하십시오. 단점은 런타임 사용자가 Docker 소켓에 접근할 수 있어야 한다는 점이며, docker 그룹에 속하는 것은 호스트의 root 권한을 갖는 것과 동일합니다. 세션별 컨테이너는 실행당 컨테이너 하나를 사용하는 자체 호스팅 에이전트 샌드박스와 동일한 형태이므로, 프로세스 탈출 시 접근 가능한 범위에 대한 논리도 그대로 적용됩니다.

kubernetes 모드는 세션 워크로드를 파드(pod)로 실행하며 kubectl exec 및 kubectl cp을 통해 구동합니다. 런타임 이미지에는 kubectl가 포함되어야 하며, 해당 ServiceAccount는 대상 네임스페이스 내에서 파드를 생성, 삭제, 조회, 목록 확인, 감시할 수 있는 RBAC(역할 기반 접근 제어) 권한과 exec 하위 리소스 권한이 필요합니다. 이 모드는 이미 클러스터를 운영 중인 경우에만 설정할 가치가 있습니다.

런타임이 127.0.0.1에 바인딩되는 이유는 무엇입니까?

인증이 꺼진 상태로 시작하기 때문입니다. 런타임은 최소 하나의 API 키가 존재할 때 Bearer 토큰 인증을 활성화하는데, 새로 설치한 init에는 키가 생성되어 있지 않습니다. 이 기본 설정 상태에서 0.0.0.0에 바인딩하면 셸 도구와 공급자 키를 가진 인증되지 않은 에이전트 런타임이 공용 인터넷에 노출됩니다.

따라서 외부에서 접근 가능하게 하려면 바인딩 주소는 그대로 두고 다음 두 가지 작업을 수행하십시오.

첫째, 인증을 켭니다. 서비스 환경 파일에 MANAGED_AGENTS_API_KEY을 설정하거나 POST /v1/api-keys로 키를 생성하십시오. 이 명령은 secret_key 필드를 한 번만 표시하며 다시는 보여주지 않습니다. 이후 클라이언트는 모든 요청에 Authorization: Bearer <key>을 포함하여 전송해야 합니다. 하나의 키는 하나의 공유된 ID를 의미하므로, 팀원별로 별도의 샌드박스 에이전트를 구성하고 단일 게이트웨이에서 공급자 키를 관리하려는 경우 OneCLI가 해당 구성에 적합하게 설계되었습니다.

둘째, 리버스 프록시를 앞에 두고 그곳에서 TLS(전송 계층 보안)를 종료하십시오. 런타임은 설계상 일반 HTTP를 제공하며, 인증서 처리는 다른 도구가 담당할 것으로 가정합니다.

server {
    listen 443 ssl;
    server_name agents.example.com;

    ssl_certificate     /etc/letsencrypt/live/agents.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/agents.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Connection "";
        proxy_buffering off;
        proxy_read_timeout 3600s;
    }
}

위 설정 중 두 줄은 단순한 장식이 아닙니다. proxy_buffering off은 중요합니다. 세션은 서버 전송 이벤트(SSE)를 통해 스트리밍되는데, 버퍼링이 켜져 있으면 nginx는 버퍼가 찰 때까지 응답을 보관합니다. 이 경우 에이전트가 작업하는 동안 콘솔에는 아무것도 표시되지 않다가 작업이 끝난 뒤에야 모든 내용이 한꺼번에 출력됩니다. proxy_read_timeout 3600s도 중요합니다. 기본값은 60초이므로, 1분 이상 데이터 흐름이 없으면 프록시가 중간에 스트림을 닫아버리며, 이로 인해 런타임이 충돌한 것처럼 보일 수 있습니다.

방화벽에서는 22번과 443번 포트만 개방하십시오. 3000번 포트는 닫아두어야 합니다. 프록시가 루프백을 통해 해당 포트에 접근하므로 외부에서 직접 접근할 필요가 없기 때문입니다.

Anthropic SDK를 로컬 서버로 연결하기

런타임은 CMA 형태의 /v1 인터페이스를 구현하므로, Anthropic SDK 클라이언트는 필드 하나만 변경하여 연결할 수 있습니다.

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

const client = new Anthropic({
  apiKey: process.env.MANAGED_AGENTS_API_KEY ?? 'local-dev-key',
  baseURL: 'http://127.0.0.1:3000'
});

또한 Claude Managed Agents 클라이언트가 전송하는 베타 헤더인 anthropic-beta: managed-agents-2026-04-01 및 anthropic-beta: agent-memory-2026-07-22도 허용합니다. 로컬 런타임에서는 이 헤더들이 선택 사항입니다. 호스팅 환경을 위해 작성된 코드를 수정 없이 그대로 실행할 수 있도록 지원하기 위해 존재합니다.

호환성은 높지만 완벽하지는 않습니다. 인터페이스가 존재한다고 가정하기 전에 체크아웃 디렉터리의 docs/api-matrix.md를 읽어보십시오. 이 프로젝트는 클라이언트 측 커스텀 도구를 포함하여 자체적인 기능 공백을 문서화하고 있으며, 이러한 도구는 현재의 이벤트-결과 프로토콜 상위에서 명시적인 등록이 필요합니다.

일반 HTTP를 사용하는 것도 가능하며, 런타임이 정상 작동하는지 확인하는 가장 빠른 방법입니다.

curl -N -X POST http://127.0.0.1:3000/v1/sessions/SESSION_ID/messages \
  -H "Content-Type: application/json" \
  -d '{"content": "Hello", "stream": true}'

정상적인 응답은 지속적으로 도착하는 이벤트 스트림입니다. 연결이 끊기면 전체 턴을 다시 재생하지 말고 마지막으로 확인한 이벤트부터 재개하십시오.

curl -N http://127.0.0.1:3000/v1/sessions/SESSION_ID/events/stream \
  -H "Last-Event-ID: EVENT_ID"

이러한 재개 가능한 스트림 덕분에 노트북을 닫아도 세션이 유지됩니다. 이벤트는 서버에 영구 저장되므로, 클라이언트는 유일한 사본을 보유하는 대신 로그를 다시 재생하는 방식을 취합니다.

자격 증명, 메모리, 감사 추적이 디스크에 저장되는 위치

런타임이 소유한 모든 데이터는 작업 공간 내의 .managed-agents/ 경로에 위치합니다.

.managed-agents/
├── config.yaml
├── data.db
├── logs/runtime.log
├── files/
├── skills/
├── snapshots/
└── sandbox/
  • data.db는 에이전트, 세션, 자격 증명 보관소 항목, 메모리 저장소 항목 및 API 키에 대한 SQLite 메타데이터를 포함합니다.
  • files/는 업로드된 파일의 바이트 데이터를, skills/은 업로드된 스킬 패키지를 보관합니다.
  • snapshots/은 세션 작업 공간의 스냅샷을 보관하며, sandbox/은 로컬 모드 세션의 작업 디렉터리를 보관합니다.
  • logs/runtime.log는 어떤 작업이 아무런 반응 없이 실패할 때 가장 먼저 확인해야 할 곳입니다.

자격 증명 보관소는 environment_variable과 같은 auth_type을 사용하여 추가된 비밀 정보들의 그룹이며, 세션 생성 시 vault_ids를 통해 세션에 연결됩니다. 메모리 저장소는 고유한 접근 설정과 지침을 가진 memory_store으로 세션에 마운트하는 명명된 항목들을 보관합니다. 두 항목 모두 data.db에 저장되며, 이는 단순한 모델 호출과 런타임의 차이점이기도 합니다. 런타임은 세션 간의 정보를 기억하고 발생한 일을 기록합니다.

해당 디렉터리는 하나로 구성되어 있으므로, 백업 시에도 전체를 하나로 묶어 수행하십시오.

sudo systemctl stop sandbase
sudo tar czf /root/sandbase-$(date +%F).tgz -C /opt/sandbase/workspace .managed-agents
sudo systemctl start sandbase

먼저 서비스를 중지하십시오. 런타임이 데이터를 기록하는 도중에 SQLite 데이터베이스를 복사하면 복원 시 열리지 않는 파일이 생성될 수 있으며, 이는 정작 복구가 필요한 시점에 문제를 일으킵니다. 에이전트 YAML은 git으로 관리하고 상태 데이터는 다른 곳에 보관하고 싶다면, 배포 문서에서 안내하는 start의 --data-dir 설정을 사용하여 상태 저장 위치를 지정할 수 있습니다.

복원 과정은 역순으로 진행합니다. 새로운 서버에서 동일한 태그를 체크아웃하고, 아카이브를 작업 공간에 압축 해제한 뒤 서비스를 시작하십시오. ${OPENAI_API_KEY} 형식을 사용했다면 공급자 키는 아카이브에 포함되지 않으므로, 별도의 안전한 장소에 보관해야 합니다.

systemd에서 실행하기

로컬 샌드박스 모드에서 도구를 호출할 때 사용자의 권한으로 동작하지 않도록, 런타임 전용 사용자를 생성하십시오.

sudo adduser --system --group --no-create-home --home /opt/sandbase sandbase
sudo chown -R sandbase:sandbase /opt/sandbase

이 내용을 /etc/systemd/system/sandbase.service로 저장하십시오.

[Unit]
Description=SandBase Harness runtime
After=network-online.target

[Service]
User=sandbase
Group=sandbase
WorkingDirectory=/opt/sandbase/workspace
EnvironmentFile=/etc/sandbase/runtime.env
ExecStart=/usr/bin/node /opt/sandbase/sandbase-harness/dist/index.js start --host 127.0.0.1 --port 3000
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

프로젝트의 자체 배포 예제는 PATH에서 managed-agents 바이너리를 호출합니다. 태그된 소스로 설치하면 해당 바이너리가 생성되지 않으므로, ExecStart은 빌드된 진입점을 대상으로 node를 실행합니다.

sudo systemctl daemon-reload
sudo systemctl enable --now sandbase
sudo systemctl status sandbase
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/dashboard

정상적인 결과는 status에서 active (running), curl에서 200가 출력되는 것입니다. 다른 결과가 나타나면 journalctl -u sandbase -n 50을 먼저 읽고 .managed-agents/logs/runtime.log을 이어서 확인하십시오. enable --now는 수동으로 시작한 프로세스가 재부팅 후 사라지기 때문에 중요한 부분입니다.

오류 발생 시 증상 및 메시지

npm run build이(가) npm 오류 없이 종료됩니다. 1 GB VPS에서 TypeScript 컴파일이 수행될 때 커널의 out-of-memory killer가 이를 중단시키면, npm이 아닌 커널 로그에 기록이 남습니다. journalctl -k | grep -i "out of memory" 명령으로 확인하면 종료된 node 프로세스 이름이 포함된 줄이 출력됩니다. 스왑을 추가하거나, 더 큰 인스턴스에서 빌드한 뒤 dist/을(를) 복사하십시오.

Error: listen EADDRINUSE: address already in use 127.0.0.1:3000. 다른 프로세스가 이미 해당 포트를 점유하고 있습니다. sudo ss -lntp | grep 3000 명령으로 해당 프로세스를 확인할 수 있습니다. 해당 프로세스를 중지하거나, --port 3001 플래그를 사용하여 런타임을 시작한 뒤 프록시 설정을 업데이트하십시오.

노트북에서 대시보드가 로드되지 않습니다. 런타임이 루프백 인터페이스에 바인딩되므로 이는 의도된 동작입니다. 위에서 설명한 SSH 터널을 사용하거나 리버스 프록시 설정을 완료하십시오. 키가 생성되기 전까지는 인증이 비활성화된 상태이므로 --host 0.0.0.0을(를) 사용하여 해결하려고 하지 마십시오.

Docker 샌드박스가 permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock 오류로 실패합니다. sandbase 사용자가 docker 그룹에 포함되어 있지 않기 때문입니다. sudo usermod -aG docker sandbase 명령으로 이 문제를 해결하고 서비스를 재시작하십시오. 단, 이 그룹은 호스트의 root 권한을 가지므로, 런타임에 별도의 사용자를 부여한 취지가 일부 무색해진다는 점을 유의하십시오.

Kubernetes 샌드박스가 Error from server (Forbidden) 오류로 실패합니다. ServiceAccount에 pod 권한이나 exec 하위 리소스 권한이 누락되었습니다. kubectl auth can-i create pods/exec -n <namespace> 명령으로 직접 확인하십시오. 결과로 yes 또는 no이(가) 반환될 것입니다.

API 키를 추가한 후 모든 요청에서 401 오류가 발생합니다. 첫 번째 키가 생성되면 인증이 활성화되며, 이는 API뿐만 아니라 콘솔에도 적용됩니다. Authorization: Bearer <key> 헤더를 포함하여 요청하십시오. 키를 분실했다면 새로 생성해야 합니다. secret_key은(는) 생성 시 한 번만 표시되며 읽을 수 있는 형태로 저장되지 않기 때문입니다.

MCP 서버의 도구가 세션에 나타나지 않습니다. tools 블록의 mcp_server_name과(와) mcp_servers의 name을(를) 대조하여 확인하십시오. 그 후 서버 자체에서 curl -i <url> 명령을 사용하여 런타임이 해당 URL에 접근할 수 있는지 확인하십시오. URL 방식의 MCP 서버는 네트워크 의존성을 가지며, VPS는 노트북과 이름 해석 및 트래픽 라우팅 방식이 다를 수 있습니다.

FAQ

OpenAI나 Anthropic 키 없이 SandBase Harness를 실행할 수 있습니까?

네, OpenAI 호환 엔드포인트가 있다면 가능합니다. 런타임은 OpenAI, Anthropic 및 OpenAI 호환 제공자를 지원하므로 OpenAI API를 사용하는 로컬 서버라면 정상적으로 작동합니다. .managed-agents/config.yaml에서 워크스페이스 제공자를 설정하고 api_key와 엔드포인트를 해당 서버로 지정하십시오. 런타임 자체에는 모델이 포함되어 있지 않으므로 호출에 응답할 대상이 반드시 필요합니다.

런타임을 공용 포트에 노출해도 안전합니까?

기본 설치 상태로는 안전하지 않습니다. 런타임은 127.0.0.1:3000에 바인딩되며 인증이 꺼진 상태로 시작되는데, 단순히 바인딩 주소를 변경하는 것만으로는 해결되지 않습니다. API 키를 생성하거나 MANAGED_AGENTS_API_KEY을 설정하여 Bearer 토큰 인증을 활성화하십시오. 그 후 nginx나 Caddy를 앞단에 배치하여 TLS를 적용하고, 방화벽에서 3000번 포트를 닫아 프록시를 통해서만 접근할 수 있도록 제한해야 합니다.

로컬, Docker, Kubernetes 샌드박스의 차이점은 무엇입니까?

local은 도구 코드를 호스트의 런타임 자식 프로세스로 실행하며, 런타임 사용자의 권한으로 동작하므로 격리되지 않습니다. docker는 각 세션에 고유한 파일 시스템, 메모리 제한, CPU 점유율을 가진 컨테이너를 할당하며 세션 종료 시 컨테이너를 제거합니다. kubernetes은 세션을 Pod로 실행하며 kubectl exec을 통해 제어합니다. 이 방식은 런타임 이미지 내부에 kubectl가 필요하며, Pod에 대한 RBAC 권한과 대상 네임스페이스 내 exec 하위 리소스 권한이 요구됩니다.

정확히 무엇을 백업해야 합니까?

워크스페이스 내의 .managed-agents/ 디렉터리를 백업해야 합니다. 이 디렉터리에는 config.yaml와 에이전트, 세션, 자격 증명 저장소 항목, 메모리 항목이 포함된 data.db SQLite 데이터베이스, 그리고 업로드된 파일, 스킬 패키지, 세션 스냅샷이 저장됩니다. SQLite가 아카이브 도중에 기록되는 것을 방지하기 위해 복사 전 서비스를 중지하십시오. ${OPENAI_API_KEY}로 참조되는 제공자 API 키는 백업에 포함되지 않으므로 별도로 보관하십시오.

왜 main 대신 v0.3.2 태그를 클론해야 합니까?

태그는 고정된 트리이므로 가이드에서 읽은 설정 키와 CLI 명령을 그대로 사용할 수 있습니다. main은 계속 변경되며, 가이드 작성 시점과 실행 시점 사이에 설정 키 이름이 바뀔 수 있습니다. 또한 프로젝트 측은 npm의 범위가 지정되지 않은 managed-agents 패키지가 본 프로젝트가 아니라고 경고하고 있으며, npx managed-agents을 실행하면 관련 없는 패키지가 설치됩니다. 릴리스 v0.3.1은 주로 해당 npm 빠른 시작 방식을 고정된 태그 소스 경로로 대체하기 위해 존재합니다.