0Pricing
AI Engineering Academy · レッスン

継続的評価パイプラインの構築

LLM-as-judge評価をCI/CDパイプラインに統合し、プロンプトやモデルを変更するたびに、デプロイ前に回帰テストスイートで自動評価できるようにします

「継続的評価パイプラインの構築」はCoddyKit上の無料AI Engineering Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Engineering Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Engineering Academyコースには全4レッスンが含まれています。

評価を継続的に行う必要がある理由

デプロイ時に一度だけ評価するのでは不十分です。LLMの品質は気付かないうちに低下します。モデルプロバイダーがモデルを更新し、システムプロンプトの変更が入り、ドキュメントコーパスの増加に伴って検索品質が変化し、ユーザークエリの分布も時間とともに変わるためです。継続的な評価パイプラインは、変更のたびに、またスケジュールに従って同じ評価スイートを実行し、数週間ではなく数時間以内に品質のリグレッションを検出します。

パイプラインの主要コンポーネント

継続的評価パイプラインは、5つのコンポーネントで構成されます。テストデータセット(期待される出力を付けた、精選済みの質問)、システムランナー(各テスト質問に対してLLMパイプラインを呼び出すもの)、ジャッジ(各応答を採点するもの)、結果ストア(過去のメトリクスを保存するデータベースまたは時系列ストア)、レポート層(ダッシュボードとアラート)です。各コンポーネントは独立してアップグレードできます。

# Pipeline architecture:
#
# test_dataset.json
#       |
#       v
# system_runner.py  --> calls your LLM pipeline
#       |
#       v
# judge.py          --> scores each (question, answer) pair
#       |
#       v
# results_db        --> stores timestamped metric history
#       |
#       v
# dashboard + alert --> Grafana / Slack notification

テストデータセットの構成

評価用のテストセットは、バージョン管理されたJSONまたはYAMLファイルとしてリポジトリに保存してください。各エントリには、質問、カテゴリ(事実、手順、対象外)、および任意で参照回答を含めます。テストセットはコードとは別にバージョン管理してください。新しいテストケースの追加は後方互換性のある変更ですが、ケースを削除するとリグレッションが見えなくなる可能性があります。関連するすべてのカテゴリで、200~500件を目標にしてください。

# eval/test_set_v3.json
# {
#   'version': '3.0',
#   'created': '2026-06-01',
#   'cases': [
#     {
#       'id': 'faq_001',
#       'category': 'factual',
#       'question': 'What is the cancellation policy?',
#       'reference': 'Cancellations must be made 24 hours in advance.',
#       'min_correctness': 4
#     },
#     ...
#   ]
# }

評価スイートの実行

評価ランナーは、各テストケースに対して本番システム(またはステージング版)を呼び出し、応答とメタデータを記録します。各評価実行には、一意のrun ID、実行のきっかけとなったコミットSHA、タイムスタンプ、テストセットのバージョンを付けてください。これにより、実行結果を正確に比較し、どのコード変更がリグレッションを引き起こしたのかを診断できます。

import asyncio
import uuid
from datetime import datetime

async def run_eval_suite(system, test_set: list, commit_sha: str) -> dict:
    run_id = str(uuid.uuid4())
    results = []
    for case in test_set:
        response = await system.answer(case['question'])
        score = await judge(case['question'], response, case.get('reference'))
        results.append({
            'run_id': run_id,
            'commit_sha': commit_sha,
            'case_id': case['id'],
            'category': case['category'],
            'response': response,
            'score': score.model_dump(),
            'evaluated_at': datetime.utcnow().isoformat()
        })
    return {'run_id': run_id, 'results': results}

過去のメトリクスの保存とクエリ

すべての評価実行結果をデータベースに永続化してください。run_id、commit_sha、case_id、scoreフィールドを持つ単純なeval_resultsテーブルで十分です。run_idごとにスコアを集計してクエリし、実行単位のメトリクスを算出します。現在の実行結果をmainブランチで最後に成功した実行と比較して、リグレッションを検出してください。InfluxDBのような時系列データベースは、継続的な監視に適しています。

