私はDockerでCoding Agent Sandboxes、別名「sbx」に取り組んでいます。このプロジェクトは、Claude Code、Gemini、Codex、Docker Agent、KiroなどのAIコーディングエージェントを実行させるための安全な microVMベースの隔離 を提供します。エージェントはホストシステムに触れることなく、サンドボックス内(自分たちのDockerデーモン、ネットワーク、ファイルシステム)内で完全な自律性を得られます。ここ数週間で、私たちはそれを基盤に、製品のテスト、問題のトリアージ、リリース後のノート、さらにはバグ修正まで行う7人のAIエージェントからなる仮想チームを構築し、すべてCI内で自律的に動作させました。私たちはそれを艦隊と呼んでいます。
艦隊は クロードコードのスキルに基づいて構築されています。マークダウンファイルはエージェントにペルソナ、責任のセット、使用可能なツールを与えます。スキルを「これらのステップを実行しろ」と言うスクリプトではなく、「あなたはビルドエンジニアです。あなたの知識と意思決定の方法を説明する」という役割説明のように考えてください。この区別が重要なのは、エージェントには指示だけでなく判断力が必要だからです。テストが予期せず失敗すると、スクリプトは停止します。役割は調査を担当します。
同じスキルファイル、同じ動作、開発者のノートパソコンでもCIでも同じです。
ローカルファースト、CIセカンド
Coding Agent Sandboxesは、サンドボックスのライフサイクルを管理するCLIツール(sbx)です。作成、開始、停止、削除、ネットワーク構成、ワークスペースのマウントなどが含まれます。MacOS、Linux、Windowsで動作します。すべてのリリースは両プラットフォーム間でのテスト、バージョン間のアップグレード経路、そして持続的な負荷下でのテストが必要で、リソース漏れを検出する必要があります。また、出荷された内容を日々把握し、増え続ける問題のバックログをフルタイムの仕事にならずにトリアージする方法も必要です。
従来のテストスクリプトやレポートツールを書くこともできたはずです。代わりに、これらのタスクを自律的に処理するエージェントロールを構築し、ノートパソコンとCIの両方で対応しました。
艦隊の設計原則はシンプルです。すべてのスキルはまずあなたのマシン上で動作します。
/cli-testerスキル(艦隊の探索的テスター、詳細は後述)を構築した際、GitHubのワークフローを最初から書くことから始めませんでした。まずはローカルで呼び起こすことから始めました。バイナリの作成、CLIコマンドの実行、問題の発見、報告の様子を見守りました。私たちはスキルを調整し、端末で正しい動作をするようにしました。その後、ワークフローに組み込むことができました。
これは重要なのです。なぜなら、代替案は痛みを伴うからです。CI専用エージェントを構築する場合、コミット・プッシュ・待機・読み取り・ログのサイクルでデバッグします。各イテレーションは数分かかります。スキルがローカルで先に実行されると、反復は数秒で完了します。エージェントが考えているのがわかる。混乱するところがわかるでしょう。スキルファイルを修正し、再度呼び出して、再挑戦します。
CIは同じスキルの別のランタイムに過ぎません。MacOSやLinux、Windowsのランナーで毎晩動作する /cli-tester は、私たちが端末から引き出しているスキルとまったく同じです。ワークフローは環境を設定し、コードをチェックし、スキルを呼び出します。それだけです。別個の「CIバージョン」はありません。翻訳レイヤーはありません。スキルは一つ、ランタイムは二つ。
これが艦隊を実用的にしている理由です。二つのシステムを維持しているわけではありません。あなたは一つのスキルセットと、それを引き出す一連のワークフローを維持しているのです。
ロースター
スキルディレクトリには合計で 20 スキルがあります。ほとんどは基礎的な知識(アーキテクチャ、コードスタイル、囲碁の慣習、セキュリティ、テストパターン)です。そのうち7つはフリートで、CI上で自律的に動作する役割です。それぞれが手続きではなく、ペルソナを説明する SKILL.md ファイルです。
/build-engineer 他のスキルが基盤を築くのです。バイナリ、コンテナテンプレート、ローカルインストールのためのトピックファイルを参照しています。Taskfile.ymlを知っている。docker-bake.hcl、プラットフォーム固有のビルドフラグも含まれます。CI単体では動作しません。他のスキルは、何かをコンパイルするときに読み込みます。
/project-manager チームの記憶です。既存の課題やPRに対する調査結果を重複から削除し、新しいものを作成する前に、GitHub Projectsボードの管理(ステータス、優先度、ラベルの設定)、ローカル実行時のインタラクティブトリアージも管理します。CIでは完全自動モードに切り替わり、質問せずに重複を解除して作成します。GraphQLのページ分けを使ってプロジェクトボード全体をスキャンし、最初のページだけでなく。何かを発見した他のスキルは、問題を開ける前にプロジェクトマネージャーに連絡します。
/product-owner コミットスピークを人間の言語に翻訳します。統合されたPRを日付範囲から収集し、それらを分類(新機能、バグ修正、改善、ドキュメント、メンテナンス)し、それぞれを平易な英語で書き換えます。「feat(cli): add TZ env passthrough」は「Docker Sandboxes Now 自動的にローカルタイムゾーンを使用します」に変わります。CIではSlack Block KitのJSONを出力します。ローカルではマークダウンテーブルをレンダリングします。ボットのノイズ(Dependabotのバンプやワークフローのみの変更)をフィルタリングし、報告すべき重要な情報がない場合は投稿をスキップします。
/cli-tester 艦隊の探査テスターであり、圧倒的に最大のスキルです。従来のテストスクリプトが期待される出力を主張し、逸脱すると失敗するのとは異なり、CLIテスターは結果を調査します。出力が期待通りでない場合、バグを報告する前に 理由 を尋ねます。
52+テストシナリオを14層に分類しています:コアライフサイクル、エージェントスモーク、ワークスペース、ネットワークポリシー、サンドボックス機能、ブループリント、CLI UX、環境、コードタスク、エージェントネットワーク、信頼性、協働、エラー回復、そして人間のみ(CIではスキップ)。ビルドエンジニアを通じてバイナリを構築し、プロジェクトマネージャーを通じて結果をトリアージし、チーム内の実際のプロダクトマネージャーが定義したプロダクトシナリオを読み込みます。テスト中はディスク容量を監視し、終了後はSlackにエグゼクティブサマリーを投稿し、MacOS、Linux、WindowsのCI上で毎晩動作します。
また、GitHub上のスラッシュコマンドも機能します。誰かがプルリクエストに /cli-tester-review コメントすると、CIは3つのランナー(MacOs、Linux、Windows)を立ち上げ、それぞれがそのプラットフォーム上でPRの変更を実行できるようにスキルを読み込みます。エージェントはコードを探索し、シナリオを実行し、発見した結果をプルリクエストに直接コメントとして投稿します。
/performance-tester 2つのモードで展開します。ライフサイクルエンデュランスは、信頼性の問題やリソースリークを検出するために作成/停止/rmを繰り返し循環させ、xUnit JSON出力を生成します。Code Exploration Benchmarkは実際のGitリポジトリをクローンし、ホストとサンドボックスのI/OパフォーマンスおよびClaude Codeセッションの動作を比較します。両モードともディスク使用量を時間経過で測定し、フラグ回帰を行います。目標は、単一のテストランでは気づかないようなゆっくりとした劣化を捉えることです。
/upgrade-tester 4段階の試験計画を実施しています。フェーズAはアップグレード前の状態(サンドボックス、構成)を作成します。フェーズBは新しいバージョンをインストールします。フェーズCはアップグレード後もすべて正常に動作することを確認します。フェーズDはオプションで格下げと再度検証を行います。2つのバージョンタグを入力として受け取り、それぞれのバイナリを作成し、VMを作成し、フェーズごとの合格・不合格を含むエグゼクティブサマリーを作成します。アップグレード回帰は、単一バージョンのテストスイートでは見えないタイプのバグです。
/software-engineer 2つのモードで動作します。リアクティブ:誰かがGitHubの問題に agent-fix ラベルを追加すると、MacOSのランナーがそれを取り上げて ラルフループ を実行し、最小限の焦点を絞った変更でPRを提供します。積極的:毎週、アーキテクトモードで実行し、コードベースの品質問題をスキャンし、最大5件の発見を生成し、プロジェクトマネージャーでトリアージし、そのうち3つのMacOSランナーを並行して修正します。各ランナーは特定の簡素化や技術債務削減をターゲットにしたPRを発表します。
作曲するスキル
個々のスキルは役に立ちます。他のスキルを負荷するスキルはチームです。
7つのフリート役職は、アーキテクチャ、コードスタイル、囲碁の慣習、ソフトウェア設計、セキュリティ、テストパターン、開発ワークフロー、gitワークツリーなど13の基礎スキルの上に位置しています。基礎的なスキルはプロジェクトの知識を符号化します。艦隊の役割は行動を符号化します。フリートの役割は、新しいチームメンバーがコードを書く前にプロジェクトの貢献ガイドを読むのと同じように、必要な基礎的なスキルを積み込みます。
/cli-testerは二元論の構築方法を知りません。そのために /build-engineer を読み込みます。見つけたバグが重複しているかどうかもわかりません。/project-managerを読み込んで確認します。テスターはテストに集中します。ビルダーは建築に注力します。マネージャーはトリアージに集中します。それぞれの役割は自分の役割を守り、構成によって単独では成し得ないものが生まれている。
/software-engineerも同じパターンをたどっています。プロジェクトをコンパイルできるように /build-engineer を読み込み、コーディングのベストプラクティスやソフトウェア設計の慣習を読み込み、チームの基準を満たすように出力します。スキルはすべてをエンコードしようとはしません。基礎的なスキルを身につけることになります。
/performance-testerは/cli-testerを読み込み、持続時間や指標で拡張します。テストロジックを重複する代わりに、再利用し、その上に測定レイヤーを追加します。
これが実務上の「スキルを役割として」原則です。スキルを明確な責任を持つペルソナとして設計すると(段階的な命令ではなく)、自然に構成されます。ビルダーを読み込むテスターとマネージャーは、人間のテスターと同じことをしています。つまり、同僚にプロジェクトをコンパイルしてもらい、バグを提出する前にPMに確認するのです。違いは、「質問」がスキル構成を通じて行われる点で、Slackのメッセージではありません。
ラルフループはエンジンです
ラルフ・ウィガムループは、2025年にジェフリー・ハントリーによって広まったパターンで、AIコーディングエージェントに同じタスクを繰り返し与えて作業が完了するというパターンです。最もシンプルに言えば、それは while :; do cat PROMPT.md | claude-code ; doneです。各反復ごとにクリーンなコンテキストウィンドウを持つ新しいエージェントが生成されます。エージェントはタスクを読み取り、一つのパーツを実装し、テストを実行し、合格すればコミットし、終了します。ループは再開され、次の反復は前の反復の続きから始まります。一発で完璧を目指すのではなく、反復を重視して設計します。
このパターンの実装はラルフループと呼ばれます。艦隊スキルは各エージェントの役割が知っている ことを 定義します。ラルフループは反復 の実行方法 を定義します。
私たちのラルフループは、基本的なパターンの上にレイヤーを追加するシェルスクリプトに支えられた複合GitHubアクションです。これは別のワーカーとレビュアーです。問題コンテキストを取得し、作業中のブランチを作成し、反復を行います。ワーカーが変更を実装し要約を書き、レビュアーが差異を評価し、SHIPかREVISEかを決定します。REVISEの場合は、フィードバックが作業員に戻って再度やり直されます。デフォルトで最大5回の反復が可能です。レビュアーがSHIPと言った場合、ループはブランチをプッシュし、PRを作成し、元の問題にコメントします。
ワーカーとレビュアーは別々のClaude呼び出しとして異なるモデルで動作します。作業者はOpusを実装に使います。レビュアーはOpusを用いて、課題要件に対してOpusを1 1M文脈で評価します。それぞれが /software-engineer スキルを読み込み(それがビルドエンジニアやコーディングのベストプラクティスを読み込む)、同じプロジェクト知識を共有しつつも異なる視点から応用しています。
生成と評価を分離するのは意図的なものです。コードを書いた同じエージェントが、そのコードの良さを評価すべきではありません。品質保証の最も古い原則です:作った人だけがテストすべきではありません。労働者の仕事は問題を解決することです。レビュアーの役割は、その問題が実際に解決されたかどうかを判断することです。
ラルフループはローカルでも機能します。CIが呼び出すのと同じ ralph-loop.sh スクリプトを端末から --issue-number 42呼び出すことができます。ローカルでは、環境変数を読み取る代わりにCLI引数を解析し、ストリーミングJSONの代わりにプレーンテキストを出力します。同じループ、同じプロンプト、同じ反復パターン。私たちは、WorkerとReviewerのプロンプトをCIで実行する前に、ノートパソコンでデバッグしていました。
ワークフローはスケジューリングとトリガーを担当します。テスターは夜間cron、ソフトウェアエンジニアはイベントラベル、アーキテクトモードは週次cronです。ラルフループは反復パターンを処理します。スキルはドメイン知識を担当します。三層に分かれていて、それぞれに明確な役割があります。
この分離が、艦隊を数週間で建造可能にした。すべての役割で自動化ループを再発明する必要はありませんでした。ラルフループはすでに反復の方法を知っていた。各役割に独自のスキルファイルを与え、トリガーを配線するだけでした。
艦隊艦とは何か
艦隊は数週間稼働しています。これが提供される内容です。
自動問題解決。チームメンバーが問題をラベル付け agent-fix。CIはMacOSのランナーを手に取り、問題を読み取り、作業を開始します。その結果、問題に対処するプルリクエストが生成されます。すべてのPRが修正なしで届くわけではありませんが、初稿は1時間以内にレビューのために用意されています。
日々のリリースノート。プロダクトオーナーは毎日gitログを閲覧し、ステークホルダー向けにSlackの要約を投稿します。「今週出荷したもの」を手動でまとめる必要はありません。ステークホルダーは、チームが実際に動くスピードでリアルタイムで進捗を把握できます。
毎晩の探索テスト。CLIテスターは毎晩MacOSとWindowsで動作します。プロダクトマネージャーが定義したプロダクトシナリオを読み込み、CLIを実行し、見つけたものに対して問題を開きます。問題を開く前に、プロジェクトマネージャーを通じて重複がないかチェックします。終了すると、結果をSlackで投稿します。
性能とアップグレードテスト。パフォーマンステスターとアップグレードテスターは両プラットフォームでCI上で動作します。ディスク使用量の回帰、サンドボックスモードと非サンドボックスモードの挙動の違い、バージョン互換性の問題は、人間のレポーターに届く前に発見されます。
毎週のテクノロジー債務削減。毎週、ソフトウェアエンジニアはアーキテクトモードで動作します。コードベースをレビューし、コードを簡略化したりレガシーパターンを整理できる3つの箇所を特定し、3つの並列ランナーを生成し、3つのPRを提供します。それぞれが小さく焦点を絞った改善です。時間が経つにつれて、その効果は積み重なります。
私たちが自動化しないこと
フリートはプルリクエストを作成します。それらは統合されません。
それが信頼の境界線であり、意図的なものです。マージの決定は人間に留まります。アーキテクチャの選択、範囲の決定、優先順位付けも同様に重要です。エージェントが仕事をします。チームはどの仕事が重要か、成果が基準を満たしているかを決めます。
監督モデルは開発者のノートパソコンで動作するのと同じようにスケールします。複数のエージェントをローカルで並列作業木で実行する場合、統合前に出力を確認します。艦隊では、CI上で稼働する7つのエージェントの役割を監督しています。監督の形は同じです:出力を確認し、承認または調整し、次に進む。違いは、エージェントが誰かのノートパソコンを使わなくても作業が始まることです。
艦隊はチームの代わりになるわけではありません。それは延長しているのです。反復的で明確に定義された仕事を扱う7つの役割で、判断力、文脈、趣味を必要とする仕事に集中できるようにします。艦隊には多くの腕がありますが、それでもチームが船を操縦します。
艦隊構築で学んだこと
派手なスキルではなく、基礎から始めましょう。CLIのテストが最も価値のあるターゲットだと感じたため、 /cli-tester から始めました。しかし、バイナリの作成、トリアージの問題の処理、製品シナリオの読み込みなど、まだ書いていない他のスキルに依存していました。最初は/build-engineer、つまり他のすべてのスキルから始めるべきでした。2つ目のスキルは、1つ目から学んだことがあったからこそ良くなりました。最初からフルフリートを設計しないでください。
まずローカルビルドを始め、次にCIに展開しましょう。コミット-プッシュ-待機-読み-ログのサイクルが、ベロシティが死にゆくところです。端末でスキルをデバッグできなければ、そのスキルはワークフローに対応できていません。一部の動作はCIランナーでのみ現れます(異なるOS、権限、ネットワーク制約など)、それらの反復は何時間もの時間をかけて作業します。CIでしか検査できないものを最小限に抑えましょう。
スキルは脚本ではなく役割として書きましょう。自問してみてください。「もし明日、同じ役割で新しいチームメンバーが入社したら、私は何と伝えるだろうか?」彼らが知るべきことは何でしょうか?どんなツールを使うことができるのでしょうか?曖昧さにはどう対処すべきでしょうか?その会話があなたの SKILL.md です。「あなたはビルドエンジニアです。知っていることを教えてください」という方が、「この5ステップを実行」よりも判断力が良いです。予期せぬことが起きると、その役割が調査を行います。台本が止まる。
チームを編成するようにスキルを構成しましょう。/cli-testerはバイナリの構築やバグのトリアージの方法を知りません。/build-engineerを読み込み、/project-managerします。それぞれの役割は自分の領域を守ります。この構成は、彼ら一人ではできなかったものを生み出しています。
生成と評価を分離する。コードを書いたエージェントだけがレビューをするべきではありません。私たちのラルフループがワーカーとレビュアーを使う理由があります。品質保証の最も古い原則はエージェントにも適用されます。
トリアージは発見よりも重要です。/cli-testerは当初、予期しない出力ごとに問題を報告していました。一時的な故障、タイミング依存の挙動、環境の癖など、すべてが問題となりました。信号対雑音比が悪化し、チームは発見を無視し始めました。トリアージを正しく行う(重複除去や提出前の確認)は、テスター自体の構築よりも時間がかかりました。それともう一つ。すべてのフリートエージェントは、たとえ一時的なCIランナーであっても、 コーディングエージェントサンドボックス内で行動します。私たちはユーザーが使っているものでテストしています。