前回のOpenAI Agents APIを試してみたの記事で気になったOpenAI-hosted sandboxesを試してみました。

今回は環境を起動し、ファイルの配置、セットアップコマンド、ネットワーク制限、成果物のダウンロードまで確認します。

OpenAI-hosted sandboxesとは

OpenAI Agents APIについて調べていると、エージェントがコマンドやプログラムを実行するenvironmentという項目が出てきました。

実行環境には、自分で用意するself_hostedと、OpenAIが用意するopenai_hostedがあるようです。

自分でサーバーやコンテナを立てなくてもAIへ作業場所を渡せるなら、どこまで準備された環境なのか気になります。

OpenAI-hosted sandboxesの公式ドキュメントを読むと、Python、Node.js、コマンドラインツールが入ったLinuxのワークスペースと説明されています。

OpenAIが環境の準備と接続を行い、自分のアプリケーションはタスクを渡して結果を受け取ります。

今回の記事で確認するのは、この実行環境です。APIを呼び出すプログラムにはPython版SDKを使いますが、Pythonの使い方を試す記事ではありません。

今回確認すること

Hosted sandboxを1つ作り、次の項目を確認します。

  • OSとカーネルの情報
  • 作業ディレクトリ
  • PythonとNode.jsのバージョン
  • APIから渡したファイルを読めるか
  • 起動前のセットアップコマンドが実行されるか
  • 環境変数を渡せるか
  • 外部ネットワークを無効にできるか
  • 作成したファイルを手元へ取得できるか

環境を起動するだけでは結果が分かりにくいため、確認した内容をMarkdownとJSONへ保存させます。

OpenAI-hosted sandbox
├── /workspace/input/message.txt
├── /workspace/setup/setup.txt
└── /workspace/outputs/
    ├── sandbox-report.md
    └── checks.json

sandbox-report.mdchecks.jsonをMacへダウンロードできれば、ファイルの出入りも確認できます。

検証用のファイル

ディレクトリは次のようにしました。

openai-hosted-sandboxes/
├── .env.example
├── .gitignore
├── cleanup_session.py
├── input/
│   └── message.txt
├── requirements.txt
├── run_sandbox_check.py
└── results/

run_sandbox_check.pyがHosted sandboxの作成と結果の取得を行います。

cleanup_session.pyは、確認後にセッションを削除して、実行環境のクリーンアップを要求するためのプログラムです。

APIキーを設定する

Hosted sandboxはAgents APIから作成します。

検証用ディレクトリへ移動します。

cd experiments/openai-hosted-sandboxes
cp .env.example .env

.envへAPIキーを設定します。

OPENAI_API_KEY=ここへAPIキーを設定
OPENAI_MODEL=gpt-6-astra

APIキーはHosted sandboxへ渡しません。自分のMacからAgents APIを呼び出すためにだけ使います。

Hosted sandboxへ渡す設定

実行環境の設定を抜き出すと、次のようになります。

{
  "type": "openai_hosted",
  "network": {
    "access": "disabled"
  },
  "env": {
    "DEMO_LABEL": "hosted-sandbox-check"
  },
  "files": [
    {
      "type": "inline",
      "path": "/workspace/input/message.txt",
      "data": "Base64へ変換したファイルの内容"
    }
  ],
  "setup_commands": [
    {
      "command": "mkdir -p /workspace/setup /workspace/outputs && printf 'setup command executed\\n' > /workspace/setup/setup.txt",
      "cwd": "/workspace"
    }
  ]
}

typeopenai_hostedを指定すると、OpenAIが実行環境を準備します。

作業ディレクトリは/workspaceです。入力ファイルの配置先や、セットアップコマンドを実行する場所もこの下にしました。

setup_commandsはエージェントが作業を始める前に実行されます。今回はディレクトリを作り、実行されたことが分かるテキストファイルを残します。

ファイルを渡す

ローカルのinput/message.txtには、次の一文だけを書きました。

OpenAI-hosted sandboxの入力ファイル確認用です。

ファイルの内容をBase64へ変換し、filesへ指定します。

Base64は、ファイルの内容をAPIへ送れる文字列に変換するために使っています。Hosted sandboxの中では、通常のテキストファイルとして/workspace/input/message.txtへ配置されます。

公式ドキュメントを見ると、インラインで内容を渡す以外に、OpenAI Files APIへアップロードしたファイルのIDを指定する方法もあるようです。

今回は小さなテキストなので、インラインで渡します。

ネットワークを無効にする

Hosted sandboxの外部ネットワークは、次の3種類から選べます。

設定動作
enabled外部ネットワークへの接続を許可する
disabled外部ネットワークへの接続を無効にする
restricted指定したホストだけ許可する

何も指定しない場合は、テンプレートのポリシーを引き継ぐ場合を除きenabledになるようです。

今回の検証は外部通信を必要としません。そのためdisabledを明示しました。

本当に無効になっているかを見るため、エージェントには次のコマンドも実行してもらいます。

curl --max-time 5 https://www.next.inc

成功させるためのコマンドではありません。接続に失敗したときの終了コードとメッセージを、確認結果へ残してもらいます。

Hosted sandboxを起動する

Python版のOpenAI SDKを使ってAPIを呼び出します。

python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install --upgrade -r requirements.txt
python3 run_sandbox_check.py

