エンジニア 登壇レポート

「開発生産性のその先へ、AI生産性について語りたい」に登壇してきました

エンジニア 登壇レポート

こんにちは!ロリポップ・ムームードメイン事業部ムームードメイングループのはるおつ(@haruotsu_hy)です。

2026年2月26日に開催された 「開発生産性のその先へ、AI生産性について語りたい」 で登壇してきました。 本記事では、発表内容の概要についてお伝えします。

発表資料

発表の概要

今回の発表では、「AIをどう使うか」だけでなく「AIが活きる構造をどう作るか」 というテーマでお話ししました。

各種AIツールの普及により、「設計→分割→実装→設計レビュー→コードレビュー→マージ」までの各ステップの速度は大きく向上しています。 一方で全体をみてみると、AIで各ステージが速くなっても、直列依存のボトルネックが残っている限り、全体のスループットは上がりません。

今回、実際にムームードメインのチームで行っている開発体制を例に挙げながら、 開発サイクルのボトルネックを構造的に排除している事例を紹介しました。

開発サイクルの6つのボトルネック

開発サイクルを「設計 → 分割 → 実装 → 設計レビュー → コードレビュー → マージ」に分解し、それぞれのフェーズで発生していたボトルネックを洗い出し、それぞれに対する解決策を紹介しました。

# ボトルネック 構造的な原因 解決策
1 設計が伝わらない パイプライン先頭のストール ドキュメントドリブン開発
2 タスク分割が遅い 順序実行するしかない AIとの協業によるタスク分割
3 実装が直列 共有リソース競合 リソースの自動分離、削除システムの構築
4 設計レビューが属人的 コード化されていないチェック スキル化による並列レビュー
5 コードレビューが属人的 基準がなく自動化不可 CCA + ガイドライン自動選択
6 レビュー待ちが長い 待ちが発生している レビュー依頼リマインド自動化

ドキュメントドリブン開発(DocDD)

Design Doc を「判断の記録」と位置づけ、リポジトリ内に以下の構造で管理しています。

docs/product/design-doc/
├── YYYYMM-NNN_プロジェクトA/
│   └── 設計書.md
├── YYYYMM-NNN_プロジェクトB/
│   ├── 基盤構想.md
│   ├── 設計方針_結論.md
│   └── Before-After.md

書くのは WHY(なぜこの設計にするのか)、WHAT(何を作るのか、構造)、設計決定とトレードオフ、データ構造・処理フロー概要です。具体的な実装コードの羅列やファイルパスの詳細リスト、メソッドシグネチャの詳細は書きません。判断を伝えるのに必要な粒度に留めることで、新メンバーがきても、新しいAIセッションでも再現性を担保できます。

AIとの協業によるPR分割

Design Doc をベースに、要件定義とPR分割をAIと協業してドキュメントに残す方法をとっています。 人間が「何を作るか」を定義し、AIが「どう作るか」を提案。 人間は常にレビュー・判断・承認の責任を持ち信頼のあるドキュメントをリポジトリに残す体制を整えています。 ドキュメントは不変なものでなく、実装とドキュメントのズレをなくし、実装を行う中で変更があれば対象のPRに合わせてドキュメントを更新し続けています。

まずフェーズごとの依存関係の大枠をMermaidで可視化し、さらに各PhaseをPR単位に分割します。実際の分割計画書の例です。

Phase 0: 基盤             Phase 1: 動線
PR-001 → PR-002          PR-007 → PR-008 → PR-009
  ↘
    PR-003 → PR-004 → PR-005
      ↘
        PR-006

Phase 2: バックエンド + フロントエンド
PR-010 → PR-011 → PR-012
PR-009 → PR-012-F(バックエンドに依存せず先行着手可能)

各PRが1日以内でマージ可能なサイズになり、各PRでなにをするかが明確にレビューされた状態で残ります。 AIでも人間でも誰が実装しても同じ状態を常に再現できる状態を整えています。

また、Design Docの分割計画書をもとに、各タスクの見積もり誤差を二乗和の平方根で合算する、SRSS法による工数見積もりと、Mermaid Ganttチャートの自動生成も行っています。

PR単位で分割済みの計画と相性がよく、各PRの見積もりから全体のバッファを統計的に決定できるため採用しました。 また、単にSRSS法による見積もりをするのではなく、AI生成ドキュメント特有の過剰な見積もりを防ぐために、営業日や稼働時間、CIやレビュー待ち時間までを考慮したskillを作成することにで、現実的な見積もりを算出する仕組みを作っています。

並列開発環境の構築

git worktreeで複数ブランチを同時に開発する場合、以下の問題が発生します。

  • ブランチA: docker compose up → ポート3000, 4000, 443を占有。ブランチBは起動失敗
  • ブランチA: MySQL volume “muu-mysql” を使用中 → ブランチBが同じvolumeを参照するとデータが混ざる
  • ブランチA: https://muu.test でアクセス → ブランチBは同じURLでアクセスできない

1台のマシンで1環境しか動かせない。これを運用ではなく構造的にゼロにします。

