
GitHub
イベント
マガジン
技術ブログ
はじめに サーバーワークスの池田です。 今週(8/28〜9/3)のClaude Codeは、v2.1.251からv2.1.259まで5バージョンが公開されました(v2.1.253〜v2.1.256はnpmとGitHub Releasesのいずれにも出ていません)。モデル切り替えに介入できるフックや、プロンプトキャッシュの実績を数字で見る手段など、長時間の自動運用を支える機能が中心の1週間でした。 なお、v2.1.260が9月3日にnpmへ公開されていますが、執筆時点では公式CHANGELOGとGitHub Releasesのいずれにも記載がないため、本記事では扱いません。 この記事で分かること…
Codespaces で開発環境を配布する はじめに エブリーでデリッシュキッチンの開発をしている本丸です。 毎年、エブリーでは夏季にインターンシップを行っているのですが、今年は今まで行っていた長期のほかに短期でのインターンシップも行っています。 そこで問題になったのが、参加者の開発環境をどうするかというものでした。 本記事では、GitHub が提供している Codespaces を利用してどのように開発環境を用意するのか、組織で Codespaces を利用する上で設定した項目についてお伝えできればと思います。 GitHub Codespaces とは GitHub Codespaces は、GitHub のリポジトリに対してクラウド上の開発環境を立ち上げ、ブラウザや手元の VS Code から接続して開発できるサービスです。Codespaces は Dev Container の仕組みの上で動いており、リポジトリに devcontainer.json を置いておくと、Codespaces はそれを読んで環境を組み立てます。 devcontainer.json とは何を決めるファイルか devcontainer.json は、「この開発環境はこう作る」という手順をリポジトリに置いておくための設定ファイルです。Codespaces 専用の形式ではなく、同じ定義をローカルの VS Code(Dev Containers 拡張)などで利用することができます。 { "name": "...", "build": { "dockerfile": "Dockerfile" }, "remoteUser": "node", "features": { "ghcr.io/devcontainers/features/github-cli:1": {} }, "postCreateCommand": "pnpm install", "forwardPorts": [3000] } build でベースになるイメージを決め、 features でそこに入っていないツール(ここでは GitHub CLI)を後乗せし、 postCreateCommand で作成後に流すコマンドを書き、 forwardPorts で見せるポートを指定する、という構成です。ほかにも docker compose を丸ごと指定したり、VS Code の拡張機能やエディタ設定を一緒に配ったりと、開発環境まわりのことは一通り設定できます。 起動方法や使い方のポイントなど 使い方 Codespace の作成は、 https://github.com/codespaces を開き、 New codespace から対象のリポジトリを選んで起動するのが基本の流れです。 codespace からの起動 Create codespace のボタンを押した後、数秒から数分待つと Codespace がブラウザで立ち上がり、そのまま開発を始められます。 devcontainer.json さえ置いてあれば、ほとんど設定不要で開発環境を作成できます。 Codespace の停止は、 https://github.com/codespaces から対象の「…」メニュー → Stop で行えます。 ポイント ポート ポートは forwardPorts と portAttributes を使って、ラベル付きで転送しています。 転送されたポート一覧 転送されたポートには、Codespace ごとの URL( https://<codespace 名>-3000.app.github.dev のような形式)が発行されます。たとえば Next.js の開発サーバーを 3000 番で動かしておけば、この URL をブラウザで開くだけで動作確認ができます。 転送されたポートには GitHub の認証がかかっているため、URL を知られただけでは開けません。 また、必要であればポートをローカルに転送することもできます。たとえばローカルの GUI クライアントから DB を見たい場合は、次のコマンドで 3306 番をローカルに持ってこられます。 gh codespace ports forward 3306:3306 Prebuild Codespace は何も設定しないと作成のたびにイメージのビルドから始まります。ビルドに時間のかかるリポジトリでは立ち上がりが遅くなるため、そうした場合は Prebuild を設定しておくと初回起動が速くなります。ビルド済みのイメージをあらかじめ GitHub 側に用意しておき、Codespace の作成時にはそれを取ってくるだけで済ませる仕組みです。 組織アカウントでの運用 最初の設定 組織アカウントに対して、次の設定が必要になります。 まず budget の設定です。 budget の設定 ここで設定した budget を上限として Codespaces を利用していくことになります。 次にアクセス権の設定です。 アクセス権の設定 どのメンバーが Codespaces を利用できるかの設定です。 加えて owner の設定と、必要に応じて policy の設定を行います。 所有権の設定 所有者の設定 ここでは組織所有かユーザー所有かを切り替え、課金対象のユーザーを指定します。 注意しなければならないのは、支出上限に達すると新規作成も起動もできなくなり、稼働中のものも停止されることです。イベント中に全員が同時に止まる事故になり得るため、上限の設定は慎重に行う必要があります。 コストの構造 課金される軸は3つだけですが、止まっていても課金され続けるものがあるのがポイントです。 項目 課金単位 課金されるタイミング compute コア時間(コア数 × 稼働時間) 稼働中のみ (Stop すれば止まる) storage GB-month 停止中も継続 (削除するまで止まらない) prebuild 生成は Actions 分数 / 保管は Codespaces storage 常時 (無効化するまで) 組織ポリシー 組織所有の Codespace に対しては、マシンタイプの制限、アイドルタイムアウトの最大値、保持期間、1ユーザーあたりの上限といった制約を設定できます。 リポジトリ単位のポリシー compute に関しては稼働中のみコストがかかる仕組みになっているので、アイドルタイムアウトを設定することで無駄なコストがかかることを防げます。 なお、ポリシーの項目にユーザー単位の上限を含めると、適用するリポジトリの選択ができなくなります。 ユーザー単位のポリシー 一定以上のスペックが必要な場合やコストを抑える目的などで設定をする場合が多いかと思います。 他メンバーの Codespace 利用の確認 ブラウザ上で見えるのは自分の Codespace だけです。組織オーナーであっても、他メンバーの Codespace を一覧する導線がありません。棚卸しや停止・削除は gh コマンドなどから行うことになります(admin 権限が必要で、対象は組織所有のものだけです)。 # 組織の Codespace を一覧(owner / 状態 / ブランチ / 作成日時) gh codespace list --org ORGANIZATION # 停止(compute 課金を止める。作業内容は保持される) gh codespace stop --org ORGANIZATION --user USER --codespace CODESPACE_NAME state が Available であれば稼働中(compute 課金中)、 Shutdown であれば停止中(storage のみ)です。 CLI から確認した Codespace の状態 その他 Prebuild の設定は組織自体の設定ではなく、個別のリポジトリごとの設定になっているので注意が必要です。 まとめ 組織で利用する場合は、課金の仕組みや所有権まわりで注意しなければならない点があります。とはいえ、 devcontainer.json を置いておくだけで、GitHub アカウントさえあれば誰でも同じ開発環境を作れるのは非常に便利で、環境構築に時間を取られることがありません。 実際、インターンシップ当日も概ね問題なく動きました。こうしたイベントに限らず、普段の開発でも使い道はありそうだと感じました。 参考文献 GitHub Codespaces とは GitHub Codespaces の課金について 組織内の Codespace を一覧する Codespace のマシンタイプ タイムアウト期間を設定する
キャディ株式会社のデータ解析チームで、MLモデル開発をしている藤田です。 本記事では、私たちのチームで取り組んだ生産性改善の話をします。 1. 電線を張らずに電波塔を建てる? アフリカの一部地域では、固定電話網が普及する前に携帯電話が一気に広まりました。電線を張り巡らせるという「これまで当たり前だった工程」を飛ばして、いきなり電波塔を建てることで通信インフラを整えたのです。いわゆる「リープフロッグ(蛙飛び)」と呼ばれる現象です。 新しい技術は、既存の工程を「速くする」だけでなく、ときに工程そのものを不要にすることがあります。 今回、私たちは機械学習の開発プロセスで、これと同じことをやりました。これまで、既存モデルのアップデートを自動化するには、ML パイプラインを構築するといった相応の開発が必要でした。しかし Agent Skills を使うことで、そのパイプライン開発という工程そのものをスキップして、効率的に自動化できたのです。電線(ML パイプライン)を張り巡らせる代わりに、電波塔(Agent Skills)を建てた、というわけです。 結果として、1モデルあたりの開発工数はおよそ半分(生産性は約2倍)になりました。この記事では、次の3点を紹介します。 なぜ、これまで自動化が続かなかったのか(ジレンマ) Agent Skills で何をやったか(電波塔を建てる) どれだけ効いたか(効果) 2. 本取り組みでの「生産性」とは 私たちのチームのミッションは、認識モデルを開発し、その成果物を素早く・安全にプロダクトへ届け続けることです。この生産性を測る指標の1つが 開発リードタイム(精度・速度が十分なモデルの平均開発期間)で、今回はこの短縮に絞って取り組みました。 3. どの作業に時間がかかっているか? まず、工程を分解して、工数を圧迫している作業を洗い出しました。その中でも特に重かったのが「学習の実行」です。原因は大きく2つありました。 学習が自動化できておらず、手作業になっている :実行のたびに人が張り付く必要がある。 既存コードの実行環境が古い :既存モデルの精度を改善しようにも、当時のコードの実行環境(Docker image やライブラリのバージョン)が古く、そのままでは動かない。 実際には他にも様々なボトルネックに対策を打ちましたが、この記事では「学習の実行」に絞って紹介します。 4. これまでの取り組み 過去数年、学習の自動化(ML パイプライン構築)を何度か試みました。しかし、あまりうまくいきませんでした。 理由はシンプルで、「アップデートするための仕組みを作る・メンテナンスすること自体に工数がかかる」からです。 モデルごとに要件がバラバラ :入力データも評価指標も学習手順もモデルごとに違うため、一度作った仕組みを他のモデルに使い回しにくい。汎用化しようとするほど、作り込みの工数が膨らむ。 メンテナンスコストがかさむ :データやモデルの前提が変わるたびにパイプラインの改修が必要になり、工数がかかる。 ML パイプラインを一度組めば以降の再学習は自動化できます。しかし、その仕組みを作る工数があれば、その工数で手作業のモデルのアップデートや再学習ができてしまう。だったら手でやったほうが早い——そういう判断になりがちでした。 こうして、多くの試みは「割に合わない」か「作っても長続きしない」という形で終わっていきました。つまり私たちは、自動化したい気持ちはあるのに、自動化への投資が回収できないというジレンマをずっと抱えていたのです。 5. 対策:ML 開発で「電波塔」を建てる そこで目をつけたのが「Agent Skills」です。 専用のパイプラインをわざわざ開発しなくても、Agent Skills を用意しておけば、エージェントがその場に応じて作業を進めてくれる。ポイントは、新しく仕組みを作るのではなく、すでにある資産(README や学習コード)をエージェントにそのまま動かさせることです。これが、まさに「電線を張らずに電波塔を建てる」に相当します。 このやり方なら、これまで自動化が続かなかった原因そのものを避けられます。 初期工数が小さい :パイプラインを作り込まないので「割に合わない」になりにくい。 壊れても直せる :環境が古くて動かなくても、エージェントがエラーを解析し、修正案まで出してくれる。 対策①:Agent Skills で学習・評価・レポート作成を自動化 我々のチームでは、学習の実行から評価・レポート作成までの手順をREADMEに記載しています。そのREADMEに沿って学習を実行するようにエージェントに任せました。 学習実行 :README の手順どおりに学習を実行する。 評価 :精度・速度を測定する。 レポート作成 :結果のレポートを作成する いずれも既存の Agent Skills を再利用でき、2件目以降のモデルはこのインフラに相乗りするだけで済みます。 対策②:学習実行 CI で「動く状態」を維持 README の手順どおりに学習を実行する Agent Skills を、hosted-runner 上でエージェントに動かさせます。ライブラリや実行環境が古くて動かないときは、エージェントがエラーを解析し、修正案まで出してくれます。これで、コードを常に「動く状態」に保てます。 %%{init: {'sequence': {'mirrorActors': false}}}%% sequenceDiagram participant Dev as エンジニア participant GH as Github participant GHA as Github Actions participant Agent as AIエージェント on hosted-runner Dev->>GH: コード修正、ライブラリのアップデート, etc GH->>GHA: readme実行のGithub Actionsを起動 GHA->>Agent: readme実行の Agent Skills を使い、学習を実行 Agent-->>GHA: 成功・失敗、実行結果レポート、改善案を提示 GHA-->>GH: 結果を返す フローは次のとおりです。 エンジニアが変更をプッシュ :コード修正やライブラリのアップデートなどを Github に反映する。 CI が起動 :その変更をトリガーに、README 実行用の Github Actions が走る。 エージェントが学習を実行 :hosted-runner 上で、README 実行の Agent Skills を使ってエージェントが学習を回す。環境が古くて動かないときは、エージェントがエラーを解析し、修正案を組み立てる。 結果を返す :成功・失敗の判定に加え、実行結果レポートと改善案を Github に返す。 これにより、変更が入るたびに「本当に動くか」を自動でチェックでき、コードを常に「動く状態」に保てます。 エージェントが作成する実行結果レポートのイメージがこちらです。エラーが出ても修正案まで示してくれるので、直すのがぐっと楽になります。 🧪 スモークテスト結果 — FAIL README 手順別サマリ README の手順 結果 備考(スキップ/失敗の理由・修正内容) セットアップ ✅ データ準備 ✅ 学習 ✅ test_run=True で 1 iteration 完了 export (TorchScript) ✅ det-gpu.pt 生成完了。 推論 ❌ 下記バグにより TypeError 発生。 発生したエラー(推論で TypeError) File "inference.py", line 1061, in main TypeError: 'NoneType' object is not iterable 原因 inference.py L985 の entry.get("results", []) は、Phase 1 で検出なしの画像に対して "results": null が JSON に書き込まれるため、キーは存在するが値が None になる。 修正提案 (以下のパッチで解消を確認) diff --git a/inference.py b/inference.py index 12038b3..a1d697d 100644 --- a/inference.py +++ b/inference.py @@ -982,7 +982,7 @@ def main( for entry in tqdm(entries): image_name = entry["file_name"] gcs_path = entry.get("gcs_path", "") - detection_results = entry.get("results", []) + detection_results = entry.get("results") or [] 新しく仕組みを作らず、既存資産(README・学習コード)を動かし続けることで、環境の再現性を保ちました。 6. 効果 結論から言うと、実際に生産性がおよそ2倍になりました。 過去に実際にかかった、既存モデル改善プロジェクトごとの工数と、今回かかった工数を、ざっくり比較すると、1モデルあたりの工数がおよそ半分——つまり生産性が約2倍になりました。 ※ 本来はプロジェクトごとに要件や状況が異なるため、単純比較はできません。ここではそれらをあえて無視した、ざっくりとした概算です。 効果が大きいのには理由があります。 「学習の実行」の自動化・環境維持が、工数削減に大きく寄与する 既存 Agent Skills を一度作ってしまえば、全てのプロジェクトで使うことができる まさに「電波塔を一度建ててしまえば、次からは同じインフラに相乗りできる」という構図です。最初のモデルで Agent Skills を整備しておけば、2件目以降はそのインフラに乗るだけで、劇的に軽くなります。 まとめ 新しい技術は、既存の工程を「速くする」だけでなく、ときに「工程そのものを不要にする」力を持っています。 アフリカが電線を飛び越えて電波塔で通信インフラを整えたように、私たちは ML パイプライン開発を飛び越えて、Agent Skills で機械学習の開発プロセスを自動化しました。その結果、1モデルあたりの工数はおよそ半分になり、生産性を約2倍に引き上げることができました。とくに既存モデル改善では、一度作った Agent Skills を再利用することで大きな工数削減を実現できています。 これからも Agent Skills のような新しい技術を開発プロセスに取り入れて、生産性を上げていきたいと思います。



















