T-CREATOR

Dify 本番運用ガイド:SLO/SLA 設定とアラート設計のベストプラクティス

Dify 本番運用ガイド:SLO/SLA 設定とアラート設計のベストプラクティス

Dify で構築した AI アプリケーションを本番環境で運用する際、安定性と信頼性を担保するためには適切なモニタリング体制が欠かせません。本記事では、SLO(Service Level Objective)と SLA(Service Level Agreement)の設定方法、そしてアラート設計のベストプラクティスを具体的に解説します。

これから紹介する内容を実践することで、ビジネス要件に合わせた信頼性の高い運用体制を構築できるでしょう。

背景

Dify における本番運用の重要性

Dify は AI アプリケーション開発を効率化する優れたプラットフォームですが、本番環境で安定稼働させるためには、従来の Web アプリケーションとは異なる観点での運用管理が求められます。

LLM(大規模言語モデル)を活用したアプリケーションでは、以下のような特有の課題があります。

  • API 呼び出しのレイテンシが不安定
  • トークン消費によるコスト変動
  • モデルの応答品質のばらつき
  • 外部 API への依存による障害リスク

これらの課題に対処するため、適切な SLO/SLA 設定とアラート体制の構築が必要になります。

SLA、SLO、SLI の関係性

本番運用を設計する前に、サービスレベルに関する 3 つの重要な概念を整理しましょう。

以下の図は、これら 3 つの指標がどのように関連しているかを示しています。

mermaidflowchart TB
    sla["SLA<br/>(Service Level Agreement)<br/>顧客との契約"]
    slo["SLO<br/>(Service Level Objective)<br/>内部目標値"]
    sli["SLI<br/>(Service Level Indicator)<br/>測定可能な指標"]

    monitor["モニタリングシステム"]
    alert["アラート発火"]

    sla -->|"より厳しい目標"| slo
    slo -->|"達成度を測定"| sli
    sli -->|"データ収集"| monitor
    monitor -->|"閾値超過"| alert

    style sla fill:#ff9999
    style slo fill:#ffcc99
    style sli fill:#99ccff

図で理解できる要点:

  • SLA は顧客との約束であり、違反するとペナルティが発生する可能性があります
  • SLO は SLA よりも厳しい内部目標として設定し、バッファを確保します
  • SLI は実際に計測可能な具体的な指標で、SLO の達成度を評価します
#用語説明
1SLAサービス提供者と利用者の間で結ぶ契約。違反時の補償も含まれる「月間稼働率 99.9% を保証」
2SLOSLA 達成のために設定する内部目標。SLA より厳しく設定「月間稼働率 99.95% を目標」
3SLISLO の達成を判断するために使用される測定可能な指標「API レスポンス時間」「エラー率」

SLO を SLA よりも厳しく設定することで、実際に SLA 違反が発生する前にアラートを受け取り、対応する時間的余裕を確保できます。

Dify のアーキテクチャと監視ポイント

Dify は複数のコンポーネントで構成されており、それぞれが異なる役割を担っています。

mermaidflowchart LR
    user["エンドユーザー"]
    web["Web<br/>フロントエンド"]
    api["API サーバー<br/>(Flask)"]
    worker["Worker<br/>非同期処理"]
    sandbox["Sandbox<br/>コード実行環境"]

    redis[("Redis<br/>キャッシュ・キュー")]
    postgres[("PostgreSQL<br/>メインDB")]
    vector[("Qdrant/Weaviate<br/>ベクトルDB")]

    llm["LLM API<br/>(OpenAI等)"]

    user -->|"HTTPS"| web
    web -->|"REST API"| api
    api -->|"タスク送信"| worker
    api -->|"安全実行"| sandbox

    api -.->|"セッション"| redis
    worker -.->|"ジョブキュー"| redis
    api -.->|"永続化"| postgres
    api -.->|"ベクトル検索"| vector

    api -->|"プロンプト送信"| llm
    worker -->|"バッチ処理"| llm

    style api fill:#99ccff
    style worker fill:#99ccff
    style llm fill:#ffcc99

図で理解できる要点:

  • API サーバーと Worker はスケーリング可能なステートレスコンポーネントです
  • Redis、PostgreSQL、ベクトル DB は状態を保持する重要なデータストアです
  • 外部 LLM API への依存があるため、その可用性も考慮する必要があります

各コンポーネントで監視すべきポイントは以下の通りです。

#コンポーネント監視項目重要度
1API サーバーレスポンスタイム、エラー率、CPU/メモリ使用率★★★
2Workerジョブ処理時間、キュー滞留数、失敗率★★★
3Redisメモリ使用率、接続数、レイテンシ★★☆
4PostgreSQLクエリ実行時間、接続数、ディスク使用率★★★
5ベクトル DB検索レイテンシ、インデックスサイズ★★☆
6LLM APIAPI レスポンスタイム、トークン消費量、エラー率★★★

課題

Dify 標準機能の限界

Dify には標準でモニタリング機能が搭載されていますが、本格的な本番運用には以下のような限界があります。

標準モニタリング機能で確認できる指標:

#指標内容制約
1質問回数1 日ごとのチャットボットとの対話回数時間単位での詳細分析は不可
2ユーザー満足度1000 メッセージごとの「いいね」数リアルタイム性に欠ける
3トークン消費量1 日ごとの LLM へのトークン消費量コスト最適化には粒度が粗い
4実行ログアプリケーションの実行履歴アラート機能がない

