🚴

GitHub Copilot SDK × DockerでAI開発の自動化と定量評価が見えてきた

に公開

はじめに

GitHub Copilot SDK が公開されたことで、CLIをプログラム的に制御する道が開けました。
https://github.com/github/copilot-sdk

最初は、実行結果を取得しながら最適なプロンプトを動的に構築し、一定品質に到達するまで外から操作し続ける、いわば「万能エージェントコントローラー」のようなものを作れるのではないかと考えていました。

しかし実際に試してみると、細かな制御をするにはCopilot SDKには高い障壁があることが分かりました。

動的な制御を実現するには、Copilot側からプログラムがパース可能な形式で実行状態を返してもらう必要があります。最初は、プロンプトでJSON形式を指定してみたものの、自由形式のテキストと混在して不安定でした。次に、トレースログを分析しましたが、履歴は追跡できるものの最新の断面の把握は困難でした。最後に、Tool Calling(AIが外部関数を呼び出す仕組み)のようなパターンも試みましたが、Tool呼び出しが実行されないことも多く全く安定しませんでした。

こうした困難さに直面する一方で、トレースログについて調査している過程で予想外の発見にも出会いました。これまで利用していたVS Code Extension版のGitHub Copilotでは取得することが出来なかった 定量データ(トークン消費、コスト、実行時間) を取得できることが判明したのです。この事実に気づいたとき、SDKの自動実行と定量値を組み合わせて、試行錯誤と比較評価を高速化する基盤を構築できるのではないかというアイディアが浮かびました。

方向転換:標準化パイプラインへ

そこで発想を変えて、「細かな制御」ではなく「フェーズ(決められた作業群)を順次実行する自動化パイプライン」という方向に切り替えることにしました。パイプラインの各フェーズは成功するまで実行されると見做し、詳細な断面の取得は行わずに次のフェーズへと進んでいくというシンプルさ重視の実装としました。

これにより、とにもかくにも Copilot SDK によって得られる価値の一端を体感することが出来たので、ここで共有させてもらうことにしました。

採用したアーキテクチャ

標準化パイプラインの設計

今回は、典型的なITデリバリーにおけるフェーズを念頭に、要件ファイルから成果物までを3つのフェーズで自動生成するパイプラインを設計しました。

フェーズ構成

Phase 1: 要件分解と設計

  • 要件ファイルを分析
  • Architecture、Data Model、ADR(Architecture Decision Record)、Tasksを生成
  • 設計判断を文書化

Phase 2: 実装

  • Phase 1の設計に基づき実装
  • ソースコード、テストコード、依存関係定義
  • 依存関係の自動インストール
  • サンプルデータの生成

Phase 3: テストと品質検証

  • テストコードの作成・実行
  • 品質チェック(black、mypy)
  • テストカバレッジ測定
  • 品質レポート生成

実行アーキテクチャ

このパイプラインは、ホスト環境とDockerコンテナ環境を組み合わせた構成で動作させることにしました。ホスト環境からGitHub Copilot SDKを通じてDockerコンテナ内のCopilot CLIを制御し、コンテナ内で安全にコード生成とテストを実行します。

このアーキテクチャでは、ホスト環境のSDKがDockerコンテナ内のCLIをTCP 3000経由で制御します。コンテナ内では、あらかじめ埋め込んだスキルやインストラクションを参照しながらコード生成とテストを実行し、品質確認後の成果物をホストへ移送します。

https://github.com/features/copilot/cli?locale=ja

Dockerコンテナによる実行サンドボックス

Copilot CLIは、AIエージェントが任意のコマンドやファイル操作をすることをユーザーの承認なしに許可するのが既定の動作となっています。これはバックグラウンドでの長時間実行や自動実行を実現するには合理的な設定です。

しかし、意図しないホスト環境への影響や重要ファイルの意図しない変更・削除、実験の再現性など、いくつかの懸念があります。こうした課題に対して、DockerコンテナにCopilot CLIを封じ込めるサンドボックス化を採用しました。

FROM node:22-slim