Agents APIはベータ版です。古いOpenAI SDKではclient.beta.agentsが見つからない場合があるため、--upgradeを付けました。

実行すると、Hosted sandboxの準備やコマンド実行などのイベントが表示されます。

イベントの内容はresults/events.jsonlにも保存します。

Hosted sandboxの結果を確認する

処理が完了すると、/workspace/outputsに作られたファイルを自動でダウンロードします。

results/
├── events.jsonl
├── summary.json
└── artifacts/
    ├── sandbox-report.md
    └── checks.json

次のコマンドで確認します。

cat results/artifacts/sandbox-report.md
cat results/artifacts/checks.json
cat results/summary.json

sandbox-report.mdはこちらです。

# Sandbox動作確認結果

## 現在の作業ディレクトリ

実行コマンド: `pwd`

標準出力:
```text
/workspace
```

## OS情報

実行コマンド: `cat /etc/os-release`

標準出力:
```text
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
```

## Pythonバージョン

標準出力:
```text
Python 3.12.12
```

## Node.jsバージョン

標準出力:
```text
v22.23.2
```

checks.jsonはこちらです。

{
  "checks": [
    {
      "id": "os",
      "label": "OS情報",
      "command": "cat /etc/os-release",
      "exit_code": 0,
      "stdout": "PRETTY_NAME=\"Debian GNU/Linux 12 (bookworm)\"\nNAME=\"Debian GNU/Linux\"\nVERSION_ID=\"12\"\nVERSION=\"12 (bookworm)\"\nVERSION_CODENAME=bookworm\nID=debian\nHOME_URL=\"https://www.debian.org/\"\nSUPPORT_URL=\"https://www.debian.org/support\"\nBUG_REPORT_URL=\"https://bugs.debian.org/\"\n",
      "stderr": ""
    },
    {
      ...(中略)...
    },
    {
      "id": "curl",
      "label": "ネットワーク接続確認",
      "command": "curl --max-time 5 https://www.next.inc",
      "exit_code": 56,
      "stdout": "",
      "stderr": "curl: (56) CONNECT tunnel failed, response 403\n",
      "failure_is_fatal": false
    }
  ]
}

確認したい結果をまとめます。

確認項目結果
作業ディレクトリが/workspacepwdの結果が/workspaceになった
入力ファイルを読めたAPIから渡した文章をそのまま読めた
セットアップコマンドのファイルを読めたsetup command executedを読めた
環境変数を読めたhosted-sandbox-checkを取得できた
外部ネットワークが遮断されたcurlが終了コード56、HTTP 403で失敗した
2つの成果物を取得できたMarkdownとJSONをMacへ保存できた

OSはDebian GNU/Linux 12、カーネルはLinux 6.18.44でした。Python 3.12.12とNode.js v22.23.2も最初から利用できました。

/workspace/outputsのファイルはartifactになる

Files and artifactsの公式ドキュメントによると、/workspace/outputsのファイルは、作業が完了すると変更できないartifactとして公開されます。

実行中のワークスペースがなくなったあとも、artifactはダウンロードできるようです。

どこへ保存しても自動で取得できるわけではありません。手元へ残したいファイルは/workspace/outputsへ置く必要があります。

今回はエージェントへの指示で、出力先を次の2つに固定しました。

/workspace/outputs/sandbox-report.md
/workspace/outputs/checks.json

Hosted sandboxの有効期限と料金

公式ドキュメントでは、セッションごとに別のワークスペースが作られ、サンドボックスが存在する間は、同じセッションの次のやり取りにもファイルが残ると説明されています。

一方で、動作や接続維持が1時間止まると、サンドボックスが削除される可能性があります。この時間は変更できないようです。

また、Hosted sandboxはコンテナ料金が発生します。利用するAIモデルのAPI料金は別です。

検証後は、必要なartifactをダウンロードしてからセッションを削除します。

python3 cleanup_session.py

{
  "id": "sess_00000000",
  "deleted": true,
  "object": "agent.session.deleted"
}

試してみて

今回確認したかったのは、AIへコードを書かせることではなく、AIが作業するLinux環境をどこまで設定できるかでした。

実際に動かすと、入力ファイル、起動前のコマンド、環境変数がすべて/workspaceへ反映されました。PythonやNode.jsも最初から使えます。

外部ネットワークを無効にした状態でcurlを実行すると、CONNECT tunnel failed, response 403で失敗しました。(当たり前体操)単にタイムアウトするのではなく、接続を拒否されたことがメッセージに残りました。これは実行環境の内部構成まで把握できた話ではなく、今回のコマンドから観測できた結果です。

作成したMarkdownとJSONは/workspace/outputsからartifactになり、Macへダウンロードできました。実行環境の中で終わらず、結果を手元へ持ち帰るところまでAPIでつながったのが分かりやすかったです。

次はrestrictedを指定し、許可したホストだけへ接続できるか試してみたいです。

ここまで読んでいただき、ありがとうございます。もしこの記事の技術や考え方に少しでも興味を持っていただけたら、ネクストのエンジニアと気軽に話してみませんか。

  • 選考ではありません
  • 履歴書不要
  • 技術の話が中心
  • 所要時間30分程度
  • オンラインOK

エンジニアと話してみる

関連リンク

AI・クラウド・データ分析のご相談はネクスト株式会社までお問い合わせください。