-- PostgreSQL schema
CREATE TABLE eval_runs (
    run_id UUID PRIMARY KEY,
    commit_sha TEXT NOT NULL,
    test_set_version TEXT NOT NULL,
    triggered_by TEXT,  -- 'ci', 'scheduled', 'manual'
    started_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE eval_results (
    id SERIAL PRIMARY KEY,
    run_id UUID REFERENCES eval_runs(run_id),
    case_id TEXT NOT NULL,
    category TEXT,
    correctness INT,
    overall INT,
    response TEXT
);

CREATE INDEX idx_run_id ON eval_results(run_id);

リグレッションの自動検出

各評価実行の後、集計スコアをベースライン(mainブランチで最後に手動承認された実行結果)と比較します。リグレッションは、いずれかのスコア項目がベースラインを5%超下回ること、またはいずれかのカテゴリの平均スコアが最低基準を下回ることと定義します。リグレッションが検出された場合はデプロイをブロックし、チームにアラートを送る必要があります。改善については自動承認できます。

def detect_regression(current: dict, baseline: dict, threshold_pct: float = 5.0) -> dict:
    regressions = []
    for metric in ['correctness', 'helpfulness', 'clarity']:
        delta_pct = (current[metric] - baseline[metric]) / baseline[metric] * 100
        if delta_pct < -threshold_pct:
            regressions.append({
                'metric': metric,
                'baseline': baseline[metric],
                'current': current[metric],
                'delta_pct': round(delta_pct, 1)
            })
    return {'has_regression': len(regressions) > 0, 'regressions': regressions}

CI/CDとの統合

すべてのプルリクエストで実行されるCIステップとして、評価スイートを追加してください。CIパイプラインはステージングシステムを呼び出し、ジャッジを実行し、結果を保存して、リグレッションを確認します。リグレッションが検出された場合、CIステップは失敗し、PRのマージをブロックします。誰も回避できないように、GitHubまたはGitLabで必須のステータスチェックとして追加してください。PRチェックでは50~100件のサブセットを使い、評価の実行時間を10分未満に抑えてください。

# .github/workflows/eval.yml
# name: LLM Quality Evaluation
# on: [pull_request]
# jobs:
#   eval:
#     runs-on: ubuntu-latest
#     steps:
#       - uses: actions/checkout@v4
#       - name: Run eval suite
#         run: python eval/run_suite.py --commit $GITHUB_SHA --mode pr
#         env:
#           OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
#       - name: Check for regressions
#         run: python eval/check_regression.py --run-id $EVAL_RUN_ID

スケジュール実行による全件評価

PRチェックに加えて、毎日、本番環境に対して全件評価スイート(300件以上の全ケース)を実行してください。これにより、単一の変更では引き起こされない、徐々に進む品質のドリフトを検出できます。たとえば、ドキュメントが追加されるにつれてベクトルデータベースの再現率が低下する場合や、LLMプロバイダーがモデルを予告なく更新する場合です。毎日の全件実行によって品質の時系列データが得られ、傾向を可視化できます。

# Separate eval modes:
EVAL_CONFIGS = {
    'pr_check': {
        'test_cases': 'eval/test_set_core_100.json',
        'target': 'staging',
        'max_runtime_min': 8
    },
    'nightly': {
        'test_cases': 'eval/test_set_full_350.json',
        'target': 'production',
        'max_runtime_min': 30
    },
    'weekly_deep': {
        'test_cases': 'eval/test_set_full_350.json',
        'target': 'production',
        'include_pairwise': True,
        'max_runtime_min': 90
    }
}

品質低下のアラート

メトリクスの推移が警告しきい値や重大しきい値を超えたときにアラートが発生するよう設定してください。過去7日間の平均正確性が3%低下した場合は警告を発生させます。1回の実行で10%低下した場合は、即時にアラートを発生させます。警告はチームのSlackチャンネルに、重大なアラートはPagerDutyに送ってください。すべてのアラートメッセージに、リグレッション分析、評価ダッシュボードへのリンク、最近の変更に関するgit blameを含めます。

import httpx

def send_regression_alert(regression_report: dict, webhook_url: str):
    regressions = regression_report['regressions']
    blocks = [{
        'type': 'section',
        'text': {'type': 'mrkdwn', 'text': '*LLM Quality Regression Detected*'}
    }]
    for r in regressions:
        blocks.append({
            'type': 'section',
            'text': {'type': 'mrkdwn',
                     'text': f'*{r["metric"]}*: {r["baseline"]} -> {r["current"]} ({r["delta_pct"]}%)'}
        })
    httpx.post(webhook_url, json={'blocks': blocks})

テストセットの拡張管理

実際の本番障害に基づいて、テストセットを継続的に拡張してください。ユーザーから不適切な応答の報告を受けたら、その質問を(必要に応じて匿名化して)人間が検証した期待回答とともにテストセットへ追加します。これにより、評価スイートが仮想的なケースではなく、実際のユーザーニーズを反映するようになります。テストセットは常に更新されるドキュメントとして扱い、古くなったケースを削除するために四半期ごとに見直してください。

def add_to_test_set(question: str, reference_answer: str, category: str,
                    source: str, test_set_path: str):
    import json, uuid
    with open(test_set_path, 'r') as f:
        test_set = json.load(f)
    test_set['cases'].append({
        'id': f'user_report_{uuid.uuid4().hex[:8]}',
        'category': category,
        'question': question,
        'reference': reference_answer,
        'source': source,  # 'user_report', 'regression', 'manual'
        'added': '2026-06-21'
    })
    with open(test_set_path, 'w') as f:
        json.dump(test_set, f, indent=2)

時間経過に伴う品質傾向の可視化

主要なメトリクスを時間経過に沿ってプロットする、シンプルな品質ダッシュボードを作成してください。対象には、平均正確性スコア、キャッシュヒット率、p95レイテンシ、クエリあたりのコストなどがあります。サンプル数が少ないことによるノイズを平滑化するため、週次移動平均を使用してください。傾向グラフを使うと、品質のドリフトをすぐに把握できます。6週間かけて徐々に3%低下する変化は個々の実行レポートでは見えませんが、時系列グラフでは明らかになります。Grafana、または単純なPythonのmatplotlibスクリプトでも十分に対応できます。

import matplotlib.pyplot as plt
import pandas as pd

def plot_quality_trend(eval_history: list):
    df = pd.DataFrame(eval_history)
    df['date'] = pd.to_datetime(df['evaluated_at'])
    df = df.sort_values('date')
    # 7-day rolling average
    df['score_ma7'] = df['mean_correctness'].rolling(window=7).mean()
    plt.figure(figsize=(12, 4))
    plt.plot(df['date'], df['mean_correctness'], alpha=0.3, label='Daily')
    plt.plot(df['date'], df['score_ma7'], label='7-day avg', linewidth=2)
    plt.axhline(y=4.0, color='r', linestyle='--', label='Min threshold')
    plt.legend()
    plt.title('LLM Answer Quality Over Time')
    plt.savefig('quality_trend.png')

クイックチェック

LLMアプリケーションの継続的評価パイプラインについて、理解度を確認します。

レッスンのまとめ

このレッスンでは、継続的評価パイプラインがすべてのPRと毎日のスケジュールで自動品質チェックを実行し、リグレッションを早期に検出すること、リグレッション検出が現在のスコアをベースラインと比較し、品質が低下した場合にデプロイをブロックすること、そして実際の障害に基づくテストセットの拡張によって評価スイートを実際のユーザーニーズに即したものに保てることを学びました。次は、エージェントの失敗モードを分類し、復旧戦略を設計します。

よくある質問

「継続的評価パイプラインの構築」レッスンは無料ですか?

はい。「継続的評価パイプラインの構築」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Engineering Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Engineering Academyコースには全4レッスンが含まれています。

「継続的評価パイプラインの構築」で何を学びますか?

LLM-as-judge評価をCI/CDパイプラインに統合し、プロンプトやモデルを変更するたびに、デプロイ前に回帰テストスイートで自動評価できるようにします ブラウザで直接実行するハンズオンコードでAI Engineering Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

AI Engineering Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAI Engineering Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「継続的評価パイプラインの構築」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAI Engineering Academyレッスンでコードを書いて実行できますか?

はい。すべてのAI Engineering Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. LLM-as-Judgeパターン
  2. ポイントワイズ評価とペアワイズ評価
  3. 評価者モデルを人間の評価に合わせて調整する
  4. 継続的評価パイプラインの構築
← AI Engineering Academyに戻る