diff が示すのは、パッチが何をすると主張しているかです。バグが本当に消えたのか、if の新しい分岐が一度でも実行されるのか、依存関係の更新がクリーンインストール時に import を壊さないのかは示しません。レビュアーはそれを知っているので、多くのレビューが「テストが通れば LGTM」で終わります。
AI が書いたパッチでは、このギャップがさらに広がります。モデルはもっともらしいコードを素早く生み出し、もっともらしいコードこそ疲れたレビュアーの目をすり抜けます。安上がりな解決策は、誰かが承認する前に、何も傷つけられない場所で変更を実行することです。
チェック:base、head、テスト
パッチが示せる最も説得力のある証拠は、旧コードでは失敗し、新コードでは通る再現です。サンドボックスを使えば、それが20行のスクリプトになります。Python 3.12、Node.js 22、git、curl を備え、約1秒で起動する Firecracker microVM です。
import os
from eqvps import Sandbox
REPO, BASE, HEAD = os.environ["REPO_URL"], os.environ["BASE_SHA"], os.environ["HEAD_SHA"]
def repro(sb, ref):
sb.exec(f"cd /root/app && git checkout -q {ref}", timeout=55)
return sb.exec("cd /root/app && python3 /root/repro.py", timeout=55).exit_code
with Sandbox.create(tariff="standard", ttl=1800) as sb:
sb.exec(f"git clone -q {REPO} /root/app", timeout=55)
sb.exec("cd /root/app && pip install -q -r requirements.txt", timeout=55)
sb.upload("/root/repro.py", open("repro.py").read())
before, after = repro(sb, BASE), repro(sb, HEAD)
tests = sb.exec("cd /root/app && python3 -m pytest -q", background=True).wait()
print(f"repro on base: {before}, on head: {after}; tests: {tests.state}, exit {tests.exit_code}")
repro.py はバグ報告にあるコード片です。base では 0 以外の終了コード、head では 0 で終われば、パッチは主張通りのものを直しています。その1行とテスト結果の要約を pull request にコメントとして投稿すれば、レビュアーは事実から始められます。
テストスイートはバックグラウンドタスクとして実行します。同期コマンドは55秒で止まるためです。30分の TTL によって、止まった実行で課金される時間に上限がかかります。
コードを実行するレビューエージェント
同じ考え方は AI レビュアーにも使えます。MCP サーバー経由で接続したエージェントは、サンドボックスの作成、コマンドの実行、ファイルのアップロードとダウンロードといったツールを持ちます。「Python 3.8 との互換性を壊すかもしれません」と書く代わりに、ブランチをチェックアウトしてコードを実行し、traceback を引用します。あるいは問題ないと報告します。
そうしたエージェントには支出上限と読み取り専用トークンを与え、確認なしで呼び出してよいツールを決めておきましょう。MCP のガードレールでは、すべてのツールがリスク別に整理されています。
どのプランを選ぶか
| リポジトリ | プラン | 典型的な1回 | おおよその費用 |
|---|---|---|---|
| 小さなライブラリ、純粋な Python または JS | small(0.5 vCPU、1 GB) | 2分 | $0.0011 |
| テストスイート付きの Web アプリ | standard(1 vCPU、2 GB) | 5分 | $0.0055 |
| ネイティブ拡張、コンパイルが必要な依存関係 | plus(2 vCPU、4 GB) | 15分 | $0.033 |
一時サンドボックスは最低60秒の秒単位で課金されます。レビュアーが数日にわたって同じ環境に戻りたい場合は、persistent として作成してください。ディスクを最大30日間保持し、開始した1時間ごとに課金されるので、2日間のレビュー用に保持した standard サンドボックスは約 $3.17 です。pull request がマージされたら削除してください。
知っておくべき制限
- アカウントあたり同時に2コマンド。 順番に進むレビューには十分です。何十件もの pull request を一度にチェックすると、順番待ちになります。
- 受信ポートなし。 アプリをブラウザで開くことはできません。中で起動し、2つ目のコマンドから
curl localhostでテストしてください。 - 内部で Docker は使えません。 コンテナを立ち上げるテストは VPS 上の runner 向きです。
- 外向きのインターネットは開いています。 だからこそ
pip installが動きます。パッチの作者に渡したくないものは、サンドボックスに入れないでください。
はじめ方
新規アカウントには $1 分のサンドボックス利用時間が付与され、standard プランで100回以上のレビューができます。プランはサンドボックスのページに、上で使ったメソッドは SDK リファレンスに、セットアップは 5分でわかる Python SDK にあります。
関連:パイプライン全体には分離された CI テスト実行、そもそもコードを書くエージェントには AI エージェント用サンドボックス。
コメント
まだコメントはありません。最初になりましょう。