TL;DR(このページは何か・専門語ゼロ): 一定の水準を満たした判断のたたき台に対し、3 種類の AI が同時にそれぞれ違う視点(事業・論理・技術)から意見を付ける仕組みの設計メモです。この段では起案を差し戻さず、意見を変更提案の本文にそのまま並べて添え、最終的にどうするかは人が決めます。なぜ差し戻さないのか、なぜ 3 つ同時に走らせるのか、1 つの AI が応答に失敗しても全体を止めない理由、テストを最小限にした判断を記録しています。

位置付け: PR #596 で実装した Phase 3 (Gate 3 並列レビュー) の 設計判断と運用ポリシー を残すドキュメント。

  • 実装コード: drp/src/nodes/parallel_review.ts
  • プロンプト原本: prompts/05_parallel_review.md v1.0
  • 全体像: README.md の「アーキテクチャ」「フェーズ計画 §Phase 3」セクション

役割分担: README = 現状の SSoT / changelog = 履歴 / 本ファイル = Phase 3 固有の設計判断 (採用しなかった代替案・運用上の注意)


1. Phase 3 の位置付け (なぜ「差戻しなし」なのか)

Phase 1〜2c で構築したゲート〔Gate=審査の関門。各段で起案を通すか差し戻すかを判定する〕は すべて差戻し型:

Gate差戻しトリガ
Gate 0 Triage〔トリアージ=そもそも記録に残す価値があるかの選別〕ADR 対象外と判定 → END
Gate 1 Socratic〔ソクラティック=前提・代替案を問い直して盲点を洗い出す段〕情報不足 → 質問返却 + END
Gate 4 Scoring40 点未満 → END
Gate 2 Consistency〔コンシステンシー=過去 ADR との整合チェックの段〕CONFLICT 検出 + supersede 宣言なし → END

これらを通過した起案ドラフトは 「ADR〔Architecture Decision Record=技術判断の記録〕として PR 化する水準を満たした」 と見なされる。Phase 3 がさらに差戻し判定を加えると:

  • レビューモデル 3 つの意見不一致の解決ロジックが必要 (どれを採用するか / 多数決か / 厳しい方を採るか)
  • レビュー LLM のハルシネーションでブロックされる事故が起きやすい (4 段ゲート目で意味不明な指摘で差し戻される)
  • レビュー品質を確かめるためのテストケースが少なくとも 9 通り (3 モデル × pass/fail/borderline) 必要になる

これらのコストに対し、Phase 1〜2c の 4 段ゲートで品質はすでに担保されている。よって Phase 3 は情報提供型 (差戻しなし) とした。レビュー結果は PR 本文に転記 され、最終承認者 (代表取締役) が見て判断する。

⚠️ 「差戻しなし」を将来 ⇒ 「条件付き差戻し」に変える際の前提: レビューモデルのハルシネーション率 (誤った指摘の頻度) を計測した上で、indicator == "CRITICAL" 等の厳格指標のみに限定する設計が必要。盲目的な多数決差戻しは禁忌。


2. なぜ Promise.all (ノード内並列) を選んだか

採用案: parallel_review.ts 内で Promise.all([gemini, claude, gpt])

const [geminiResult, claudeResult, gptResult] = await Promise.all([
  callGemini(prompt).catch(err => ({ error: err.message })),
  callClaude(prompt).catch(err => ({ error: err.message })),
  callGpt(prompt).catch(err => ({ error: err.message })),
]);

検討した代替案

採用しなかった理由
A. LangGraph 並列分岐 (graph.addBranch(...))3 ノードに分割するとグラフ可視化が煩雑、State チャネルが 3 倍化、合流ノードが追加で必要
B. 直列実行 (Gemini → Claude → GPT)レイテンシ 3 倍 (各 5-10 秒 → 計 15-30 秒)。Cloudflare Workers の CPU 制約 (30 秒) を超過リスク
C. Cloudflare Queues 経由の非同期起案者の Web UI レスポンスから外れる。「PR が出てから 30 秒以内にレビューも揃う」UX が崩れる

Promise.all 採用の根拠

  1. レイテンシ: 3 モデルの中で最も遅い 1 つの応答時間 = 全体応答時間
  2. コード単純さ: グラフ定義はノード 1 つで済む。エラー処理も各 catch で完結
  3. Cloudflare Workers 適合: Workers Paid plan の 30 秒 CPU 上限内に余裕で収まる (Gemini Flash ~ 3 秒 / Claude Sonnet ~ 8 秒 / GPT-4o ~ 6 秒)

3. なぜ 3 モデル + その役割分担なのか

モデル選定の根拠

モデル特化視点選定理由
Gemini Flashビジネスインパクト / アーキテクチャ整合性 / 長期負債リスクGoogle ecosystem 文脈 (Workspace / GCP) への理解度が高い + 高速・安価で網羅レビューに向く
Claude Sonnet論理的一貫性 / 問題定義と決定のつながり / 撤退条件の現実性長文の論理矛盾検出に強い (RQ-038 で確認済)。撤退条件の現実性判定は ADR-0019 の Reject 条件設計でも有用と判明
GPT-4o技術的実現可能性 / コスト試算の妥当性 / 完了条件の検証可能性数値計算・コスト試算の整合性確認に強い。完了条件 (Definition of Done) の検証可能性チェックも得意領域

