7月22日、Towards Data Scienceが「Build an LLM Agent That Can Write and Run Code」と題した記事を公開した。LLM自身はコードを一切実行しない——この一見シンプルな設計原則が、コード実行エージェントのセキュリティと再現性を支えている。LLMはコードを「書く」だけで、「動かす」のはDockerコンテナ側だ。この分離をOpenAI Agents SDKで実装し、CSVの異常検知タスクを自律実行させるまでの手順が本記事では詳解されている。
なぜ今「コード実行エージェント」が注目されるのか
LLMにコードを書かせて実行させるアイデア自体は新しくない。ChatGPTのCode Interpreter(現Advanced Data Analysis)が2023年に公開されたとき、ファイルをアップロードしてPythonで分析・可視化できる機能が大きな話題を呼んだ。しかし当時の実装はOpenAIのクラウド環境に閉じており、開発者が独自のパイプラインに組み込む手段は限られていた。
その後、OpenAI Agents SDKの登場により、コード実行サンドボックスを自前のアプリケーションに組み込むことが現実的になった。ローカルのDockerコンテナをランタイムとして使うことで、実行環境の完全な制御・秘匿データのクラウド非送信・ライブラリ構成の固定が同時に実現できる。データ分析・レポート自動生成・科学計算など、反復的なコード試行が必要なユースケースで特に有効なアーキテクチャだ。
コード実行エージェントの核心:3つのコンポーネント
コードを書いて実行できるエージェントは、LLMそのものがコードを実行するわけではないという点が重要だ。実際の構成要素は次の3つに分かれる。
- モデル(LLM): ファイルを調べ、必要な処理を判断し、コードを生成する
- ワークスペース: 入力ファイルを受け取り、成果物を保存する共有領域
- 実行環境: 生成されたコードを実際に動かす場所(今回はDocker)
LLMはコードを「書く」だけで、「動かす」のはDockerコンテナ側だ。この分離がセキュリティと再現性を担保する。
OpenAI Agents SDKには、このパターンを実装したSandboxAgentクラスが用意されている。SandboxAgentはエージェントのロジック・ワークスペース管理・サンドボックスセッションの制御を一体化したクラスで、後述するManifest(入出力ファイルのマッピング定義)と組み合わせて使う。
ハンズオン:CSVを分析してレポートと図を生成する
記事ではケーススタディとして、ビル電力消費データ(CSV)の異常検知タスクを実装している。エージェントへの指示は「CSVを調べて異常なエネルギー使用イベントを検出し、以下3ファイルを保存せよ」というものだ。
output/anomalies.csv
output/energy_anomalies.png
output/anomaly_report.md
Step 1: Docker環境を構築する
エージェントが使うPythonランタイムをDockerイメージとして定義する。必要なライブラリを事前インストールしておくことで、実行時にエージェントが都度インストールする手間を省ける。
FROM python:3.12-slim
ENV MPLBACKEND=Agg
RUN pip install --no-cache-dir numpy scipy pandas matplotlib
WORKDIR /workspace
MPLBACKEND=Aggの設定がポイントで、ディスプレイのない非インタラクティブなコンテナ内でもmatplotlibでグラフを保存できるようになる。
Step 2: ワークスペースとエージェントを定義する
Manifestはローカルファイルとワークスペース内パスのマッピングを定義するオブジェクトだ。これをSandboxAgentに渡すことで、エージェントが参照・出力するファイルの所在が一元管理される。
from agents.sandbox import LocalFile, Manifest, SandboxAgent
manifest = Manifest(
entries={
"input/building_energy.csv": LocalFile(src=Path("data/building_energy.csv")),
},
)
agent = SandboxAgent(
name="Energy anomaly analyst",
instructions=INSTRUCTIONS,
model="gpt-4o", # ※元記事記載のモデル名を使用。実行時は利用可能なモデルを確認すること
default_manifest=manifest,
)
※元記事のコードサンプルにはモデル名の記載がある。利用できるモデルは時期によって異なるため、OpenAIのモデル一覧で最新情報を確認されたい。
エージェントへの指示文では、役割・使えるライブラリ・期待する出力を明示的に記述している。
INSTRUCTIONS = """
You are a practical data analyst.
Use the sandbox workspace to inspect files, write and run code when useful,
and save clear artifacts.
Keep conclusions grounded in computed evidence.
The sandbox has Python with numpy, scipy, pandas, and matplotlib available.
""".strip()
Step 3: Dockerサンドボックスセッションを作成して実行する
import docker
from agents.sandbox.sandboxes.docker import DockerSandboxClient, DockerSandboxClientOptions
from agents import Runner, RunConfig
from agents.sandbox import SandboxRunConfig
docker_client = DockerSandboxClient(docker.from_env())
sandbox_options = DockerSandboxClientOptions(image="energy-agent-sandbox:latest")
sandbox_session = await docker_client.create(manifest=manifest, options=sandbox_options)
await sandbox_session.apply_manifest()
result = await Runner.run(
agent,
PROMPT,
max_turns=25,
run_config=RunConfig(sandbox=SandboxRunConfig(session=sandbox_session)),
)
max_turns=25を指定することで、エージェントが何度もコードを書き直しながら反復できる上限を設けている。
Step 4: 出力ファイルをホストに取り出す
実行後、サンドボックスのワークスペースをtarアーカイブとして保存し、必要なファイルだけを抽出する。
workspace_archive = await sandbox_session.persist_workspace()
with tarfile.open(fileobj=workspace_archive, mode="r:*") as tar:
for filename in ["anomalies.csv", "energy_anomalies.png", "anomaly_report.md"]:
source = tar.extractfile(f"output/{filename}")
(OUTPUTS_DIR / filename).write_bytes(source.read())
await sandbox_session.aclose()
実際の実行では、エージェントはまずCSVをpandasで読み込んでデータ形状を確認し、次にnumpyで時間帯別ベースラインを構築して残差とロバストzスコアを計算、最終的に異常イベントを1件検出してグラフとレポートを出力した。
Dockerを使わない選択肢もある
記事ではSandboxAgent以外のアプローチも言及されている。
CodeInterpreterTool: 通常のエージェントに付与するツールで、OpenAI管理のクラウド環境でコードを実行する。Docker不要でセットアップが楽。前述のChatGPT Code Interpreterと同等の実行基盤をAPI経由で利用するイメージに近い。ShellTool: よりCLI寄りのワークフロー向けにシェル実行を提供する。SandboxAgentではシェルがデフォルトで含まれている。
ローカルのDockerを管理したくない場合や、データをクラウドに送ることに問題がない場合はCodeInterpreterToolが現実的な選択肢だ。一方、機密データを扱う場合や実行環境を厳密に固定したい場合はDockerサンドボックスの優位性が高い。
このパターンを使い回すための4原則
記事の締めくくりで整理されている実践的なポイントは以下の通りだ。
- エージェントの指示文に役割・タスク・期待する成果物を明示する
- ワークスペースに入れるファイルを事前に決める
- ランタイムと依存ライブラリをDockerイメージに固める
- 出力ファイルのパスと名前をプロンプトで明示する(後の抽出が楽になる)
この4点が揃えば、同じ構造を別の分析タスクに転用できる。CSVの異常検知に限らず、ログ解析・財務データの集計・科学実験結果の可視化など、「ファイルを渡して成果物を受け取る」パターン全般に応用が利く設計だ。
詳細はBuild an LLM Agent That Can Write and Run Codeを参照していただきたい。