ACES エンジニアブログ

ACESのエンジニアブログです。

ソフトウェアサプライチェーン攻撃にどう向き合うか:ACESの8つの対応方針

はじめに

こんにちは、株式会社ACES の共同創業者 / ソフトウェアエンジニアの三田村です。

2024〜2026年にかけて、OSS パッケージや CI/CD を経由したソフトウェアサプライチェーン攻撃が増加しています。当社は Python と JavaScript/TypeScript を主な開発言語として使用し、CI/CD パイプラインやクラウドサービスに依存しているため、以前からこの問題を認識していました。

直接的なきっかけとなったのは、2026年初頭に発生した Trivy(セキュリティスキャナ)の侵害と axios(HTTP クライアントライブラリ)のメンテナー権限悪用の 2 件です。Trivy の件はセキュリティツール自体が攻撃対象になりうることを示し、axios の件は広く利用されている有名パッケージであっても依存関係の改変リスクがあることを示しました。いずれも当社の開発環境に直接関係するツール・ライブラリであったため、個別対応ではなく全社のガイドラインとして整備することにしました。

本記事では、その内容を紹介します。同程度の規模・技術スタックの開発組織にとって、参考になる部分があれば幸いです。

背景:攻撃手法の変化

従来のサプライチェーン攻撃は、タイポスクワッティング(名前を似せた悪意あるパッケージの登録)が主でした。近年は、信頼済みの経路そのものを利用した攻撃が増えています。

  • OSS メンテナーのアカウント乗っ取りによる正規パッケージの改変
  • GitHub Actions のタグ書き換え(tag poisoning)
  • postinstall / preinstall を経由した不正コード実行
  • CI トークン等を起点としたワーム型の横展開
  • セキュリティスキャナ自体の侵害

近年のインシデントから得た教訓

  • xz-utils(2024年): 数年にわたるソーシャルエンジニアリングで上流コンポーネントにバックドアが混入された。長期間利用されている OSS であっても安全とは限らない。
  • tj-actions/changed-files(2025年): GitHub Actions のタグが書き換えられ、利用者が意図せず改変済みコードを実行した。@v1 等の可変タグ指定にはリスクがある。
  • npm/PyPI のワーム型攻撃(2025〜2026年): CI の秘密情報を起点に自己増殖的に感染が拡大した。単一のトークン漏洩がリポジトリ横断の問題に発展しうる。
  • セキュリティツールの侵害(2026年): セキュリティツール自体が攻撃対象になり、スキャン処理中に認証情報が窃取された。検査ツールもゼロトラストで扱う必要がある。

標準化した 8 つのルール

これらの状況を踏まえ、以下を全社の標準ルールとして導入しました。

1. 依存関係のゼロトラスト

利用実績の長さや知名度に関わらず、すべての外部依存を侵害されうるものとして扱います。

2. ロックファイルの必須化

以下のロックファイルをリポジトリにコミットし、CI ではロックファイルに基づくインストールのみ許可しています。

  • uv.lock(uv)
  • poetry.lock(Poetry)
  • package-lock.json(npm)
  • yarn.lock(Yarn)

CI での実行コマンドは以下の通りです。

# Python (uv)
uv sync --locked

# JavaScript/TypeScript (npm)
npm ci --ignore-scripts

# JavaScript/TypeScript (Yarn Berry)
yarn install --immutable

3. インストールスクリプトの原則無効化

npm / Yarn のライフサイクルスクリプトは既定で無効としています。

  • postinstall / preinstall を無効化
  • ネイティブ拡張等で必要なパッケージのみ個別に許可

設定例:

# .npmrc
ignore-scripts=true
save-exact=true
# .yarnrc.yml (Yarn Berry)
enableScripts: false

4. GitHub Actions の SHA 固定

第三者アクションは可変タグではなくフルコミット SHA で固定しています。

  • @v1 / @v3 等のタグ指定は禁止
  • フルコミット SHA にピン留め
# NG
- uses: some-org/some-action@v1

# OK
- uses: some-org/some-action@a3fcfb04bbe59c91f973cb6447e1bb1523abcb0b

既存ワークフローは pinact で一括変換し、CI に漏れ検知ステップを追加しています。SHA 固定後のバージョン追従は Dependabot で管理しています。

5. CI/CD 権限の最小化

GITHUB_TOKEN は既定で読み取り専用とし、必要なジョブにのみ最小限の権限を付与しています。本番環境へのアクセスは OIDC ベースへの移行を進めています。

permissions:
  contents: read

jobs:
  deploy:
    permissions:
      contents: read
      id-token: write  # OIDC

6. 検疫期間の設置

新規リリースのパッケージを即時反映せず、48〜72 時間のクールダウン期間を設けています。

  • Python: uvexclude-newer を利用。v0.9.17 以降、 "3 days" のような相対指定にも対応している
  • JavaScript/TypeScript: Renovate の minimumReleaseAge で同等の運用

設定例:

# Python (uv) - pyproject.toml
[tool.uv]
exclude-newer = "3 days"
// JavaScript/TypeScript (Renovate) - renovate.json
{
  "minimumReleaseAge": "3 days"
}

7. SBOM / 脆弱性スキャンの標準化

全リリースで SBOM を生成し、PR・main・release の各段階で依存関係スキャンを実施する方針です。脆弱性管理ツールの選定は現在進行中です。

8. 新規依存関係の導入ルール

新しいパッケージの導入時は、以下を確認するプロセスを設けています。

  • 保守状況・メンテナー体制
  • 代替可能性
  • ライセンス
  • install script の有無
  • 認証・暗号・通信に関わるライブラリかどうか

上記のうち、特にリスクの高い条件に該当する場合は追加の精査を行います。

技術スタック別の対応

Python

新規プロジェクトでは uv を第一候補としています。exclude-newer による検疫や、locked / frozen オプションによる厳格なインストール制御が利用できます。既存の Poetry プロジェクトは即時移行を求めず、いずれの場合もロックファイルと監査の運用を必須としています。

JavaScript/TypeScript

インストール時のライフサイクルスクリプトが主なリスクです。

  • 既定でスクリプトを無効化
  • 必要なパッケージのみ allowlist 方式で許可

GitHub Actions / CI/CD

SHA ピン留め、最小権限の permissions 設定、build/test とデプロイの分離を基本方針としています。pull_request_target の利用は原則禁止です。

インシデント対応

対策を講じても侵害を完全に防ぐことはできないため、発生時の対応フローも整備しています。

検知・トリアージ(0〜2 時間)→ 封じ込め(2〜24 時間)→ 根絶(24〜72 時間)→ 復旧 → 事後分析の各フェーズで対応内容を定義しています。サプライチェーン攻撃では CVE の有無よりも悪性挙動の有無を判断基準としています。

おわりに

サプライチェーンセキュリティは特定のツール導入で完了するものではなく、開発プロセス全体の運用を継続的に見直す取り組みです。当社でも脆弱性管理ツールの選定やプライベートレジストリの導入など、未着手の項目が残っています。

同様の課題に取り組んでいる開発組織の参考になれば幸いです。

#6|1チームの実践を組織の力に変える — AI駆動型の組織をどう作るか

はじめに

こんにちは、株式会社ACES でテックリードをしている福澤 (@fuku_tech) です!

本シリーズでは、AI駆動開発における人間とAIの役割分担を、自動運転になぞらえた4つのPhaseで整理してきました(詳細は以下を参照)。

tech.acesinc.co.jp

ここまで5回にわたってお届けしてきたのは、ACES Meet開発チームという1つのチームの実践録です。最終回となる今回は、この実践を組織全体に広げる話と、6回かけてたどり着いた一つの結論をお伝えします。

1チームだけ速くなっても、組織は変わらない

パフォーマンスチューニングの経験がある方なら実感があると思いますが、ある処理のレイテンシーを半分にしても、その先のボトルネックが詰まっていれば全体のスループットは変わりません。組織も同じで、開発チームだけがAIを駆使して速くなっても、ボトルネックが別の場所に移るだけです。

シリーズ1回目の記事で書いたCursorのような組織、つまり職種や部門の垣根を超えてAI活用が全体に浸透し、事業そのものがスケールする状態を、ACESでも実現しようとしています。

自チームから全社への展開

自チームへの浸透

展開にあたって最初にやったのは、ツールの説明ではありませんでした。「なぜ今これをやるのか」を、事業背景ごとチームに話すことから始めました。課題、目指す姿、そこに至るステップとスケジュールを事前に共有したのは、全体像が見えないまま動き始めることへの不安を、あらかじめ取り除きたかったからです。

大上段の共有と並行して進めたのが、業務プロセスの細分化と可視化です(詳細はシリーズ2回目の記事を参照)。サブプロセス単位まで分解して「ここは人間が判断する」「ここはAIに任せる」を明確にし、どこがボトルネックかを図に落としました。優先度の高いサブプロセスからスラッシュコマンドを整備しながら、構想と進捗を随時共有することで「今自分たちは全体のどこにいるか」を常に見えるようにしていきました。