# 開発ツールチェーンのインストール
RUN apt-get update && apt-get install -y \
    git curl unzip \
    python3 python3-pip python3-venv \
    && rm -rf /var/lib/apt/lists/*

# GitHub Copilot CLIのインストール(公式npm package)
RUN npm install -g @github/copilot

# Python/JSツールチェーン
RUN curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="/usr/local/bin" sh
RUN curl -fsSL https://bun.sh/install | env BUN_INSTALL="/usr/local" bash

WORKDIR /workspace

# Skills(Python環境構築、テスト実行、品質チェック)を埋め込み
COPY skills /workspace/.github/skills
# Custom Instructions(Pythonコーディング規約)を埋め込み
COPY instructions /workspace/.github/instructions

# Copilot CLIをサーバーモードで起動(TCP 3000)
# ホスト側のSDKがこのポート経由でCLIと通信する
CMD ["copilot", "--server", "--port", "3000"]

コンテナの破棄/作成により実験環境をリセットが可能で、コンテナはホスト環境から分離された安全な実行空間として機能します。

そして、成果物の生成はすべてコンテナ内で実行し、成果物の品質が確認されてから、成果物のみをコンテナの中から取り出すことで、ホストPC側の安全性を高めることにしました。

SDKを使った実装

Copilot SDKを使ってDockerコンテナ内のCLIと通信し、先ほどの3つのフェーズを逐次実行するパイプラインを実装しています。

実装の要点

from copilot import CopilotClient

# 1. CLI接続とセッション作成
client = CopilotClient({"cli_url": "localhost:3000"})
await client.start()
session = await client.create_session({"model": "claude-sonnet-4.5"})

# 2. イベントハンドラ登録
session.on(event_handler)  # ストリーム応答、ツール実行、トークン消費を処理

# 3. フェーズ実行
await session.send({"prompt": "Phase 1: 設計ドキュメントを作成..."})
await done.wait()  # session.idleイベントまで待機

イベントハンドラの全体像はこのGitHubにあるコードで確認できます。

主要なイベントタイプ

  • assistant.message_delta: ストリーミング応答(リアルタイム出力)
  • tool.execution_start/complete: ツール実行の開始・完了
  • assistant.usage: トークン消費・premiumリクエスト数(Claude/GPT等の高性能モデル呼び出し回数)・コスト
  • session.idle: フェーズ完了の通知

この実装により:

  • ✅ Dockerコンテナ内のCLIとTCP経由で通信
  • ✅ ストリームイベントでリアルタイムに応答を取得
  • ✅ 各フェーズのトークン消費、premiumリクエスト、実行時間を記録
  • ✅ skills/instructionsを埋め込んだコンテキストで実行

詳細な実装コード: 全てのコードは以下のレポジトリで公開しています。
https://github.com/mahitotsu/dwarven

3. 比較実験の詳細

さっそく、構築したパイプラインを使って、異なるモデルと設定で同一タスクを実行し、実行時間・コスト・品質などを定量的に比較する実験をおこなってみました。この実験の狙いは、SDKによる自動実行と定量的な観測を組み合わせることで、高速に試行錯誤できる可能性を確かめることにあります。

3.1 実験設計

同一の要件ファイルを用いて、異なるモデルと設定で実行しました。

要件ファイルの概要 (examples/simple_script.md):

  • タスク: CSVデータ分析スクリプトの作成
  • 機能: CSV読み込み、統計情報計算、グラフ生成、HTMLレポート出力
  • 技術スタック: Python, pandas, matplotlib/plotly, argparse
  • 成果物: analyze.py, requirements.txt, README.md, sample_data.csv
  • 複雑度: 小規模プロジェクト(単一スクリプト・明確な要件)

共通条件

  • 実行環境:同一のDockerイメージ
  • 各ケースを1回ずつ実行

比較ケース

Case# モデル instructions
(コーディング規約などのカスタム指示)
A Claude Sonnet 4.5 なし
B Claude Sonnet 4.5 あり
C GPT-5 mini なし
D GPT-5 mini あり
E GPT-5.3 Codex あり
F Gemini-3-Pro-Preview あり

3.2 実験結果:包括的な比較

Case# 実行時間 premium
消費
Input
tokens
Output
tokens
Cache
利用率
カバレッジ
(単体テスト)
総合評価
A 772s
(12.9分)
51 2,175,509 41,581 91.7% 82% ⭐⭐⭐⭐
良好
B 874s
(14.6分)
65 3,376,109 63,151 92.2% 89% ⭐⭐
低効率
C 326s
(5.4分)
0 757,498 18,469 76.7% 74% ⭐⭐⭐⭐⭐
無料・高速
D 430s
(7.2分)
0 195,787 19,086 73.4% 0%(失敗)
実行失敗
E 746s
(12.4分)
66 2,105,333 23,357 87.1% 95% ⭐⭐
高品質・低効率
F 382s
(6.4分)
34 800,067 13,832 78.4% 95% ⭐⭐⭐⭐⭐
最高効率

実運用でのコスト試算

Case# 1回実行 週次(4回/月) 日次(30回/月)
A 51 204 1,530
B 65 260 1,950
C 0 0 0
D 0 0 0
E 66 264 1,980
F 34 136 1,020

※ コストは、プレミアムリクエスト回数にモデルごとに定義されている係数を乗算した値です。
※ Copilot Pro+プランの月額料金($39)に含まれる、プレミアムリクエストの実行回数は 1500回/月です。

3.3 観察された傾向

実行速度とコスト効率

  1. Claude Sonnet 4.5:カバレッジ82%、コスト51で良好

    • 実行時間12.9分、API呼び出し51回
    • Cache利用率91.7%と高いが処理時間は長め
  2. GPT-5 mini:カバレッジ74%、コスト0で頻繁実行に有利

    • 実行時間5.4分で最速
    • 無制限実行可能だが品質はやや劣る
  3. GPT-5.3 Codex:カバレッジ95%だがコスト66でコスト高

    • 実行時間12.4分、API呼び出し66回で最多
    • 高品質だがコスト効率は最も低い
  4. Gemini-3-Pro-Preview:カバレッジ95%、コスト34で最高効率

    • 実行時間6.4分で高速 + 高品質のバランスが優れる
    • API呼び出し34回で効率的

フェーズ別の傾向

  • Phase 1(設計): 全モデルとも60-130秒で大きな差なし
  • Phase 2(実装): GPT-Codexが426秒と突出、他は120-294秒
  • Phase 3(品質検証): Claudeが390-449秒と長い、GPT-5 miniは123-196秒で短い

アーキテクチャと品質

  • モジュラー設計が主流:
    • Claude以外は全てsrc layout等のモジュラー構造
  • テストコード量と品質:
    • Claude B: 527行で最多(37テストケース、カバレッジ89%)
    • Gemini/Codex: 75-141行で少ないがカバレッジ95%を達成(効率的なテスト設計)
    • GPT-5 mini: 17-34行でテスト不足(カバレッジ0-74%)

instructionsの影響

Claude/Codexでは詳細な実装になるが実行時間とpremium消費が増加(Claude: +13%, Codex初回のため比較不可)。一方、GPT-5 miniのような軽量モデルでは扱いきれずに品質が悪化(instructionsなし: カバレッジ74% → あり: カバレッジ0%で実行失敗)

[参考] 実際の実行ログ

※ 全文はリンクをクリックしてGitHubのレポジトリを参照してください。
https://github.com/mahitotsu/dwarven/blob/main/artifacts/simple_script_claude-sonnet-4.5_wz_instruction/execution.txt

4. Dockerの新しい価値

当初、Dockerはサンドボックス化による安全性のために採用しているだけでしたが、検証を進める中で、別の価値が見えてきました。

このDockerイメージは、単なる実行環境ではなく、標準化された開発パイプラインとして機能する可能性があります。

埋め込まれる資産

# Skills:開発プロセスを自動化するツール
COPY skills /workspace/.github/skills
# - python-setup-dependencies: Python環境構築
# - python-run-tests: pytest実行、カバレッジ測定
# - python-run-quality-checks: black, mypy実行

# Instructions:コーディング規約とベストプラクティス
COPY instructions /workspace/.github/instructions
# - python.instructions.md: Pythonコーディング規約、プロジェクト構造、ツールチェーン

従来のアプローチとの違い

項目 従来のアプローチ パイプラン配布のアプローチ
配布するもの 開発環境 開発環境 + skillsとinstructions
実行主体 開発者(人間) AIエージェント
実行方法 手動実行 SDKによる自動実行
ガイドの扱い 開発者がREADMEを読んで理解・実行 AIエージェントがskillsとinstructionsを理解・実行
品質の確保 開発者の理解と実行に依存 組織標準プロセスがAIエージェントにより自動実行される

つまり、従来は「環境を配って、開発者がルールとガイドを読んで頑張る」だったのが、「環境 + skillsとinstructionsを配って、SDKが起動したAIエージェントがルールとガイドを理解して作業する」に変わります。これにより、組織が定めた標準プロセスの実践が推進されるようになります。

おわりに

当初は Copilot SDK を活かして「細かく制御できる万能エージェントコントローラー」を作ろうと考えていましたが、実際に試してみると、そうした細かな制御には高い障壁があることが分かりました。

一方で、「試行錯誤と比較評価を高速化する基盤」という別の可能性を見出すことも出来ました。SDK経由で取得できるトークン消費量やコスト、実行時間といった定量的なデータがあることで、異なるモデルや設定を短いサイクルで比較し続けられる環境の実現への第一歩を踏み出せています。

さらに、Docker環境にskillsやinstructionsを埋め込むことで、組織のベストプラクティスを配布可能なパイプラインとして扱えるという、別の視点も得られました。これは従来の「環境を配って、開発者がガイドを読んで頑張る」という形から、「環境 + skills/instructionsを配って、SDKがAIを自動実行し、AIがガイドを理解して作業する」という形への変化と見ることもできます。

応用と展開

今回構築したのは「要件定義から実装・テストまで」のパイプラインでしたが、同じアプローチは様々な場面に応用できると考えています。例えば、バグ修正パイプライン(障害チケットから修正パッチまで)、インフラ改善パイプライン(メトリクスから設定変更まで)、ドキュメント生成パイプライン(ソースコードからAPI仕様書まで)など、異なる技術スタックやプロジェクト規模でも、同じ枠組みで特化したパイプラインを構築できる可能性があります。

これから、再現性の検証や異なる要件での比較、プロンプトの最適化など、さらに試行錯誤を重ねていきたいと考えています。もしあなたのプロジェクトでも同様のアプローチが役立ちそうであれば、ぜひ試してみてください。本稿が、SDKを使った開発パイプラインの構築や、AIを活用した試行錯誤について考えるきっかけになれば幸いです。

Discussion