> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# サンドボックスで Devin Outposts を実行する

> Devin には Devin Cloud で計画を立てさせつつ、コマンドはお客様が管理する CoreWeave サンドボックス内で実行できます。

[Devin Outposts](https://docs.devin.ai/cloud/outposts/overview) では、Devin の計画立案とモデル推論は Devin Cloud で行われます。一方、コマンドの実行、ファイルの編集、リポジトリへのアクセスは、お客様が運用するマシン上で Devin が行います。このガイドでは、そのマシンとして CoreWeave のサンドボックスを使用します。サンドボックスは、イメージ、CPU、メモリ、GPU、有効期間を任意に指定できる分離環境です。

アウトポストとは、Devin Cloud 上の名前付きキューです。ワーカーとは `devin worker` プロセスのことで、アウトバウンド HTTPS で Devin Cloud に接続し、キューからセッションを取得してローカルで実行します。インバウンドのポート、パブリック IP アドレス、仮想プライベートネットワーク (VPN) は必要ありません。このガイドでは、1 つのサンドボックスで 1 つのワーカーを実行します。そのワーカーは、サンドボックスが存続している間、セッションを順番に処理します。

各ワーカーが同時に処理できる実行中のセッションは 1 つだけです。それ以外のセッションは、ワーカーが空くまで待機します。このガイドでは、起動するワーカーの数は固定です。セッションがキューに溜まっても、サンドボックスが自動で追加されることはありません。ワーカーを手動で追加起動するか、オーケストレーターを使用して自動的にプロビジョニングしてください。

<h2 id="prerequisites">
  前提条件
</h2>

始める前に、次のものが揃っていることを確認してください。

* Outposts が有効になっている Devin 組織。Devin Cloud の **Settings > Environment** に **Outposts** が表示されない場合は、Devin の管理者に問い合わせてください。
* `SANDBOX_USER` action が付与された [CoreWeave API アクセストークン](/ja/products/sandboxes/placement#choose-and-get-credentials)。
* SDK (ソフトウェア開発キット) を直接使用する場合は、Python 3.11 以降と [`uv`](https://docs.astral.sh/uv/)、または Node.js 22 以降。

このガイドの手順を実行するターミナルで、CoreWeave API アクセストークンをエクスポートします。

```bash theme={"system"}
export CWSANDBOX_API_KEY="[API-ACCESS-TOKEN]"
```

<h2 id="create-an-outpost-in-devin-cloud">
  Devin Cloud でアウトポストを作成する
</h2>

アウトポストを作成してトークンを取得するには、次の手順に従います。

1. [Devin Cloud](https://app.devin.ai) で、**Settings > Environment > Outposts** に移動します。
2. **Create Outpost** をクリックし、名前を入力して **Linux** を選択します。
3. アウトポストのトークンをコピーします。トークンは Devin Cloud で一度しか表示されません。

アウトポストの準備が完了したら、`cws-agent` または Sandboxes SDK のいずれかでワーカーを起動し、検証セッションを実行します。

<h2 id="quick-start-with-cws-agent">
  cws-agent によるクイックスタート
</h2>

[`cws-agent` のインストール手順](https://github.com/coreweave/cws-agent#install)に従ってください。このツールは、[ファイルシステムスナップショット](/ja/products/sandboxes/file-system-snapshots#start-a-sandbox-with-a-snapshot-mount)でワークスペースを保存およびリストアするためのスナップショットボリュームを設定します。

`[OUTPOST-TOKEN]` はコピーしたトークンに、`[OUTPOST-NAME]` はアウトポスト名に、`[SANDBOX-NAME]` はこのサンドボックス用の `cws-agent` セッション名に置き換えてください。セッション名は英小文字、数字、ハイフンを使用した 1～40 文字で指定し、先頭は英字または数字にしてください。

```bash theme={"system"}
export DEVIN_OUTPOSTS_TOKEN="[OUTPOST-TOKEN]"
cws-agent launch [SANDBOX-NAME] --outpost [OUTPOST-NAME]
```

このツールはトークンをサンドボックスに渡し、ワーカーを 1 つ起動します。

ワーカーのターミナルを表示するには、次のコマンドを実行します。

```bash theme={"system"}
cws-agent connect [SANDBOX-NAME] --cmd 'tmux attach -t outpost-0'
```

**Ctrl-b** を押してから **d** を押してデタッチし、[Devin セッションを実行して検証する](#run-and-verify-a-devin-session)に進みます。このワーカーは Devin Cloud に接続します。`--agent devin` で起動する対話型の Devin コマンドラインインターフェース (CLI) とは別のものです。

<h2 id="set-up-with-the-sandbox-sdk">
  Sandboxes SDK を使用して設定する
</h2>

`cws-agent` を使用せずにワーカーを直接起動する場合は、この代替手段を使用します。この方法では永続ストレージは構成されません。

Python のスニペットは、[認証情報を設定してクライアントをインストールする](#configure-credentials-and-install-the-client)で作成した仮想環境で実行してください。TypeScript のスニペットは、クライアントをインストールしたプロジェクトに `.mts` ファイルとして保存し、`npx tsx [FILENAME].mts` で実行してください。

<h3 id="configure-credentials-and-install-the-client">
  認証情報を設定してクライアントをインストールする
</h3>

スクリプトを実行するターミナルで、アウトポストの作成時にコピーしたトークンをエクスポートします。

```bash theme={"system"}
export DEVIN_OUTPOSTS_TOKEN="[OUTPOST-TOKEN]"
```

クライアントを選択し、ローカルにインストールします。

<Tabs>
  <Tab title="Python">
    Python 3.11 以降と `uv` を使用します。

    ```bash theme={"system"}
    uv venv --python 3.11
    source .venv/bin/activate
    uv pip install 'cwsandbox>=1.14.2'
    ```
  </Tab>

  <Tab title="TypeScript">
    Node.js 22 以降を使用します。お使いのプロジェクトにクライアントと TypeScript ランナーをインストールしてください。

    ```bash theme={"system"}
    npm install @coreweave/cwsandbox@0.5.0-beta.0 tsx
    ```
  </Tab>
</Tabs>

<h3 id="start-the-worker">
  ワーカーを起動する
</h3>

<Tip>
  ワーカーの起動時間を短縮するには、Devin CLI、Git、言語ランタイム、プロジェクトの依存関係をプリインストールした独自のイメージを使用してください。Python では `container_image`、TypeScript では `containerImage` にそのイメージを指定します。イメージに Git と認証局 (CA) 証明書がすでに含まれている場合は、例から `apt-get` コマンドを削除してください。
</Tip>

次のスクリプトは、Cognition の公式ワーカーイメージからサンドボックスを作成し、サンドボックスのメインコマンドとして `devin worker` を実行します。クライアントはローカル環境から `DEVIN_OUTPOSTS_TOKEN` を読み取り、その値をサンドボックスリクエストに含めて渡すことで、ワーカーの環境変数を設定します。ワーカーの出力はサンドボックスのログとして記録されます。ワーカーがエラーで終了した場合、プラットフォームは再起動の上限に達するまでコンテナーを再起動します。

<Tabs>
  <Tab title="Python">
    ```python title="start_outpost_worker.py" theme={"system"}
    import os
    import sys

    from cwsandbox import ResourceOptions, Sandbox

    outpost = sys.argv[1]

    # ワーカーイメージには Devin CLI が含まれていますが、Devin がリポジトリを
    # クローンするために必要な git は含まれていません。git をインストールしてから、プロセスをワーカーに引き渡します。
    command = """
    apt-get update -qq
    DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git ca-certificates >/dev/null
    mkdir -p /workspace
    cd /workspace
    exec devin worker start --outpost="$DEVIN_OUTPOST"
    """

    sandbox = Sandbox.run(
        "bash", "-ec", command,
        container_image="public.ecr.aws/e0h8a4b6/devin-cli:stable",
        environment_variables={
            "DEVIN_OUTPOSTS_TOKEN": os.environ["DEVIN_OUTPOSTS_TOKEN"],
            "DEVIN_OUTPOST": outpost,
        },
        max_lifetime_seconds=8 * 3600,
        resources=ResourceOptions(
            requests={"cpu": "2", "memory": "4Gi"},
            limits={"cpu": "2", "memory": "4Gi"},
        ),
        tags=["devin-outpost-worker"],
    )
    try:
        sandbox.wait()
    except BaseException:
        sandbox.stop().result()
        raise

    print(f"Worker sandbox ID: {sandbox.sandbox_id}")
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript title="start_outpost_worker.mts" theme={"system"}
    import { createSandboxClientFromEnv } from "@coreweave/cwsandbox/node";

    const token = process.env.DEVIN_OUTPOSTS_TOKEN;
    if (!token) throw new Error("Set DEVIN_OUTPOSTS_TOKEN.");
    const outpost = process.argv[2];
    if (!outpost) throw new Error("Pass an outpost name.");

    const command = `
    apt-get update -qq
    DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git ca-certificates >/dev/null
    mkdir -p /workspace
    cd /workspace
    exec devin worker start --outpost="$DEVIN_OUTPOST"
    `;

    const client = createSandboxClientFromEnv();
    const sandbox = await client.run(["bash", "-ec", command], {
      containerImage: "public.ecr.aws/e0h8a4b6/devin-cli:stable",
      environmentVariables: {
        DEVIN_OUTPOSTS_TOKEN: token,
        DEVIN_OUTPOST: outpost,
      },
      resources: { cpu: "2", memory: "4Gi" },
      maxLifetimeSeconds: 8 * 3600,
      waitUntilRunning: false,
      tags: ["devin-outpost-worker"],
    });
    try {
      await sandbox.wait();
    } catch (error) {
      await sandbox.stop();
      throw error;
    }
    console.log(`Worker sandbox ID: ${sandbox.sandboxId}`);
    ```
  </Tab>
</Tabs>

[Devin Cloud でアウトポストを作成する](#create-an-outpost-in-devin-cloud) で作成したアウトポスト名を指定して、スクリプトを実行します。

<Tabs>
  <Tab title="Python">
    ```bash theme={"system"}
    python start_outpost_worker.py [OUTPOST-NAME]
    ```
  </Tab>

  <Tab title="TypeScript">
    ```bash theme={"system"}
    npx tsx start_outpost_worker.mts [OUTPOST-NAME]
    ```
  </Tab>
</Tabs>

Python の `sandbox.wait()` は、サンドボックスが実行中になった時点、またはすでに完了している場合に制御を返します。その時点ではインストールやワーカーの認証がまだ完了していない可能性があるため、タスクを送信する前にワーカーの状態を確認してください。ワーカーは `/workspace` を作業ディレクトリとして起動します。`your-org/app` のセッションでは、リポジトリが `/workspace/repos/app` 配下にチェックアウトされます。

このスクリプトは `with` ブロックを使用していないため、スクリプトの終了後も実行中のサンドボックスは動作し続けます。

<Warning>
  `max_lifetime_seconds` は厳格な上限であり、後から延長することはできません。期限に達するとプラットフォームがサンドボックスを終了するため、そのワーカーを使用しているすべてのセッションで実行が中断されます。このスクリプトでは、スナップショットや Persistent Volume は設定していません。コンテナーが再起動すると、`/workspace` 配下のファイルを含め、書き込み可能なファイルシステムはリセットされます。結果は、Devin がプッシュ先とするリポジトリなど、サンドボックスの外部に保存してください。
</Warning>

<h3 id="optional-use-a-secret-store">
  オプション: シークレットストアを使用する
</h3>

アウトポストトークンの値の代わりに [Forge シークレット参照](/ja/products/sandboxes/secrets)を渡すことができます。このオプションには、Forge 認証とサーバーレス配置が必要です。アウトポストトークンを Forge チームの Secret Manager に保存してから、そのチームの認証情報をエクスポートします。

```bash theme={"system"}
export FORGE_API_KEY="[FORGE-API-KEY]"
export FORGE_TEAM="[FORGE-TEAM]"
```

これらの認証情報を使用して、SDK を明示的に設定してください。`FORGE_API_KEY` と `FORGE_TEAM` は説明用の環境変数名であるため、SDK はこれらを自動的に検出しません。

<Tabs>
  <Tab title="Python">
    サンドボックスを作成する前に、`AuthHeaders` をインポートして `auth` を定義します。

    ```python theme={"system"}
    import os

    from cwsandbox import AuthHeaders

    auth = AuthHeaders(
        headers={
            "x-wandb-api-key": os.environ["FORGE_API_KEY"],
            "x-entity-id": os.environ["FORGE_TEAM"],
        },
        strategy="wandb_api_key",
    )
    ```

    `Sandbox.run()` に `auth=auth` を渡します。以降の Python の例でもこの設定を含め、`Sandbox.from_id()` を呼び出す際にも必ず `auth=auth` を渡してください。
  </Tab>

  <Tab title="TypeScript">
    クライアントのインポートと初期化を次の内容に置き換えます。以降の TypeScript の例でも、このクライアント設定を使用してください。

    ```typescript theme={"system"}
    import { createSandboxClient } from "@coreweave/cwsandbox/wandb";

    const client = createSandboxClient({
      apiKey: process.env.FORGE_API_KEY,
      entity: process.env.FORGE_TEAM,
    });
    ```
  </Tab>
</Tabs>

`[SECRET-NAME]` はチームシークレットの名前に置き換えてください。

<Tabs>
  <Tab title="Python">
    `cwsandbox` から `Secret` をインポートし、`environment_variables` から `DEVIN_OUTPOSTS_TOKEN` を削除したうえで、`Sandbox.run()` に `secrets=[Secret(store="wandb", name="[SECRET-NAME]", env_var="DEVIN_OUTPOSTS_TOKEN")]` を追加します。
  </Tab>

  <Tab title="TypeScript">
    `const token` の宣言と、それに続く `if (!token)` チェックを削除します。`environmentVariables` から `DEVIN_OUTPOSTS_TOKEN` を削除し、`client.run()` に渡すオプションに `secrets: [{ store: "wandb", name: "[SECRET-NAME]", envVar: "DEVIN_OUTPOSTS_TOKEN" }]` を追加します。
  </Tab>
</Tabs>

これで、アウトポストトークンをローカルでエクスポートする必要はなくなります。参照はプラットフォームによって解決され、ワーカーの環境変数に設定されます。

<h2 id="run-and-verify-a-devin-session">
  Devin セッションを実行して検証する
</h2>

テストには、このワーカーのみが接続され、キューに追加されたセッションや実行中のセッションが他にないアウトポストを使用してください。このテスト用に、シークレットではない一意の値を決めて、以下のタスク内の `[PROOF-VALUE]` をその値に置き換えます。Devin Cloud で新しいセッションを開始し、**Configuration > Virtual environment** でアウトポストを選択します。続いて、`Write the exact text` で始まる以下のタスクを送信します。Slack を使用する場合は、次のメッセージ全文を送信してください。

```text theme={"system"}
@Devin !outpost [OUTPOST-NAME] Write the exact text [PROOF-VALUE] to /workspace/outpost-proof.txt and read the file back. Report its contents.
```

Devin が完了を報告したら、ご利用の環境に対応するコマンドを使用して、ご自身のターミナルからファイルを読み取ります。`[SANDBOX-NAME]` を `cws-agent` のワークスペース名に、または `[SANDBOX-ID]` を SDK スクリプトが出力した ID に置き換えてください。

<Tabs>
  <Tab title="cws-agent">
    ```bash theme={"system"}
    cws-agent exec [SANDBOX-NAME] 'cat /workspace/outpost-proof.txt'
    ```
  </Tab>

  <Tab title="Sandboxes SDK">
    <Tabs>
      <Tab title="Python">
        ```python theme={"system"}
        from cwsandbox import Sandbox

        sandbox = Sandbox.from_id("[SANDBOX-ID]").result()
        result = sandbox.exec(["cat", "/workspace/outpost-proof.txt"], check=True).result()
        print(result.stdout, end="")
        ```
      </Tab>

      <Tab title="TypeScript">
        ```typescript theme={"system"}
        import { createSandboxClientFromEnv } from "@coreweave/cwsandbox/node";

        const client = createSandboxClientFromEnv();
        const sandbox = await client.fromId("[SANDBOX-ID]");
        const result = await sandbox.commands.run(["cat", "/workspace/outpost-proof.txt"], { check: true });
        process.stdout.write(result.stdout);
        ```
      </Tab>
    </Tabs>
  </Tab>
</Tabs>

出力が指定した一意の値と一致することを確認してください。そのサンドボックスの ID を指定して読み取ることで、セッションによるファイル書き込みが、作成したサンドボックス上で行われたことを確認できます。また、絶対パスを使用しているため、セッションの作業ディレクトリに依存しません。

セッションがキューに追加されたままの場合は、次のセクションの手順に従ってワーカーのログを確認してください。以前のセッションを処理中のワーカーは、そのセッションが終了または一時停止されるまで、別のセッションを取得できません。以前のセッションが不要であれば、Devin Cloud で終了してください。または、別のワーカーを起動することもできます。

<h2 id="check-the-worker-and-stop-it">
  ワーカーを確認して停止する
</h2>

`cws-agent` の場合は、クイックスタートで示したとおりワーカーのターミナルにアタッチします。SDK を使用する場合は、ステータスと最近のログを確認します。`[SANDBOX-ID]` は出力された ID に置き換えてください。

<Tabs>
  <Tab title="Python">
    ```python theme={"system"}
    from cwsandbox import Sandbox

    sandbox = Sandbox.from_id("[SANDBOX-ID]").result()
    print("Sandbox status:", sandbox.get_status())
    for container in sandbox.container_statuses:
        print(container.name, container.state, container.exit_code, container.restart_count)
    for line in sandbox.stream_logs(tail_lines=100):
        print(line, end="")
    ```
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"system"}
    import { createSandboxClientFromEnv } from "@coreweave/cwsandbox/node";

    const client = createSandboxClientFromEnv();
    const sandbox = await client.fromId("[SANDBOX-ID]");
    console.log("Sandbox status:", sandbox.status, "Exit code:", sandbox.exitCode);
    for (const line of await sandbox.logs.read({ tailLines: 100 })) {
      process.stdout.write(line);
    }
    ```
  </Tab>
</Tabs>

新しいログを取得するには、この確認を再度実行します。Python クライアントでは、コンテナーごとの状態、終了コード、再起動回数も確認できます。TypeScript クライアントでは、これらの詳細は取得できません。

Outposts API がワーカーのトークンを拒否したことがログに記録されている場合は、アウトポストの作成時にコピーしたトークンを使用しているかどうか、またそのトークンがアウトポストを所有するアカウントのものであるかどうかを確認してください。代わりにサービスユーザーの v3 API トークンを使用する場合は、そのロールに **Outposts write** (`account.outposts.write`) の権限が必要です。認証情報を修正したうえで、サンドボックスを再作成してください。

ワーカーが終了と再起動を繰り返していても、サンドボックスのステータスが `running` と表示される場合があります。ログを確認し、Python クライアントを使用している場合は、前述の例で示したコンテナーごとの詳細も確認してください。

認証に失敗し続けるワーカーは、代わりのワーカーを作成する前に停止してください。起動に失敗し、原因を特定できる情報が得られない場合は、サンドボックス ID とログを保存し、[CoreWeave Support](/support/contact) にお問い合わせください。

ワーカーが不要になったら、サンドボックスを停止してください。サーバーレスのセットアップについては、[はじめに](/ja/products/sandboxes/get-started)を参照してください。

実行中の Devin セッションが完了して結果が保存されるのを待ってから、ご利用の構成に応じたコマンドでコンピュートを停止します。

<Tabs>
  <Tab title="cws-agent">
    ```bash theme={"system"}
    cws-agent down [SANDBOX-NAME]
    ```

    `down` は停止前にワークスペースのスナップショットを作成します。スナップショットの取得に失敗した場合は、表示されたエラーと `cws-agent status [SANDBOX-NAME]` の出力を確認し、問題を解決してから再試行してください。保存されていない変更を破棄してもかまわない場合は、`cws-agent down [SANDBOX-NAME] --no-snapshot` を使用します。
  </Tab>

  <Tab title="Sandboxes SDK">
    <Tabs>
      <Tab title="Python">
        ```python theme={"system"}
        from cwsandbox import Sandbox

        sandbox = Sandbox.from_id("[SANDBOX-ID]").result()
        sandbox.stop().result()
        ```
      </Tab>

      <Tab title="TypeScript">
        ```typescript theme={"system"}
        import { createSandboxClientFromEnv } from "@coreweave/cwsandbox/node";

        const client = createSandboxClientFromEnv();
        const sandbox = await client.fromId("[SANDBOX-ID]");
        await sandbox.stop();
        ```
      </Tab>
    </Tabs>

    この例では永続マウントを使用していません。停止する前に、ファイルを外部にコピーするか、変更をリポジトリにプッシュしてください。
  </Tab>
</Tabs>

Devin セッションを終了しても、このワーカーのサンドボックスは停止しません。`cws-agent` のワークスペースをリストアする方法については、[Devin Outposts ガイド](https://github.com/coreweave/cws-agent/blob/main/docs/self-hosted.md#devin-outposts)を参照してください。

<h2 id="optional-customize-the-environment">
  オプション: 環境をカスタマイズする
</h2>

ワーカー環境は、次の方法でカスタマイズできます。

* **独自のイメージを使用する。** 公式イメージには `devin` CLI 以外ほとんど何も含まれていません。公式イメージをベースに独自のツールチェーンを追加したイメージをビルドし、Python では `container_image`、TypeScript では `containerImage` として渡します。Devin には `git` が必要です。画面録画には `ffmpeg` が、ブラウザーツールとコンピューター操作ツールには互換性のあるブラウザーのバイナリが必要です。

  公式 Ubuntu イメージをベースにした amd64 イメージの場合は、Google Chrome をインストールしてください。Ubuntu の `chromium` パッケージは snap のスタブであり、コンテナー内では動作しません。詳しくは [Devin のコンテナーセットアップ](https://docs.devin.ai/cloud/outposts/quickstart)を参照してください。また、コンピューター操作を行うには、Xvfb などのグラフィカルディスプレイが実行されており、ワーカーに `DISPLAY` が設定されている必要があります。

  ワーカーは標準のインストール場所を検索します。バイナリが見つからない場合は、`DEVIN_CHROME_PATH` にその絶対パスを設定してください。詳しくは [Devin Outposts リファレンス](https://docs.devin.ai/cloud/outposts/reference)を参照してください。
* **GPU を設定する。** 使用可能なオプションについては、[サンドボックスの GPU 設定](/ja/products/sandboxes/client/guides/sandbox-configuration#gpu)を参照してください。このガイドのワーカーの例では CPU リソースのみを使用します。
* **ワーカーを増やす。** 1 つのワーカーが同時に処理できるセッションは 1 つだけです。同じアウトポスト名でスクリプトを再度実行すると、そのキューに別のワーカーが追加で起動します。
* **セッションごとにサンドボックスを作成する。** この例のワーカーは、複数のセッションで同じサンドボックスを使い回します。セッションごとに新しいサンドボックスを用意する方法については、Devin の[オーケストレーションガイド](https://docs.devin.ai/cloud/outposts/orchestration)を参照してください。