その上でPilot-Tower開発への移行にあたっては、モブプログラミング会を90分×4回実施しました(詳細はシリーズ4回目の記事を参照)。振り返ってみると、AI活用の文脈で最も重要で、かつ最も難しいのは、AIに運転席を譲ることへの抵抗感を越えてもらうことだったと感じています。「自分でやった方が正確で早い」「本当に任せて大丈夫なのか」という感覚は、言葉でいくら説明しても拭いきれません。実際に動くものを目の前で見て触れてもらうことで、思った以上に早く「任せてみよう」という空気が生まれました。AIに任せる文化は、言葉ではなく体験から醸成されると実感しています。

元々は3ヶ月かけて段階的に浸透させる計画でしたが、メンバーのモチベーションが想定以上に高く、自分自身も楽しくなって全力でアクセルを踏んだ結果、想定の倍近いスピードで改善サイクルが回りました。メンバーが感じた使いにくさや改善ポイントがすぐ自分に届く仕組みを整えていたことも、このサイクルを速める一因だったと思っています。今では自分がいなくてもメンバーが自発的にコマンドやガイドラインの改善を回せるレベルになりつつあります。

他チームへの横展開

自チームが自走し始めたことで、自分のリソースをチームに張り付ける必要がなくなりました。次の展開先として選んだのは、社内のプロジェクト型の開発チームです。前提が異なる部分もあり、全体に一斉に声をかけるのは非効率だと判断したため、まずリーダー層のキーマンを捕まえて現状をヒアリングしながら進めることにしました。

ACES Meet開発チームと大きく違ったのは、開発プロセスが可視化・標準化されておらず、各プロジェクトの特性に応じて都度適切な進め方が取られていた点です。そのため、自チームへの展開と同様にAIに何を任せるかを定義していく前に、まずプロジェクト横断で共通する開発プロセスの洗い出しと可視化から始めました。

一方で、プロジェクト型特有のボトルネックの所在も見えてきました。顧客とのやり取りやPMの仮説といった1次情報をどう扱うか、AIモデル出力に関するレポートの正確性をどう担保するか、ナレッジをプロジェクト横断で再利用できる形にするには開発プロセスのどのタイミングでどんな工程やアウトプットを定義しておくべきかを整理する必要もありました。

そうした中で、PM側でもAI駆動のプロジェクトマネジメントに取り組む動きが生まれており、開発側との合流が始まっていました。PMが持つ情報と開発側の成果物が一貫してつながることで、プロセス全体の精度が上がる可能性があると考えています。その整理がようやく終わり、まさに本格運用が始まるところです。

全社への展開

全社の開発チームがAI駆動開発を始めやすい環境として、汎用的に利用可能なAgents SkillsやAI向けドキュメントの雛形をGitHubで社内に公開しており、setupコマンド一発で既存リポジトリに適用できる設計にしました。今後いかに質の高いAgents Skillsを量産しフィードバックサイクルを回せるかが競争優位性に直結すると考えており、まずは自分の肌感のある開発文脈での共通基盤を整えるところから始めました。開発の文脈で得た知見を、ゆくゆくはBizサイドへの展開にも活かしていけないか、模索していくつもりです。

ただ、仕組みだけでは広がりません。2026年2月、全社向けの勉強会を開催しました。冒頭で伝えたのはシンプルな話で、AI活用を組織全体に広げてACESをスケールさせたいという想いと、自分一人では実現できないから一緒に取り組んでほしいということです。ライブデモでAI駆動開発の現在地を実演し、AIがオーケストレートする体験を共有しました。

勉強会後、PM・CS・Bizの各方面から個別に相談が届くようになり、全社横断のAI活用チャンネルが立ち上がるなど、共感してくれる人が増えて波を感じ始めています。こうした活動が呼び水となり、ACESではChatGPT / Claude / CursorのEnterprise版を職種・雇用形態を問わず全員に標準整備する動きへとつながりました(詳細は以下の記事を参照)。

tech.acesinc.co.jp

4月からはBizサイド向けに週次で計8回以上のAI活用勉強会を開催予定です。#1で書いた「個人の2倍よりチーム全体の底上げ」、つまり一人ひとりの能力を劇的に高めるより全員が少しずつ底上げされる方が組織全体のアウトプットは大きくなるという考え方を全社に広げ、まずは100人×1.1倍を最速で実現しにいきます。

AI OSの社内実装

1チームの実践を組織全体に広げながら、ずっと頭にあった問いがあります。「そもそも、AIを本当に活かせている組織とそうでない組織の違いは何か」ということです。ツールを入れているかどうかではなく、AIが活躍しやすいようにプロセスそのものを再設計できているかどうか、それが本質的な差だと考えるようになりました。AIを前提として業務の構造そのものを作り直した組織のことを、自分はAIネイティブな組織と呼んでいます。

DORAの2025年レポートは、約5,000人の技術者を対象にした調査でこう結論づけています。AIはチームを修復しない、すでにあるものを増幅する、と。良い土台があればAIはその組織を良い方向に増幅し、土台のない組織はいくらツールを入れても変わらない。このシリーズで6回かけてやってきたことの意味が、この一文に集約されていると感じています。

dora.dev

振り返ってみると、自分たちがやってきたことは、代表の田村が語る「AI OS」の社内実装の一つの形だったと思っています。AI OSとは、どのモデルを使うかではなく、組織・文化・業務プロセスを含めてAIが動く前提を設計すること。1チームの実践から始まり、他チームへの横展開、全社への浸透へと広げてきた取り組みは、まさにそのOSを組織にインストールしていく作業でした。

note.com

ただ、OSはまだ完成していません。AIが活躍しやすい構造へと組織を再定義していく作業は続きます。開発領域から始めたこの取り組みをBizサイドも含めた事業全体に広げ、組織そのものをAIネイティブに作り替えていくことが、自分が次に向き合っていくテーマです。

おわりに

正直、まだ道半ばです。Phase 4は構想段階ですし、組織全体の最適化もこれからです。ただ、#1で「完成した成功事例ではなく、進行中の実践のリアルな姿をお伝えできれば」と書いた約束は、6回を通じて果たせたのではないかと思っています。

このシリーズでやってきたことは、1チームの小さな実践から始まり、AI OSを組織にインストールしていく取り組みへと広がりました。その先にある、組織全体がAIで動く世界の構想については、代表の田村が近日ブログで公開予定です。AIの力で組織がどう変わっていくかに興味がある方はぜひそちらも読んでみてください。

もしこのシリーズを読んで「自分のチームでもやってみたい」と思っていただけたなら、まず目の前の業務プロセスを言語化するところから始めてみてほしいと思っています。

この旅はまだ続きます。一緒に切り拓いていく仲間を探しています。

ACESでは現在、複数のエンジニアポジションで採用を行っています。本シリーズを読んでACESの開発に興味を持っていただけた方は、ぜひカジュアル面談でお話ししましょう!

ACESの採用情報はこちら↓

recruit.acesinc.co.jp

open.talentio.com

ACES、AIを全員の標準装備へ - ChatGPT Enterprise / Claude Enterprise / Cursor Enterpriseを全員に導入しました

はじめに

こんにちは、株式会社ACES の共同創業者 / ソフトウェアエンジニアの三田村です。

ACESではこのたび、ChatGPT Enterprise / Claude Enterprise / Cursor Enterprise を、職種・業務形態を問わず全員が業務で使える環境として整備しました。これまでもChatGPTは全員に付与しており、ClaudeやCursorはエンジニアを中心に配布・活用を進めてきました。今回、対象をさらに広げ、Bizメンバーを含む全職種、正社員・インターン・業務委託を含む約150名のメンバーが利用できる体制にしています。

今回の整備で重視したのは、AIを一部の人だけが使うものにしないことです。個人ごとの工夫に任せるのではなく、実際の業務の中で使える環境を会社として整えています。

全員付与

AIツールの価値は、個人の作業が速くなることに加えて、チームで使い方が共有され、職種をまたいで知見が回り、仕事の進め方そのものが変わっていくところにあります。

そのためには、希望者だけが触れられる状態よりも、全員が同じスタートラインに立てる状態の方が強いと考えています。ライセンスの有無で試行機会が分かれると、活用は局所的になりやすく、組織としての再現性も育ちにくくなります。

ACESでは、AIを個人の持ち込みに任せず、会社が整えた環境の中で活用を広げていきます。エンジニア、Bizメンバー、インターン、業務委託まで含めて共通の土台を持つことで、役割を越えた連携や知見共有も進めやすくなります。

利用環境

今回、ChatGPT / Claude / Cursor の3サービスはいずれも Enterprise 契約とし、会社管理の利用環境を整えました。活用を広げることと、安心して使える利用環境を整えることの両立を重視したためです。

こうしたサービスの導入にあたっては、社内のセキュリティ・法務観点での確認や所定の審査を行った上で、利用可否を判断しています。その上で、生成AIサービスでは、入力データがモデル学習に利用されない利用環境であることも重視しています。個人契約や設定の違いに依存せず、会社が管理する環境を整えることで、全員が同じ条件で使い始めやすくなります。

契約体系上も、固定のシート課金に加えて利用量に応じた課金を組み合わせられるものがあり、全員向けに利用環境を用意しつつ、利用状況に応じたコスト管理がしやすい形になっています。

加えて、Google Workspace上で利用可能な Gemini も含め、業務内容に応じて複数のAIツールを組み合わせて使える環境を整えています。

ルール整備

全員が使える環境とあわせて、ルールと手順も整備しました。