Dify の標準機能では、以下のような重要な運用要件を満たせません。

  • リアルタイムアラート通知
  • 複数サービスの統合監視
  • 詳細なパフォーマンス分析
  • カスタマイズ可能な SLI 設定
  • 障害時の自動エスカレーション

SLO/SLA 設計における課題

AI アプリケーション特有の特性により、従来の Web アプリケーションと同じ SLO/SLA 設計は適用できません。

mermaidflowchart TB
    subgraph traditional["従来の Web アプリ"]
        web_req["リクエスト"]
        web_db[("DB クエリ")]
        web_res["レスポンス"]

        web_req --> web_db
        web_db --> web_res

        web_note["予測可能な<br/>レスポンスタイム<br/>(10-100ms)"]
    end

    subgraph ai_app["AI アプリ (Dify)"]
        ai_req["リクエスト"]
        ai_vector[("ベクトル検索")]
        ai_llm["LLM API<br/>呼び出し"]
        ai_res["レスポンス"]

        ai_req --> ai_vector
        ai_vector --> ai_llm
        ai_llm --> ai_res

        ai_note["不安定な<br/>レスポンスタイム<br/>(1-10s+)"]
    end

    style traditional fill:#e6f3ff
    style ai_app fill:#fff3e6

AI アプリケーション特有の課題:

  1. レイテンシの変動が大きい

    • LLM の応答時間は入力長やモデルの負荷状況に依存します
    • P50、P95、P99 で大きな差が生じるため、単純な平均値では評価できません
  2. 品質指標の定量化が難しい

    • 「正しい回答」の基準が曖昧です
    • ユーザー満足度は主観的で、即座に測定できません
  3. 外部依存による制御不可能性

    • OpenAI や Anthropic などの外部 API に依存します
    • 外部サービスの障害やレート制限の影響を直接受けます
  4. コストと品質のトレードオフ

    • 高速化のためのキャッシュ戦略が品質に影響します
    • より高性能なモデルを使うとコストが増加します

これらの課題を考慮した SLO/SLA 設計が必要になります。

アラート設計の難しさ

適切なアラート設計がなければ、以下のような問題が発生します。

#問題影響発生頻度
1アラート疲れ重要な通知を見逃す
2検知遅延障害対応が後手に回る
3誤検知無駄な対応コスト
4エスカレーション不備適切な担当者に届かない

Dify の標準機能にはアラート機能が組み込まれていないため、外部ツールとの統合が必須となります。

解決策

SLI の定義と選定

まず、Dify アプリケーションで測定すべき具体的な SLI を定義しましょう。

システム境界での SLI 設定

モダンなシステムでは、個々のコンポーネントではなくシステム境界で SLI を設定することが推奨されています。

mermaidflowchart LR
    subgraph boundary["システム境界"]
        direction TB
        endpoint["API エンドポイント"]

        subgraph internal["内部コンポーネント<br/>(監視対象外)"]
            api_comp["API"]
            worker_comp["Worker"]
            db_comp["DB"]
        end

        endpoint --> internal
    end

    user_app["クライアント<br/>アプリケーション"]

    user_app -->|"SLI 測定ポイント"| endpoint

    style boundary fill:#e6f3ff
    style endpoint fill:#99ccff

システム境界でのみ SLI を測定することで、以下のメリットがあります。

  • 顧客視点での品質を直接測定できます
  • 監視対象が絞られ、運用負荷が軽減されます
  • 内部実装の変更に影響されません

Dify 向け推奨 SLI 一覧

Dify アプリケーションで設定すべき主要な SLI を以下にまとめました。

可用性(Availability)関連:

#SLI 名測定方法計算式
1リクエスト成功率HTTP ステータスコードで判定(成功リクエスト数 / 総リクエスト数) × 100
2エンドポイント稼働率ヘルスチェックの成功率(成功チェック数 / 総チェック数) × 100

レイテンシ(Latency)関連:

#SLI 名測定方法目標値の考え方
1API レスポンスタイム P95リクエスト送信から完了までの時間ユーザー体験を損なわない範囲
2LLM 応答時間 P99LLM API 呼び出しの所要時間プロバイダの SLA を考慮
3ベクトル検索時間 P95ベクトル DB への検索クエリ時間全体レイテンシの 10% 以内

品質(Quality)関連:

#SLI 名測定方法評価タイミング
1ユーザー満足度スコアいいね/よくない の比率週次集計
2エラー応答率LLM からのエラー応答の割合リアルタイム
3タイムアウト率設定時間内に応答できなかった割合リアルタイム

コスト効率(Cost Efficiency)関連:

#SLI 名測定方法監視目的
11 リクエストあたりのトークン消費量総トークン数 / リクエスト数コスト最適化
2キャッシュヒット率キャッシュヒット数 / 総検索数パフォーマンス向上

これらの SLI を組み合わせて、ビジネス要件に合った SLO を設定していきます。

SLO の設定戦略

SLI が定義できたら、次は具体的な目標値(SLO)を設定しましょう。

SLO 設定の基本原則

SLO を設定する際は、以下の原則に従ってください。

  1. 理想値ではなく許容可能な最低ライン

    • 100% の可用性を目指すとコストが膨大になります
    • ビジネスに必要な最低限の品質レベルを設定します
  2. SLA よりも厳しく設定

    • SLA が 99.9% なら、SLO は 99.95% に設定します
    • バッファを持つことで、SLA 違反前に対処できます
  3. 測定可能で自動化可能

    • 手動で確認する必要がある SLO は避けます
    • モニタリングツールで自動計測できる指標にします
  4. 段階的に厳しくする

    • 最初は達成可能な目標から始めます
    • 安定稼働できたら徐々に目標を引き上げます

