Orchardmicrosoft/Orchard)は、AIエージェントの訓練と評価に使う実行環境を、Kubernetes上の独立したサービスとして切り出したMicrosoft ResearchのOSSだ。エージェントに実際のコードを実行させる話題では、実行環境は「1つをどれだけ安全に隔離できるか」「起動を何ミリ秒まで縮められるか」で語られやすい。だがエージェントを訓練する側から見ると、問われるものが変わる。同じ環境を数千個並べられるか、学習に使った環境と実運用の環境がズレていないか、そして半年後に別のモデルを試すとき同じ土台を再利用できるか。2026年5月に論文が公開されたOrchardは、この後者の問題への回答として、サンドボックスを学習スタックの内部部品から引き剥がしている。

エージェント基盤全体のなかでどこに位置するものなのかは、AIエージェントフレームワーク比較2026|LangGraph・CrewAI・Dify等9種をStar数・実コードで検証で整理している。本記事はそのうち「エージェントを走らせる土台」の層を、Orchardの一次資料(README・同梱ドキュメント・Dockerfile・Pythonソース・Kubernetesマニフェスト)から読み解く。

Orchardの全体像:下層に多様な実行環境、中央にOrchard Env、上層に学習レシピと3つのモデル成果を積む4層構造
Orchardの全体像。中央のOrchard Envを共通の土台として、その上に学習レシピと3つのモデル(SWE / GUI / Claw)を積む(出典: microsoft/Orchard README同梱図 docs/figures/orchard-overview.png
30秒でわかるOrchard
何ができるか:Kubernetes上に隔離コンテナを大量に立ち上げ、エージェントとの複数ターンのやり取り(コマンド実行・ファイルI/O・gitパッチ)をHTTP越しに回す
何を解決するか:訓練用の環境と評価用の環境がプロジェクトごとに作り直される問題。環境を独立サービスにして、データ・学習レシピ・評価手順を横断で使い回せるようにする
何を代替できるか:学習スタックに内蔵された自前のサンドボックス層。REST APIが契約でSDKはその薄いクライアントなので、他言語のプロジェクトからも同じ土台に載せられる
特徴codex / claude / pi / opencode / hermes の5つのエージェントCLIが全サンドボックスのPATHに最初から入っている
前提:Kubernetes(Calico NetworkPolicy対応)。手元のDockerだけでは完結しない。リリース版・タグは未作成

Orchardとは——エージェントを「動かす」基盤ではなく「訓練する」基盤

まず名前について確認しておく。Orchardという名前のOSSは複数ある。よく知られているのは.NET製CMSのOrchard CMS / OrchardCoreだが、本記事が扱う microsoft/Orchard はそれとは無関係のリポジトリで、2026年4月10日に作成されている。READMEの1行説明は “Orchard: An Open-Source Agentic Modeling Framework” で、中身もCMSの痕跡は一切なく、Kubernetesオーケストレーター・サンドボックスSDK・強化学習トレーナーで構成されている。Microsoft公式である点は、リポジトリが microsoft organization 配下にあること、CODE_OF_CONDUCT.md がMicrosoft Open Source Code of Conductを採用していること、SECURITY.md がMicrosoftの脆弱性報告窓口を案内していること、そしてLICENSEの著作権表記が Microsoft Corporation であることから確認できる。

リポジトリは3つの層に分かれている。

実体 役割
Recipes 論文で報告された3つの研究(Orchard-SWE / GUI / Claw) 学習レシピそのもの。コードではなく成果と手法
Orchard Env orchard_env/ Kubernetesネイティブのサンドボックスサービス+Python SDK。本体
Trainer trainer/slime(gitサブモジュール) RL学習スタック。THUDM/slime のフォークを参照

実測したリポジトリの基本情報は以下のとおり。

ライセンス:MIT(著作権表記は Microsoft Corporation)
Star / Fork:259 / 14(2026-08-04時点、GitHub API実測)
作成日 / 最新コミット:2026-04-10 / 2026-07-30(trainer: track MSR-Orchard/slime as a submodule
リリース・タグ:いずれも0件。mainブランチのcloneが前提
主要言語:GitHub APIの言語統計は空を返すが、実測ではPythonが413,848バイト(30ファイル)、Shellが59,646バイト(11ファイル)

サブモジュールについては一点補足がいる。.gitmodules が指しているのは上流の THUDM/slime ではなく https://github.com/MSR-Orchard/slime.git で、Microsoft Research側のフォークを参照している。README自身も「vendored fork」と書き、フォーク固有の変更は trainer/slime/ORCHARD_CHANGES.md で追跡していると説明している。トレーナー側まで取得するなら --recurse-submodules が必要になる。

研究成果側の一次資料も揃っている。論文は arXiv:2605.15040(Peng et al.、著者14名)で、v1が2026年5月14日、最新のv3が2026年7月30日。データセットは Hugging Face の microsoft/Orchard に2つのサブセットが置かれており、READMEによれば swe が19,287タスク・2,788リポジトリにまたがる107,185本のマルチターン軌跡(解決74,649・未解決32,536、平均47.5ターン)、gui が409タスク・3,070本のスクリーンショット付きロールアウトとされる。

「訓練するための基盤」という位置づけがなぜ効くのかは、READMEのNews欄に書かれた後続研究にはっきり出ている。2026年7月公開のOpenForge RL(arXiv:2607.21557)は、エージェントを「実際にデプロイされるハーネスの中で」訓練する試みで、学習用に簡略化した再実装ではなく本物のCLIを相手にすることで訓練時と運用時のズレを消すことを狙う。これが成立するのは、Orchard Envがどのハーネスにも依存しない土台として先にあるからだ、というのがリポジトリ側の主張になっている。

Orchard Envのアーキテクチャ——Kubernetes APIサーバーを迂回する経路

Orchard Envの設計上の芯は、コマンド実行とファイルI/OをKubernetes APIサーバーに通さないことにある。一般的な実装では、Pod内でコマンドを走らせるのに kubectl exec 相当(APIサーバー経由のWebSocket)を使う。だがサンドボックスを数百・数千個動かして各々が何十ターンもやり取りすると、APIサーバーがそのまま詰まる。Orchardはこれを避けるため、すべてのサンドボックスPodに小さなHTTPサーバー(in-pod agent)を注入し、オーケストレーターからPod IPへ直接叩く構成をとる。

flowchart LR T["trainer/slime
ロールアウト要求"] --> O["orchestrator
FastAPI・複数レプリカ"] O -->|"Pod作成・削除
NetworkPolicy管理"| K["Kubernetes
APIサーバー"] K --> P["サンドボックスPod
in-pod agent :9090"] O -.->|"exec・ファイルI/O
Pod IPへ直接HTTP"| P P -.-> O O --> T O --- R[("Redis
状態共有・分散ロック")]

点線がAPIサーバーを迂回する経路にあたる。同梱の orchard_env/docs/architecture.md は、Podのライフサイクル管理とNetworkPolicy管理だけがAPIサーバーを通り、execとファイルI/Oは通らないと明記している。in-pod agentはFastAPI製で、既定のリッスンポートは9090。

Orchard Envのアーキテクチャ図。オーケストレーターのDeployment、Redis、サンドボックス用namespaceとdeny-all-egressのNetworkPolicyを含む構成
Orchard Envの構成図。サンドボックスPodは専用namespaceに置かれ、namespace全体にdeny-all-egressのNetworkPolicyがかかる(出典: microsoft/Orchard 同梱図 orchard_env/docs/figures/orchard-architecture.png

任意のベースイメージを使えるのも、この注入方式の副産物だ。エージェントはinit containerが注入するが、そのinit containerは自分専用のPythonインタプリタを丸ごと抱えている。そのためユーザーが指定するサンドボックスイメージ側にPythonが入っている必要がない。SWE-bench用のイメージのように、中身に手を入れたくないものをそのまま使える。

オーケストレーター側の既定値は orchard_env/orchard_env/orchestrator/settings.py にまとまっている。数字の桁感がそのまま設計思想を表しているので、主要なものを抜き出す。

設定 既定値 意味
default_cpu / default_memory 4 / 16Gi サンドボックス1つあたりの割り当て
default_block_network True 外向き通信を既定で遮断する
sandbox_ttl_hours 2 放置されたサンドボックスの寿命
max_concurrent_execs 400 レプリカあたりの同時実行数
max_concurrent_creates 50 レプリカあたりの同時作成数
k8s_api_concurrency 100 レプリカあたりのK8s API同時呼び出し上限
agent_pool_size 500 in-pod agentへのHTTP接続プール
heartbeat_timeout_seconds 180 ハートビート断からdead判定までの秒数
use_redis True 複数レプリカで状態を共有する

max_concurrent_execs(400)や agent_pool_size(500)といった値は、単発の開発用サンドボックスを想定した設計では出てこない。1台のオーケストレーターレプリカが数百のサンドボックスを同時に相手にする前提で調整された数字だ。K8s API呼び出しに独自のスロットル(k8s_api_concurrency)と再試行回数(k8s_api_retries: 3、コメントには「スロットを早く解放するため低く保つ」と書かれている)が用意されているのも同じ理由による。

なお、コード上の細かい配慮として、exec投入前の準備状況の判定にPodWatcherのインメモリキャッシュを使う設計が入っている。sandbox.ready フラグはTrueに倒れたら二度とFalseに戻らない(latched)ため、これに頼らず「現在到達可能か」をキャッシュから見る、とコメントで説明されている。

すべてのサンドボックスに同梱される5つのエージェントCLI

Orchard Envで最も特徴的なのが、どのサンドボックスにもエージェントCLIが5つ最初から入っている点だ。orchard_env/Dockerfile.tools がこのペイロードを組み立てている。

Orchardが同梱する5つのエージェントCLIと、それぞれの配布経路・glibc下限を並べた図
同梱される5つのCLIと配布経路。5つとも取得元が異なり、いずれもサンドボックス内でのインストールとネットワーク接続を不要にしている(出典: orchard_env/Dockerfile.tools の記述を基に作成)
CLI 提供元 配布経路 動作要件(Dockerfile.toolsの記述)
codex OpenAI Codex CLI npm(配送のみ) musl静的PIEバイナリ
claude Anthropic Claude Code npm(配送のみ) ネイティブELF、GLIBC_2.17
pi earendil-works/pi GitHub Release ネイティブELF、GLIBC_2.17
opencode OpenCode npm(配送のみ) ネイティブELF、GLIBC_2.17
hermes Nous Research Hermes PyPI+再配置可能CPython 同梱インタプリタで動作

「npmは配送手段であってペイロードの一部ではない」とコメントが明示しているとおり、ビルド段階でnpmから取り出したネイティブバイナリだけを抜き出して固めている。結果としてサンドボックスの中にNode.jsもPythonも要らず、インストール手順もネットワーク接続も不要になる。glibcの下限は2.17(CentOS 7相当)に揃えられ、Ubuntu 22.04ベースのSWE-benchイメージ群を含む現実的なイメージをカバーする、というのが同ファイルの説明だ。

入れなかったものについても理由が書かれているのが珍しい。GitHub Copilot・Cursor Agent・Geminiの各CLIは「ペイロードがGLIBC_2.28を要求するため意図的に同梱しない」とされ、対応するにはpatchelfで専用glibcを抱き込む必要があり、それは得られるものに対して影響範囲(blast radius)が大きすぎる、と説明されている。同様に opencode については、名前に反して musl 版ではなく glibc 版を採用したことと、その理由(musl版は名前と裏腹にmuslおよびlibstdc++/libgcc_sへ動的リンクされており、muslローダーを渡してもglibcホストでは動かない)がコメントで残されている。

配置まわりでは2点、運用に効く配慮がある。ひとつはPATHへの追加が「末尾」であること。コメントは「先頭に足さない。ユーザーのイメージに既にあるツールチェーンが常に勝つ」と明記している。もうひとつは各CLIのラッパーが PYTHONHOME / PYTHONPATH / LD_LIBRARY_PATH を明示的に unset していること。in-pod agentが同梱Pythonで動くため、その環境変数がCLI側に漏れないようにしている。

ペイロードをサンドボックスへ届ける方式は2つあり、sandbox_tools_volume_mode で切り替える。

image モード(既定):イメージを読み取り専用ボリュームとして直接マウントする。kubeletがノードごとに1回pullするだけでPodごとのコピーが発生しない。ただし Kubernetes 1.33以上・containerd 2.0以上が必要
initcontainer モード:init containerが共有emptyDirへコピーする移植性重視のフォールバック。ただしPodあたり約600MBのエフェメラルディスクを消費する

ひとつ注意したいドキュメントのズレがある。settings.py のコメントは、このツール群を「codexclaude のCLI」と2つだけ挙げたままになっている。実際に Dockerfile.tools がビルドするのは上記の5つで、READMEも5つと書いている。設定値そのものに影響はないが、コメントを読んで判断すると同梱物を取り違える。

この「ハーネスを差し替えられる」性質が、Orchardが訓練基盤として狙っているところに直結する。READMEの表現を借りれば、訓練や評価の相手を変えるのはイメージの入れ替えではなくコマンドの変更で済む。

Orchard Envの公称値と、ベンチマークの計測条件

READMEはOrchard Envの性能値をいくつか掲げている。まず数字を並べ、そのうえで何をどう測ったのかをリポジトリのコードから確認する。

Orchard Envの公称値:平均実行遅延0.28秒、1000個同時起動で成功率100%、26秒で完了
READMEが掲げるOrchard Envの数字。いずれもリポジトリの公称値であり、後述するとおり計測時の設定は既定値と異なる(出典: microsoft/Orchard README)

READMEによれば、コマンド実行の平均遅延は0.28秒、1,000個のサンドボックスを並列起動して成功率100%・26秒で完了(平均作成時間11.75秒、毎秒約154コマンド)。コストは2 vCPU / 8 GiB のサンドボックス128個を240時間動かした場合でオンデマンド$3,362、スポットなら$673と見積もられている。またTerminal-Bench 2.0でDockerから置き換えても劣化しない(GPT-4.1が34.1→35.1、MiniMax-M2.5が52.6→54.4、Qwen3-8B-Thinkingが7.0→8.8)としており、学習と評価の両方で素の実行環境の代わりに使える、という主張になっている。

これらの数字を測っているのは orchard_env/tests/integration/bench_concurrent.pybench_concurrent_pty.py で、ベンチマークのコード自体が同梱されている。測り方を読めるのは良い点だ。そのうえで、読むと2つ気づくことがある。

既定はblock_network=True、ベンチマークの計測対象呼び出しはblock_network=False、計測結果のJSONはgitignoreで除外という3段の図
公称値の計測条件。既定とベンチマークでNetworkPolicy作成の有無が変わり、計測結果そのものはリポジトリに含まれない(出典: settings.py / tests/integration/bench_concurrent.py / .gitignore

ひとつめはネットワーク設定だ。本番既定の default_block_networkTrue で、この場合オーケストレーターはサンドボックスごとにNetworkPolicyを作る。一方ベンチマークは create_sandbox(..., block_network=False) を渡しており、しかもその呼び出しは計測区間の内側にある(start = time.time() の直後に create_sandbox を呼び、戻ってから end = time.time() を取る構造)。同様の呼び出しはベンチマーク2本で計5箇所ある。つまり公称の作成時間には、既定構成なら発生するNetworkPolicy作成の分が入っていない。これは不正確という話ではなく、条件が違うという話で、自分の環境で既定のまま測ると数字が変わりうる、という読み方をすべき箇所になる。

ふたつめは計測結果そのものが同梱されていないことだ。ベンチマークは結果を timing_<日時>.json として自分の隣に書き出すが、.gitignore**/timing_*.json**/pty_timing_*.json が並んでいるため、実行結果はリポジトリに入らない。手法は完全に読めるが、READMEの数字を裏づける生データは付いてこない。再現したければ自分でクラスタを立てて回すことになる。

モデル側の成果はレシピ表にまとまっている。

レシピ ベースモデル 学習データ 主な結果(README)
Orchard-SWE Qwen3.5-35B-A3B 蒸留軌跡107K SWE-bench Verified 73.0%
Orchard-GUI Qwen3-VL-4B-Thinking SFT 0.4k+RL 2.2k 平均68.4%(74.1 / 67.0 / 64.0)
Orchard-Claw Qwen3-30B-A3B-Thinking 合成タスク0.2k pass@3 59.6%、ZeroClaw下で73.9%
Orchard-SWEとOrchard-GUIの結果を総パラメータ数の対数軸に対してプロットした散布図
総パラメータ数に対する位置づけ。左がSWE-bench Verified、右がWebVoyager・Online-Mind2Web・DeepShopの平均成功率(出典: microsoft/Orchard 同梱図 docs/figures/orchard-performance.png

ここでもうひとつ、同じ指標に2つの数字が併記されている箇所がある。SWE-bench Multilingualについて、READMEの本文は51.0と書き、同じREADMEが貼っている図には62.3と表示されている。図はOrchard-SWEを69.7(RL)・73.0(+value model)・62.3(Multilingual)と構成別に並べており、本文の51.0がどの構成のものかはREADMEからは判別できない。どちらかが誤りだと決めつけられる材料は無く、条件の違う数値が別の場所に載っていると読むのが妥当だろう。Multilingualの数字を引用する用途がある場合は、READMEではなく論文本体(arXiv:2605.15040、v3)で条件まで確認したい。

ネットワーク遮断とカーネルCVE——リポジトリに同梱された運用の実際

セキュリティ面でOrchardが実際に何をしているかは、マニフェストとコードを読むとかなり具体的にわかる。

外向き通信の遮断は、Kubernetes NetworkPolicyの仕様をそのまま使っている。k8s_client.pycreate_network_policypolicy_types=["Egress"] を指定したうえで、遮断する場合に policy_spec.egress = []空リストを設定する(コメントも「Empty egress list = deny all」)。許可する場合は空のルールを1つ入れて全許可にする。加えて sandbox_manager.py にはサンドボックス用namespace全体に対する deny-all-egress を一度だけ作る処理があり、個別Podごとの作成・削除を不要にしている。多数のサンドボックスを立てるときにNetworkPolicyオブジェクトが増え続けない構成になっている。

より目を引くのは、このリポジトリが実運用の後始末まで公開していることだ。orchard_env/scripts/remediate_kernel_cve.sh は、AKSクラスタのノードを脆弱なカーネルから巻き直すための運用スクリプトで、ヘッダーには対象カーネルが 6.8.0-1052-azure6.8.0-1054-azure であること、リストの出所がIcM(Microsoftのインシデント管理)であることが書かれている。

カーネルCVEへの2系統の対処:ノードプールのアップグレード、修正イメージ未公開時のDaemonSet暫定対処、kernelVersionでの確認
同梱されているカーネルCVE対処の流れ。修正済みノードイメージがまだ来ていないリージョン向けに、暫定策が別途用意されている(出典: scripts/remediate_kernel_cve.sh / k8s/algif-aead-blacklist.yaml

暫定策のほうが orchard_env/k8s/algif-aead-blacklist.yaml で、修正済みのAKSノードイメージが自分のリージョンにまだ公開されていない場合に限り適用するDaemonSetとして書かれている。やることは単純で、各ノードのホスト側に /etc/modprobe.d/disable-algif.conf を書いて algif_aead の読み込みを禁止し、既に読み込まれていれば nsenter --target 1 でホスト名前空間に入って rmmod を試みる。ヘッダーには適用条件だけでなく、撤去条件(修正カーネルのノードイメージが出て、ノードプールを巻き直して、kernelVersion に旧カーネルが残っていないことを確認したら消す)まで書かれている。

ここは扱いに注意が要る箇所でもある。このDaemonSetは privileged: truehostPID: truehostNetwork: true でホストのルートファイルシステムをマウントする。つまりノードに対して非常に強い権限を持つ。自分のクラスタに持ち込む前に中身を読むべきもので、恒久対策ではなくノードイメージが来るまでのつなぎとして書かれている点も、マニフェスト自身が明示している。なおリポジトリは対応するCVE番号を書いていない。「algif_aead CVE」とだけ記され、識別子は与えられていないので、追跡するならカーネルのバージョン文字列を手がかりにすることになる。

自分のクラスタが同じカーネルに乗っていないかは、スクリプトが検証に使っているのと同じ方法で確認できる。

# ノードごとのOSイメージとカーネルバージョンを一覧する
kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.osImage}{"\t"}{.status.nodeInfo.kernelVersion}{"\n"}{end}'

# スクリプトが「脆弱」と判定するのと同じ正規表現で数える
kubectl get nodes -o jsonpath='{range .items[*]}{.status.nodeInfo.kernelVersion}{"\n"}{end}' \
  | grep -Ec '6\.8\.0-(1052|1054)-azure'

公開されているスクリプトを読むときは、ヘッダーの説明と実際に走る処理がずれている点も押さえておきたい。ヘッダーは6段階の手順として、ノードプールのアップグレード後に provisioningState をポーリングして完了を待つこと(手順3の後半)と、クラスタ全体で --node-os-upgrade-channel NodeImage および --auto-upgrade-channel patch を有効化すること(手順5)を挙げている。だが公開されている版では、そのポーリングのループと手順5がまるごとコメントアウトされている。処理対象のクラスタリストも5件中4件がコメントアウトされ、実際に走るのは1件だけになっている。手順書としてそのまま流用するのではなく、自分の環境に合わせて書き直す前提のスナップショットとして読むのが妥当だ。

類似ツールとの比較——microVM系・マネージド系との違い

エージェント用サンドボックスは選択肢が増えており、Orchardがどこに位置するのかは比較すると見えやすい。当サイトで扱ってきたものと並べる。

  Orchard Env AgentENV CubeSandbox Cloudflare Sandboxes AIO Sandbox
隔離の単位 Kubernetes Pod(コンテナ) Firecracker microVM MicroVM(RustVMM/KVM) マネージドサービス Dockerコンテナ1つ
設計の主眼 訓練・評価で使い回す共通土台 大量維持とfork 起動の速さ 提供形態そのもの 開発用オールインワン
走行中の分岐 ロードマップ(未実装) 最大16分岐 スナップショット
エージェントCLI同梱 5種をPATHに配置
前提環境 Kubernetesクラスタ Linux+KVM Linux+KVM 不要(マネージド) Docker

※ Orchard Env以外の列は各プロジェクトの公表内容に基づく。詳細は各記事を参照。

構成の近さで言えば、CubeSandbox解説:60ms起動MicroVMでAIエージェントを安全実行するTencentの設計思想が扱うようなmicroVM系が「隔離の強さと起動の速さ」を軸にしているのに対し、Orchardは既にKubernetesを運用している組織が、その上に大量のPodを立てる方向を選んでいる。カーネルレベルの隔離という点ではmicroVMのほうが強い一方、Orchardは既存のクラスタ運用・オートスケール・NetworkPolicyという枠組みをそのまま使える。

自前で運用しない選択肢との対比も明確だ。Cloudflare Sandboxes GA:AIエージェント用孤立実行環境が一般提供、PTY・スナップショット・認証情報安全注入が揃うのようなマネージドサービスは、クラスタを持たなくても始められる。Orchardのコスト表がマネージドサービスとの比較を掲げているのは、裏を返せばクラスタ運用のコストを自分で負う前提だということでもある。前節で見たカーネルCVEの巻き直しスクリプトは、まさにその「自分で負う」部分に相当する。

用途がそもそも違うものもある。AIO Sandbox入門:AIエージェント実行環境をDocker1つで構築する方法が扱うのは、ブラウザ・シェル・エディタを1コンテナに詰めて開発中のエージェントに触らせるタイプで、規模ではなく手軽さが価値になる。Orchardはその対極で、手元1台で試すのには向かない。

最も本質的な差は「走行中の分岐ができるか」だろう。Orchardのロードマップは、現在の環境が線形であること、つまり作成してN回駆動して破棄する一方向しか持たないことを明記している。同じ軌跡を何度も再実行するコストと、平均47.5ターンの軌跡に対して1つの結果報酬しか得られないというクレジット割り当ての難しさが、その帰結として挙げられている。この点は、走行中サンドボックスの分岐を既に実装している基盤との実務上の違いになる。

導入手順と、ロードマップに書かれた「これから」

導入は、既にオーケストレーターが立っているかどうかで分かれる。立っている場合はSDKを入れて接続先を指すだけになる。

pip install -e "orchard_env[dev]"

export SANDBOX_BASE_URL="http://your-orchestrator-host"
export SANDBOX_API_KEY="your-api-key"

SDKは同期版 SandboxClient と非同期版 AsyncSandboxClient があり、いずれもコンテキストマネージャで後始末まで面倒を見る。

from orchard_env import SandboxClient

with SandboxClient() as client:  # SANDBOX_BASE_URL / SANDBOX_API_KEY を読む
    with client.create_sandbox("python:3.11-slim") as sandbox:
        result = sandbox.exec("echo 'Hello, Orchard!'")
        print(result.stdout)

オーケストレーターが無い場合はクラスタから作ることになる。リポジトリにはAzure AKS向けに、プロビジョニング・イメージのビルドとpush・デプロイ・スモークテストの4本のスクリプトが同梱され、READMEは所要時間を約20分としている。要件はCalico NetworkPolicyに対応したクラスタと workload=sandbox ラベルの付いたノードプールで、orchard_env/docs/deployment.md はAzure以外のクラスタについても設定項目を列挙している。デバッグ用のスクリプトも scripts/debug/ に6本置かれており、クラスタ設定の確認・サンドボックスの掃除・RBACの検証といった実運用で必要になるものが揃っている。

認証は既定で有効(require_api_key: True)で、キーはカンマ・空白・改行のいずれでも区切れる。エージェントCLI用のクレデンシャルについては、settings.py のコメントが「意図的に焼き込んでいない」と明記し、呼び出しごとに渡す形(sandbox.exec("codex exec ...", env={"OPENAI_API_KEY": "..."}))を示している。イメージに鍵を埋めない設計になっている点は、大量のPodを立てる用途では重要になる。

ロードマップとして挙げられているのは、前節で触れた線形性の解消にあたる3つだ。

pause / resume:任意のターンでサンドボックスの状態(ファイルシステム・プロセス・環境)をチェックポイントし、後から復元する
branching:あるターン t のスナップショットから独立した継続を k 本fork する。同じ状態から何度も先に進めることで、その状態の価値をモンテカルロ的に見積もれるようにする
prefix sharing:分岐前の共通部分を1回だけ実行することで、木構造の探索やターンごとの優位性推定を平坦なロールアウトより安く済ませる

READMEはこれを「トレーナー側ではなく環境層に置くべきプリミティブだ」と位置づけている。線形なロールアウトでは1本の軌跡に1つの結果報酬しか付かず、平均47.5ターンのどこが効いたのかを推定で埋めるしかない。分岐が使えれば、その推定を実測に置き換えられる、という筋書きになる。

導入を検討する際に押さえておきたい現状は3点ある。リリース版もタグも無くmainブランチのcloneが前提であること、トレーナーまで使うならサブモジュールMSR-Orchard/slime)の取得が要ること、そして本体がKubernetes前提で手元のDockerだけでは完結しないこと。逆に言えば、既にクラスタを運用していて、エージェントの訓練・評価を継続的に回す予定があり、そのたびに環境層を作り直すのを避けたい、という状況であれば、REST APIを契約として据えたこの分離のしかたは検討に値する。

読者の3つの問いへの答え
何ができる?——Kubernetes上に隔離コンテナを数百〜数千個立て、コマンド実行・ファイルI/O・gitパッチをHTTP越しに何十ターンも回せる。codex / claude / pi / opencode / hermes がPATHに入った状態で起動する
何を解決する?——学習スタックの内側に作り込まれた自前サンドボックス層を、独立したRESTサービスへ切り出す。訓練で使った環境と評価で使う環境を同じものにできる
何を代替できる?——プロジェクトごとに書き直される環境層と、そのために組む学習・評価パイプライン。ただし手元1台で試す用途や、走行中サンドボックスの分岐が要る用途の代わりにはならない(分岐はロードマップ段階)

参照ソース

microsoft/Orchard — GitHubリポジトリ(README、orchard_env/Dockerfile.toolsorchard_env/orchard_env/orchestrator/settings.pyorchard_env/orchard_env/orchestrator/k8s_client.pyorchard_env/k8s/algif-aead-blacklist.yamlorchard_env/scripts/remediate_kernel_cve.shorchard_env/tests/integration/bench_concurrent.py.gitignore。2026-08-04時点のmainブランチを実読)
Orchard: An Open-Source Agentic Modeling Framework — arXiv:2605.15040(Peng et al.、著者14名。v1: 2026-05-14、v3: 2026-07-30)
microsoft/Orchard — Hugging Face Datasetsswe / gui の2サブセット)
OpenForge RL — arXiv:2607.21557(README「News」欄が挙げる後続研究)
THUDM/slimetrainer/slime が参照するフォークの上流)