ストーリー
田
田中VPoE
LLMOpsの全体像を掴んだ。次は運用の要 — モニタリングだ。AIシステムは「動いている」と「正しく動いている」が全く違う
あなた
従来のシステムモニタリングとは何が違うんですか?
あ
田
田中VPoE
従来のシステムはHTTP 200が返ればほぼ正常だ。だがAIシステムはHTTP 200を返しつつ、堂々と嘘をつく。レイテンシが正常でも、回答品質が劣化していることがある。これを検知するのがAI品質モニタリングだ
あなた
「見えない劣化」を検知する必要があるんですね
あ
田
田中VPoE
そうだ。品質の4つの軸 — 精度、レイテンシ、コスト、安全性 — を継続的に監視する仕組みを設計しよう
AI品質の4つの軸
品質フレームワーク
AIシステムの品質は、以下の4つの軸で測定します。
| 軸 | 測定対象 | なぜ重要か |
|---|
| 精度 | 回答の正確性、関連性、完全性 | ユーザーへの価値提供の根幹 |
| レイテンシ | 応答時間、TTFT(Time To First Token) | ユーザー体験に直結 |
| コスト | トークン消費量、API呼び出し回数 | 運用の持続可能性 |
| 安全性 | ハルシネーション率、有害出力、データ漏洩 | 組織のリスク管理 |
AI品質の4軸モデル:
精度
▲
│
│
安全性 ◄──┼──► レイテンシ
│
│
▼
コスト
4軸すべてのバランスが重要:
- 精度を上げるとコスト・レイテンシが増加
- コストを下げると精度が低下
- 安全性を強化すると応答の柔軟性が低下
各軸の具体的メトリクス
| 軸 | メトリクス | 計測方法 | 目標値の例 |
|---|
| 精度 | 回答品質スコア | LLM-as-a-Judge(5段階) | 平均4.0以上 |
| 精度 | RAG検索適合率 | 検索結果と回答の整合性 | 80%以上 |
| 精度 | ユーザー満足度 | 明示的フィードバック | 肯定率80%以上 |
| レイテンシ | TTFT | 最初のトークンまでの時間 | p95 < 2秒 |
| レイテンシ | 総応答時間 | 完全な応答が返るまでの時間 | p95 < 10秒 |
| コスト | リクエスト単価 | トークン数 x 単価 | 平均 $0.05/req以下 |
| コスト | 日次API費用 | 全リクエストの合計費用 | 予算内 |
| 安全性 | ハルシネーション率 | ファクトチェック結果 | 5%以下 |
| 安全性 | 有害出力率 | 安全性フィルタ検知率 | 0.1%以下 |
LLM出力品質の自動評価手法
手法1: LLM-as-a-Judge
別のLLMを「審査員」として使い、出力品質を自動評価する手法です。
# LLM-as-a-Judge の実装例
JUDGE_PROMPT = """
あなたはAI回答品質の審査員です。以下の基準で回答を1-5のスコアで評価してください。
## 評価基準
- 正確性: 事実に基づいているか(1-5)
- 関連性: 質問に適切に回答しているか(1-5)
- 完全性: 必要な情報を網羅しているか(1-5)
- 明確性: わかりやすく説明されているか(1-5)
## 入力
質問: {question}
コンテキスト(参照情報): {context}
AI回答: {response}
## 出力形式(JSON)
{{
"accuracy": <1-5>,
"relevance": <1-5>,
"completeness": <1-5>,
"clarity": <1-5>,
"overall": <1-5>,
"reasoning": "<評価理由>"
}}
"""
class LLMJudge:
def __init__(self, judge_model="gpt-4o"):
self.judge_model = judge_model
def evaluate(self, question, context, response):
prompt = JUDGE_PROMPT.format(
question=question,
context=context,
response=response
)
result = call_llm(self.judge_model, prompt)
return parse_json(result)
| LLM-as-a-Judgeの利点 | 制限事項 |
|---|
| 大量の回答を自動評価できる | 審査LLM自体のバイアスがある |
| 人間の評価と高い相関を示す | コストがかかる(追加のAPI呼び出し) |
| 定性的な判断も可能 | 審査基準の設計が品質に直結 |
| スケーラブル | 完全な代替にはならない(人間評価も必要) |
手法2: 自動メトリクス
| メトリクス | 説明 | 適用場面 |
|---|
| BLEU | n-gramの一致度を測定 | 翻訳、定型的な回答の評価 |
| ROUGE | 参照テキストとの重複度 | 要約タスクの評価 |
| BERTScore | BERT埋め込みの類似度 | 意味的な類似性の評価 |
| Faithfulness | RAGソースとの整合性 | RAGシステムの事実性評価 |
| Answer Relevancy | 質問と回答の関連度 | 質問応答タスクの評価 |
手法3: カスタム評価関数
ビジネス要件に特化した評価ロジックを実装します。
# カスタム評価関数の例
class CustomEvaluators:
@staticmethod
def check_source_citation(response, sources):
"""回答にソースの引用が含まれているか"""
cited = sum(1 for s in sources if s.title in response)
return cited / len(sources) if sources else 0
@staticmethod
def check_format_compliance(response, expected_format):
"""期待されるフォーマットに準拠しているか"""
if expected_format == "json":
try:
json.loads(response)
return 1.0
except json.JSONDecodeError:
return 0.0
elif expected_format == "markdown_table":
return 1.0 if "|" in response and "---" in response else 0.0
@staticmethod
def check_prohibited_content(response, prohibited_terms):
"""禁止用語が含まれていないか"""
violations = [t for t in prohibited_terms if t in response]
return 0.0 if violations else 1.0
モデルドリフトと品質劣化の検出
ドリフトの種類
AIシステムの品質は時間とともに劣化します。これを「ドリフト」と呼びます。
| ドリフト種別 | 原因 | 検出方法 |
|---|
| データドリフト | ユーザーの質問傾向が変化 | 入力データの分布監視 |
| コンセプトドリフト | 正解の基準が変化(規則改定等) | 定期的なベンチマーク評価 |
| モデルドリフト | プロバイダーのモデル更新 | モデルバージョン監視 + 回帰テスト |
| RAGドリフト | ナレッジベースの陳腐化 | ドキュメント鮮度の追跡 |
品質劣化の検出フロー:
日次バッチ評価
│
├── 品質スコアの移動平均を計算
│ │
│ ├── 7日移動平均 < 閾値 → Warning
│ └── 3日連続で低下 → Critical
│
├── 入力分布の変化を検出
│ │
│ └── KLダイバージェンス > 閾値 → データドリフトアラート
│
└── カテゴリ別品質分析
│
└── 特定カテゴリの品質低下 → RAGドリフトの可能性
品質劣化の検出ルール
| 検出ルール | 条件 | アクション |
|---|
| 急激な品質低下 | 品質スコアが前日比20%以上低下 | 即座にアラート、原因調査開始 |
| 緩やかな品質低下 | 7日移動平均が2週間で10%低下 | 週次レビューで議論 |
| カテゴリ別異常 | 特定カテゴリのみ品質が低下 | RAGデータの更新確認 |
| レイテンシ劣化 | p95が基準値の150%を超過 | インフラ調査、モデル変更の確認 |
| コスト急増 | 日次コストが予算の120%を超過 | 利用パターンの分析、レート制限の検討 |
ハルシネーション検出と対策
ハルシネーションの分類
| 種別 | 説明 | 例 | 危険度 |
|---|
| 事実誤認 | 存在しない事実を生成 | 架空の法律条文を引用 | 極めて高い |
| 過度の一般化 | 特定の事実を過度に一般化 | 一社の事例を業界全体の傾向と説明 | 高い |
| 文脈逸脱 | コンテキストにない情報を追加 | RAGソースにない情報を「ソースによると」と記述 | 高い |
| 自信過剰 | 不確実な情報を断定的に記述 | 「必ず」「確実に」等の表現 | 中 |
検出手法
# ハルシネーション検出の実装例
class HallucinationDetector:
def detect(self, query, response, rag_sources):
results = {
"source_grounding": self._check_source_grounding(
response, rag_sources
),
"entity_verification": self._verify_entities(response),
"confidence_calibration": self._check_overconfidence(response),
"self_consistency": self._check_self_consistency(
query, response
),
}
return results
def _check_source_grounding(self, response, sources):
"""回答がRAGソースに基づいているか検証"""
claims = extract_claims(response)
grounded = 0
for claim in claims:
if any(is_supported(claim, source) for source in sources):
grounded += 1
return grounded / len(claims) if claims else 1.0
def _check_self_consistency(self, query, response):
"""同じ質問を複数回実行し、回答の一貫性を検証"""
responses = [generate_response(query) for _ in range(3)]
consistency = calculate_similarity(responses)
return consistency # 低い一貫性 = ハルシネーションの可能性
対策マトリクス
| 対策 | 効果 | 実装コスト | 適用場面 |
|---|
| RAGの活用 | 高 | 中 | ナレッジベースが整備されている場合 |
| ソース引用の強制 | 中 | 低 | 回答の根拠を示す必要がある場合 |
| 信頼度スコアの付与 | 中 | 中 | ユーザーが判断材料を必要とする場合 |
| 人間によるレビュー | 高 | 高 | 高リスクな回答(法務、医療等) |
| 出力のファクトチェック | 高 | 高 | 事実性が重要な場面 |
| temperatureの調整 | 低-中 | 低 | 創造性より正確性が重要な場合 |
アラート設計
いつ人間が介入すべきか
| アラートレベル | 条件 | 対応 | 通知先 |
|---|
| P1 Critical | 有害出力の検出、データ漏洩の疑い | 即座にサービス停止を検討 | オンコール担当 + マネージャー |
| P2 High | ハルシネーション率が10%超、品質スコアが急落 | 4時間以内に原因調査 | オンコール担当 |
| P3 Medium | 品質スコアの緩やかな低下、コスト超過 | 24時間以内に対応 | チームチャンネル |
| P4 Low | レイテンシの軽微な増加、利用量の変動 | 次回の定期レビューで確認 | ダッシュボード |
# アラートルール定義の例
alerts:
- name: "critical_safety_violation"
level: "P1"
condition: |
safety_filter.violation_count > 0
AND safety_filter.severity == "critical"
action:
- notify: ["oncall", "manager", "security-team"]
- auto_action: "enable_fallback_mode"
cooldown: 0 # 即座に通知
- name: "quality_degradation"
level: "P2"
condition: |
quality_score.7day_moving_avg < 3.5
OR quality_score.daily_change < -20%
action:
- notify: ["oncall"]
- auto_action: "increase_sampling_rate"
cooldown: 3600 # 1時間に1回
- name: "cost_overrun"
level: "P3"
condition: |
daily_cost > budget_daily * 1.2
action:
- notify: ["team-channel"]
- auto_action: "enable_rate_limiting"
cooldown: 86400 # 1日に1回
ダッシュボード設計
3層ダッシュボード
| 層 | 対象者 | 表示内容 | 更新頻度 |
|---|
| エグゼクティブ | 経営層 | ROI、利用量推移、コスト概要 | 週次 |
| オペレーション | 運用チーム | 品質スコア、エラー率、レイテンシ | リアルタイム |
| テクニカル | 開発チーム | トレース詳細、プロンプト別性能、RAG精度 | リアルタイム |
オペレーションダッシュボードの構成例
┌──────────────────────────────────────────────────────┐
│ AI品質モニタリング ダッシュボード │
├──────────────┬──────────────┬──────────────┬─────────┤
│ 品質スコア │ レイテンシ │ コスト │ 安全性 │
│ ████ 4.2/5 │ p95: 1.8s │ $234/日 │ 0.05% │
│ ▲ +0.1 │ ▼ -0.2s │ ▲ +12% │ ● 正常 │
├──────────────┴──────────────┴──────────────┴─────────┤
│ 品質スコア推移(30日) │
│ 5 ┤ │
│ 4 ┤ ────────────────────────────── │
│ 3 ┤ │
│ 2 ┤ │
│ └────────────────────────────────────────── │
├──────────────────────────────────────────────────────┤
│ カテゴリ別品質 │ 直近のアラート │
│ FAQ: 4.5 ████████ │ ● P3 コスト超過 (2h前) │
│ 技術: 4.0 ███████ │ ● P4 レイテンシ微増 (6h前) │
│ 規約: 3.8 ██████ │ │
│ 一般: 4.3 ████████ │ │
├──────────────────────────────────────────────────────┤
│ ハルシネーション率: 3.2% │ ユーザー満足度: 82% │
│ 目標: <5% ● 達成 │ 目標: >80% ● 達成 │
└──────────────────────────────────────────────────────┘
ダッシュボードに含めるべき主要ウィジェット
| ウィジェット | 表示内容 | アラート連携 |
|---|
| 品質スコアゲージ | 現在の品質スコアと目標値 | 閾値割れでP2アラート |
| レイテンシグラフ | p50/p95/p99の推移 | p95超過でP3アラート |
| コスト推移 | 日次/月次のAPI費用推移 | 予算超過でP3アラート |
| ハルシネーション率 | 検出されたハルシネーションの割合 | 急増でP2アラート |
| トラフィックマップ | リクエスト数とカテゴリ分布 | 異常なパターンでP4アラート |
| フィードバック集計 | ユーザー評価の集計 | 満足度低下でP3アラート |
| エラー一覧 | 直近のエラーとスタックトレース | エラー率急増でP2アラート |
まとめ
| ポイント | 内容 |
|---|
| 品質の4軸 | 精度、レイテンシ、コスト、安全性のバランスを取る |
| 自動評価 | LLM-as-a-Judge、自動メトリクス、カスタム評価関数を組み合わせる |
| ドリフト検出 | データ、コンセプト、モデル、RAGの4種類のドリフトを監視する |
| ハルシネーション | ソース照合、エンティティ検証、自己一貫性チェックで検出 |
| アラート設計 | P1-P4の4段階で、対応の緊急度と通知先を明確化する |
| ダッシュボード | エグゼクティブ、オペレーション、テクニカルの3層で設計 |
チェックリスト
次のステップへ
次は「AIインシデント対応」です。AIシステム固有の障害にどう対応するか、プレイブックの作成方法を学びましょう。
推定読了時間: 30分