TL;DR
- 対象: マルチエージェント開発で解釈のブレや人間のブロッキングに悩む開発/運用チーム。
- 課題: 曖昧な要件共有とレビュー待ちが連携破綻と手戻りを招く。
- アプローチ: SDD で共通言語化 → TDD で到達基準を固定 → ノンブロッキング運用(ログ・CI 合格・相互レビュー)。
- 結果: 仕様の揺れを抑え、自律性と透明性を両立(レビュー負荷と手戻りを削減)。
はじめに
最近、マルチエージェント開発に取り組んでいます。
Claude、Gemini、Codex、Copilot など、複数のエージェントを連携させて、人間は要件を伝え、エージェントが自律的にコードを書くという理想的な開発スタイルを目指して試行錯誤してきました。
実際にやってみると、確かに近づいている現実だと感じます。でも、最初からうまくいったわけではありません。
エージェント同士のやり取りは破綻していきます:
- 「修正したら CI がエラーで通らない」
- 「エラーを修正していくと、仕様が変わっていく」
- 「エージェントごとに解釈が違う」
これらの問題が重なると「これは本当に動くのか?」と不安になり、つい人間がブロッキングしてしまいます。
改善しては失敗する、を繰り返してきました。
そんな中で見つけたのが、3 つの原則です。本記事では、実際のプロジェクトでの適用例とともに、この原則をお伝えします。
マルチエージェント開発でよくある課題
まず、私が実際に経験した課題から見ていきましょう。
エージェント連携の破綻
私が最初に直面した問題は、曖昧な自然言語要件をそのまま渡すと、エージェントごとに解釈が異なることでした。
- エージェント A:「平日 = 月曜〜金曜」
- エージェント B:「平日 = 営業日(祝日除く)」
このズレが積み重なると、最終的にテストや実装が食い違い、連携が破綻してしまいます。
失敗シナリオ(会話ログ風)
A: 平日アラームを設定しました(Mon-Fri)。
B: 平日は祝日を除外しました(営業日)。
B: テストを用意しました。
A: 実装しました → しかしテストが通らない…
C: 仕様が曖昧で、どちらが正しいかわからない!
具体的なコード例:解釈のズレ
// エージェントAの実装:曜日ベース
const isWeekdayByDow = (date) => {
const day = date.getDay();
return day >= 1 && day <= 5; // 月-金のみ(祝日は考慮しない)
};
// エージェントBの実装:営業日カレンダーベース
const isWeekdayByCalendar = (date) => {
const day = date.getDay();
const isMonToFri = day >= 1 && day <= 5;
return isMonToFri && !isHoliday(date); // 月-金かつ祝日除外
};
// 結果:同じ「平日」でも、祝日の扱いで動作が分岐する
注: 本来どちらも isWeekday という同じ名前で実装されがちですが、ここでは差異を示すため別名にしています。isHoliday は祝日判定を行う擬似関数です。
人間がブロッキングしてしまう
私がよく陥った問題は、エージェントがどこまで進んでいるのかが分からないことでした。
仕様の確認が発生しているのか、レビュー待ちで止まっているのか。仕様抜け・変更で止まっているのか、それが意図的な変更なのか、経緯が見えないと不安になります。
その不安から「レビュー」「承認」といったブロック要素を差し込んでしまい、結局エージェントの自律性を損なってしまうのです。
課題解決のための 3 つの原則
これらの課題を解決するために、私は 3 つの原則を導き出しました。まず、全体の関係性を図で見てみましょう。
ログの重要性
原則を説明する前に、重要な前提があります。それがログです。私の経験では、ログがあることで以下の効果がありました:
- エージェント同士のやり取りを記録する
- 人間は「なぜこうなったか」を後から理解できる
- 無用なブロックを減らせる
- 意思決定の透明性が担保される
ログは安心感の源泉であり、エージェントの自律性を保つための土台になります。
原則 1: SDD(仕様駆動開発)
仕様を共通言語にすることで、エージェントが同じ前提で進められます。
ダメな例
- 平日 7時にアラーム
- スヌーズは適宜
良い例(requirements.md)
# requirements.md
- 平日 = 月曜〜金曜(土日・祝日は除外)
- アラーム時刻 = 07:00(ユーザー指定可能)
- スヌーズ = 5 分間隔、最大 3 回まで
SDD 実装例:OpenAPI 仕様書
paths:
/alarm:
post:
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
weekday_only:
type: boolean
description: "平日のみ(月-金、祝日除外)"
alarm_time:
type: string
pattern: '^([01]\d|2[0-3]):[0-5]\d:[0-5]\d$'
example: "07:00:00"
description: "アラーム時刻(HH:MM:SS形式)"
required:
- weekday_only
- alarm_time
responses:
"200":
description: "アラーム設定成功"
仕様を文書化することで、解釈の揺れを防ぎます。
原則 2: TDD(テスト駆動開発)
SDD で仕様を明確にしたら、次は実装前にテストを書くことで、到達すべきゴールが明確になります。
テストがあれば、エージェントは「これを通すこと」に集中できるのです。
テストの種類
- 受け入れテスト(ユーザーが期待する動作を検証)
- インターフェーステスト(エージェント間の仕様を保証)
例:acceptance.alarm.md
## シナリオ 1: 平日 7:00 に鳴る
前提: 月曜日 07:00 にアラーム設定
期待: 07:00 に通知が 1 回鳴る
## シナリオ 2: スヌーズ 5 分
前提: アラームが 07:00 に鳴った状態でスヌーズを押す
期待: 07:05 に再度通知が鳴る
契約テスト例:contract.clock.md
## Clock インターフェース契約
- getCurrentTime(): Date - 現在時刻を返す
- isWeekday(date: Date): boolean - 平日判定
- addMinutes(date: Date, minutes: number): Date - 分を加算
## 境界値テスト
- 23:59 + 1 分 = 00:00(日付またぎ)
- 祝日判定の正確性
- タイムゾーン処理
原則 3: ノンブロッキング(人間は進行を止めない)
SDD と TDD で仕様とテストが整ったら、最後に重要なのは人間は進行を止めないことです。
人間はまず要件を伝える。エージェントが仕様にまとめ、必要に応じて調整を行う。確認はするが、承認待ちのようなブロック要素にはしない。
最終的に人間がレビューを行うのは、次の条件がすでに満たされた後です。
- エージェント同士のレビュー(設計レビューや PR レビュー)が実施済み
- ドキュメント(README や仕様書)が更新済み
- CI が通過し、すべてのテストが合格している
この流れを徹底することで、エージェントは自律的に進み、人間は最小限の関与で最大の効果を発揮できます。
実際の開発フロー
3 つの原則を組み合わせた実際の開発フローを見てみましょう。
エージェント間のやり取りフロー
ログ例
A(要件/Claude): requirements.md を作成
B(設計/Gemini): contract.clock.md を定義
B(調査/Gemini): Node.js のタイマーライブラリを比較、採用案を提示
C(実装/Codex): コード実装 → 初回テストで失敗
D(QA/Claude): acceptance.alarm.md を実行 → シナリオ 2 で失敗
C(実装/Codex): 修正 → テスト再実行 → 成功
B(レビュー/Gemini): PR レビュー、設計との整合性を確認 → レビュー通過(人間の承認待ちではなくエージェント間のレビュー合格)
E(Docs/Gemini): README に差分まとめ、既知の制約を記録
3原則を支えるツール:Serena MCP
ここで紹介するのが Serena MCP です。
Serena は、オープンソースの MCP サーバで、LSP(Language Server Protocol)を用いてコードベースを構造的に理解し、検索・参照・編集を効率的に行えます。
さらに .serena/memories/ によって、エージェント間の会話や判断の履歴を記録し、人間が後からレビューしやすい環境を整えてくれます。
- SDD を補強:仕様解釈のズレを減らす
- TDD を支援:テスト対象や修正範囲を迅速に特定
- ノンブロッキングを補完:ログと履歴により、人間が安心して「止めずに任せる」ことができる
Serena を導入することで、今回紹介した 3 原則がより確実に機能するようになります。
実践的な効果と注意点
3 つの原則を実践した結果、どのような効果が得られるのでしょうか。私の経験を基に、実感ベースの効果と注意点をお伝えします(大規模な定量データはこれからの課題です)。
効果測定
現時点では、大規模なプロジェクトでの成果は十分に出せていません。
ただし、小規模な検証を通じて以下の実感を得ました:
- 仕様の曖昧さがテストで顕在化する前に共有されるようになった
- エージェント間のやり取りをログに残すことで、人間のブロッキングを減らせた
- 最終レビューに集中できる体験が得られた
注意点・制限事項
3 原則は強力ですが、以下の点に注意が必要です:
- 複雑なビジネスロジック:人間の判断が必要な場面は残る
- セキュリティ要件:必ず人間がレビュー・承認する
- エージェントの学習データ:偏りがある可能性を考慮
- コスト管理:API 呼び出し回数の監視が必要
人間レビュー時の確認ポイント
最終的な人間レビューでは、以下のポイントを確認しましょう:
- 曖昧語の排除(「平日」「休日」など)
- 境界値の定義(23:59 など日付またぎ)
- 仕様変更の経緯がログに残っているか
- テストカバレッジが十分か
- ドキュメントが最新化されているか
関連ツールの紹介(試してみたいリスト)
本文では Serena MCP に焦点を当てましたが、他にも試してみたい MCP やフレームワークがあります:
- PlanGate:実装前に計画・スコープ・テスト観点を固定するためのワークフロー
- River Review:PR差分に対してレビュー観点を再利用できる形で適用するAIレビュー運用フレームワーク
- AutoGen(Microsoft):イベント駆動型のマルチエージェント構築フレームワーク
- LangGraph / CrewAI:ワークフローを視覚的に設計できるフレームワーク
- LlamaIndex / PydanticAI:軽量で実装例に使いやすいライブラリ
それぞれ特徴が異なるため、用途やチームの成熟度に応じて選ぶのが良いでしょう。個人的には、まずは軽量なものから試してみて、徐々に本格的なフレームワークに移行していくのがおすすめです。
まとめ
マルチエージェント開発は確かに便利ですが、破綻リスクも高いです。私自身、何度も失敗を繰り返してきました。
だからこそ、今回お伝えした 3 つの原則 が重要です:
- SDD(仕様を共通言語にする)
- TDD(到達基準を先に定める)
- ノンブロッキング(人間は進行を止めない)
さらに、Serena MCP を導入することで、これらの原則を支える実践基盤が整います。
この 3 つを守ることで、エージェントは自律的に動き、透明性と効率を両立できます。
🚀 実際に試してみてほしいこと
もしあなたもマルチエージェント開発に興味があるなら、まずは小さなプロジェクトから始めることをお勧めします。
- 簡単なツールやスクリプトから始める
- 3 原則を意識して進める
- ログを必ず残す
- 失敗を恐れずに試行錯誤する
未来の開発では、人間は要件と最終レビューに集中し、エージェントは仕様とテストを頼りに止まらず進む。
そんなスタイルが当たり前になると感じています。
参考・関連
- 📕 Zenn Book: AI にコードを書かせる前にやること — PlanGate 実践ガイド - 本記事の「計画→実装→検証」を全9章で体系化した実践ガイドです。
- Zenn: アジャイルでAI駆動開発をどう回すか — PlanGateの考え方とテンプレート - 仕様とレビューのゲートをAIワークフローに置く実践例です。
- Zenn: Next.js App Router時代のAI-driven TDD - テストを先に置いてAI実装を止めない方法を具体化しています。
- PlanGate GitHub / River Review GitHub
本記事は Zenn 版 を Qiita 向けに再構成したものです。