社内では「生成AIサービス利用ガイドライン」や「AIコーディングツール利用手順」などのマニュアルを用意し、利用環境、入力情報の扱い、判断に迷いやすいケース、相談先を整理しています。

これらのルールは、社内での検討に加えて、顧問弁護士とともに法的観点の確認を行いながら整備しています。

特に意識したのは、入力してよい情報、確認が必要な情報、入力を避ける情報を明確にすることです。たとえば、公開情報やACES自社データは、利用環境の要件を満たす範囲で活用できます。一方で、クライアントに関する情報は、契約や法務・セキュリティ上の条件を確認した上で慎重に扱う前提としています。認証情報や不要な個人情報は入力しないこととしています。

あわせて、会社が管理する環境で利用すること、判断に迷うケースは都度確認すること、生成結果は利用者自身で確認することといった前提もそろえています。こうした運用を通じて、AI活用を個人の判断に依存しない形で進めていきます。

AI駆動開発

エンジニア組織では、以前からAIを前提にした開発の進め方を進めてきました。重視しているのは、個人の作業速度を上げることだけではなく、AIを組み込んだ開発フローをチームで再現できる形にすることです。

この考え方は、先日公開した「#1|AI駆動開発の4フェーズと私たちの現在地 — AIに運転席を譲れるか」にもつながっています。そこで示しているのは、AI活用を個人の補助にとどめず、チームの開発プロセスに組み込み、さらに組織全体へ広げていくための段階です。

今回の全員付与も、こうした考え方をエンジニア組織の外へ広げていく流れの中にあります。AI活用を開発チームの中にとどめず、会社全体の業務プロセスの中に組み込んでいきます。

活用

実際に、社内の各職種で活用の広がりが見え始めています。

Bizチームでは、提案資料やサマリ資料のたたき台作成、関連情報の整理など、日々のアウトプットを進める場面でAIを使うケースが増えています。ゼロからすべてを作り始めるのではなく、最初の構成や下書きをAIに任せ、人が判断や修正に時間を使う形が少しずつ定着し始めています。

エンジニアリングでは、共通のコマンドや運用の工夫を共有しながら、PR作成やレビュー準備を含む日常の開発フローにAIを組み込む動きが進んでいます。個人の工夫にとどめず、チームで再利用できる形にしていくことを意識している点が特徴です。

また、幅広い職種に向けた実践機会づくりも始まっており、職種をまたいで知見を共有する流れが出てきています。

おわりに

株式会社ACESでは、「アルゴリズムで、社会はもっとシンプルになる」というビジョンを掲げ、テクノロジーで社会課題の解決を目指す仲間を積極的に募集しています。

ACESでは、AIを前提に開発や業務の進め方を見直し、それを価値提供につなげていく仲間を求めています。重視しているのは、AIで個人の作業を速くすることに加えて、AIを業務や開発の進め方に組み込み、その知見をチームで蓄積し、お客様への価値提供につなげていくことです。

ChatGPT / Claude / Cursor を全員が使える環境と、活用を支えるルールや運用の土台を整えた上で、実践を進めています。個人の工夫をチームの力に変えたい方、AIと一緒に仕事の進め方を磨いていきたい方は、ぜひACESの採用情報をご覧ください。

ACESの採用情報はこちら↓

recruit.acesinc.co.jp

open.talentio.com

#5|AIが書いたコードをどう本番に出すか — リリース安全基盤の設計と展望

はじめに

こんにちは、株式会社ACES でテックリードをしている福澤 (@fuku_tech) です!

本シリーズでは、AI駆動開発における人間とAIの役割分担を、自動運転になぞらえた4つのPhaseで整理しています(詳細は下図を参照)。

本記事は#3#4で整備した品質ゲートの上に、リリース安全基盤を積み上げる話のため、以下を先にお読みいただくとよりスムーズです。

tech.acesinc.co.jp

tech.acesinc.co.jp

前回の記事では、AIが自律的に実装を回し人間は要所でレビューする開発スタイルを実際にチームで運用してみた成果と摩擦を率直にお伝えしました。品質ゲート(Lint・Tests・セルフレビュー・別LLMレビュー)による予防が機能し運用開始以来AI実装起因のインシデントは0件という実績を積めた一方で、AIが品質ゲートを通過したPRを量産しても人間側のレビューが追いつかず「これ本当に出して大丈夫か?」という不安も拭えないという課題が残りました。暫定的にタスク分解やPR分割で凌いではいるものの、これは人間の介入を増やす方向の対処であり、スケールする解ではないと感じていました。

シリーズ初回で「壊れたときどう直すか」として予告した問いを、ここで回収します。「壊れないようにする」だけでは限界がある。発想を転換して「壊れても速く直せる」仕組みを作ることで、AIへの委譲範囲をさらに広げていく。この記事では、その設計と構築の現在地をお伝えします。

発想の転換: 「壊れないようにする」から「壊れても速く直せる」へ

#3#4で整備した品質ゲート(Lint・Tests・セルフレビュー・別LLMレビュー)は、コードレベルの予防策として確かに機能しています。E2Eテストなど統合レベルの検証強化も今後の投資対象ですが、本記事ではその先のレイヤー、つまりリリース後の検知・復旧の仕組みに焦点を当てます。

さらに、本番トラフィックでのみ顕在化するパフォーマンス劣化や、長時間稼働で初めて現れるメモリリークといった、コードレビューだけでは見えないリスクもあります。AIが書いたコードが機能テストを通過していても、本番環境で想定外の負荷を生むかもしれません。これは人間が書いたコードでも同じですが、AI生成コードの量が増えるほどリスクの総量も増えていきます。

ここで発想を転換しました。安全の判断基準を「人間の目」から「データとシステム」に移す。具体的には、壊れないようにすることに全力を注ぐのではなく、壊れたときに速く検知し速く戻せる仕組みを作ることで、「これ出して大丈夫か?」という不安を「なんとなく怖い」から数値に基づく判断に置き換えていきます。そうすれば、人間がコードの一行一行を見なくても、AIへの委譲範囲をさらに広げていけるはずです。

リリース安全基盤の現在地

この発想の転換を実現するために、私たちはリリース安全基盤を段階的に積み上げています。すでに運用実績のあるものから、まだ手をつけていないものまで成熟度に差があります。現在地を正直にお伝えします。

01 Progressive Delivery: Feature Flagで段階ロールアウト

Feature Flagサービス(DevCycle)は、AI活用が本格化する以前から導入済みです。自社テナントのみに先行公開し、エラーレートなどを監視しながら段階的にロールアウトしていく、いわゆるProgressive Deliveryの運用がすでに回っています。ロールアウトのステップは「自社テナントのみ → 一部顧客 → 全体」で、判断基準は「一定期間、関連する不具合が0件であること」としています。

直近の実績として、コア機能である音声解析周りの改修でこの仕組みが効きました。自社テナントのみに先行リリースしたところエラーを検知し、修正後に改めてロールアウトを進めて安全にリリースを完了しています。この事例はAI生成コードによるものではありませんが、すでに回っている運用をAI生成コードのリリースにもそのまま適用できるという確信を持てました。現在、AI生成コードのリリースにFeature Flagをどう組み込むかの検討を始めたところです。

02 Observability: アラートの信頼性確保と異常検知

監視・検知の基盤が機能するには、まずアラートが信頼できる状態でなければなりません。Sentryのアラートノイズ撲滅から着手し、ClaudeのSlack連携を使ってノイズアラート(対応不要なのに繰り返し発火するアラート)をコツコツ潰しているところです。地味ですが、ここを丁寧に整えることが安全基盤の土台になります。

その上で、SentryのTrace機能を使ったN+1クエリの検知など、新たな検知の追加を進めています。これはAI生成コード固有の話ではなく、プロダクト全体の検知能力を底上げする取り組みですが、AI駆動開発の安全基盤としてもこの基盤が効いてきます。

03 Error Triage Automation: 検知から修正PRまでの自動化

アラートの信頼性確保と並行して、検知から修正提案までを一気通貫で回すワークフローの構築を進めています。GitHub Actionsで定期的にSentryを監視し、新規エラーを検知したらIssueを自動作成します。その際にClaude APIでエラーの原因調査と修正方針の起案を行い、改善PRの生成まで自動化する設計で、最終的には人間がPRをレビューして判断します。

まだ検証段階ですが、このパイプラインが回り始めれば、エラーの検知から修正PRの作成までの時間を大幅に短縮できる見込みです。

04 SLO / Error Budget: データ駆動のリリース判断

ここまで述べた仕組みが揃ってきたとき、次に必要になるのはリリース可否の判断基準です。現在のロールアウト判断は不具合0件かどうかのオール・オア・ナッシングですが、これだけではリリース速度と安定性のバランスを柔軟にコントロールできません。そこで目指しているのが、SLO(サービスレベル目標)とエラーバジェットの導入です。たとえば可用性99.9%とSLOを設定すると、月あたり約43分のダウンタイムが許容されます。この許容される余白がエラーバジェットです。余白が十分残っていればリリース速度を上げ、減ってきたら安定化に集中する。リリース判断を感覚ではなく数字で行えるようにする仕組みです。これをAI駆動開発の文脈で設計していく段階です。

これで何が変わるのか

前回の記事で悩んでいた課題に、ここまで述べたリリース安全基盤がどう答えるのかを整理します。