なぜ 3 つで、4 つや 2 つではないのか

  • 3 つの根拠: ビジネス / 論理 / 技術 の意思決定 3 視点に対応 — どれが欠けても重大な見落としが残る
  • 4 つ以上にしない理由: コスト・レイテンシが膨らむ + プロバイダ依存性が増える + レビュー結果の PR 本文転記で冗長化
  • 2 つにしない理由: 多数決が成立せず、ハルシネーション検知の参照点が不足

📝 将来の変更余地: モデルが進化すれば役割を再配置する (Gemini 2.5 が論理に強くなれば Claude と入れ替え等)。役割と LLM の固定的な紐付けは避け、prompts/05_parallel_review.md役割視点だけを SSoT〔Single Source of Truth=唯一の正となる出どころ〕化 している。


4. エラー処理ポリシー — 「3 モデル中 1 つ失敗してもパイプライン継続」

設計

// 各モデル呼出を個別 catch で吸収
const results = await Promise.all([
  callGemini(prompt).catch(err => ({ role: "business", error: err.message })),
  callClaude(prompt).catch(err => ({ role: "logic",    error: err.message })),
  callGpt(prompt).catch(err => ({ role: "tech",        error: err.message })),
]);

// PR 本文には成功したレビューのみ転記、失敗したものは「(レビュー取得失敗)」と注記

なぜ全失敗時もパイプラインを止めないか

  • Phase 3 は 情報提供型: レビューが 1 つも取れなくても、Phase 1〜2c で ADR の起案品質は既に担保されている
  • 1 モデル障害で起案フロー全体が止まると、代表取締役 (1 人開発) のADR 起案サイクルが LLM プロバイダ可用性に依存してしまう
  • 起案件数 (推定週 3-5 件) に対し、レビュー取得失敗率の許容ライン (3 モデル全失敗 = ほぼ起きない) を考えると、止めるコストの方が大きい

モニタリング項目 (Phase 3 運用後に整備)

  • 各モデルの呼出成功率 (LiteLLM Gateway のログから集計可能)
  • レビュー文面の有用性 (代表取締役が PR 本文を読んでレビュー指摘で実際に判断を変えた件数)
  • ハルシネーション率 (誤った技術的指摘・存在しない過去 ADR への言及など)

5. PR 本文への転記フォーマット

src/nodes/webhook.ts で 3 モデルのレビュー結果を指定セクションとして PR 本文に転記。フォーマット例:

## Gate 3: 並列レビュー (Phase 3)

> Scoring + Consistency 通過後の 3 モデル並列レビュー (情報提供型・差戻しなし)

### ビジネスインパクト視点 (Gemini Flash)

<gemini_review_text>

### 論理的一貫性視点 (Claude Sonnet)

<claude_review_text>

### 技術的実現可能性視点 (GPT-4o)

<gpt_review_text>

---

💡 設計意図: 3 視点が並列に並ぶことで、代表取締役が PR レビュー時に「ビジネス → 論理 → 技術」の順で頭を切り替えられる。同じ指摘を重複読みする苦痛を避ける。


6. テスト戦略 (Phase 3 固有の事情)

単体テストを最小限にした理由

Phase 1〜2c では test-tc.mjs / test-tc-socratic.mjs / test-tc-consistency.mjs差戻し判定が正しく出るかを検証していた。Phase 3 は差戻しを持たないため、テスト対象は:

  • 3 モデル呼出が並列に走るか → コード上の Promise.all で自明
  • 1 モデル失敗時に残り 2 つで PR 生成できるかcatch ブロックで自明
  • レビュー文面の品質 → これは実起案でしか測れない

→ よって自動テストでカバーすべき差分が薄いため、test-tc-parallel-review.mjs敢えて作らず、運用後にプロンプト改訂の必要性が見えた段階で TC を追加する方針 (YAGNI)。

運用後の TC 整備指針

  • TC-P01: 高品質起案 (TC-07 派生) で 3 モデル全合格 → 全レビュー文が PR 本文に転記されることのみ確認
  • TC-P02: Claude のみ意図的に失敗させて 2 モデルで PR 生成 (モック差し替え)
  • TC-P03: 3 モデル全失敗のとき「(レビュー取得失敗)」セクションが出ること

7. 関連ドキュメント


8. 次の投資領域 (Phase 3 完了後)

設計時に想定した全ゲートが本番稼働。全フェーズ完了を受け、次の投資領域は以下:

  1. ADR 事後評価ループ (ADR-0021 候補) — ADR-0020 §決定 #4 で予告した DORA 指標 / インシデント相関分析。実装した ADR が本当に良い決定だったかを 3-6 ヶ月後に評価
  2. Phase 3 レビュー品質モニタリング — 3 モデルのうちどのレビューが PR 本文で実際にレビュアーの判断を変えたかを記録 → モデル選定 / プロンプト改訂のフィードバック
  3. 02_scoring.md の根拠注記 — ADR-0020 §決定 #2 で予告した「数値閾値は外部根拠なし」明記 (未実施)
  4. MAS 案件起票フローへの応用 (RQ-040 起案中) — Decision Pipeline のゲート設計思想を MAS 案件起票にも展開する案。RQ-040 の調査結果次第