具体的な SLO 設定例

以下は、一般的な Dify アプリケーションでの SLO 設定例です。

可用性の SLO:

#SLO 項目目標値測定期間許容ダウンタイム
1API エンドポイント稼働率99.9%月次43.2 分/月
2リクエスト成功率99.5%日次7.2 分/日

パフォーマンスの SLO:

#SLO 項目目標値測定期間備考
1API レスポンスタイム P95< 3 秒時間単位チャットボット用途
2API レスポンスタイム P99< 5 秒時間単位タイムアウト前に完了
3LLM 応答時間 P95< 2 秒時間単位外部 API の SLA 考慮

品質の SLO:

#SLO 項目目標値測定期間評価方法
1ユーザー満足度> 80%週次いいね率で評価
2LLM エラー応答率< 1%日次エラーレスポンス数で測定

コスト効率の SLO:

#SLO 項目目標値測定期間目的
1平均トークン消費量< 500 トークン/リクエスト日次コスト管理
2ベクトル検索キャッシュヒット率> 60%日次パフォーマンス向上

これらの SLO は、あくまで参考値です。実際のビジネス要件やユーザー体験に基づいて、適切な値を設定してください。

エラーバジェットの活用

SLO を設定したら、エラーバジェット(許容されるエラーの量)を計算し、活用しましょう。

mermaidflowchart TB
    slo_target["SLO 目標: 99.9%"]
    error_budget["エラーバジェット: 0.1%"]

    subgraph usage["バジェット使用状況"]
        remaining["残り 50%"]
        consumed["消費済み 50%"]
    end

    decision{"バジェット<br/>残量は?"}

    action_safe["新機能リリース OK"]
    action_warn["慎重なリリース"]
    action_freeze["リリース凍結<br/>安定化に注力"]

    slo_target --> error_budget
    error_budget --> usage
    usage --> decision

    decision -->|"> 70%"| action_safe
    decision -->|"30-70%"| action_warn
    decision -->|"< 30%"| action_freeze

    style action_safe fill:#99ff99
    style action_warn fill:#ffff99
    style action_freeze fill:#ff9999

エラーバジェットの計算例:

SLO が 99.9%(月次)の場合、許容されるダウンタイムは以下の通りです。

  • 1 ヶ月(30 日)= 43,200 分
  • エラーバジェット = 43,200 × 0.1% = 43.2 分/月

このバジェットを使い切った場合は、新機能開発を停止し、安定性向上に集中します。

外部モニタリングツールの統合

Dify の標準機能だけでは本格的な運用は困難なため、外部のモニタリングツールと統合しましょう。

推奨ツールスタック

以下は、Dify の本番運用で推奨されるモニタリングツールの組み合わせです。

mermaidflowchart TB
    subgraph dify_app["Dify アプリケーション"]
        api["API サーバー"]
        worker["Worker"]
    end

    subgraph llm_observability["LLM Observability"]
        langfuse["Langfuse"]
        langsmith["LangSmith"]
    end

    subgraph infra_monitoring["インフラ監視"]
        prometheus["Prometheus"]
        grafana["Grafana"]
    end

    subgraph alerting["アラート管理"]
        alertmanager["Alertmanager"]
        pagerduty["PagerDuty"]
    end

    dify_app -->|"トレース・メトリクス"| langfuse
    dify_app -->|"トレース・メトリクス"| langsmith
    dify_app -->|"システムメトリクス"| prometheus

    langfuse -.->|"可視化"| grafana
    prometheus -->|"メトリクス"| grafana

    prometheus -->|"アラート"| alertmanager
    alertmanager -->|"通知"| pagerduty

    style llm_observability fill:#fff3e6
    style infra_monitoring fill:#e6f3ff
    style alerting fill:#ffe6e6

各ツールの役割:

#ツール役割監視対象統合方法
1LangfuseLLM トレーシングプロンプト、応答、レイテンシ、コストDify 標準統合(ワンクリック)
2LangSmithLLM モニタリング同上 + 詳細なデバッグ情報Dify 標準統合(ワンクリック)
3Prometheusメトリクス収集CPU、メモリ、API レート/metrics エンドポイント公開
4Grafanaダッシュボード全体の可視化Prometheus データソース
5Alertmanagerアラート管理閾値超過時の通知Prometheus ルール定義
6PagerDutyインシデント管理オンコール通知Alertmanager Webhook

Langfuse 統合の実装

Langfuse は Dify と公式に統合されており、ワンクリックで設定できます。

