第7章 設計パターン ── レベルを横断する実装の工夫
パターン一覧
各レベルで共通して現れる設計パターンと、各レベルに特有のパターンを整理する。Martin Fowler.com の “Emerging Patterns in Building GenAI Products” が優れた整理をしており、本章はそれを実プロダクトの事例と照合しながら補足する。
パターン1:RAG(検索拡張生成)
適用レベル:Level 2・3・4に共通
解決する問題:LLMの知識は訓練データで固定されている。プロダクト固有の知識(ヘルプセンター・コードベース・社内ドキュメント)をモデルが知らないために、的外れな回答が出る。
仕組み:
flowchart LR
Q["ユーザーの質問"]
E1["クエリの埋め込み<br/>(ベクトル化)"]
VS["ベクトルDB検索<br/>(コサイン類似度)"]
R["関連ドキュメント断片"]
LLM["LLM"]
A["回答"]
Q --> E1
E1 --> VS
VS --> R
R --> LLM
Q --> LLM
LLM --> A
実装の工夫:
単純なRAGは本番では不十分なことが多い。以下の拡張が実用上必要だ。
| 拡張手法 | 問題 | 解決策 |
|---|---|---|
| Hybrid Retrieval | ベクトル検索だけでは完全一致が弱い | ベクトル検索 + キーワード検索(BM25)を組み合わせる |
| Query Rewriting | ユーザーのクエリが短すぎる | LLMで3〜5通りに言い換えて全パターン検索 |
| Reranker | 検索結果の上位が必ずしも最適でない | 別モデルで「このクエリへの関連度」を再評価 |
| Chunk戦略 | チャンクサイズが合わないと文脈が切れる | 文書の構造に合わせた動的チャンキング |
Sierraの事例:Sierra のナレッジ検索エージェントはRAGを使い、ブランド固有のポリシーやFAQをリアルタイムで取得する。エージェントが回答を生成する前に「この回答の根拠となる文書」を必ず参照し、ハルシネーションを構造的に抑制している。
パターン2:ガードレール(Guardrails)
適用レベル:Level 2・3・4に共通(重要度は上位レベルほど高い)
解決する問題:AIが有害・不適切・ポリシー違反の出力を生成することを防ぐ。マルウェアコードの生成、個人情報の漏洩、ブランドを損なう発言など。
実装アプローチ:
graph TD
IN["ユーザー入力"]
IGU["入力ガードレール<br/>(Input Guardrails)"]
LLM["メインLLM<br/>(タスク実行)"]
OGU["出力ガードレール<br/>(Output Guardrails)"]
OUT["ユーザーへの出力"]
IN --> IGU
IGU -->|"問題なし"| LLM
IGU -->|"脅威検知"| BLOCK["ブロック・リダイレクト"]
LLM --> OGU
OGU -->|"問題なし"| OUT
OGU -->|"違反検知"| FIX["修正・エスカレーション"]
実装の種類:
- LLMベースのガードレール:別モデルが入出力を評価(NeMo Guardrails、Llama Guard)。柔軟だがコストがかかる
- 埋め込みベースのルーティング:Semantic Routerを使って「これはオフトピックな質問か」を高速判定
- ルールベース:正規表現・PII検出(Presidio)。シンプルで高速だが、柔軟性が低い
コストとのトレードオフ:
ガードレールはLLMの追加呼び出しを伴うため、レイテンシとコストが増加する。公開サービスでは必須だが、社内限定ツールでは簡略化を検討できる。判断基準は「誤回答が起きたとき、どのくらいのダメージがあるか」だ。
パターン3:Human-in-the-Loop設計
適用レベル:Level 3・4(Level 2も含む場合あり)
解決する問題:AIが完全に自律している場合、意図しないアクションが実世界に影響を与えてしまう。人間の判断を適切なタイミングで挟む設計。
三種のHuman-in-the-Loop設計:
前置き承認(Pre-approval)
計画作成 → 人間が承認 → 実行
適用:Claude CodeのPlan Mode、Devinのセッション開始、GitHub Copilot AgentのPR作成前
リスクが高いタスク・初回実行・スコープが大きいタスクに適する。
後置き確認(Post-approval)
実行 → 結果 → 人間が確認・承認
適用:GitHub CopilotのPR作成(PRを作って人間がマージ)、Figma AIのデザイン生成
実行が軽微でロールバック可能なタスクに適する。
例外エスカレーション(Exception-based)
自律実行 → 通常は完結 → 例外発生時のみ人間へ
適用:Sierra・Intercom Fin(カスタマーサービス)、Glean Agents
大量の繰り返しタスクで、標準ケースは自律処理し、非標準ケースのみ人間が対応する。
パターン4:信頼度スコアによるルーティング
適用レベル:Level 4に特有(Level 3でも使用)
解決する問題:エージェントは「わからない」ことを「わかる」かのように回答することがある(ハルシネーション)。不確実性を定量化し、対応を分岐させる。
実装:
# 信頼度スコアに基づくルーティングの疑似コード
async def route_by_confidence(query: str, context: str) -> Response:
# メインモデルで回答生成
answer, confidence = await generate_with_confidence(query, context)
if confidence >= HIGH_THRESHOLD: # 例: 0.85以上
return Response(answer, source="ai_autonomous")
elif confidence >= MEDIUM_THRESHOLD: # 例: 0.60以上
# ドラフトとして提示、人間が確認
return Response(answer, source="ai_draft", needs_review=True)
else:
# 人間エージェントへエスカレーション
return escalate_to_human(query, context, answer)
Zendesk AIのデフォルト閾値が60(0-100スケール)で設定されているのは、「まあまあ自信がある場合だけ自律回答する」という安全寄りの設定だ。
パターン5:コンテキスト最適化(Context Engineering)
適用レベル:Level 2・3・4に共通
解決する問題:コンテキストウィンドウは有限だ。詰め込みすぎると、重要な情報が「Lost in the Middle」問題(中間部分の情報が無視されやすい)に陥る。適切な情報を適切な形で渡す設計が必要だ。
主な手法:
プログレッシブ開示:全情報を一度に渡さず、タスクの進行に応じて段階的に提供する。
❌ 悪い例
全APIドキュメント(10,000行)をコンテキストに詰め込む
✅ 良い例
目次 → 「認証について知りたい」と判断 → 認証関連の章のみ提供
ツール出力の圧縮:テスト結果・コマンド出力のような大量のテキストをコンテキストに入れるときは「エラーのみ」にサマリーする(ハーネスエンジニアリングのベストプラクティスと同一)。
階層的なメモリ:
| メモリ種別 | 内容 | 更新頻度 |
|---|---|---|
| 永続メモリ | プロジェクトルール・ユーザー設定 | まれに更新 |
| セッションメモリ | 今回のタスクの文脈 | セッション中 |
| 作業メモリ | 直前の数ターンの会話 | 常時更新 |
Reranker:RAGで検索した複数ドキュメントを、「このクエリへの関連度」で再スコアリングして上位のみをコンテキストに含める。
パターン6:ファインチューニングとRAGの使い分け
適用レベル:Level 2・3・4
解決する問題:ドメイン知識をモデルに持たせる方法として、プロンプトで注入する(RAG)のか、モデル自体を学習させる(ファインチューニング)のかの判断。
意思決定フレームワーク:
Step 1: プロンプトエンジニアリングで解決できるか?
→ できる → そうする(最も安い)
Step 2: RAGで解決できるか?
→ できる → そうする(次に安い)
Step 3: それでも不十分か?
→ ファインチューニングを検討する(高コスト)
ファインチューニングが有効なのは:
- 「回答のフォーマット・トーン・スタイル」を根本から変えたい場合
- ドメイン特有の語彙・概念が多く、毎回プロンプトで説明するコストが高い場合
- モデルの挙動を一貫して特定方向に向けたい場合
コスト警告:Martinfowler.comのパターン集が強調するように、「ファインチューニングの労力の半分はデータ準備・キュレーションに費やされる」。安易にファインチューニングを選ぶとROIが合わないことが多い。
パターン7:Evals(評価基盤の整備)
適用レベル:Level 2・3・4に共通(Level 4では特に重要)
解決する問題:AIの出力は非決定論的だ。「良い出力が出ているか」を機械的に評価する仕組みがなければ、品質の変化に気づけない。
評価の三種類:
| 評価方式 | 内容 | 長所 | 短所 |
|---|---|---|---|
| LLM-as-Judge | 別モデルが出力を採点 | スケール可能・一貫性 | 評価モデルのバイアス |
| 人間評価 | 人間が定性評価 | 最も正確 | スケールしない・高コスト |
| 自己評価 | 同モデルが自分を採点 | 最も安い | エラーの自己強化が起きる |
Level 4での重要性:Level 4では毎回人間が結果を確認しない。そのため、定期的なサンプリングと自動評価のループが「人間の目の代替」として機能する。
SierraがPost-conversation Analysisとして本番会話の自動品質評価を行っているのは、このパターンの実装だ。
パターン8:サブエージェントとオーケストレーション
適用レベル:Level 3・4
解決する問題:単一エージェントが長いタスクを処理するとき、コンテキストが汚染され、精度が落ちる。タスクを分割し、専門エージェントに委任することで品質を維持する。
オーケストレーションの二パターン:
プランナー + ワーカー型:
オーケストレーターエージェント
├── 計画立案
├── タスクA → 検索エージェント(検索に特化)
├── タスクB → コーディングエージェント(実装に特化)
└── タスクC → 検証エージェント(テスト・QAに特化)
パイプライン型:
入力 → エージェントA → エージェントB → エージェントC → 出力
(前処理) (コア処理) (後処理・検証)
コンテキストファイアウォールの効果:サブエージェントが独立したコンテキストウィンドウで処理し、「結果のサマリーのみ」を親エージェントに返すことで、親エージェントのコンテキストが汚染されない。
パターンの適用マップ
graph TD
subgraph L1["Level 1"]
P1a["プロアクティブ提案UX"]
P1b["採用・却下コストの最小化"]
end
subgraph L2["Level 2"]
P2a["RAG(知識注入)"]
P2b["コンテキスト最適化"]
P2c["草稿の明示"]
end
subgraph L3["Level 3"]
P3a["計画・実行の分離"]
P3b["サンドボックス化"]
P3c["ガードレール"]
P3d["観測可能性"]
P3e["最小権限原則"]
end
subgraph L4["Level 4"]
P4a["ポリシー階層化"]
P4b["信頼度ルーティング"]
P4c["エスカレーション設計"]
P4d["継続的Evals"]
P4e["コンステレーション型アーキテクチャ"]
end
次章では、これらのパターンを知らない、あるいは適用を誤ったときに起きるアンチパターンを解剖する。