ムームードメインチームではmake branch/start を実行すると、裏で6つのスクリプトが連鎖します。

  1. stop-old-branch-containers.sh — docker inspectで同じディレクトリからマウントされた別ブランチを検出し自動停止
  2. normalize-branch-name.sh — ブランチ名をDNS安全な形に変換
  3. generate-env.sh — worktree固有のハッシュで .env を生成
  4. gopose up --config .gopose.yaml — 動的ポート割り当て
  5. update-muu-url.sh — 各サービスのURLを動的設定
  6. docker compose up -d — 起動

それぞれの仕組みを紹介します。

ワイルドカードDNS + SSL

dnsmasq + mkcertでブランチごとのHTTPアクセスを実現しています。

# dnsmasq: *.muu.test を全て 127.0.0.1 に解決
echo 'address=/.muu.test/127.0.0.1' >> "$(brew --prefix)/etc/dnsmasq.conf"

# mkcert: ワイルドカードSSL証明書を生成
mkcert -cert-file wildcard.muu.test.crt.pem \
       -key-file wildcard.muu.test.key.pem "*.muu.test"
# Nginx: 正規表現でホスト名からブランチ名を抽出
server {
    server_name ~^(?<branch>[^.]+)\.muu\.test$;
    ssl_certificate     wildcard.muu.test.crt.pem; # 1枚の証明書で全ブランチ対応
    proxy_set_header X-Branch $branch;              # 下流サービスにブランチ名を伝播
}

goposeで動的ポート割り当て

ポート衝突をゼロにするために、ムームードメイングループのはらちゃんが開発した gopose を活用しています。

# ブランチA                    # ブランチB(衝突しない)
proxy: 443 → 8443:443         proxy: 443 → 8543:443
rb:    3000 → 8300:3000       rb:    3000 → 8500:3000
php:   4000 → 8400:4000       php:   4000 → 8600:4000

worktreeごとのVolume分離

絶対パスのMD5ハッシュでvolumeを完全分離しています。

# generate-env.sh: worktree の絶対パスからハッシュ生成
calculate_dir_hash() {
    echo -n "$(cd .. && pwd)" | md5 | cut -c1-8
}
# Worktree A (/Users/dev/muu)         → hash: a3f2b1c9
# Worktree B (/Users/dev/muu-feature) → hash: 7e4d8f12
# compose.yml: ハッシュでvolume名を動的に決定
volumes:
  bundler:  { name: "${MUU_DIR_HASH:-muu}-bundler" }  # a3f2b1c9-bundler
  npm:      { name: "${MUU_DIR_HASH:-muu}-npm" }
  composer: { name: "${MUU_DIR_HASH:-muu}-composer" }

DB、node_modules、gem、composerパッケージが完全分離して混ざらない仕組みを作っています。

レビュー観点のskill化

設計レビューの観点を .claude/skills/design-review/ 配下にコード化しています。

.claude/skills/design-review/
├── review-guidelines.md           ← 共通ガイドライン
├── rb-design-agent.md             ← Rails 観点
├── php-design-agent.md            ← PHP 観点
├── js-design-agent.md             ← フロントエンド観点
├── k8s-design-agent.md            ← Kubernetes 観点
├── rest-api-design-agent.md       ← REST API 設計
├── authentication-design-agent.md ← 認証・認可
├── security-design-agent.md       ← セキュリティ
├── database-design-agent.md       ← データベース設計
├── unit-test-design-agent.md      ← テスト設計
├── e2e-test-design-agent.md       ← E2Eテスト
├── refactoring-design-agent.md    ← リファクタリング
└── error-handling-design-agent.md ← エラーハンドリング

.claude/commands/design-review.md から全12エージェントをTask toolで並列起動し、該当/非該当の判断は各エージェント自身が行います。 Actionsでも発火し、これらのレビューによる指摘事項を修正または説明してから、人間にレビュー依頼をする体制を整えています。

slack-review-notify

はるおつが作成し社内で運用されているslack-review-notify を活用して、レビュー依頼に関わる全てを自動化しています。

  • GitHubにラベルが付くと通知
  • レビュワーのランダムアサイン
  • スレッドで定期リマインド
  • レビュワー変更・レビュー後自動通知
  • 営業時間考慮
  • スラッシュコマンドでの設定変更

レビュー依頼、アサイン、リマインド、完了が全自動になり、シニアや特定の人ばかりにレビューが偏る属人化を構造的に排除しています。

まとめ

今回の発表では、AIツールを導入するだけでは開発サイクル全体の速度は変わらないという問題意識のもと、ムームードメインのチームで実際に取り組んでいるボトルネックの構造的な排除について紹介しました。

「AIをどう使うか」ではなく「AIが活きる構造をどう作るか」。 個々のステージを速くするだけでなく、直列依存を構造的に排除して並列に動けるパイプラインに変えることで、初めてAI・自動化の効果がリリース速度に反映されると考えています。

イベントを運営してくださったForkwellのみなさま、聴講してくださったみなさま、ありがとうございました。 同じような課題感を持っている方の参考になれば幸いです。