まず、巨大PR問題です。PRの粒度を小さく保つ努力は引き続き重要ですが、Feature Flagによる段階ロールアウトと高速ロールバックの仕組みが整えば、仮にPRが大きくなっても致命傷にはなりません。PRの粒度だけに安全を依存しない構造を作ることが狙いです。

次に、レビューが追いつかない問題です。リリース安全基盤が整うと、レビューの焦点がコードの一行一行から、段階ロールアウトの各ステップの判断に移ります。人間の介入ポイントが減ることで、AIへの委譲範囲を広げられます。

そして、出して大丈夫かという不安です。品質ゲートを通過していて、段階ロールアウトで実際の挙動も確認できていれば、Go判断はずっとしやすくなります。さらにSLO/エラーバジェットが整えば、その判断を数字で裏付けることもできるようになります。まだこの段階には到達していませんが、目指している方向はここです。

その先に見える世界

ここまで述べたリリース安全基盤が整った先には、さらなる自動化が見えています。

1つは、Feature Flagの操作自体をAIに委ねることです。AIが段階ロールアウトの各ステップをメトリクスに基づいて自律的に判断し、異常を検知したら自動でロールバックする*1。まずは既存機能のロールアウト拡大のような定型的な判断から段階的に自動化し、不確実性の高い判断は人間が行うという線引きで、自律性の範囲を慎重に広げていく方針です。

もう1つは、AIが生ログに瞬時にアクセスできる環境の整備です。SentryだけでなくCloudWatchやGrafanaなど、複数の監視基盤のログをAIがリアルタイムに確認できるようになれば、sandbox環境でのリリース前検証でも本番環境でのリリース後監視でも、AIが自律的にフィードバックサイクルを回せるようになります。

この2つが揃うと、AIが自分でコードを書き、自分で検証し、自分でリリースし、問題があれば自分で直すというループが成立します。人間に残るのは最終承認と、ループ自体の設計・改善です。

おわりに

シリーズ初回からここまで振り返ると、一つのストーリーが見えてきます。Phase 1→2で何をAIに任せるかを整理し、Phase 2→3でどうすれば安全に任せ切れるかを設計し、そしてPhase 3→4で壊れたときどう直すかに向き合っています。各Phaseで手放してきたのは、全部自分で書く、自分がやった方が早い、壊れないようにする、という、それぞれの段階で当たり前だった前提です。

そして今、人間がコードを見なければ安全は担保できないという前提を手放そうとしています。この前提が手放せたとき、AIが長時間自律的に稼働するPhase 4への道が開けます。データとシステムに安全の判断を委ねられれば、AIへの委譲範囲はさらに広がります。そのための基盤づくりはまだ始まったばかりで、正直まだまだ足りないことだらけです。ただ、この記事で語ったFeature Flagやアラート整備は、AI時代に突然必要になったものではなく、ずっと大事だったものがAI時代にさらに重要になっただけです。まっとうなエンジニアリングプラクティスこそが、最大の武器だと考えています。

ここまで語ってきたのは、1つのチームの実践です。次回の #6|1チームの実践を組織の力に変えるでは、この実践を組織全体に横展開するために何が必要かを語ります。

tech.acesinc.co.jp

ACESでは現在、複数のエンジニアポジションで採用を行っています。本シリーズを読んでACESの開発に興味を持っていただけた方は、ぜひカジュアル面談でお話ししましょう!

ACESの採用情報はこちら↓

recruit.acesinc.co.jp

open.talentio.com

*1:AI時代のFeature Flagの未来像についてはこちらの考察が示唆に富んでいます。

#4|Pilot-Tower開発を回してみた — 成果と摩擦のリアル

はじめに

こんにちは、株式会社ACES でテックリードをしている福澤 (@fuku_tech) です!

