型付き辺: 出 16 / 入 3
ADR-0042: LLM プロンプトのライフサイクル管理ポリシーを採択する
- Status: Accepted
- Mode: Standard
- Kruchten Type: Existence/Property/Executive
- Scope: platform
- Implementation Status: Done (PR #743, #744, #745, #746, #1090)
- Notes: 2026-05-28 — ADR-0085 で全ノードへの
loadPromptパターン適用が完了 (PR #1090)。対象 8 ノード:gate0-triage/gate1-da/gate1-pm/gate1-judge/gate2-consistency/gate4-scoring/policy-alignment/cross-validation。parallel_reviewは動的テンプレートのためスコープ外 (今後の課題) - 起案者: [email protected]
- 起案日時 (JST): 2026-05-15 15:39
- 承認日時 (JST): 2026-05-15 17:00
- Deciders: [email protected]
決定の早わかり(Y-statement)
本節は ADR-0140 の方針で遡及追加された本文の要約で、新しい意味は加えていない (意思決定内容は不変)。「文脈で問題に直面し、対抗案でなくこの案を選び、目的のため代償を受け入れる」と読む。詳細はコンテキスト以降の本文に展開する。
- 文脈: bizlp には Decision Pipeline (Gate 0-4)・調査プロンプト (RQ-NNN)・Claude Code エージェントテンプレートなど複数種のプロンプトが存在する。
- 問題: バージョン管理・評価・デプロイ・ロールバックのポリシーが未定義のまま ad-hoc に変更され、Prompt Drift と Prompt Regression を検知する仕組みがない。障害時は手動切り戻しに 30 分〜数時間を要した。
- 問題点と課題(直せる原因 → 発生を止めるためにやること):
- eval CI・回帰テストの不在 →
prompts/production/**への PR 時に Promptfoo を自動実行し、閾値割れを merge block する。 - ロールバック手順の未整備 → Cloudflare KV の Active Pointer パターンで、ポインタ書き換えのみで復旧する (目標 5 分以内)。
- プロンプト種別ごとの管理方針が未統一 → Type 1〜4 の分類と状態遷移・SemVer ルールを定義する。
- eval CI・回帰テストの不在 →
- 前提(解決を課題に立てない与件):
- 月予算 $50 以内 (SaaS 費用 + LLM API 従量課金を含む)・実働 1 名。
- 既存スタック (Cloudflare Workers + GAS + LangGraph TS + GitHub Actions) を前提とする。
- 調査用プロンプト (Type 3) への厳格管理の適用と SaaS 導入は Non-Goals。
- 決定(対応策): 案 A (Monorepo + Promptfoo + GHA のみ) や案 B (Polyrepo + Cloudflare KV) でなく、案 C (Monorepo + Cloudflare KV 動的ロード + Langfuse Hobby) を採用する。git を唯一の source of truth とし、CI が本番プロンプトを KV に自動プッシュする。
- 目的: 本番プロンプト (Type 1) に「バージョン管理 → eval CI → デプロイ → ドリフト監視 → ロールバック」の一貫したライフサイクルを確立する。
- 代償: golden.jsonl 初期構築 (計 100 件以上) の人手作業と、Cloudflare KV プロビジョニング + CI 構築の初期工数 (AI 支援あり 2-3 日) が発生する。git と KV に「正本」と「キャッシュ」の概念が生まれ、運用ガイドが必要になる。
- 詳細は本文の影響・撤退条件セクションを参照のこと
1. コンテキスト
1.1 背景 (Background)
bizlp では ADR Decision Pipeline(Gate 0-4)・調査プロンプト(RQ-NNN)・Claude Code エージェントテンプレートなど複数種のプロンプトが存在するが、バージョン管理・評価・デプロイ・ロールバックのポリシーが未定義のまま運用されている。RQ-044(3 モデル並列調査)にて Promptware Engineering(arXiv:2503.02400)をはじめとする学術・業界知見を収集し、ADR 起草の根拠とした。
1.2 現状 (Current State / As-Is)
- 本番 LLM パイプライン(Gate 0-4)のプロンプトはコード内にハードコードまたは非構造的ファイルとして散在(対象 5 本 / Gate 0〜4)
- バージョン履歴は git commit のみ(変更理由の文書化率は業界実証研究で 21.9% / arXiv:2412.17298)。変更頻度は月 2〜4 回程度
- eval CI なし・回帰テストなし・ロールバック手順未定義。過去の対応実績では障害確認から手動切り戻しまで 30 分〜数時間を要した(MTTR 非計測)
- 調査用プロンプト(RQ-NNN)は
docs/_internal/research_prompts/に整理済みだが、本番プロンプトとの管理方針が統一されていない
1.3 課題 (Problem)
本番 Gate プロンプトをモデルアップデートや文言修正のたびに ad-hoc に変更しており、Prompt Drift(モデル更新による無編集の挙動変化)と Prompt Regression(意図的編集による性能劣化)を検知する仕組みがない。障害発生時のロールバック手順も未整備のため、復旧に不定の時間がかかる。
1.4 制約・要件 (Constraints & Requirements)
- 月予算 $50 以内(SaaS 費用 + LLM API 従量課金を含む)。eval CI での LLM API 使用は temperature=0 固定・Type 1 が 5 本の場合 PR 実行 20 回/月 × 3 サンプル = 300 リクエスト程度で Claude API 費用は $1 未満の見込み
- 実働 1 名(Jr. 参加 D-180 以降)
- 既存スタック:Cloudflare Workers + GAS + LangGraph TS + GitHub Actions
- 監査要件:変更履歴・判断根拠の追跡可能性
1.5 目標 (Goals / To-Be)
本番プロンプト(Type 1)に対して「バージョン管理 → eval CI → デプロイ → ドリフト監視 → ロールバック」の一貫したライフサイクルを確立する。Non-Goals:調査用プロンプト(Type 3)への厳格管理の適用、SaaS 導入。
2. 判断基準 (Decision Drivers)
- 品質保証の再現性 — プロンプト変更が性能を劣化させないことを PR 段階で機械的に検証できるか
- Prompt Drift の検知 — モデルアップデート後の性能変化を自動検知できるか
- ロールバック速度 — 本番障害時に 5 分以内に復旧できるか
- 月 $50 予算制約 — SaaS を最小化し OSS で完結できるか
- Jr. 参加後の拡張性 — 業務委託アクセス制御・観測基盤を段階的に追加できるか
3. 検討した代替案 (Alternatives Considered)
案 A: Monorepo + Promptfoo + GHA のみ(アプリ同梱)
- Good, because コードとプロンプトを同一 PR で atomic に変更でき、バージョン同期崩れがない
- Good, because 追加インフラゼロ
- Bad, because アプリ再デプロイなしでプロンプトだけ更新・ロールバックできない
- Bad, because モデル更新ドリフトの自動検知機構がなく週次監視が手動になる
案 B: Polyrepo(
bizlp-prompts専用リポ)+ Cloudflare KV- Good, because 業務委託者へのリポジトリ単位アクセス制御が可能
- Good, because KV 経由でアプリ再デプロイ不要のプロンプト更新が可能
- Bad, because 現状(1 人法人)ではアクセス制御要件が存在せず 2 リポジトリ管理の運用コストが過剰
- Bad, because コードとプロンプトの変更が別 PR になり atomic 性が失われる
案 C: Monorepo + Cloudflare KV 動的ロード + Langfuse Hobby(採用案)
- Good, because 案 A の atomic 変更を維持しつつ、案 B の KV ロールバック速度も確保
- Good, because Phase 2(業務委託要件発生時)の Polyrepo 移行パスを保持
- Bad, because Cloudflare KV のプロビジョニングと CI パイプライン構築が初期コストになる
- Bad, because git と KV の 2 箇所に「正本」と「キャッシュ」の概念が生まれ、運用ガイドが必要
4. 決定 (Decision Outcome)
採用: 案 C(Monorepo + Cloudflare KV 動的ロード + Langfuse Hobby)。
git を唯一の source of truth とし、CI が本番プロンプトを Cloudflare KV に自動プッシュするアーキテクチャを採用する。以下のポリシーをすべて同時に採択する。
プロンプト分類(Type)
| Type | 対象 | 管理レベル |
|---|---|---|
| Type 1 | 本番 LLM パイプライン(Gate 0-4 等) | SemVer 厳格 / eval CI 必須 / KV デプロイ |
| Type 2 | Claude Code エージェントテンプレート | v1.14 形式 / git 追跡 / self-review 可 |
| Type 3 | 調査・使い捨てプロンプト(RQ-NNN) | YYYYMMDD-topic 命名 / 任意レビュー |
| Type 4 | 生成中間物 | .gitignore 対象(バージョニング不要) |
状態遷移(Type 1)
draft → experiment → candidate → production → deprecated → archived
production は Immutable。変更は必ず新バージョンの PR を経由する。deprecated から 90 日後に archived へ自動遷移。
SemVer ルール(Type 1 のみ)
| バンプ | 定義 | 補足 |
|---|---|---|
| MAJOR | 出力スキーマ破壊・必須入力変数追加・呼び出し側契約変更 | — |
| MINOR | 後方互換の機能追加・Few-shot 追加・評価観点拡張 | — |
| PATCH | 表現修正・誤字・同世代モデル差し替え | eval 閾値を下回ったら merge block(PATCH のままリトライ可、意味的破壊を伴う場合は MAJOR に手動昇格) |
eval CI(Static 方式)
prompts/production/** への PR 時に GitHub Actions(Promptfoo)が自動実行。合格率が prompt.meta.yaml の eval_pass_threshold を下回ったら merge block。全体絶対下限は .promptpolicy.yaml の global_min_threshold: 0.70 で定義(個別設定はこの値以上でなければならない)。
meta.yaml 必須フィールド(Type 1)
id: # kebab-case 一意識別子
owner: # メールアドレス
status: # draft | experiment | candidate | production | deprecated | archived
semver: # X.Y.Z
model_pin: # 【廃止 2026-06-08】runtime 未使用 (SSoT=src/llm/gateway.ts MODELS)・必須から削除。下記「モデル Pin による Drift 検知」は未実装の建前だった
inputs: [] # 入力変数定義
output_schema: # JSON Schema ファイルへの相対パス
eval_suite: # golden.jsonl への相対パス(最低 20 件)
eval_pass_threshold: # 例: 0.85(global_min_threshold 0.70 以上)
kv_key: # Cloudflare KV キー名(例: bizlp:prompts:gate0:active)
deprecation_at: # null または ISO 8601 日付
Cloudflare KV デプロイ(Active Pointer パターン)
KV に複数バージョンのプロンプト本文を並存させ、{kv_key}:active が現在有効バージョンを指す。ロールバックはポインタ書き換えのみで完了(目標 5 分以内)。
5 分の時間予算内訳(KV の Eventually Consistent 特性を考慮):
| 工程 | 上限 |
|---|---|
| 障害検知(Langfuse アラート → 担当者確認) | 1 分 |
| 判断・ポインタ書き換え操作 | 1 分 |
| KV エッジへの伝播完了(グローバル整合性) | 最大 60 秒 |
| 動作確認 | 1 分 |
伝播完了前(最大 60 秒)は新旧プロンプトが混在する状態が発生しうるが、Gate 審査の冪等性(同一入力に対して合否判定が逆転しない)を前提に許容する設計とする。
CI は PR マージ後に KV を自動更新する。GAS 側 LLM 呼び出しが発生した場合は UrlFetchApp 経由で KV を参照し、CacheService(TTL 60 秒)でキャッシュして日次クォータと 6 分実行制限への影響を最小化する(source of truth = git、KV = ランタイムキャッシュ)。
eval 2 層構成
- PR 時:ノード単体 eval(Promptfoo、merge block 判定)
- 週次 cron(月曜 0:00 JST):パイプライン end-to-end eval(品質俯瞰・GitHub Issue 自動起票)。golden.jsonl が各プロンプト 20 件以上揃った段階で有効化
LLM-as-Judge 設計原則
位置スワップ(A/B と B/A の両方を評価)+ マルチサンプル(単発評価禁止)+ rubric にスタイルバイアス無視を明示 + 判定モデルと被判定モデルを別系列に。pairwise 評価結果は絶対順位として扱わない(非推移性 / arXiv:2502.14074)。
Observability
Langfuse Hobby(無料)で開始。2 名体制以降は Core $29/月へ移行(月 $50 制約内)。
5. 影響 (Consequences)
5.1 正の影響 (Good)
- Good, because PR ごとの eval gate により「壊れたプロンプトが本番に入る」事故を機械的に防止できる
- Good, because KV Active Pointer パターンにより本番障害時のロールバックが 5 分以内で完了する
Good, because モデル Pin(【撤回 2026-06-08】model_pin は runtime 未使用で drift 検知に未配線だった (週次 cron は promptfoo 回帰=出力ベース)。model_pin を廃止しモデル選択 SSoT をmodel_pin)+ 週次 cron により Prompt Drift を自動検知し、無編集での挙動変化に気づけるsrc/llm/gateway.tsMODELS に一本化- Good, because Phase 2 で Polyrepo に移行する場合も KV パイプラインをそのまま継続できる
5.2 負の影響 (Bad)
- Bad, because golden.jsonl の初期構築(各プロンプト 20 件)は人手作業を要し、Type 1 が 5 本であれば計 100 件以上のテストケース設計が必要
- Bad, because Cloudflare KV のプロビジョニングと CI(GHA → KV push)の実装が初期工数として発生する(AI 支援あり: 2-3 日 / 手作業: 5-7 日)。KV 運用コストは Workers Paid($5/月)の範囲内に収まる見込み(Read ~10k 件/月・Write ~100 件/月は無料枠内)
- Bad, because git と KV の 2 箇所に「正本」と「キャッシュ」が存在することを全員が理解していないと、KV を直接手動編集してしまうリスクがある。KV と git の乖離検知は CI の
kv:getvsgit show差分チェックで毎週実施する - Bad, because eval CI が flaky になった場合(LLM 非決定性・ネットワーク断)の誤 merge block を防ぐため、Promptfoo 実行時は
temperature: 0固定 + 同一ケースを 3 サンプル実行して多数決判定とし、CI 失敗時は--retries 2でリトライ、2 回連続失敗のみ block 扱いとする。golden.jsonl への本番機密情報・個人情報の混入を防ぐため、CI に PII スキャン(正規表現ベース)ステップを追加する
5.3 中立・トレードオフ (Neutral / Trade-offs)
- Neutral, because Type 2(Claude Code テンプレート)への SemVer 適用は Jr. 参加後・20 本超えで再評価する(現状は過剰投資と判断)
- Neutral, because A/B テストの統計的有意性(Bradley-Terry モデル)は本番トラフィックが 1 日 100 件超になった時点で再評価。現状は offline eval 優先
- Neutral, because golden.jsonl が 20 件/プロンプトに肥大化すると週次 cron の実行時間・コストが増大する。Type 1 が 10 本を超えた段階でサンプリング戦略(最新 20 件のローリングウィンドウ)への移行を検討する
- Review After: 2026-11-11(Jr. 参加 D-180 時点)。全再評価トリガーの棚卸しと golden.jsonl 整備状況を確認する
- 中間マイルストーン:
- D+60(2026-07-14 目安): golden.jsonl 初期整備完了(Type 1 全 5 本 × 20 件)。これをもって週次 cron を有効化
- D+90(2026-08-13 目安): 初回ロールバック演習実施。KV ポインタ切り替えの MTTR を実測し「5 分以内」を検証
6. 撤退条件 (Rollback Plan)
- 再評価トリガー 1: 業務委託者に特定プロンプトのみ編集権限を付与する要件が発生した場合 → Polyrepo(
bizlp-prompts分離)を評価 - 再評価トリガー 2: プロンプト数が Type 1 で 20 本超かつ評価管理の UI が必要になった場合 → Agenta OSS 自己ホストを評価
- 再評価トリガー 3: Cloudflare KV コスト(現在 $5/月〜)が他サービス合計で $50 を超えた場合 → 案 A(アプリ同梱・KV なし)への後退、または Upstash Redis(従量課金 $0.2/10 万リクエスト)への移行を評価。PropertiesService は GAS 専用・Workers から参照不可のため代替にならない
- 判定タイミング: Jr. 参加時(D-180)に全トリガーを棚卸し
- 判定主体: [email protected]
Confirmation (準拠確認 / Fitness Function)
- 検証手段 1(eval CI):
.github/workflows/prompt_eval.yml—prompts/production/**への PR 時に Promptfoo を実行しeval_pass_thresholdとglobal_min_thresholdの両方を検証 - 検証手段 2(週次 Drift 監視):
.github/workflows/prompt_regression_cron.yml— 毎週月曜 0:00 JST に全 Type 1 × golden.jsonl を実行、閾値割れで GitHub Issue 自動起票 - 検証手段 3(meta.yaml lint):
prompt_eval.ymlの第 1 ステップで必須フィールド・eval_pass_threshold ≥ global_min_thresholdを静的チェック - 実行頻度: PR ごと(eval CI)/ 週次(cron)/ golden.jsonl 20 件充実後に cron を有効化
- 違反時の対応: eval CI → merge block / 週次 cron → GitHub Issue 自動起票
- ビジネス KPI(完了条件):
- 本番障害時の MTTR ≤ 5 分(KV ポインタ切り替えで達成、初回ロールバック演習で実測)
- Prompt Drift 検知まで ≤ 1 週間(週次 cron が golden.jsonl 有効化後に達成)
- eval pass rate トレンドを Langfuse ダッシュボードで可視化できる状態
7. 参照 (References)
- 関連 ADR:
- ADR-0019(Decision Pipeline LangGraph 採用)— 依存: 本 ADR は Gate 0-4 プロンプトを Type 1 として管理対象とする。ADR-0019 で確立した Workers + KV インフラを前提とするため、ADR-0019 の Supersede・廃止が生じた場合は本 ADR も再評価する
- ADR-0013(Env モジュール / Feature Flag)— 依存 / 非衝突: KV バインディングの命名空間(
bizlp:prompts:*)を ADR-0013 の Feature Flag namespace(bizlp:flags:*)と分離することで衝突を回避。KV バインディングの追加は ADR-0013 の設計を拡張するが、既存 Env モジュールの変更は不要
- 関連 RQ: RQ-044(LLM プロンプトライフサイクル管理ベストプラクティス調査)
- Synthesis 資料:
docs/_internal/01_discovery/research_prompts/RQ-044_synthesis.md
Status / Mode / Scope は 2026-06-11 に遡及追加 (ADR-0031 corrigendum パターン)。出典: Status = 旧形式「## ステータス」節の機械転記 / Mode = 旧 README §既存 ADR 一覧の推定値 (git 履歴) / Scope = ADR-0049 4 層分類の遡及付与 (PR レビューで確定)。
- 主要論文:
- Promptware Engineering — arXiv:2503.02400
- Prompts Are Programs Too — arXiv:2409.12447
- Prompting in the Wild(GitHub 243 リポ実証研究)— arXiv:2412.17298
- SPEAR / Prompts as First-Class Citizens — arXiv:2508.05012
- LLM-as-Judge Survey — arXiv:2411.15594
- pairwise judge 非推移性 — arXiv:2502.14074
- 関連 PR/Issue: -
- 後続 ADR からの逆参照(ADR-0031 メタデータ後付け・本文不変): 運用プロンプト(
tasks/prompts/の申し送り・実装指示・調査メモ)は本 ADR の Type 体系の対象外 — 所属の定義は ADR-0132、退避機構と Type 1 昇格フロー(production_pipeline: trueフラグ →prompts/production/へ編入)は ADR-0134 を参照(2026-06-11 追記)