統合手順:

  1. Langfuse アカウントを作成します(https://langfuse.com
  2. プロジェクトを作成し、API キーを取得します
  3. Dify の管理画面で「モニタリング」タブを開きます
  4. Langfuse を選択し、API キーを入力します
  5. 保存すると、自動的にトレースデータが送信されます

Langfuse で確認できる指標:

typescript// Langfuse が自動収集する主要メトリクス

interface LangfuseMetrics {
  // レイテンシ分析
  latency: {
    total: number;        // 全体の処理時間
    llm: number;          // LLM API 呼び出し時間
    retrieval: number;    // ベクトル検索時間
  };

  // コスト分析
  cost: {
    inputTokens: number;   // 入力トークン数
    outputTokens: number;  // 出力トークン数
    totalCost: number;     // 推定コスト(USD)
  };

  // 品質分析
  quality: {
    userFeedback: 'positive' | 'negative';  // ユーザー評価
    errorRate: number;                      // エラー率
  };

  // トレース情報
  trace: {
    traceId: string;      // 一意のトレース ID
    spans: Span[];        // 処理ステップの詳細
    metadata: object;     // カスタムメタデータ
  };
}

Langfuse のダッシュボードでは、以下のような分析が可能です。

  • リクエストごとの詳細トレース
  • コストのトレンド分析
  • レイテンシの P50/P95/P99 分布
  • ユーザーフィードバックの集計

Prometheus + Grafana によるインフラ監視

LLM 特有の指標は Langfuse で監視し、インフラレベルの指標は Prometheus + Grafana で監視します。

Prometheus メトリクスのエクスポート:

Dify の API サーバーでメトリクスエンドポイントを公開します。

python# Dify API サーバーにメトリクスエンドポイントを追加
# api/app.py

from prometheus_client import Counter, Histogram, Gauge, generate_latest
from flask import Response

# メトリクスの定義
request_count = Counter(
    'dify_api_requests_total',
    'Total API requests',
    ['method', 'endpoint', 'status']
)
python# レスポンスタイムのヒストグラム
request_duration = Histogram(
    'dify_api_request_duration_seconds',
    'API request duration',
    ['method', 'endpoint']
)
python# アクティブな接続数
active_connections = Gauge(
    'dify_api_active_connections',
    'Number of active connections'
)
python# メトリクスエンドポイントの公開
@app.route('/metrics')
def metrics():
    """Prometheus メトリクスを返す"""
    return Response(
        generate_latest(),
        mimetype='text/plain'
    )

上記のコードでは、Prometheus が収集できる形式でメトリクスを公開しています。

Prometheus 設定ファイル:

yaml# prometheus.yml
# Prometheus の設定ファイル

global:
  scrape_interval: 15s  # 15 秒ごとにメトリクスを収集
  evaluation_interval: 15s
yaml# スクレイプ対象の設定
scrape_configs:
  # Dify API サーバーのメトリクス収集
  - job_name: 'dify-api'
    static_configs:
      - targets: ['dify-api:5001']
        labels:
          service: 'api'
yaml  # Dify Worker のメトリクス収集
  - job_name: 'dify-worker'
    static_configs:
      - targets: ['dify-worker:5002']
        labels:
          service: 'worker'
yaml  # Redis のメトリクス収集(redis_exporter 使用)
  - job_name: 'redis'
    static_configs:
      - targets: ['redis-exporter:9121']
yaml  # PostgreSQL のメトリクス収集(postgres_exporter 使用)
  - job_name: 'postgres'
    static_configs:
      - targets: ['postgres-exporter:9187']

この設定により、Dify の各コンポーネントとデータストアのメトリクスを一元管理できます。

Grafana ダッシュボードの作成:

Grafana で SLO ダッシュボードを作成し、リアルタイムで達成状況を可視化します。

json{
  "dashboard": {
    "title": "Dify SLO Dashboard",
    "panels": [
      {
        "title": "API Availability (SLO: 99.9%)",
        "targets": [
          {
            "expr": "sum(rate(dify_api_requests_total{status=~\"2..\"}[5m])) / sum(rate(dify_api_requests_total[5m])) * 100"
          }
        ]
      }
    ]
  }
}

上記は、API の成功率を計算する PromQL クエリの例です。

アラート設計のベストプラクティス

SLO を設定したら、その達成状況を監視し、違反時にアラートを発火する仕組みを構築しましょう。

アラートの優先度設定

すべてのアラートを同じ扱いにすると、重要な通知が埋もれてしまいます。以下のように優先度を設定しましょう。

mermaidflowchart TB
    alert["アラート発生"]

    decision_slo{"SLO への<br/>影響は?"}
    decision_user{"ユーザーへの<br/>影響は?"}
    decision_auto{"自動復旧<br/>可能?"}

    p0["P0: Critical<br/>即座に対応"]
    p1["P1: High<br/>1時間以内に対応"]
    p2["P2: Medium<br/>営業時間内に対応"]
    p3["P3: Low<br/>週次で確認"]

    alert --> decision_slo

    decision_slo -->|"SLO 違反"| p0
    decision_slo -->|"SLO に近い"| decision_user

    decision_user -->|"影響あり"| p1
    decision_user -->|"影響なし"| decision_auto

    decision_auto -->|"不可"| p2
    decision_auto -->|"可能"| p3

    style p0 fill:#ff0000,color:#fff
    style p1 fill:#ff9900
    style p2 fill:#ffff00
    style p3 fill:#99ff99

優先度別の対応方針:

#優先度条件通知先対応時間
1P0 (Critical)SLO 違反、全ユーザー影響電話 + SMS即座API 全体ダウン
2P1 (High)SLO に近い、一部ユーザー影響PagerDuty1 時間以内エラー率 5%
3P2 (Medium)SLO 余裕あり、影響限定的Slack営業時間内レイテンシ増加
4P3 (Low)情報提供、自動復旧可能メール週次確認キャッシュミス増加

Prometheus アラートルールの設定

Prometheus で SLO ベースのアラートルールを定義します。

yaml# prometheus-rules.yml
# Prometheus アラートルールの定義

groups:
  # API 可用性のアラート
  - name: dify_slo_availability
    interval: 1m
    rules:
      # P0: API 成功率が 99% を下回る(SLO 99.9% 違反)
      - alert: DifyAPIAvailabilityCritical
        expr: |
          (
            sum(rate(dify_api_requests_total{status=~"2.."}[5m]))
            /
            sum(rate(dify_api_requests_total[5m]))
          ) < 0.99
yaml        for: 2m  # 2 分間継続したら発火
        labels:
          severity: critical
          priority: P0
        annotations:
          summary: "Dify API の可用性が SLO を下回っています"
          description: "成功率: {{ $value | humanizePercentage }}"
yaml      # P1: API 成功率が 99.5% を下回る(SLO に近い)
      - alert: DifyAPIAvailabilityWarning
        expr: |
          (
            sum(rate(dify_api_requests_total{status=~"2.."}[5m]))
            /
            sum(rate(dify_api_requests_total[5m]))
          ) < 0.995
        for: 5m
        labels:
          severity: warning
          priority: P1
        annotations:
          summary: "Dify API の可用性が低下しています"
          description: "成功率: {{ $value | humanizePercentage }}"

上記のルールでは、SLO に対する余裕度に応じて異なる優先度のアラートを発火します。

yaml  # API レイテンシのアラート
  - name: dify_slo_latency
    interval: 1m
    rules:
      # P0: P95 レイテンシが 5 秒を超える(SLO 3 秒違反)
      - alert: DifyAPILatencyCritical
        expr: |
          histogram_quantile(0.95,
            rate(dify_api_request_duration_seconds_bucket[5m])
          ) > 5
yaml        for: 3m
        labels:
          severity: critical
          priority: P0
        annotations:
          summary: "Dify API のレイテンシが SLO を大幅に超過"
          description: "P95 レイテンシ: {{ $value }}s"
yaml      # P1: P95 レイテンシが 3.5 秒を超える(SLO に近い)
      - alert: DifyAPILatencyWarning
        expr: |
          histogram_quantile(0.95,
            rate(dify_api_request_duration_seconds_bucket[5m])
          ) > 3.5
        for: 5m
        labels:
          severity: warning
          priority: P1
        annotations:
          summary: "Dify API のレイテンシが上昇しています"
          description: "P95 レイテンシ: {{ $value }}s"

レイテンシのアラートでは、パーセンタイル値を使うことで、一時的なスパイクを無視し、持続的な劣化を検知します。

yaml  # LLM エラー率のアラート
  - name: dify_slo_quality
    interval: 1m
    rules:
      # P1: LLM エラー率が 1% を超える
      - alert: DifyLLMErrorRateHigh
        expr: |
          (
            sum(rate(dify_llm_requests_total{status="error"}[10m]))
            /
            sum(rate(dify_llm_requests_total[10m]))
          ) > 0.01
        for: 5m
        labels:
          severity: warning
          priority: P1
        annotations:
          summary: "LLM エラー率が上昇しています"
          description: "エラー率: {{ $value | humanizePercentage }}"

LLM の一時的な障害は外部要因の可能性があるため、10 分間の平均で評価しています。

Alertmanager による通知ルーティング

Alertmanager で、アラートの優先度に応じた通知先を設定します。

yaml# alertmanager.yml
# Alertmanager の設定ファイル

global:
  resolve_timeout: 5m
yaml# 通知先の定義
route:
  # デフォルトの設定
  group_by: ['alertname', 'service']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 12h
  receiver: 'default'
yaml  # 優先度別のルーティング
  routes:
    # P0: Critical - 即座に電話とページャー
    - match:
        priority: P0
      receiver: 'pagerduty-critical'
      group_wait: 0s
      repeat_interval: 5m
yaml    # P1: High - PagerDuty に通知
    - match:
        priority: P1
      receiver: 'pagerduty-high'
      group_wait: 30s
      repeat_interval: 1h
yaml    # P2: Medium - Slack に通知
    - match:
        priority: P2
      receiver: 'slack-medium'
      group_wait: 5m
      repeat_interval: 3h
yaml    # P3: Low - メールで通知
    - match:
        priority: P3
      receiver: 'email-low'
      repeat_interval: 24h

優先度に応じて、通知のタイミングと頻度を調整しています。

yaml# 受信者の設定
receivers:
  # デフォルト(全通知)
  - name: 'default'
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'
        channel: '#dify-alerts'
yaml  # P0: PagerDuty(Critical)
  - name: 'pagerduty-critical'
    pagerduty_configs:
      - service_key: 'YOUR_PAGERDUTY_SERVICE_KEY'
        severity: critical
        description: '{{ .CommonAnnotations.summary }}'
yaml  # P1: PagerDuty(High)
  - name: 'pagerduty-high'
    pagerduty_configs:
      - service_key: 'YOUR_PAGERDUTY_SERVICE_KEY'
        severity: error
yaml  # P2: Slack(Medium)
  - name: 'slack-medium'
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'
        channel: '#dify-monitoring'
        title: '⚠️ {{ .CommonLabels.alertname }}'
yaml  # P3: Email(Low)
  - name: 'email-low'
    email_configs:
      - to: 'ops-team@example.com'
        from: 'alertmanager@example.com'
        smarthost: 'smtp.example.com:587'

このように、アラートの重要度に応じて適切な通知手段を選択します。

アラート疲れを防ぐ工夫

アラートが多すぎると重要な通知を見逃してしまいます。以下の工夫で、ノイズを減らしましょう。

1. 適切な閾値設定

#指標不適切な閾値適切な閾値理由
1エラー率> 0%> 1%ゼロエラーは現実的でない
2レイテンシ平均値 > 1sP95 > 3s平均値は外れ値に影響されやすい
3CPU 使用率> 50%> 80%50% は正常範囲内

2. 時間ベースのフィルタリング

一時的なスパイクを無視するため、for 句で持続時間を指定します。

yaml# 3 分間継続した場合のみアラート
- alert: HighErrorRate
  expr: error_rate > 0.01
  for: 3m  # 3 分間継続した場合のみ

3. メンテナンスウィンドウの設定

計画的なメンテナンス中はアラートを抑制します。

yaml# メンテナンス中はアラートを抑制
inhibit_rules:
  - source_match:
      alertname: 'MaintenanceMode'
    target_match_re:
      severity: '.*'
    equal: ['service']

4. 関連アラートのグループ化

同じ原因で複数のアラートが発生する場合、グループ化して 1 つの通知にまとめます。

yaml# 同じサービスのアラートをグループ化
route:
  group_by: ['service', 'alertname']
  group_wait: 10s  # 最初のアラートから 10 秒待つ
  group_interval: 10s  # 追加のアラートを 10 秒間隔で集約

これらの工夫により、運用チームは本当に重要なアラートに集中できます。

具体例

ケーススタディ:カスタマーサポートチャットボット

ここでは、実際の Dify アプリケーションでの SLO/SLA 設定とアラート設計の具体例を見ていきましょう。

ビジネス要件の定義

あるEC サイトが、カスタマーサポートの効率化のため Dify でチャットボットを構築したとします。

ビジネス要件:

#要件理由影響
1営業時間中(9-21 時)は常時利用可能ユーザーサポートの代替手段利用不可時は有人対応が増加
2レスポンスは 3 秒以内ユーザー体験の維持遅延するとユーザー離脱
3正確な回答率 80% 以上顧客満足度の維持低いと信頼性が低下
4月間コストを 10 万円以内に抑制費用対効果の確保超過すると採算が悪化

これらの要件を、測定可能な SLI/SLO に変換していきます。

SLI/SLO の具体的な設定

ビジネス要件から、以下のような SLI/SLO を設定します。

mermaidflowchart LR
    subgraph business["ビジネス要件"]
        b1["常時利用可能"]
        b2["3秒以内"]
        b3["正確な回答 80%"]
        b4["コスト 10万円/月"]
    end

    subgraph slo["SLO(内部目標)"]
        s1["稼働率 99.9%"]
        s2["P95 < 2.5s"]
        s3["満足度 85%"]
        s4["8.5万円/月"]
    end

    subgraph sli["SLI(測定指標)"]
        i1["HTTP 2xx 率"]
        i2["API レスポンスタイム"]
        i3["いいね率"]
        i4["トークン消費量"]
    end

    b1 --> s1 --> i1
    b2 --> s2 --> i2
    b3 --> s3 --> i3
    b4 --> s4 --> i4

    style business fill:#ffe6e6
    style slo fill:#fff3e6
    style sli fill:#e6f3ff

具体的な SLO 設定表:

#カテゴリSLISLO 目標値SLA(顧客約束)測定方法
1可用性API 成功率99.9%(営業時間)99.5%Prometheus: success_rate
2レイテンシAPI P95 レスポンス< 2.5 秒< 3 秒Prometheus: http_request_duration_seconds
3レイテンシAPI P99 レスポンス< 4 秒< 5 秒同上
4品質ユーザー満足度> 85%> 80%Langfuse: positive_feedback_rate
5品質エラー応答率< 0.5%< 1%Langfuse: error_rate
6コスト月間トークン消費< 17M トークン< 20M トークンLangfuse: total_tokens
7コスト1 リクエスト平均< 450 トークン< 500 トークン同上

SLO を SLA より 15-20% 厳しく設定することで、バッファを確保しています。

アラートルールの実装

上記の SLO に基づいて、具体的なアラートルールを実装します。

可用性のアラート:

yaml# 営業時間中の API 可用性監視
- alert: ChatbotAvailabilityCritical
  expr: |
    # 営業時間(9-21時)のみ評価
    (
      sum(rate(dify_api_requests_total{
        service="chatbot",
        status=~"2.."
      }[5m]))
      /
      sum(rate(dify_api_requests_total{
        service="chatbot"
      }[5m]))
    ) < 0.995
    and
    hour() >= 9 and hour() < 21
yaml  for: 2m
  labels:
    severity: critical
    priority: P0
    team: platform
  annotations:
    summary: "チャットボットの可用性が SLO を下回っています"
    description: |
      現在の成功率: {{ $value | humanizePercentage }}
      SLO 目標: 99.9%
      影響: 営業時間中のユーザーサポートに影響
    runbook_url: "https://wiki.example.com/runbooks/chatbot-availability"

営業時間外は SLO の対象外とするため、hour() 関数で時間帯を限定しています。

レイテンシのアラート:

yaml# P95 レスポンスタイムの監視
- alert: ChatbotLatencyHigh
  expr: |
    histogram_quantile(0.95,
      sum(rate(dify_api_request_duration_seconds_bucket{
        service="chatbot"
      }[5m])) by (le)
    ) > 2.5
  for: 3m
  labels:
    severity: warning
    priority: P1
    team: platform
  annotations:
    summary: "チャットボットのレスポンスが遅延しています"
    description: |
      現在の P95 レスポンス: {{ $value }}s
      SLO 目標: < 2.5s
      ユーザー体験への影響が懸念されます
yaml# P99 レスポンスタイムの監視(タイムアウト直前)
- alert: ChatbotLatencyCritical
  expr: |
    histogram_quantile(0.99,
      sum(rate(dify_api_request_duration_seconds_bucket{
        service="chatbot"
      }[5m])) by (le)
    ) > 4.5
  for: 2m
  labels:
    severity: critical
    priority: P0
    team: platform
  annotations:
    summary: "チャットボットのレスポンスがタイムアウト間近です"
    description: |
      現在の P99 レスポンス: {{ $value }}s
      タイムアウト設定: 5s
      一部ユーザーでタイムアウトが発生している可能性があります

P95 と P99 で異なる閾値を設定することで、段階的なアラートが可能になります。

コスト超過のアラート:

yaml# 日次トークン消費量の監視(月間予算の 1/30)
- alert: ChatbotCostOverBudget
  expr: |
    sum(increase(dify_llm_tokens_total{
      service="chatbot"
    }[24h])) > 566666  # 17M / 30 日
  labels:
    severity: warning
    priority: P2
    team: product
  annotations:
    summary: "チャットボットのトークン消費が予算を超過しています"
    description: |
      本日の消費量: {{ $value }} トークン
      目標値: 566,666 トークン/日
      このペースでは月間予算を超過します
yaml# 1 リクエストあたりの平均トークン数の監視
- alert: ChatbotTokenPerRequestHigh
  expr: |
    (
      sum(rate(dify_llm_tokens_total{
        service="chatbot"
      }[1h]))
      /
      sum(rate(dify_api_requests_total{
        service="chatbot"
      }[1h]))
    ) > 450
  for: 30m
  labels:
    severity: info
    priority: P3
    team: product
  annotations:
    summary: "1 リクエストあたりのトークン消費が増加しています"
    description: |
      現在の平均: {{ $value }} トークン/リクエスト
      目標値: < 450 トークン/リクエスト
      プロンプト最適化を検討してください

コストアラートは即座の対応は不要なため、P2/P3 に設定しています。

ダッシュボードの構成

Grafana で、SLO の達成状況を一目で確認できるダッシュボードを作成します。

ダッシュボードのパネル構成:

#パネル名表示内容目的
1SLO サマリー各 SLO の達成率全体状況の把握
2エラーバジェット残量残りの許容エラー量リスク評価
3API 可用性(時系列)成功率の推移トレンド分析
4レスポンスタイム(パーセンタイル)P50/P95/P99 の推移パフォーマンス分析
5トークン消費量日次・月次の消費トレンドコスト管理
6ユーザー満足度いいね率の推移品質評価

Grafana パネルの PromQL 例:

promql# SLO 達成率の計算(可用性)
(
  sum(rate(dify_api_requests_total{status=~"2.."}[30d]))
  /
  sum(rate(dify_api_requests_total[30d]))
) * 100
promql# エラーバジェット残量(月次 99.9% SLO の場合)
# 残りの許容エラー数を計算
(
  0.001 * sum(increase(dify_api_requests_total[30d]))
  -
  sum(increase(dify_api_requests_total{status!~"2.."}[30d]))
) /
0.001 * sum(increase(dify_api_requests_total[30d])) * 100
promql# レスポンスタイムのパーセンタイル(P95)
histogram_quantile(0.95,
  sum(rate(dify_api_request_duration_seconds_bucket[5m])) by (le)
)

これらのクエリで、SLO の達成状況をリアルタイムで可視化できます。

インシデント対応フローの整備

アラートが発火した際の対応フローを事前に定義しておきます。

mermaidflowchart TB
    alert_fire["アラート発火"]

    check_severity{"優先度は?"}

    p0_action["P0: 即座に対応<br/>1. オンコール担当者に架電<br/>2. インシデント作成<br/>3. 顧客への通知準備"]
    p1_action["P1: 1時間以内に対応<br/>1. PagerDuty で通知<br/>2. 状況確認<br/>3. 必要に応じエスカレーション"]
    p2_action["P2: 営業時間内に対応<br/>1. Slack で共有<br/>2. 原因調査<br/>3. 対応策の検討"]

    investigate["原因調査<br/>・ログ確認<br/>・メトリクス分析<br/>・トレース追跡"]

    resolve{"解決<br/>できた?"}

    escalate["エスカレーション<br/>・上位管理者へ報告<br/>・開発チーム招集<br/>・ベンダーへ問い合わせ"]

    monitor["継続監視<br/>・再発防止<br/>・ポストモーテム"]

    alert_fire --> check_severity

    check_severity -->|"P0"| p0_action
    check_severity -->|"P1"| p1_action
    check_severity -->|"P2/P3"| p2_action

    p0_action --> investigate
    p1_action --> investigate
    p2_action --> investigate

    investigate --> resolve

    resolve -->|"Yes"| monitor
    resolve -->|"No"| escalate

    escalate --> investigate

    style p0_action fill:#ff0000,color:#fff
    style p1_action fill:#ff9900
    style p2_action fill:#ffff00
    style monitor fill:#99ff99

対応手順の詳細化(例:P0 可用性アラート):

#ステップ担当者目安時間実施内容
1初動確認オンコール5 分アラート内容確認、影響範囲の特定
2暫定対応オンコール10 分再起動、ロールバック等の即効性のある対応
3顧客通知サポート15 分ステータスページの更新、重要顧客への連絡
4根本対応開発チーム1 時間原因特定と恒久対策の実施
5事後対応全員24 時間以内ポストモーテムの作成、再発防止策の策定

このように、優先度ごとに明確な対応フローを定義することで、混乱を防げます。

高可用性構成での SLO 達成

単一インスタンスでは 99.9% の可用性を達成するのは困難です。以下のような高可用性構成を検討しましょう。

Kubernetes による冗長化

Alibaba Cloud ACK や AWS EKS などの Kubernetes プラットフォームを活用し、自動復旧とスケーリングを実現します。

yaml# dify-deployment.yaml
# Dify API サーバーのデプロイメント設定

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dify-api
  labels:
    app: dify
    component: api
yamlspec:
  # 最低 2 つのレプリカで冗長化
  replicas: 2

  # ローリングアップデート戦略
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0  # ダウンタイムゼロ
      maxSurge: 1        # 1 つずつ更新
yaml  selector:
    matchLabels:
      app: dify
      component: api

  template:
    metadata:
      labels:
        app: dify
        component: api
yaml    spec:
      # Pod アンチアフィニティ設定
      # 同じノードに複数の Pod を配置しない
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: component
                    operator: In
                    values:
                      - api
              topologyKey: kubernetes.io/hostname
yaml      containers:
        - name: api
          image: dify/api:latest

          # リソース制限
          resources:
            requests:
              cpu: 500m
              memory: 1Gi
            limits:
              cpu: 2000m
              memory: 4Gi
yaml          # ヘルスチェック設定
          livenessProbe:
            httpGet:
              path: /health
              port: 5001
            initialDelaySeconds: 30
            periodSeconds: 10
            timeoutSeconds: 5
            failureThreshold: 3
yaml          readinessProbe:
            httpGet:
              path: /ready
              port: 5001
            initialDelaySeconds: 10
            periodSeconds: 5
            timeoutSeconds: 3
            failureThreshold: 2

この設定により、以下を実現できます。

  • 最低 2 つの Pod が常に稼働(単一障害点の排除)
  • 異なるノードに配置(ノード障害時の影響を最小化)
  • 自動ヘルスチェックと再起動
  • ゼロダウンタイムデプロイ

HPA によるオートスケーリング

負荷に応じて自動的にスケールする設定を追加します。

yaml# dify-hpa.yaml
# Horizontal Pod Autoscaler の設定

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: dify-api-hpa
yamlspec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: dify-api

  # スケール範囲
  minReplicas: 2   # 最小 2 つ(冗長性確保)
  maxReplicas: 10  # 最大 10 つ(コスト上限)
yaml  # スケール条件
  metrics:
    # CPU 使用率ベース
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
yaml    # メモリ使用率ベース
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80
yaml  # スケール動作の調整
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 60
      policies:
        - type: Percent
          value: 100  # 最大で現在の 2 倍まで増やす
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300  # 5 分間の猶予
      policies:
        - type: Pods
          value: 1  # 1 つずつ減らす
          periodSeconds: 60

急激な負荷増加にも対応しつつ、無駄なスケールダウンを防ぐ設定になっています。

マネージドサービスの活用

データストア層は、マネージドサービスを活用することで SLA を向上させられます。

#コンポーネントオープンソースマネージドサービスSLA 向上
1PostgreSQLセルフホスト PostgreSQLAWS RDS / Cloud SQL99.5% → 99.95%
2Redisセルフホスト RedisAWS ElastiCache / Upstash99% → 99.9%
3ベクトル DBセルフホスト QdrantPinecone / Weaviate Cloud99% → 99.9%

マネージドサービスを使うことで、以下のメリットがあります。

  • 自動バックアップと復旧
  • 高可用性構成(マルチ AZ 配置)
  • パッチ適用の自動化
  • 24/7 のサポート

コストは増加しますが、SLO 達成のためには有効な選択肢です。

まとめ

Dify で構築した AI アプリケーションを本番環境で安定運用するためには、適切な SLO/SLA 設定とアラート設計が不可欠です。

本記事で紹介した内容を以下にまとめます。

SLO/SLA 設定のポイント:

  1. SLI の選定:システム境界で測定可能な指標を選び、顧客視点での品質を評価します
  2. SLO の設定:理想値ではなく許容可能な最低ラインを設定し、SLA よりも厳しい目標にします
  3. エラーバジェット:許容されるエラーの量を明確化し、開発速度と安定性のバランスを取ります

アラート設計のポイント:

  1. 優先度の設定:P0 から P3 まで明確に分類し、対応時間と通知先を定義します
  2. 適切な閾値:一時的なスパイクを無視し、持続的な劣化を検知する設定にします
  3. アラート疲れ対策:グループ化、時間フィルタ、メンテナンスウィンドウで不要な通知を削減します

ツールスタックの選定:

  1. Langfuse/LangSmith:LLM 特有の指標(トークン消費、プロンプト品質)を監視します
  2. Prometheus + Grafana:インフラレベルの指標を収集・可視化します
  3. Alertmanager + PagerDuty:優先度別にアラートをルーティングし、適切な通知を実現します

高可用性の実現:

  1. Kubernetes:Pod の冗長化、自動復旧、ゼロダウンタイムデプロイを実現します
  2. HPA:負荷に応じた自動スケーリングで、突発的なトラフィックにも対応します
  3. マネージドサービス:データストア層は SLA の高いマネージドサービスを活用します

これらの実践により、ビジネス要件を満たす信頼性の高い AI アプリケーション運用が可能になります。

最初は小さく始めて、段階的に SLO を厳しくしていくアプローチがおすすめです。まずは最も重要な指標(可用性とレイテンシ)から監視を開始し、運用が安定してきたら品質やコスト効率の指標を追加していきましょう。

関連リンク