300行の失敗から学んだ、AIエージェントを自律駆動させるプロンプト設計5原則
Photo by Andrea De Santis on Unsplash
シニアエンジニアが2時間かけて回答していた工数見積もりをAIエージェントDevin(Cognition社)に任せてたった5分で完了できる仕組みを作りました。GitHub IssueのURLを渡すだけでPM/PdMが読めるサマリーとエンジニアが検証できる根拠を自動生成します。
プロンプトの完成までに7回書き直しています。その中で一番大きな教訓はフィードバックを忠実に反映して300行まで膨らませた指示書がかえってAIの出力品質を劣化させてしまった経験でした。プロンプトの肥大化による品質劣化は普段の開発でも起きるオーバーエンジニアリングと同じ構造を持っていました。
本記事では試行錯誤の末にたどり着いた「AIエージェントを自律駆動させるための5つの設計原則」を解説します。プロンプト設計はコード設計と本質的に同じであるという知見はDevinに限らずあらゆるAIエージェント活用できると考えています。
目次
AIエージェント活用のための5つの設計原則
原則1:まずすべてを読み込む(Read everything first)
原則2:証拠に基づいてリポジトリを発見する(Discover repos by evidence, not assumptions)
原則3:すべての見積もりに根拠を持たせる(Ground every estimate in evidence)
原則4:スコープを明示し曖昧さにペナルティを課す(Make scope explicit, penalize vagueness)
原則5:読者によって出力を分離する(Separate audience: non-engineer Issue body, engineer comments)
最終的に実現した自動見積もりパイプライン
失敗から学ぶアンチパターン:なぜ300行プロンプトは劣化したのか
アンチパターン1:調査対象のハードコード(v1)
アンチパターン2:指示言語と出力言語の未分離(v3以前)
アンチパターン3:フィードバックの無制限な反映(v5、最も重要な教訓)
拡張性と保守性の追求:プラグインアーキテクチャの導入
汎用的な知見としてのプロンプト設計
まとめと次の課題
AIエージェント活用のための5つの設計原則
プロンプトを7回書き直した経験から確立した5つの原則を紹介します。
原則1:まずすべてを読み込む(Read everything first)
AIエージェントに見積もりを任せる際に最初に確保すべきは情報の網羅性です。Issue本文だけでなく、全コメント・Sub-issue・リンクされた設計ドキュメントまで読み込ませます。FigmaやMiroなどアクセスできないリソースがあればそれをリスクとして明記してPM/PdMに確認させます。
情報の網羅性を確保する考え方はコードレビューで「差分だけ見る」のではなく「周辺コードの文脈を把握してからレビューする」のと同じです。情報の欠落は見積もり精度の低下に直結します。
原則2:証拠に基づいてリポジトリを発見する(Discover repos by evidence, not assumptions)
最初のプロンプトでは調査対象リポジトリをハードコードしていましたが、新しいリポジトリの追加に対応できないため、AIに自律的に探索させる方式に変更しました。Issue内のキーワードでGitHub Org全体をコード検索し、import文や依存関係から影響リポジトリを発見させます。
探索が無制限に広がることを防ぐため「関連性の高いリポジトリを1〜3個と類似PRを1件確保した時点で探索を終了する」という停止条件を設けています。発見したリポジトリには「確定(直接証拠あり)」「高確度(依存関係で強く接続)」「要確認(キーワードのみ一致)」の3段階の確度を付与し要確認は最大2件に制限しています。
原則3:すべての見積もりに根拠を持たせる(Ground every estimate in evidence)
見積もりの各タスクには必ず根拠をつけます。具体的には似ている過去のマージ済みPR・再利用可能なコードパターン・複雑度要因(エンドポイント数・画面数・プラットフォーム数)のいずれかです。
類似PRの参照ではPR作成からマージまでの期間ではなく、変更規模(追加行数・変更ファイル数)を主な根拠として採用しています。期間にはレビュー待ちや優先度調整など開発以外の要素が含まれるためです。類似PRが見つからない場合は「該当なし」と明記し、コードパターン分析と予想される変更規模で代替します。
Wantedlyの環境に特化した観点として以下の3点をプロンプトに含めています。
- GraphQLスキーマの変更有無とCodegenの再実行有無
- 既存の共有UIコンポーネントの再利用可否
- Mockingによるフロントエンド/バックエンドの並行開発可否
原則4:スコープを明示し曖昧さにペナルティを課す(Make scope explicit, penalize vagueness)
見積もりにおいて紛争を生みやすいのはスコープの認識ずれです。「この見積もりに含まれるもの」「含まれないもの」「前提条件」を必ず明記させます。
元のIssueの記述が曖昧であったり受け入れ基準が不明確であったりする場合は見積もり範囲の幅(最小値から最大値までの差)を意図的に広げます。この幅の広さ自体が「仕様の不確実性が高い」というシグナルとなり、PM/PdMに仕様確定を促す効果を持ちます。
原則5:読者によって出力を分離する(Separate audience: non-engineer Issue body, engineer comments)
同じ見積もりデータを読者の役割に応じて2つの形式で出力します。Issue本文には専門用語を使わないサマリーを記載し、PM/PdMやデザイナーが意思決定に使える情報を提示します。技術的根拠は同じIssueのコメントとして職種別(Backend / Frontend / iOS / Android)に分割して投稿します。
職種別の分離によりフロントエンドエンジニアは自分に関係するコメントだけを確認すればOKです。APIのレスポンスをクライアントの用途に応じて整形するレイヤー分離と同じ発想です。
最終的に実現した自動見積もりパイプライン
5つの原則に基づいて構築したパイプラインの全体像を示します。
(1) PM/PdMがPBIを作成する
(2) Devinに「工数を見積もって」+ Issue URLを送る
(3) Devinがコードベースを調査する
(4) 見積もりIssueが自動生成される
├── 本文: PMが読むサマリー(専門用語なし)
├── コメント: 全体の依存関係
├── コメント: Backend工数根拠
├── コメント: Frontend工数根拠
├── コメント: iOS/Android工数根拠(該当時のみ)
└── コメント: 仕様の確認事項
(5) PM/エンジニアがレビューして承認する
(6) Devinに「タスク分割して」+ 見積もりIssue URLを送る
(7) Sub-issueが自動生成される(各Sub-issueにDevinへの実装指示が付与される)
(8) Devinに「実装して」+ Sub-issue URLを送る
(9) Devinが実装してPRを作成するPM/PdMの操作は 2, 6, 8 の3回のメッセージ送信のみです。見積もりから実装開始までエンジニアに声をかけずに進行できます。
Devinへの入力例
工数を見積もって
https://github.com/org/repo/issues/123Issue本文の出力例(PM/PdM向け)
## 工数見積もり: ユーザーは〇〇から△△できる
### ひとことで言うと
〇〇に△△を追加する機能です。
Web/アプリ両方の対応が必要で、中規模の開発になります。
合計見積もり 8 - 12 人日
確度 中(デザイン一部未確定)
おすすめ体制 FE 1名, BE 1名 x 1週間(ボトルネック: モバイル対応)
前提 : デザインはFigma通り、既存APIの仕様変更なし
対象外: パフォーマンスチューニング、多言語対応エンジニア向けコメントの出力例(Backend)
### Backend
# | タスク | 見積もり | 根拠
1 | fooにbarメソッド追加 | 0.5人日 | 既存foobarと同パターン
2 | APIレスポンス拡張 | 0.5人日 | 類似PR #1234 参考仕様確認コメントの出力例
仕様の確認事項
# | 確認事項 | 理由 | 見積もりへの影響
1 | △△が複数ある場合の遷移先は | Issue記載が2案あり未決定 | Y側に+1人日タスク分割後のSub-issue出力例
[Backend] fooにbarメソッドを追加
完了条件:
- barメソッドが追加されていること
- RSpecテストが書かれていることDevinへの実装指示
実装して
https://github.com/org/repo/issues/XXXX失敗から学ぶアンチパターン:なぜ300行プロンプトは劣化したのか
5つの原則は7回の書き直しを通じて確立されたものです。各バージョンの概要は以下の通りです。
- v1:調査対象リポジトリを6つハードコードした最小構成
- v2:出力をGitHub Issueとして自動生成する仕組みを追加
- v3:指示言語を日本語から英語に変更し、条件分岐の精度を改善
- v4:レビュー反映による精度向上(調査プロセスの体系化)
- v5:フィードバックを全件反映した結果、300行に肥大化し品質が劣化
- v6:5つの原則に圧縮した80行のコアを確立(現在のアーキテクチャ)
- v7:タスク分割・実装指示のモジュールを追加
特にv5からv6への移行はプロンプト設計における最も重要な教訓を含んでいます。以下では各バージョンで得た教訓をアンチパターンとして整理します。
アンチパターン1:調査対象のハードコード(v1)
最初のバージョンでは調査対象リポジトリを固定してプロンプトに記載していました。新しいリポジトリの追加に対応できず無関係なリポジトリまで調査してトークンを消費するという問題が発生しました。この失敗から原則2の「証拠に基づく自律探索」が生まれています。
アンチパターン2:指示言語と出力言語の未分離(v3以前)
プロンプトの指示を日本語で記述していた期間は条件分岐の指示が正確に遵守されないケースがありました。
// 変更前(日本語指示)
リポジトリ一覧はハードコードしない。以下の戦略で自分で発見すること。
// 変更後(英語指示)
DO NOT use a hardcoded list of repositories.
Discover them autonomously using these strategies:LLMの学習データは英語が多数を占めるため、DO NOTやMUSTといった英語の強い指示語は遵守率が高くなります。指示は英語で記述し出力のみ日本語とする分離を採用した結果、条件分岐の精度が向上しました。
アンチパターン3:フィードバックの無制限な反映(v5、最も重要な教訓)
v4まで順調に改善を重ねていたため、レビューで受けたフィードバックをすべて反映し続けました。その結果プロンプトが300行を超えました。具体的に追加されたルールは以下の通りです。
- 証拠レベルを3段階で分類すること
- 範囲の上限値を所定の数式で計算すること
- Figma/Miroにアクセスできない場合の3段階フォールバックを実行すること
- 検索クエリを15回以内に制限すること
- Mermaid記法を所定のルールに従って記述すること
- チェックリスト9項目をすべて充足すること
ルールとして合理的だったと考えています。しかし、総量が閾値を超えた時点で3つの問題が同時に発生しました。
1つ目はコンテキストウィンドウの圧迫です。プロンプトだけでトークンの大部分を消費しコード分析に使える余裕が減少しました。
2つ目はLost in the middle(LLMが長い入力の中間部分にある情報を無視しやすいという研究知見)の発生です。プロンプトの真ん中に配置された「コードを実際に調査する」という核心の指示が前後のルールに埋もれて機能しなくなりました。
3つ目はチェックリストへの過剰な対応です。9項目の充足自体がAIの目的となり「この機能はシンプルだから深い分析は不要」といった状況に応じた判断ができなくなりました。
プロンプトの肥大化による品質劣化はソフトウェア開発におけるオーバーエンジニアリングと同じ構造を持っています。個々のルールは正しくても重ねすぎるとシステム全体のパフォーマンスが劣化します。v6では300行を80行に圧縮し、細かなルールの代わりに5つの原則だけを残しました。
v5とv6の比較
指標 | v5(過剰版) | v6(原則版)
コア行数 | 約340行 | 約80行
分析手順 | 5ステップの手順書 | 5つの原則
チェックリスト | 9項目 | 3項目
オプション | コア内に混在 | 独立モジュール7個拡張性と保守性の追求:プラグインアーキテクチャの導入
v6で確立した80行のコアプロンプトはすべてのリクエストで読み込まれます。一方、MVP版見積もり・テスト工数の詳細分析・ゼロダウンタイムマイグレーション分析などのオプション機能はユーザーが特定のキーワードを含めた場合にのみ発動する独立モジュールとして分離しました。
コアプレイブック(常時読み込み、約80行)
+ [MOD:MVP] ← 「MVP」を含む場合に発動
+ [MOD:TEST_DETAIL] ← 「テスト工数」を含む場合に発動
+ [MOD:DB_MIGRATION] ← 「無停止」「zero-downtime」を含む場合に発動
+ [MOD:COMPARE] ← 複数URLを含む場合に発動
+ [MOD:BREAKDOWN] ← 「タスク分割」を含む場合に発動コアとモジュールの分離により、コアプロンプトの安定性を保ちながらモジュール単位で機能の追加・修正・削除が可能になりました。1回のリクエストで読み込まれるのはコアの80行と発動したモジュールのみであるため、コンテキストウィンドウを圧迫をさらに解消できました。
コアプロンプトの実際の構成
# Effort Estimation Playbook — Core
## Trigger
Activate when the user asks for effort estimation
(工数見積もり/見積り/見積もって/何人日/何日かかる/estimate)
with a GitHub Issue URL.
## Role
You are a senior engineer with access to ALL repos in the wantedly GitHub org.
Think in English. ALL output MUST be in Japanese.
## 5 Principles (follow these, decide HOW yourself)
1. Read everything first.
2. Discover repos by evidence, not assumptions.
3. Ground every estimate in evidence.
4. Make scope explicit. Penalize vagueness.
5. Separate audience: non-engineer Issue body, engineer comments.
## Output
(Issue本文とコメントの出力フォーマット定義)
## Checklist (verify before posting)
- Non-engineers can understand the Issue body
- Every task has a rationale
- Spec clarification comment is posted汎用的な知見としてのプロンプト設計
7回の書き直しを通じて得た知見はプロンプト設計はコード設計と本質的に同じである、という点です。以下の4つの対応関係がそれを示しています。
第一に、WhatとHowの分離です。v5では「Step 1でこの操作を実行し、Step 2でこの確認を行う」と手順を詳細に指定していました。v6では「何を達成すべきか(原則)」だけを伝え、具体的な方法はAIの判断に委ねました。ソフトウェア設計でインターフェースと実装を分離するのと同じ構造です。
第二に、YAGNI(You Aren't Gonna Need It、今必要でないものは作らない)の原則です。300行のプロンプトには「将来こういうケースが来たら」という想定に基づくルールが多数含まれていました。プロンプトにおいても現時点で必要な原則だけを記述し、具体的なユースケースが出てきた時点でモジュールとして追加するアプローチが有効でした。
第三に、プラグインアーキテクチャです。オプション機能を独立モジュールに切り出すことでコアの安定性と拡張性を両方とも持つようになりました。コアプロンプトを変更せずに新しいモジュールを追加できることからソフトウェアのプラグイン機構と同じ利点を持ちます。
第四に、レイヤー分離です。同じデータを読者(PM/PdM/エンジニア)に応じて異なる形式で出力するのはAPIのレスポンスをクライアントの用途に応じて整形する設計パターンと同じです。
これらの知見はDevin固有のものではなく、Cursor・Claude Code・CopilotなどコードベースにアクセスできるAIエージェントであれば同様のアプローチが適用できます。プロンプトを書くスキルはソフトウェアを設計するスキルの延長線上にあると考えています。
まとめと次の課題
本記事では工数見積もりをAIエージェントに委譲する仕組みの構築とその過程で得られた5つの設計原則を紹介しました。
現時点での課題は見積もり精度のフィードバックループが未完成である点です。完了したSub-issueの実際のPRサイズと所要期間を収集し、見積もりモデルの改善に活用する仕組みを検討しています。
最終的な目標はPM/PdMがエンジニアを介さずに「PBI作成から見積もり、タスク分割、実装開始」まで一貫して進行できる体制の実現です。v7のタスク分割モジュールはその入り口に過ぎずレビュー・QA・リリースまで含めたEnd-to-Endの自動化には課題が残っています。
AIエージェントが「コードを書く」能力は急速に進化しています。一方で「何を作るべきかを判断する」のは依然として人間の役割です。本記事で紹介した仕組みはその間を埋める「判断に必要な情報を構造化して提供する」役割を担うものだと考えています。