本シリーズでは、AI駆動開発における人間とAIの役割分担を、自動運転になぞらえた4つのPhaseで整理しています(詳細は下図を参照)。前回の記事(以降、「#3」と呼称)では、AIに運転席を譲るPhase 3の設計思想として「Pilot-Tower開発(P&T開発)」を紹介しました。plan.md をSSoTとしたループ構造、AIが判断に迷ったときだけ停止するDecision Required(DR)、そしてAIに任せない領域を定めるガードレール。この3つの仕掛けで自走と統制を両立する、という話でした。

思想については前回語りました。本記事では plan.md、DR、ガードレールなど以下の#3の記事で導入した概念を前提としているため、先にお読みいただくとよりスムーズです。では実際にこの思想で開発を回してみてどうだったか。今回は、P&T開発の実践の手触りと、そこで起きたつまずきを語ります。

tech.acesinc.co.jp

/plan-execute の実際: 1本のPRができるまで

/plan-execute は、plan.md を入力にAIが自律的に実装→品質ゲート(Lint・Tests)→レビュー→PR作成の4フェーズを回すコマンドです。

Phase 1: 実装
  └→ plan.mdに沿って実装
  └→ 適宜worklog.mdに作業のサマリーを記録
  └→ DRが必要なら停止して開発者にエスカレーション(暴走防止)

Phase 2: 品質ゲート
  └→ Lint / Format 自動実行
  └→ テスト自動実行
  └→ 失敗したらまずは自己修正
  └→ 自己修正では解消が難しい場合は Codex CLI 等を使って別の LLM に修正を依頼
  └→ エラーがなくなるまで or 上限回数に到達するまで繰り返す

Phase 3: レビュー
  └→ セルフレビュー
  └→ Codex CLI 等を使って別の LLM にレビューを依頼
  └→ 指摘があれば自動修正
  └→ 修正すべき指摘項目がなくなるまで or 上限回数に到達するまで繰り返す

Phase 4: PR作成
  └→ PRタイトル・説明を自動生成

「張り付き」から「離れられる」へ

シリーズ第二回目の記事(以降、「#2」と呼称)で解説したPhase 2の運用では、コマンド実行→出力レビュー→次のコマンド選択の繰り返しで、AIが動いている間ずっと人間が張り付いている必要がありました。AIの処理待ち時間そのものは短くても、次に何をさせるかを判断して指示を出す工程が常に発生していました。

tech.acesinc.co.jp

Phase 3では、この体験が大きく変わりました。/plan-execute に投げたら30分から2時間は離れられます。会議の裏で仮実装や本実装が進み、戻ってきたらDRに答えるかPRを確認するだけです。/plan-execute コマンドの内部にworklogの記録、DRでの停止、ガードレール領域での報告といった複雑さが隠蔽されたことで、エンジニアの認知負荷が下がりました。「planを作って育てて /plan-execute を実行する」というシンプルな運用に収束しています。

ただし、これは#2で整えたガイドライン・ガードレールという土台があってこそ回っている点は強調しておきたいと思います。

実際の事例

具体的なイメージを持ってもらうために、実際のタスクをベースに一連の流れを追ってみます。題材は、複数のSpeech(文字起こし)テキストを一括更新するAPIの実装です。以下はバックエンド側の plan.md を例に、一連の流れを追っていきます。

最初に人間がやることは、plan.md の「種」を書くことです。この段階ではGoalとざっくりした制約だけで構いません。

## Goal
複数のSpeech(文字起こし)テキストを一括更新するAPIを実装し、
フロントエンドのキーワード一括置換機能を実現する。

## Constraints
- サーバーサイドの実装のみ(フロントエンドは対象外)
- 既存のSpeech単体更新APIには変更を加えない

## Definition of Done
- 一括更新APIが正常に動作し、テストが通ること

この種を /plan-refine でAIと対話しながら育てます。CursorのPlanモードやClaude CodeのPlan機能を使ったことがある方にはおなじみの体験ですが、ポイントはその対話結果が plan.md というファイルに永続化され、後続の /plan-execute が参照するSSoTになることです。以下は /plan-refine を経て育った plan.md の抜粋です(社内固有の情報はマスキングしています)。

## Goal
複数のSpeech(文字起こし)テキストを一括更新するAPIを実装し、
フロントエンドのキーワード一括置換機能を実現する。

## Constraints
- サーバーサイドの実装のみ(フロントエンドは対象外)
- 既存のSpeech単体更新APIには変更を加えない
- 既存のbulk_executeパターンを踏襲
- All-or-Nothing(部分成功なし): 不正が1件でも含まれる場合、
  1件も更新せず4xxを返す

## Definition of Done
- 一括更新サービスが実装されている
- 空文字や最大文字数超過のバリデーションが実装されている
- 存在しないIDが含まれる場合は404を返す
- 他テナントのリソースが指定された場合はテナント隠蔽のため404を返す
- All-or-Nothing: 上記いずれかに該当するIDが1件でも含まれる場合、
  更新を1件も行わない
- DB更新と検索インデックス更新・キャッシュ削除が整合する順序で
  実行される
- 単体テストカバレッジ100%

なお、今回のように実装の方向性が見えている場合は /plan-refine の対話だけで十分ですが、要件レベルでも技術的にもふわっとしていて人間にもイメージがついていない場合は、/plan-spike(仮実装による技術検証)でカジュアルに探索的な実装をさせてみることで、制約やDoDをクリアにしていけます。

/plan-execute を実行すると、AIが自走し、実装→品質ゲート(Lint、Tests)→セルフレビュー→PR作成の一連が人間の介在なしに回ります。途中でAIが判断に迷った場合、DRを発行して停止します。このタスクでは2件のDRが発行されました。

### DR-001: バルク更新の上限件数

- Priority: P0
- Context: 一回のバルクアップデートで更新できる件数の上限
- Options:
  - A: 100件(既存のバルク操作と同じ)
  - B: 1000件(長時間会議に対応)
- Recommendation: B
- Decision: B(1000件)

### DR-002: エンドポイント設計

- Priority: P1
- Context: 新APIを既存の汎用バルク実行エンドポイントに統合するか、
  独立したエンドポイントにするか
- Options:
  - A: 既存のバルク実行エンドポイントに新オペレーションを追加
  - B: 独立した専用エンドポイントを新設
- Recommendation: B
- Decision: A(既存エンドポイントに統合)

DR-001ではAIの推奨(B: 1000件)をそのまま採用し、DR-002ではAIの推奨(B: 独立エンドポイント)とは異なるA(既存エンドポイントに統合)を選択しました。人間はDRを読んでA/Bのどちらかを書き込むだけです。選択肢と推奨案がすでに提示されているので、背景を一から調べる必要がなく、判断のコストが大幅に下がります。DR-002でAIの推奨を覆したのは、既存のバルク処理APIの実装パターンとの一貫性を優先したためです。こうしたプロダクト全体のコンテキストに基づく判断は人間が担う方が適切で、DRの仕組みがあるからこそ判断ポイントが自然に浮上し、見落とされずに済みます。

DRに答えるとAIが再走し、残りの実装を完了させます。

チームで見えてきた変化

この一括置換機能(APIと画面)の開発 (設計からmainブランチへのマージまでの全工程) は、従来であれば2〜3日と見積もっていた規模感でした。P&T開発で回した結果、人間の実稼働時間は2〜3時間で完了しました。これは私個人の体感だけではなく、API認証のClient Credentials対応など他のタスクでも同様の短縮効果がチーム内で報告されています。

AIに自走させている間に別のタスクのplanを作れるようになったことで、2〜3プロジェクトを同時並行で進められるようになったというメンバーもいます。Phase 2では人間がAIに張り付いていたため、基本的に1タスクずつの直列作業でした。Phase 3では人間の役割がDRへの判断回答に絞られたことで、並列度が上がりました。

設計判断が難しい箇所はDRでその都度判断しながら進められるため、後からAIが書いたコードを大きく手戻りさせるといったことがなくなったという実感もあります。#3で「DRのログ蓄積によってAIの自律判断範囲が拡大し、人間の介入がさらに減っていく」と書きましたが、実際にその兆候は出始めています。似たような設計判断が過去のdecision-logに蓄積されることで、以前はDRに上がっていた判断がAI側で自律的に処理されるケースが増えてきました。

エンジニアだけでなく、非エンジニアによる実践事例も出てきています。例えば、PdMがP&T開発を用いてスマホアプリの不具合修正を自ら完結させたケースです。これまでエンジニアの工数を待たなければならなかった微細な修正が、PdMの手によって迅速に解消されるようになりました。この事例における具体的な実装ロジックはほとんどAIの生成結果そのままであり、コードレビューこそエンジニアが最終確認として実施したものの、品質担保の軸は実機での動作確認に置かれていました。P&T開発の仕組みが、個人のコード執筆能力とは別のレイヤーで品質を担保しているからこそ成り立っている、象徴的な事例だと考えています。

つまずきとその乗り越え方

成果だけを並べると順風満帆に聞こえるかもしれませんが、もちろんつまずきもありました。ここでは、実際に起きた失敗エピソードとその対処を率直に共有します。

git reset --hard で数時間分の作業が消えた

初期に起きた分かりやすい失敗です。AIが自走中に git reset --hard を実行し、数時間分の作業が消えました。実際には git reflog で復元できたので事なきを得ましたが、破壊的な操作を勝手に判断して実行されると、心理的にAIに任せにくくなります。

対処はシンプルで、 settings.json に禁止操作として明記しました。ルールに書けば再発しない。AIのやらかしは仕組みで潰す、という原則を最初に教えてくれたエピソードです。

コンテキスト蓄積による精度低下

AIが長時間稼働すると、コンテキストウィンドウに情報が積み上がりすぎて判断精度が落ちるという課題もあります。後半のタスクでガードレール領域に不用意に手を出しそうになったり、前半で合意した方針と矛盾する実装をしたりすることがありました。

現状では、セッションを意図的に切り替えて plan.md で状態を復元する運用と、SubAgentsの活用で緩和しています。plan.md がSSoTとして機能しているからこそ、セッションを切っても文脈を失わずに再開できます。ただ、完全な解はまだ見つかっていません。

「手放す怖さ」をどう越えたか

技術的なつまずき以上に大きかったのは、心理的な壁です。「AIに任せて大丈夫なのか」「本番に出して問題ないのか」という不安は、仕組みの説明だけでは払拭できませんでした。

この不安を越えるために、モブプログラミング会(90分×4回)を実施しました。チームメンバーが実際に一緒にP&T開発を動かす場を設け、DRできちんと停止すること、ガードレール領域に触ったらAIから報告が来ること、Lint→Tests→セルフレビュー→別LLMによるレビューを通過した上でPRが作られること、この一連を目の当たりにしてもらいました。百聞は一見にしかずという諺の通り、品質ゲートが実際に機能する様子を確認できたことで、不安が払拭され大きな手応えを得ることができました。

ここ数ヶ月の運用で、AIの実装に起因するインシデントは0件です。#2で整えた土台(ガイドライン・品質ガードレール・AI向けドキュメント)が効いている結果だと考えています。皮肉なことに、この間にヒヤリハット*1が起きたのはむしろ人間が書いたコードの方でした。

今いちばんの悩み: 巨大PRとレビューの限界

一方で、まだ乗り越えられていない課題もあります。AIが自走してくれるのはいいのですが、1つのPRに大量の変更を詰め込んでくるケースが頻発します。品質ゲート(lint・テスト・セルフレビュー・別LLMレビュー)は通っているものの、変更差分の大きなPRが量産されると、人間側のレビューが追いつきません。「これ本当に出して大丈夫か?」という不安が残り続けます。

暫定策としては、タスクを設計段階で小さく分解してから /plan-execute に渡すことでPR粒度を制御したり、PRを意味のある単位に分割するスラッシュコマンドで事後的に対処したりしています。ただ、これらはいずれも人間の介在を増やす方向の対処です。#1で「人間が運転席に座り続ける限り、AIの稼働時間は人間の稼働時間に縛られる」と書きましたが、タスク分解やレビューについても同じ構造が当てはまります。人間の介入を増やすことでしか品質を担保できない状態では、ボトルネックが別の場所に移るだけで、AIの自律稼働時間を最大化するという当初の目的はスケールしません。

この問題は、タスク分解自体をAIに動的にやらせることで緩和できる可能性もあります。Claude CodeのTask Systemのように、AIが実装中にサブタスクを切り出して並列処理する仕組みを応用すれば、結果的にPRの粒度も小さくなることが期待できます。現在試験的に導入を始めていますが、本格運用はこれからです。

さらに言えば、そもそもこの問題自体が一過性のものかもしれません。GitHub元CEOのThomas Dohmke氏が新会社Entireを立ち上げた際にXで発信していたように、コードを理解してレビューするという行為自体が死にゆくパラダイムだとすれば、意図と成果を検証するワークフローへの移行が進み、人間がコードを逐一レビューする前提自体が変わりうる。そうなれば、PR粒度の問題も構造ごと解消される可能性もあります。

とはいえ、その日まで待つわけにはいきません。本命は、人間の目視に頼らなくても安全にリリースできる仕組みです。「壊れないようにする」だけではなく「壊れても速く直せる」リリース安全網が整えば、レビューで事前に品質を担保しなければならないという不安を感じにくくなる効果があると考えています。次回の#5|AIが書いたコードをどう本番に出すかでは、そのアプローチについて語ります。

tech.acesinc.co.jp

おわりに

P&T開発を数ヶ月回してみて、planを作って /plan-execute を投げるというシンプルな運用に収束し、人間はAIの自走中に別のタスクを進められるようになりました。一方で、AIの暴走やコンテキスト蓄積、巨大PRのレビュー負荷といったつまずきも経験しました。ルールに書けば再発しないものは仕組みで潰し、構造的に解決できないものは投資先を見極めて手を打つ。そして、その仕組みが本当に機能することをチームで一緒に体験して初めて、次のステップに進めます。その積み重ねが、小さなチームで大きなことをやる力になると考えています。

ACESでは現在、複数のエンジニアポジションで採用を行っています。本シリーズを読んでACESの開発に興味を持っていただけた方は、ぜひカジュアル面談でお話ししましょう!

ACESの採用情報はこちら↓

recruit.acesinc.co.jp

open.talentio.com

*1:デプロイ直後に検知し、影響ユーザー0人で即revert

#3|AIが自走し、人間は管制する — Pilot-Tower開発の設計思想

はじめに

こんにちは、株式会社ACES でテックリードをしている福澤 (@fuku_tech) です!

本シリーズでは、AI駆動開発における人間とAIの役割分担を、自動運転になぞらえた4つのPhaseで整理しています(詳細は下図を参照)。前回の記事では、人間が運転席に座りつつAIに作業実行を任せるPhase 2として、開発プロセスをサブプロセス単位に分解し、スラッシュコマンドとしてAIに割り当てる実践を解説しました。コマンド単位ではAIが精度よく動くようになった一方で、コマンド間をつなぐ「次に何をすべきか」の判断は常に人間が担っている、という構造的な限界が見えてきました。

今回は、この「組み合わせて回す」役割自体をAIに委ねるPhase 3の設計思想について解説します。私たちが「Pilot-Tower開発」と名付けたこのアプローチが、どういう問いから出発し、どういう思想に至り、どういう仕組みに結実したのか。設計の思想と仕組みに焦点を当てます。

Phase 3とは何か: 「管制塔モデル」への転換

Phase 2の限界の再確認

Phase 2では、人間が運転席に座りながら「コマンド実行→出力レビュー→次のコマンド選択→実行」のループを回していました。各コマンドの実行精度はAIのおかげで十分に上がりましたが、このループ自体は人間が回している以上、AIの稼働時間は人間の稼働時間に縛られます。会議中も、夜間も、AIは人間の次の指示を待っている状態です。

Phase 3の定義

Phase 3は、運転席自体をAIに譲るフェーズです。AIが自ら計画を読み、実装し、検証し、次のステップを判断して進む。人間は管制塔として、AIが「自分では判断できない」と停止したポイントにだけ介在します。

観点 Phase 2 Phase 3
運転席 人間 AI
人間の役割 コマンド選択→実行→レビュー→次のコマンド選択... 要所での判断のみ

Pilot-Tower開発というメタファー

この役割分担を、私たちは航空管制に見立てて「Pilot-Tower開発」(通称P&T開発)と呼んでいます。AIがPilot(操縦)、人間がTower(管制塔)です。

命名には意図があります。後述するHarness EngineeringやSDD(仕様駆動開発)といった考え方が最近注目されていますが、それらはコードベースやインフラの環境設計、あるいは仕様書を起点としたワークフローに主眼を置いています。私たちがPilot-Tower開発と名付けたのは、開発プロセスそのものの設計に焦点を当てているためで、既存の概念とはレイヤーが異なると考えたからです。この違いについては後ほど詳しく触れます。

核心問題: AIに自走させつつ逸脱を防ぐ

Phase 3の設計で向き合うべきトレードオフは明快です。AIに自走させるほど人間の手は空くが、逸脱のリスクも高まる。逸脱を防ごうとチェックポイントを増やせば、結局Phase 2に逆戻りする。このトレードオフをどう解くかが、今回のテーマです。

思想: 上流と下流の境界を溶かす

プロセスの構造そのものが問題だった

#2|スラッシュコマンドで回す開発 — プロセスを分解してAIに割り当てるでの結論は「プロセスを細分化してAIに渡せば精度は上がる」でした。これは正しいのですが、個々のコマンドの精度が上がっても、人間が毎回つなぎ直すループが残っている限り、スループットは人間の処理速度に律速されます。解くべきは個々の精度ではなく、プロセスの構造そのものではないかと考えました。

なぜ「仕様を先に固める」だけでは足りないのか

従来のソフトウェア開発は、要件定義→設計→実装という直列プロセスが基本です。上流が詰まると全体が止まる。最近は「vibe codingではなく、まず仕様を書こう」という方向性が注目されていますし、その方向性自体は正しいと考えています。

ただ、私たちがPhase 3で解きたかった問題は、「AIの出力精度を上げる」ことのさらに先にありました。出力精度の向上はもちろん重要ですが、私たちの問題意識は、人間の関与を最小化し、AIの自律稼働時間を最大化することにあります。仕様の精度がいくら上がっても、人間がゲートとして介在し続ける構造のままでは、AIの稼働時間は人間の稼働時間に縛られたままです。この構造自体を変えたいと考えました。

【直列プロセス】
要件定義 → 設計 → 実装 // 上流が詰まると全体が止まる

要件定義・設計・実装の境界を溶かす

この問題意識から至った思想の転換は、要件定義・設計・実装の境界を溶かすというものです。

「どういう要求を満たし、どんなユーザー体験を提供したいか」(What/Why)さえ明確であれば、How(どう実装するか)はAIが探索的に実装しながら、影響範囲やリスクを洗い出せます。要件定義の完了を待ってから設計・実装に入るのではなく、探索ループの中で要件の理解・設計の具体化・仮実装による検証が相互にフィードバックし合いながら深まっていくイメージです。仕様は完成品ではなく、探索を通じて育てていく指針として扱います。

【同時に回すプロセス】
      What/Why を定める
            │
      ┌─────┼─────┐
      ↓     ↓     ↓
  要件の   設計の   仮実装で
  深掘り   具体化   検証
      └─────┼─────┘
            ↓
     plan.md に知見を蓄積
            │
        本実装へ

ただし、探索と本実装は明確に分けています。探索はあくまで捨てる前提の仮実装(plan-spike)であり、コードは捨てても、得られた知見は plan.md に蓄積されます。

3つのモードで不確実性を段階的に減らす

具体的には、以下の3つのモードを使い分けて不確実性を段階的に減らしていきます。

モード 目的 成果物
plan-refine 対話で計画を詳細化 plan.md の更新
plan-spike 仮実装で技術検証 知見(コードは捨てる)
plan-execute 本実装 プロダクションコード + PR

plan-refineは、AIと対話しながら plan.md の不明瞭な点や矛盾を潰していくモードです。plan-spikeは、実際にコードを書いて技術的な不確実性を検証するモードで、コードは捨てる前提ですが学びは plan.md に残します。この2つのモードで十分に不確実性が減ったら、plan-executeで本実装に移行します。

移行の目安として、セッションを切り替えて別のLLMに「この plan.md だけで迷いなく実装できるか」をレビューさせるという方法を使っています。実装文脈を持たない別のLLMが問題なく理解できるなら、plan.md は本実装に十分な精度に達していると判断できます。

仮実装が効いた実例

直近で取り組んでいる認可基盤の大幅アップデートで、plan-spikeの効果を実感しました。このタスクでは、Cerbosという新規ライブラリの導入、既存コードベースの整理、データ移行の安全性確保、機能的な後方互換性の維持と、不確実性とリスクが多く重なっていました。

初手でplan-spikeを実施したことで、いくつかの重要な知見が得られました。実装イメージが具体的になったこと、影響範囲の洗い出しができたこと、そして何より、本格的な指示を与えていない状態でAIがどういう設計・実装をしてしまうかを事前に把握できたことが大きかったです。この「AIの癖」を事前に知れることで、plan.md の制約やDoDをより的確に書けるようになります。

一方で、plan-refineの対話だけで十分にイメージが掴める場合もあります。実装者がAIからの質問に一問一答で回答していくだけで計画が固まるようなケースでは、仮実装を挟む必要はありません。見えていないものが多いタスクほど、plan-spikeの価値は高くなります。

各タスクにおけるSSoTとしての plan.md

この思想が結実したのが、各タスクにおけるSSoT(信頼できる唯一の情報源)として機能する plan.md です。ここで重要なのは、plan.md は人間が読み書きする仕様書ではないという点です。AIが読み、AIが更新し、AIがそれに基づいて自律的に判断するためのドキュメントです。人間はGoalやConstraintsの大枠を与えますが、探索ループの中で plan.md が詳細化されていく過程を細かくレビューするわけではありません。大事なポイントだけ確認し、問題なければ実装を進めてもらうという運用です。

plan.md には、Goal(何を達成するか)、Constraints(やらないこと・守るべきルール)、DoD(完了条件)を記載します。最初は「種」の状態で構いません。探索ループを通じて育てていけばよいからです。

## Goal
<!-- このタスクで実現すること。1-2行で簡潔に -->

## Constraints
<!-- やらないこと・守るべきルール -->

## Definition of Done
<!-- 完了とみなす条件。検証可能な形で -->

plan.md は静的な仕様書ではなく、開発が進むにつれて常に更新される「生きたドキュメント」です。AIは plan.md を読むことで「何をすべきか」「何をしてはならないか」「いつ完了とみなすか」を自律的に判断でき、人間に確認する回数を極限まで減らせます。

つまり、人間がやることの起点は plan.md の種を与えることであり、Goal(何を達成するか)、Constraints(やらないこと)、DoD(完了条件)を定めることです。最初からすべてを詰める必要はなく、ラフな種から始めて探索ループで育てていけるのがこの設計の強みです。ただし、AIに自走させるには「次に何をすべきかをどう判断するか」「判断に迷ったらどうするか」「踏み込んではいけない領域をどう守るか」という仕組みが要ります。次に紹介する3つの仕掛けが、これらを解決します。

自走と統制を両立する3つの仕掛け

思想だけでは仕組みにならないので、Pilot-Tower開発では3つの仕掛けで自走と統制を両立させています。

仕掛け1: ループ構造

Phase 2では人間がスラッシュコマンドの連鎖を手動で回していましたが、Phase 3ではこのループ自体をAIが回します。

AIは plan.md を読んで実装を進め、作業ログを worklog.md に記録し、判断が必要な事項をDR(Decision Required、後述)として抽出し、plan.md を更新する。このサイクルを人間の介入なしに回し続けます。

仕掛け2: Decision Required(DR)

AIが自走中に「自分では判断できない」と認識した場合、DRを発行して停止します。DRには設計原則があります。

まず、DRはブロッカーに限定します。進行を止める判断のみをDR化し、些末な確認事項でAIを止めません。次に、A/B形式で選択肢と推奨案を提示します。人間は背景を読み込んで判断を組み立てる必要はなく、選択肢の中から選ぶだけです。

### DR-001: 移行の進め方(一括 vs 段階的)

- Priority: P1
- Context: 約145個の関連クラスが存在し、約53個が未移行...
- Options:
  - A: **一括移行** - 未移行の関連クラスを一度に移行
  - B: **段階的移行** - ドメインごとに分けて順次移行
- Recommendation: B(段階的移行)
- Reason: PRが巨大になりレビューが困難、問題発生時の影響範囲を限定できる...
- Decision: <!-- ここに A or B を記入するだけ -->

実際の運用では、1つのタスクで発生するDRは多くても3〜5個程度です。しかもDRへの回答はdecision-logとして蓄積され、AIが過去の判断パターンを参照できるようになるため、似たような判断は今後DRに上がらなくなっていく方向に進みつつあります。

運用イメージとしては、AIが夜間や会議中に自走し、判断が必要な箇所でDRを出して停止する。人間は翌朝まとめてDRに回答すると、AIが再走し始めます。いわば「AIとの朝会」のようなリズムです。

仕掛け3: ガードレール

3つ目の仕掛けは、AIに任せない領域を事前に定義するガードレールです。認証・認可、課金・決済、セキュリティ・プライバシー、コアビジネスロジック、不可逆操作、外部公開APIの破壊的変更といった領域は、AIが触れた場合に自動的にDRが発生し、必ず人間がレビューする設計になっています。

ポイントは「何を任せるか」ではなく「何を任せないか」を定めていることです。任せない領域さえ明確にすれば、それ以外はすべてAIに委ねられます。#2では、人間が必ずレビューする領域の線引きとしてガードレールに触れましたが、Phase 3ではこれをAIの自走中に自動的にDRを発生させる仕組みとして機能させています。なお、ガードレールの具体的な内容はプロダクトの特性によって変わります。私たちのプロダクトでは会議データという機密性の高い情報を扱うため上記の領域を定めていますが、別のプロダクトであれば異なるラインになるはずです。

3つの仕掛けが「自己改善するシステム」を成す

これら3つの仕掛けは、独立した機能ではなく、互いに連動して使うほど賢くなるシステムを成しています。

DRのログ蓄積によってAIの自律判断範囲が拡大し、人間の介入がさらに減っていきます。worklogの蓄積によってよく詰まるパターンが可視化され、ガイドラインやスキルの追加・改善につなげられます。この自己改善のループが回り続ける限り、Phase 3は時間とともに成熟していく設計になっています。実際、まだ数ヶ月の運用ですが、開発がどんどん安定して回るようになってきている実感があります。

加えて、この仕組みは「失敗を許容する」設計でもあります。緊急度の高いタスクでは人間の介在を増やしてしっかりレビューしますが、時間的な余裕があるタスクは、あえてAIに自走させて失敗パターンを蓄積する「成長タスク」として捉えることもあります。上手くいかなかったケースはフィードバックとして残し、次のタスクに活かす。このサイクルを回すことで、システム全体が育っていきます。

業界の潮流と私たちのアプローチ

近いアプローチとの関係

最近、AIを前提とした開発の進め方にいくつかの方向性が出てきています。ここでは、私たちのPilot-Tower開発と関係の深い2つのアプローチを取り上げ、それぞれの位置づけを整理します。

2026年2月、OpenAIが「Harness Engineering」*1というアプローチを発表しました。3人のエンジニアがCodexエージェントを使い、人間が一切コードを手書きしないという制約のもとで約100万行のプロダクトを構築した実践報告です。リンター、構造テスト、CI、Observabilityといった環境を整えることで、AIが自律的に動ける「ハーネス(馬具、制御装置)」を構築するという考え方です。

また、SDD(仕様駆動開発)*2は、KiroやGitHub Spec Kit等のツールとともに広まりつつあるアプローチで、仕様書の品質を上げることでAIの出力精度を向上させるワークフローを体系化しています。

私たちのPilot-Tower開発を含め、これらのアプローチは「AIに自律的に動いてもらうために何を整えるか」という同じ問いに対する異なるアプローチだと考えています。

比較軸 Harness Engineering SDD(仕様駆動開発) Pilot-Tower開発
設計のゴール AIが正しく動ける環境を作る AIの出力精度を仕様の品質で上げる 人間の関与を最小化しAIの自律稼働時間を最大化する
主な焦点 コードベース・インフラの環境設計 仕様書を起点としたワークフロー 開発プロセスの設計
仕様の位置づけ 仕様書は明示的には扱わない(環境・ツールで制御) 人間が策定しAIに渡す起点ドキュメント AIが自律的に更新し続ける「生きたドキュメント」(plan.md
整えるもの リンター、構造テスト、CI、Observability等 要件定義書、設計書、タスクリスト等 plan.md、DR、 worklog.md、ガードレール等
人間の介在 環境設計とPRレビュー 仕様策定と承認ゲート DRへの判断回答

これらは対立するアプローチではなく、レイヤーが異なる補完関係にあると考えています。AIが自律的に動ける環境を整えること(Harness Engineering)、AIに渡す仕様を体系化すること(SDD)、AIが自律的に動くプロセスを設計すること(Pilot-Tower開発)は、それぞれ異なるレイヤーで同じ方向を向いています。私たちはプロセス設計のレイヤーからこの問いにアプローチしています。

なお、これらのアプローチを正確に比較するには、それぞれを本格的に実践してみる必要があります。上の整理はあくまで公開情報に基づく私の解釈であり、実際の運用上の差異はもっと複雑だろうと思います。

次回予告

思想と設計の話はここまでです。ではこの設計思想で実際に開発を回してみてどうだったか。DRのリアルな運用、想定と異なったポイント、そして成熟に伴うチームの変化について、次回の #4|P&T開発を回してみた — 成果と摩擦のリアル で解説します。

tech.acesinc.co.jp

おわりに

Phase 3の設計を通じて一貫しているのは、「AIに任せること」と「放任すること」は違うという認識です。plan.md で方向を定め、DRで判断を止め、ガードレールで領域を守る。この3層があるから安心して任せられますし、使い続けるほどシステム全体が成熟していきます。

この設計は、小規模チームで大きなことをやるために、必然的にたどり着いたものでもあります。人間の稼働時間に縛られない開発スループットを実現することが、私たちにとってはAI駆動開発の核心です。

正直なところ、この設計が理想通りに回るかどうかは、まだ日々検証中です。次回は、実際にこの設計で開発を回した中で見えてきた成果と摩擦を率直にお伝えします。

ACESでは現在、複数のエンジニアポジションで採用を行っています。本シリーズを読んでACESの開発に興味を持っていただけた方は、ぜひカジュアル面談でお話ししましょう!

ACESの採用情報はこちら↓

recruit.acesinc.co.jp

open.talentio.com

*1:https://openai.com/index/harness-engineering/

*2:SDD(Spec-Driven Development / 仕様駆動開発)について、私たち自身は実践していないため、本記事では公開情報に基づく概念的な位置づけの整理にとどめています。

#2|スラッシュコマンドで回す開発 — プロセスを分解してAIに割り当てる

はじめに

こんにちは、株式会社ACES でテックリードをしている福澤 (@fuku_tech) です!

前回の記事では、AI駆動開発の4フェーズモデルを紹介し、「人間が運転席に座り続ける限り、AIの稼働時間は人間に縛られる」という構造的な課題を提示しました。

tech.acesinc.co.jp

この構造を変えるにはAIに運転席を譲る必要がありますが、それには人間のマインドセットの転換も不可欠であり、一朝一夕に実現できるものではありません。AIが自律的に動くためには、まず人間とAIの役割分担を整理しておく必要があります。つまり、「何をAIに任せ、どう動かすか」を事前に決めておくことが求められるのです。

今回はその役割分担の設計の話です。鍵になるのは、開発プロセスを細かく分解して、AIが実行できる単位に落とし込むことです。「プロセスの細分化」と「スラッシュコマンドへのマッピング」という2つの軸で、私たちがPhase 2をどう組み立てたかを解説します。

Phase 2のリキャップ

Phase 2(Hybrid Co-Driving)は、人間が運転席に座り、AIに実行を任せる分業モデルです。「何をするか(What)」と「出力の品質判断(Review)」は人間が担い、「どうやるか(How)」はAIに任せます。

この分業を成り立たせるために導入したのが「スラッシュコマンド」です。人間がこれまで手作業でやっていた繰り返し作業をコマンドとして定義し、AIに実行させます。たとえば「ブランチを切る」「コードレビューをする」「PRを作る」といった作業を、 /branch-create /code-review /pr-create のようなコマンドに対応させます。

人間はコマンドを選んで実行し、出力をレビューして次のコマンドを選ぶ。この繰り返しでPhase 2の開発フローが回ります。

プロセスを分解して、スラッシュコマンドを割り当てる

なぜサブプロセス単位まで分解するのか

Phase 2の核心は、業務プロセスを細分化し、各サブプロセスにスラッシュコマンドを対応させることです。(以降、スラッシュコマンドは単に「コマンド」と呼称します。)

「要件定義して」「設計して」のような大きな粒度でAIに投げても、期待通りの精度は出にくいと感じています。曖昧な指示はAIの出力を不安定にし、人間のレビューコストをかえって増やしてしまいます。サブプロセス単位まで分解して初めて「ここは人間が判断すべき」「ここはAIに任せられる」という線引きが明確になります。

実際に開発プロセスを分解すると、次のようなイメージになります。

なお、この考え方は開発に閉じたものではなく、汎用的に利用できます。業務プロセスを理解する→細分化する→AIに任せる領域を選定する→コマンド化(エージェント化)するという流れは、マーケティングやCS、リサーチなど他の領域にも横展開できます。この点は、2026/03/25公開予定の#6「1チームの実践を、組織の力に変える」で改めて取り上げます。

設計原則: 単一責任とUNIX哲学

コマンドを設計するうえで最も重要な原則は、「1つのコマンドに1つの責務だけを持たせる」ことです。小さなコマンドを組み合わせて大きな作業を実現するという、UNIX哲学に通じるパイプライン的な発想で設計します。

この原則を守らないと何が起きるか。複数の責務を1つのコマンドに詰め込むと、Context Confusion(コンテキストの混乱)やContext Rot(コンテキストの劣化)が発生し、後半の工程がスキップされたり、仕様と異なるコードが生成されたりと、品質が不安定になります。しかもどの指示がボトルネックなのか特定も困難です。責務ごとにコマンドを分割することで、この問題は解消されます。サイバーエージェント社のテックブログ*1でも同様の知見が報告されています。

具体的な手順

コマンドを整備するための手順は、以下のように整理できます。

  1. 既存の開発フローを棚卸しし、定型的に発生する作業を特定する
  2. 各作業を「入力→処理→出力」の形に分解する
  3. AIに実行させるコマンドとして定義する
  4. コマンドの精度を左右するガイドラインやルールを整備する

特に4のガイドライン整備は見落とされがちですが、コマンドの出力品質を安定させるうえで欠かせません。コーディングルール、命名規則、アーキテクチャの方針といったドキュメントが、AIが正確に動くための前提条件になります。私たちが具体的に何を整備したかは、後述の「なぜワークしたか」セクションで詳しく解説します。

コマンドの実例

私たちACES Meet開発チームでは、一例として以下のようなコマンドを運用しています。

コマンド 責務
/branch-create 実装内容に基づいて新規ブランチを自動作成
/api-build 対話的にAPIを実装
/code-scan 変更差分に対するクイックレビュー
/code-review 各レイヤーに対する詳細なセルフレビュー
/code-refactor レビュー指摘に基づくクイックフィックス
/commit 意味のある変更単位でのコミット自動生成
/pr-create PRタイトル・説明の自動生成とプッシュ
/pr-comment PR上のポイント箇所にセルフコメントを付与

これらを表の上から順に実行することで、ブランチ作成からPRコメントまでの一連の開発フローが回ります。各コマンドが単一責任を持っているため、問題が起きたときにどのステップが原因かすぐに特定できますし、特定のコマンドだけを差し替えたり改善したりすることも容易です。なお、/api-build/commit のように、内部的に複数のコマンドをパイプしたオーケストレーションコマンドも混在しています。たとえば /commit は内部で /commit-stage/commit-create がパイプされています。この発展形については次のセクションで説明します。

発展形: オーケストレーターコマンド

コマンドを使い込んでいくと、自然と「複数のコマンドを組み合わせた上位コマンド」が欲しくなります。たとえば、レビューからリファクタまでの反復ループを1つのコマンドにまとめるような発想です。

このオーケストレーターコマンドは、Phase 3への布石でもあります。Phase 2ではこの「組み合わせて回す」役割を人間が担っていますが、Phase 3では運転席自体をAIに譲ります。AIが自律的にプロセスを回し、人間は判断が必要な箇所にだけ介在する。そのために必要な探索ループ、判断停止の仕組み、ガードレールの設計思想を次回の記事にて解説します。

なぜワークしたか

すでにあった下地

Phase 2への移行がスムーズに進んだ背景には、もともとチームに備わっていた前提条件がありました。

開発プロセスが可視化・標準化されていたことで、全員が同一のフローで動けていたため、「どの作業を切り出してコマンド化するか」の議論が具体的に進められました。また、コーディングルールがすでに文書化されていたため、AIに渡すガイドラインの整備もゼロからではなく、既存資産をベースに拡張する形で進められました。

意図的に作った下地

一方で、AI駆動開発のために意図的に整備したものもあります。2025年12月の約1ヶ月間を準備期間とし、私が既存のプロセスを見直しながら以下の整備を進めました。2026年1月からチーム運用を開始し、現在も継続中です。

まず、ユビキタス言語の整備です。社内固有の概念や用語が一般的な意味と異なる場合、そのままプロンプトに入れてもAIが適切に解釈できないことがあります。プロダクト内の用語を整理し、AIが正確に理解できる状態を作りました。

次に、各種ガイドラインの整備です。コーディングルール、命名規則、アーキテクチャ方針、テスト方針といったドキュメントを、AIが参照できる形に整えました。これがコマンドの出力精度を左右する最も重要な要素です。ガイドラインが曖昧なままだと、チームで使ったときに出力の精度が安定しにくくなります。

なお、認証・認可やコアビジネスロジックといった人間が必ずレビューする領域の線引き(ガードレール)もガイドラインの一部として定めています。

これらのガイドラインをAIが必要なタイミングで参照できるよう、AGENTS.mdCLAUDE.md(プロジェクトルートに配置するAI向けの設定ファイル)で各ドキュメントの場所を示すようにしています。ポイントは、ファイルの中身を直接埋め込むのではなく、パスだけを記載している点です。たとえば、以下のようにドキュメントの場所を一覧で示しています。

## Quick Reference

Refer to these resources proactively as needed during development.

| What | Where |
|------|-------|
| **Product Overview** | `docs/guidelines/acesmeet-overview.md` |
| **DB Design** | `docs/guidelines/db-design-guideline.md` |
| **API Design** | `docs/guidelines/api-design-guideline.md` |
| **Architecture** | `docs/guidelines/architecture-guideline.md` |
| **Coding Style** | `docs/guidelines/coding-guideline.md` |
| **Code Quality & Testing** | `docs/guidelines/code-quality-charter.md` |
| **Error Handling Guideline** | `docs/guidelines/error-handling-guideline.md` |
| **Ubiquitous Language** | `docs/glossary/ubiquitous-language.csv` |

こうすることで、AGENTS.md / CLAUDE.md 自体は目次のような役割に留まり、AIが必要なタイミングで必要なドキュメントだけを参照しにいく段階的開示の構造になります。セッション開始時にすべてをコンテキストに載せない設計にすることで、コンテキストの肥大化を防いでいます。

下地が成否を分ける

Phase 2の成否は、こうした「下地」で決まるというのが私たちの実感です。#1|AI駆動開発の4フェーズと私たちの現在地でも述べたとおり、マインドセットの転換自体は小さいものの、チームとして再現性のある状態に持っていくには、この下地づくりが成否を分けます。人間がやっていることを言語化し、コマンドとして定義し、AIに実行させていく。やること自体はシンプルですが、下地の整備には相応の労力がかかります。私たちの場合、2025年12月の約1ヶ月を集中的な準備期間に充てました。ただ、下地を一気に整えたこととチームのモチベーションが高かったことで、その後の運用立ち上げは想像以上に速く、Phase 2からPhase 3の入口まで数ヶ月で到達できました。

一方で、ガイドラインが不十分なままチームで使い始めると、コマンドの出力精度は安定しにくくなります。Phase 2を機能させるうえで、下地の整備は欠かせないステップだと考えています。

Phase 2の限界

Phase 2の運用が回り始めると、別の課題が見えてきます。

毎回「コマンドを実行する→出力をレビューする→次のコマンドを選択する→実行する」という人間介在のループが発生します。各コマンドの実行自体はAIが担いますが、コマンド間の接続、つまり「今の出力は問題ないか」「次に何をすべきか」の判断は常に人間です。

人間が運転席に座り続ける限り、AIの稼働時間は人間の稼働時間に縛られる。これは#1で提示した構造問題そのものです。Phase 2はその問題を解消するものではなく、AIが動ける範囲を広げるための土台づくりでした。

次のステップは、「組み合わせて回す」役割自体をAIに委ねることです。AIが自律的にプロセスを回し、人間は判断が必要な箇所にだけ介在する。それがPhase 3の話です。

おわりに

Phase 2を始めるにあたって、まず試してみてほしいのは、自分のチームの開発フローを一度棚卸ししてみることです。「この作業は毎回同じ手順を踏んでいる」と気づいたら、それがコマンド化の候補です。小さく始めて、ガイドラインを育てながら広げていくのが現実的な進め方だと思います。

ただし、Phase 2を回していくと、「毎回人間がコマンドをつなぐループ」がボトルネックになることにも気づきます。次回の記事では、このループ自体をAIに委ねる「Pilot-Tower開発」の設計思想について解説します。

tech.acesinc.co.jp

ACESでは現在、複数のエンジニアポジションで採用を行っています。本シリーズを読んでACESの開発に興味を持っていただけた方は、ぜひカジュアル面談でお話ししましょう!

ACESの採用情報はこちら↓

recruit.acesinc.co.jp

open.talentio.com