DeepEvalは、LLMアプリが返した回答を指標で採点し、合否をpytestのテストとして判定するPython製のOSSです。社内文書を検索して答えるRAGやチャットボットで、プロンプトやモデルを変えたときに回答の質が落ちていないかを、リリース前に機械的に確かめる用途で使われます。この記事では、2026年10月27日公開の4.3.2を前提に、インストールと最初のテスト、RAG向け指標の必須入力、G-Evalで独自の採点基準を書く方法、閾値の決め方、GitHub Actionsでの実行と費用の抑え方、採用を見送る場面までを実装者向けに整理します。
まとめ:DeepEvalはLLMの回答をテストとして書き、CIで劣化を止める道具
DeepEvalの役割は、LLMの回答を「書いたテストが通るか落ちるか」で扱えるようにすることです。テストケースに質問・実際の回答・期待する回答・検索したチャンクを入れ、指標と閾値を指定すると、採点役のLLMが0〜1のスコアを付け、閾値を下回ればテストが失敗します。
最初に押さえるのは3点です。採点にはLLMのAPI呼び出しが発生し、4.3.2の既定はOpenAIのgpt-5.4であること。RAGでは検索側と生成側で使う指標が分かれ、指標ごとに必須の入力が違うこと。既定の閾値0.5は出発点にすぎず、人が付けた正誤と突き合わせて決め直すことです。
Pythonでアプリを書いていて、開発者が評価を保守するチームなら採用してよい道具です。評価データを社外のAPIへ送れない場合は、採点役をOllamaなどのローカルモデルに替えるか、別の手段を選びます。
DeepEvalとは:LLMの回答を指標で採点するApache 2.0のOSS
DeepEvalはConfident AI社が開発するLLM評価フレームワークで、GitHubのリポジトリconfident-ai/deepevalでApache 2.0ライセンスのもと公開されています。2026年11月1日時点のスター数は約1.9万です。評価結果をチームで共有する有償のクラウドサービスConfident AIもありますが、評価そのものはローカルで完結します。
4.3.2が最新、指標の入力名はSingleTurnParamsへ改名
PyPIのdeepevalのページによると、最新版は2026年10月27日公開の4.3.2で、対応するPythonは3.9以上4.0未満です。4.0.0は2026年5月8日に出ており、3.x系の時代に書かれた解説記事のコードはそのままでは警告が出ます。
差が出やすいのが、指標に渡す入力の種類を表すクラスの名前です。日本語の解説記事の多くはLLMTestCaseParamsを使っていますが、4.3.2のtest_caseモジュールのソースではSingleTurnParamsが正式な名前です。旧名を読み込むと非推奨の警告を出したうえでSingleTurnParamsを返し、会話用のTurnParamsもMultiTurnParamsへ同じ扱いで改名されています。新しく書くコードは新名に揃えておけば、旧名が削除されたときに書き直さずに済みます。
採点役のLLMは既定でgpt-5.4、評価のたびにAPI料金が発生
DeepEvalの指標の多くは、別のLLMに回答を読ませて採点させるLLM-as-a-Judgeの方式です。4.3.2のモデル定数を定めたソースでは、OpenAIを使うときの既定モデルがgpt-5.4と定められています。指標ごとにmodel引数で別のモデルを指定でき、CLIのdeepeval set-ollamaやdeepeval set-geminiで全指標の採点役をまとめて切り替えられます。
費用の面では、1件のテストケースに3つの指標を付ければ、採点のためのAPI呼び出しが指標ごとに複数回発生します。回答から主張を抜き出し、主張ごとに根拠と照らす、という段階を踏む指標があるためです。採点役のLLMが判断を誤る典型と対策はLLM-as-a-Judgeの評価プロンプトとバイアス対策で扱っています。
インストールから初回実行まで:pip・テストファイル・deepeval test run
ここからは、返品や領収書の問い合わせに答える社内向けRAGを例に、最初のテストを通すまでを追います。コードは公式のQuickstartとGitHubのサンプルの記法に沿って組んだもので、手元での実行結果ではありません。
pip install -U deepevalとAPIキー、テレメトリ停止の環境変数3つ
公式のQuickstartの手順は、仮想環境にパッケージを入れ、採点用のAPIキーを環境変数に置くだけです。Quickstartの範囲はすべてローカルで動き、deepeval loginはConfident AIに結果を送る場合だけ使います。
python -m venv .venv
source .venv/bin/activate
pip install -U deepeval
# 採点役のLLM(既定はOpenAI)
export OPENAI_API_KEY="sk-..."
# 利用状況の送信を止める
export DEEPEVAL_TELEMETRY_OPT_OUT=1
deepeval test run tests/test_rag_answer.py
見落としやすいのが利用状況の送信です。データの扱いを説明する公式ページによると、既定では実行したイベント名・使った指標名・匿名のUUID・公開IPアドレスなどがPostHogへ送られます。評価の中身は含まれないと説明されていますが、社内規程で外部送信を申請制にしている環境では、DEEPEVAL_TELEMETRY_OPT_OUT=1をCIの設定にも入れておきます。
LLMTestCaseとassert_testで書くRAG回答のテストと3指標
テストファイルの形はpytestそのものです。parametrizeで質問と期待する回答の組を並べ、アプリを呼んだ結果をLLMTestCaseに詰め、assert_testに指標のリストと一緒に渡します。pytestのparametrizeやfixtureの書き方はpytestの使い方とparametrizeの書き方を参照してください。
# tests/test_rag_answer.py
import pytest
from deepeval import assert_test
from deepeval.test_case import LLMTestCase, SingleTurnParams
from deepeval.metrics import AnswerRelevancyMetric, FaithfulnessMetric, GEval
from app.rag import answer # 自社のRAG:(回答文, 検索したチャンクのリスト) を返す想定
CASES = [
("返品は何日以内までできますか?", "購入日から30日以内であれば返品できます。"),
("領収書は再発行できますか?", "マイページの注文履歴から1回まで再発行できます。"),
]
correctness = GEval(
name="Correctness",
evaluation_steps=[
"期待する回答に含まれる数値・期限・条件が、実際の回答に過不足なく含まれているか確かめる",
"期待する回答と矛盾する記述があれば大きく減点する",
"言い回しや語順の違いは減点しない",
],
evaluation_params=[SingleTurnParams.ACTUAL_OUTPUT, SingleTurnParams.EXPECTED_OUTPUT],
threshold=0.7,
)
@pytest.mark.parametrize("question,expected", CASES)
def test_rag_answer(question, expected):
actual, chunks = answer(question)
test_case = LLMTestCase(
input=question,
actual_output=actual,
expected_output=expected,
retrieval_context=chunks,
)
assert_test(test_case, [
AnswerRelevancyMetric(threshold=0.7),
FaithfulnessMetric(threshold=0.8),
correctness,
])
実行はpytestではなくdeepeval test runを使います。CI/CDでの単体テストの公式ページは、素のpytestでも動くものの強く非推奨としており、並列実行や結果のキャッシュ、指標ごとのスコア一覧の表示はdeepevalのコマンド側の機能です。テストにせず手元でスコアだけ見たいときは、evaluate()関数か、指標のmeasure()を直接呼びます。
指標の選び方:RAG・会話・エージェントで変わる必須入力と閾値
指標の一覧ページには、RAG・エージェント・複数ターンの会話・安全性・画像などの分類で数十の指標が並びます。全部を付ける必要はありません。最初はアプリの種類に合う2〜3個に絞り、落ちたテストの理由を読めるようにします。
RAGの5指標は検索側3つと生成側2つに分かれ、必須の入力も指標ごとに違う
RAGの指標は、検索したチャンクの質を測るものと、回答の質を測るものに分かれます。どの指標もinputとactual_outputは必須で、それ以外にLLMTestCaseへ入れる項目は指標ごとに異なり、足りないと実行時にエラーになります。
| 指標クラス | 測るもの | 期待する回答 | 検索したチャンク |
|---|---|---|---|
| ContextualPrecisionMetric | 関連チャンクが上位に並んでいるか | 必須 | 必須 |
| ContextualRecallMetric | 期待回答の根拠を取りこぼしていないか | 必須 | 必須 |
| ContextualRelevancyMetric | チャンクに質問と無関係な文が多くないか | 不要 | 必須 |
| AnswerRelevancyMetric | 回答が質問に答えているか | 不要 | 不要 |
| FaithfulnessMetric | 回答がチャンクと矛盾していないか | 不要 | 必須 |
表の「期待する回答」はexpected_output、「検索したチャンク」はretrieval_contextに入れる値です。
実務で先に入れるのは生成側の2つです。期待する回答を作る手間がかからず、本番のログからでもテストケースを起こせます。Faithfulnessの公式ページによると、スコアは回答から抜き出した主張のうち、チャンクと矛盾しないものの割合です。検索側の指標は期待する回答が要るぶん準備が重い一方、Contextual Precisionの公式ページが説明するとおり順位を考慮するため、リランクモデルを入れ替えたときの比較に向きます。Recallが高くPrecisionが低ければ、必要なチャンクは取れているが並び順に問題がある、と読めます。
独自の基準はG-Evalのevaluation_stepsで固定して採点のぶれを抑える
用意された指標で測れない基準、たとえば「金額と期限を必ず書く」「社外秘の部署名を出さない」は、GEvalで自分で定義します。G-Evalの論文の手法をもとにした指標で、採点基準の文章からLLMが評価手順を組み立て、その手順でスコアを付けます。
G-Evalの公式ページによると、criteriaとevaluation_stepsはどちらか一方だけを指定します。criteriaだけだと評価手順を毎回LLMが作るため、同じ回答でも実行ごとにスコアが揺れやすくなります。上のテストでevaluation_stepsを書いたのはこのためです。公式も、短いcriteriaで試して生成された手順を確かめ、それをevaluation_stepsに固定する進め方を勧めています。
もう一つの注意はevaluation_paramsの絞り込みです。手順で触れていない項目まで渡すと、採点の精度が下がることがあると公式は書いています。それでも結果を完全に固定したい基準は、G-Evalではなく判断の分岐を木で書くDAGMetricの対象です。
閾値は既定の0.5のまま使わず人手評価20件前後との一致で決める
全指標の閾値の既定値は0.5です。この値はどのアプリにも当てはまる根拠を持った数字ではなく、そのまま使うと「明らかに誤った回答なのに通る」「十分な回答なのに落ちる」の両方が起きます。
決め方は単純です。本番に近い質問を20件前後選び、人が回答を正しい・誤りの2値で判定する手順です。同じ20件をDeepEvalで採点し、人が誤りとした回答が落ち、正しいとした回答が通る値を探して閾値にします。人の判定と食い違ったケースは、指標のreasonを読んで原因を分ける作業が必要です。採点役の誤読なら評価手順を直し、テストケースの期待回答が古いならデータを直します。評価データセットの件数や作り方は、ハブ記事のLLM評価の指標とデータセット設計で扱っています。
CIへの組み込み:GitHub Actionsの設定と実行時間・費用の管理
テストが手元で通ったら、プロンプトやRAGの設定を変えるプルリクエストで自動的に走らせます。毎回LLMのAPIを呼ぶため、通常の単体テストと違い、実行の範囲と費用を決めてから組み込みます。
GitHub Actionsのワークフロー例とOPENAI_API_KEYの渡し方
公式ページの例はPoetry前提なので、pipの構成に書き換えた例を示します。採点用のキーはリポジトリのSecretsに置き、ステップのenvで渡します。
name: llm-eval
on:
pull_request:
paths:
- "app/**"
- "prompts/**"
- "tests/**"
jobs:
deepeval:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements.txt
- name: Run deepeval
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
DEEPEVAL_TELEMETRY_OPT_OUT: "1"
run: deepeval test run tests/test_rag_answer.py -n 4
pathsで、アプリ・プロンプト・テストを変えたときだけ動くようにしています。READMEの修正でも評価が走ると、そのたびにAPI料金がかかるためです。フォークからのプルリクエストではSecretsが渡されず採点できないので、外部からの貢献を受けるリポジトリでは別の起動条件を考えます。キーの置き場所と漏えいの経路はGitHub ActionsのSecrets管理にまとめています。
-n・-c・-rの3フラグとmax_concurrentで実行時間と費用を抑える
フラグと設定の公式ページには、deepeval test runに付けられるフラグが並んでいます。CIで使うのは主に次の3つです。
| フラグ | 動き | CIでの使いどころ |
|---|---|---|
| -n 数 | 指定したプロセス数で並列に評価 | テストケースが数十件を超えたら |
| -c | 評価済みのケースはローカルキャッシュを読む | 手元で落ちたケースだけ直して再実行するとき |
| -r 数 | 各ケースを指定回数くり返す | スコアの揺れ幅を測るとき |
並列数を上げると、採点役のAPIのレート制限に当たりやすくなります。evaluate()で回す場合はAsyncConfigのmax_concurrent(既定20)で同時に評価するケース数を、throttle_value(既定0秒)で間隔を調整する指定です。-rで3回程度くり返してスコアの幅を見ておくと、閾値ぎりぎりのケースが実行ごとに通ったり落ちたりする状態を事前に見つけられます。
採点役をOllamaのローカルモデルに替えて評価データを社外に出さない
テストケースには社内文書のチャンクがそのまま入るため、外部のAPIへ送れないデータもあります。その場合の対応は、採点役をローカルのLLMに替える方法です。Ollama連携の公式ページのとおり、CLIで全指標の既定をまとめて替えるか、指標ごとにOllamaModelを渡します。
# 全指標の採点役をOllamaに(元に戻すときは deepeval unset-ollama)
deepeval set-ollama --model=qwen3:8b --base-url="http://localhost:11434"
# 指標ごとに指定する場合
from deepeval.models import OllamaModel
from deepeval.metrics import FaithfulnessMetric
judge = OllamaModel(model="qwen3:8b", base_url="http://localhost:11434", temperature=0)
faithfulness = FaithfulnessMetric(threshold=0.8, model=judge)
引き換えに採点の精度は下がります。数Bパラメータのモデルは、日本語の長いチャンクと回答の矛盾を見落としやすいためです。替えたら、閾値を決めるときに使った人手評価の20件で一致率を測り直し、閾値も決め直します。自作のモデルクラスでlogprobsを返さない場合、G-Evalは確率による重み付けをせず整数の生スコアに戻ると公式は説明しており、スコアの刻みが粗くなる点も考慮が必要です。ローカルで動かすモデルの選び方と必要なGPUはローカルLLMの必要スペックとOllamaでの構築手順が参考になります。
DeepEvalを採用する条件と見送る場面、RAGAS・promptfooとの使い分け
LLM評価の道具は、評価をどこに書くかで分かれます。DeepEvalはPythonのテストコード、promptfooはYAMLの設定ファイル、RAGASは分析用のスクリプトが基本の置き場所です。
採用する条件:Python製のLLMアプリにリリース前の回帰テストを入れる
採用してよいのは、アプリ本体がPythonで、開発者がpytestでテストを書く習慣を持っているチームです。プロンプト・モデル・チャンク分割・リランカーのどれかを変えるたびに同じ質問セットで採点し、スコアが下がったらプルリクエストを止める、という使い方がDeepEvalの設計にそのまま合います。
導入の順番も決めておきます。最初の手順は、本番ログから選んだ20〜50件に、AnswerRelevancyとFaithfulnessの2指標だけを付けてCIに入れることです。落ちたケースの理由が読めるようになってから、検索側の指標やG-Evalの独自基準を足します。評価基盤まで含めてRAGを作り直したい、既存のチャットボットに回帰テストを後から入れたい、という案件はRAG構築支援としてご相談いただけます。
見送る場面:採点APIを使えない環境と、非エンジニアが評価を書く体制
見送るのは2つの場面です。1つ目は、評価データを外部のAPIへ送れず、かといって採点に耐えるローカルモデルを動かすGPUも用意できない環境です。採点役の質が足りないと、スコアが人の判断と合わず、テストが落ちても誰も信用しなくなります。この場合は、正規表現やキーワードの含有で判定できる項目だけを通常のテストで書くほうが確実です。
2つ目は、評価観点を業務部門の担当者が書き足していく体制です。DeepEvalの評価はPythonのコードなので、非エンジニアが触るとレビューの負担が開発者に集まります。評価をYAMLで書けるpromptfooのほうが合います。
RAGAS・promptfoo・LangSmithとの比較:書く場所と得意分野で選ぶ
4つとも採点役にLLMを使う指標を持ちますが、評価の書き方と得意分野が違います。
| 道具 | 評価を書く場所 | 得意なこと |
|---|---|---|
| DeepEval | Pythonのテストコード | pytest形式の回帰テストとCI |
| RAGAS | Pythonの分析スクリプト | RAG指標の算出と合成テストセットの生成 |
| promptfoo | YAMLの設定ファイル | プロンプト・モデルの比較とレッドチーミング |
| LangSmith | SaaSの画面とSDK | 本番トレースの収集と評価の記録 |
RAGの指標を研究的に比べたいならRAGAS、CIで品質の下限を守りたいならDeepEval、と分けて併用する構成もよくあります。それぞれの詳細はRAGASの指標と0.4系の実装手順とpromptfooのYAML設定とCI組み込みで扱っています。
よくある質問
DeepEvalを使い始める前に確認されることの多い質問をまとめました。
DeepEvalは無料で使えますか?
ライブラリ自体はApache 2.0のOSSで、商用のシステムでも無料で使えます。費用が発生するのは採点役のLLMのAPI料金で、OpenAIの既定モデルを使う場合はテストケースの件数×指標の数に応じて増える仕組みです。有償なのは、評価結果をチームで共有したりデータセットを管理したりするクラウドサービスのConfident AIで、使わなくてもテストの実行と結果の表示はローカルで完結します。
DeepEvalは日本語の回答も評価できますか?
評価できます。採点は採点役のLLMが回答と根拠を読んで行うため、採点役が日本語を理解できれば、質問・回答・チャンクが日本語でも動きます。指標の内部の評価プロンプトは英語ですが、G-Evalのevaluation_stepsは日本語で書いても構いません。ローカルの小さなモデルを採点役にした場合は日本語の読み取りが弱くなりやすいため、人手で判定した20件前後と突き合わせて一致率を確かめてから使います。
LLMTestCaseParamsが非推奨と警告されるのはなぜですか?
4系でクラス名がSingleTurnParamsに改名されたためです。4.3.2では旧名を読み込むと非推奨の警告を出し、中身はSingleTurnParamsを返すので、コードはそのまま動きます。ただし将来のリリースで削除すると明記されているため、from deepeval.test_case import SingleTurnParamsに書き換えておきます。会話用のTurnParamsも同じ理由でMultiTurnParamsへの置き換えが必要です。
同じテストでもスコアが実行ごとに変わるのはなぜですか?
採点役のLLMの出力が毎回わずかに違うためです。特にG-Evalでcriteriaだけを指定していると、評価手順そのものが実行ごとに作り直され、揺れが大きくなります。対策は、evaluation_stepsで手順を固定する、採点役のtemperatureを0にする、-rで数回くり返してスコアの幅を見たうえで閾値を幅の下側から離して置く、の順に試すことです。完全に固定したい基準はDAGMetricで分岐を書きます。
DeepEvalでAIエージェントも評価できますか?
できます。エージェント向けには、タスクを達成したかを見るTaskCompletionMetric、呼ぶべきツールを呼んだかを見るToolCorrectnessMetric、引数の正しさを見るArgumentCorrectnessMetricなどがあります。エージェントの途中の手順を評価するには、関数に@observeを付けて実行の記録(トレース)を取る必要があり、質問と回答だけを詰めたテストケースでは足りません。評価の設計そのものはAIエージェント評価の指標と実装の進め方で扱っています。
関連記事
- RAG評価とは?検索と生成を分けて測る指標・Ragasでの実装・運用への組み込み【2026年版】:RAGの評価を検索と生成に分ける考え方の全体像です。
- LLM評価とは?指標・データセット設計・評価ツールの選び方を実装視点で解説【2026年版】:DeepEvalを含む評価ツールの守備範囲と、評価データセットの作り方です。
- Langfuseとは?読み方・機能・使い方とLangSmithとの違い【v4対応・2026年10月】:本番のトレースを集めて、評価用の質問セットを起こす基盤です。
- LangSmithとは?トレース送信の設定・評価の実行・料金とリージョンの選び方【2026年版】:評価結果をSaaSで記録・共有したい場合の選択肢です。
- LLMOpsとは?MLOpsとの違いとトレース・評価・コスト管理の実装を解説【2026年版】:評価をLLMアプリの運用全体の中に位置づける記事です。