03. Body Generation Node
TL;DR(このノードは何をする・専門語ゼロ): 起案者が自由に書いた背景や代替案のメモを受け取り、決まった書式の判断記録の本文を AI に書き起こさせるノード。前段で見つかった弱点リストがあれば、それも本文の risk 欄などに必ず触れるよう織り込む。ここでは合否を出さず、後続の採点・整合チェック・レビューにかける「原稿」を生み出すのが役目。
実装:
drp/src/nodes/body_generation.tsプロンプト SSoT (KV デプロイ):drp/prompts/production/body-generation/prompt.md(ADR-0042 Type 1) フォールバックプロンプト:body_generation.ts内FALLBACK_PROMPT定数 (KV 取得失敗時) 基盤 ADR: ADR-0023 (テンプレ形式) / ADR-0024 (§1/§5 サブ見出し) / ADR-0030 (Kruchten Type) / ADR-0032 (Implementation Status) / ADR-0036 (Confirmation) / ADR-0042 (KV SSoT)
1. 役割と位置づけ
Socratic〔ソクラテス式問答=前提・代替案を問い直して盲点を洗い出す手法〕を通過した起案を、docs/adr/_template.md 準拠の Markdown ADR〔Architecture Decision Record=技術判断の記録〕本文 に変換するノード。スコアリング・整合性チェック・並列レビューの全ての評価対象となる「素材」を生成する。
- 解決する課題: 起案者は自由記述で context・options を提出するだけで良く、ADR テンプレート (Status / Mode / Kruchten Type〔クルヒテン分類=決定を存在・横断ルール・技術選定のどれかに振り分ける軸〕 / §1.1-1.5 等の構造) は LLM 側で組み立てる。
- 設計思想: 差戻しなし (情報提供型ですらない、純生成ノード)。生成失敗時は例外スロー。
- プロンプトサイズが最大: ADR-0023/0024/0030/0032/0036 で追加された 6 つのテンプレート規約を全て system prompt に詰め込んでいる (約 5KB)。
2. フロー図
flowchart LR
S[socratic] -->|socraticPass=true| B[body_generation]
B --> SC[scoring]
3. トリガー条件
| 条件 | 挙動 |
|---|---|
socratic から socraticPass=true | 実行 |
socratic から socraticPass=false | スキップ (socratic が END に飛ばす) |
buildPreGraph (/chat/start) では実行されない (グラフに含まれない)。
4. 入力 (State)
| State フィールド | 用途 |
|---|---|
title | ADR タイトル (numbering ノードで ADR-??? → ADR-NNNN 置換) |
context | 背景・コンテキスト |
options | 検討した代替案 (任意) |
author | 起案者名 (テンプレの 起案者 メタデータに記載) |
triageMode | Light / Standard / Critical (§1 / §5 のサブ見出し採用判断) |
triageReason | プロンプトに「トリアージ判定理由」として注入 |
blindSpotFindings | Gate 1 (socratic) の盲点検出結果。あれば user message に「## 盲点検出レポート (Gate 1)」として注入し、本文の Risks / Alternatives / 影響範囲 で言及を強制 |
プロンプトに渡す形式:
タイトル: {title}
モード: {triageMode}
起案者: {author}
起案日時 (JST): YYYY-MM-DD HH:MM
## 背景・コンテキスト
{context}
## 検討した代替案
{options} ← options 空なら省略
## トリアージ判定理由
{triageReason}
5. 処理ロジック
1. dateJst を 'sv-SE' + Asia/Tokyo で「YYYY-MM-DD HH:MM」生成 (ADR-0023 統一書式)
2. loadPrompt(env, 'body-generation', FALLBACK_PROMPT) で KV から system prompt 取得
- 成功: KV active pointer の本文を使用
- 失敗: FALLBACK_PROMPT (ハードコード) にフォールバック
- source を console.log で記録
3. loadLlmParams(env, 'body-generation', { temperature: 0.6 }) → createLlm(env, MODELS.body='claude-opus', params.temperature) // 実効値は KV 優先
4. state.blindSpotFindings があれば「## 盲点検出レポート (Gate 1)」を user message に注入 (Risks/Alternatives/影響範囲 で言及を強制)
5. user message を組み立て invoke
6. response.content を文字列化 → adrBody として返す
テンプレート構造 (FALLBACK_PROMPT より):
- Status / Mode / Kruchten Type / Scope (ADR-0049: corporate / platform / product / ops) / Implementation Status / 起案者 / 起案日時 / Deciders をメタデータ表で先頭出力
- §1 コンテキスト: Light=単一節 / Standard・Critical=§1.1-1.5 (背景・現状・課題・制約・目標)
- §2 決定 / §3 検討した代替案 / §4 影響 (Light=単一節 / Standard・Critical=§5.1-5.3) / §5 撤退条件 / §6 参照
- §6.5 Confirmation (ADR-0036): 検証手段 / 実行頻度 / 違反時対応の 3 要素 (Standard/Critical は N/A 不可)
Implementation Status: 必ず Not Started で起案 (固定値、Pipeline は他値を自動付与しない)。
Kruchten Type: Existence / Property / Executive のうち 1〜3 個を / 区切りで列挙。
数値・固有名詞の原文転記ルール (FALLBACK_PROMPT §7): 金額・工数・%・件数・日付・ファイル名・モジュール名・過去 ADR 番号は要約せず原文のまま転記する。
6. LLM 設定
| 項目 | 値 | 根拠 |
|---|---|---|
| モデル | claude-opus (MODELS.body = claude-opus-4-7) | 長文生成・テンプレ厳守・構造化が必要 |
| temperature | KV body-generation params (fallback 0.6) | 文体にバリエーション許容しつつ構造は維持。実効値は KV 優先 (loadLlmParams) |
| プロンプト読み込み | KV (PROMPTS_KV) → active pointer → 失敗時 FALLBACK_PROMPT | ADR-0042 Type 1 ライフサイクル |
| コスト目安 | 0.10〜0.30 USD / 起案 | 入力 5KB + 出力 3〜10KB |
| レイテンシ | 15〜40 秒 | claude-opus の長文生成 |
7. 副作用
PROMPTS_KV.get('body-generation:active')の読込 (失敗は catch 内でフォールバック)console.logでsystem_prompt source=を出力 (Workers Logs で観測)- GitHub API・PR 作成には触れない
8. 出力 (State)
{ adrBody: string } // ADR 本文 (Markdown)、ADR 番号部分は "ADR-???"
ADR 番号は後段の numbering ノードが ADR-NNNN に置換する。
9. 分岐 (次ノード)
.addEdge('body_generation', 'scoring')
無条件で scoring へ。差戻しなし。
10. エラー時の挙動
- KV 取得失敗:
loadPrompt内で catch → FALLBACK_PROMPT を使用 → pipeline 継続 - LLM 失敗: catch なし → 例外スロー → グラフ全体が失敗 (500 エラー)
- 空文字レスポンス: catch なし →
adrBody=''のまま scoring へ → scoring が 0 点判定で差戻し (実用上の防御層)
11. 既知の弱点・運用注意
- プロンプト SSoT 二重管理: FALLBACK_PROMPT (ハードコード) と KV の
prompts/production/body-generation/prompt.mdを一字一句同じに保つ運用 (ADR-0042)。変更時は同一 PR で両方更新 +prompt-kv-push.mjsで KV 反映必須。 - テンプレ規約の追加コスト: 新規 ADR (例: ADR-0036 Confirmation 必須化) のたびに FALLBACK_PROMPT が肥大化。現状約 5KB。将来は section ごとに分割した prompt composition を検討余地。
ADR-???プレースホルダ: body_generation 時点では番号未確定。numbering ノードで置換するため、生成プロンプトでもADR-???と書かせる。numbering 後に検索置換できる形式を維持。- JST 日時:
'sv-SE'ロケール +Asia/Tokyoで ISO 風表記 ("2026-05-13 00:23")。テンプレ「起案日時 (JST): YYYY-MM-DD HH:MM」と一致させる必要 (ADR-0023)。 - 長文生成のタイムアウト: claude-opus の出力 10KB を超えると Cloudflare Workers の CPU 30s 制限に近づく。長すぎる context は LLM 側で要約させるか、起案前に分割を促す運用が必要。
12. テストケース
専用テストなし。実起案で scoring が機能 / 構造を検証する設計 (テンプレ準拠なら 10 項目スコアで合格できるはず)。
将来の改善: _template.md との diff を計算する構造 lint を追加する余地。
13. 過去の設計判断ログ
| 日時 | 変更 | 経緯 |
|---|---|---|
| 2026-05-11 | Phase 2a' 初期実装 | LangGraph 移行と同時 |
| ADR-0023 採択 | 4 桁ハイフン形式・日時書式統一 | 採番形式変更に追随 |
| ADR-0024 採択 | §1.1-1.5 / §5.1-5.3 サブ見出し導入 | Standard/Critical で必須化 |
| ADR-0030 採択 | Kruchten Type 必須化 (3 分類) | 起案者明示 → 過半数一致 → 起案者裁定の優先順位 |
| ADR-0032 採択 | Implementation Status 必須化 | 起案時は Not Started 固定 |
| ADR-0036 採択 | Confirmation セクション必須化 | fitness function〔適合度関数=決定が実装で守られているか継続検証する仕掛け〕3 要素 (検証手段/頻度/違反対応) |
| ADR-0042 採択 | KV SSoT + FALLBACK_PROMPT 二重化 | プロンプト lifecycle 管理 |
14. 関連リンク
- 前ノード: 02_socratic.md
- 次ノード: 04_scoring.md
- ADR テンプレート:
docs/adr/_template.md - テンプレガイド:
docs/adr/README.md("Kruchten 3 分類ガイド" / "Implementation Status ガイド" 節) - 関連 ADR: ADR-0023 / ADR-0024 / ADR-0030 / ADR-0032 / ADR-0036 / ADR-0042 (上記ヘッダー参照)