deepeval について
DeepEvalは、LLMアプリケーションをテストする開発者向けのpytestベースのフレームワークです。RAG、会話、エージェント、安全性を評価でき、カスタムメトリクスとコンポーネント単位のトレースにも対応します。
主な機能
- 01RAG、会話、エージェント、安全性のメトリクス
- 02カスタムおよびマルチモーダルなテストケース
- 03コンポーネント単位のトレースと評価
- 04非同期実行、キャッシュ、並列実行
- 05合成評価データセットの生成
活用シーン
- 01CI/CDでのLLMアプリケーションテスト
- 02RAGの検索と生成品質の確認
- 03複数ターンの会話とエージェントのツール利用の評価
- 04有害な出力、偏見、個人情報漏えいの検出
MCP 対応
MCPUseMetricを備え、エージェントがMCPを正しく利用するか評価できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sammcj/ agentic-coding --skill deepevalインストール後、Claude Code で/deepevalを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/async_performance.mdcustom_metrics.mddataset_management.mdmodel_providers.md詳細
DeepEval
概要
DeepEvalは、LLMアプリケーションをテストするためのpytestベースのフレームワークです。RAGパイプライン、会話型AI、エージェント、安全性、カスタム基準を対象とする50以上の評価指標を提供します。DeepEvalはpytestを通じて開発ワークフローに統合でき、複数のLLMプロバイダーをサポートし、@observeデコレーターによるコンポーネントレベルのトレース機能も備えています。
リポジトリ: https://github.com/confident-ai/deepeval ドキュメント: https://deepeval.com
インストール
pip install -U deepeval
Python 3.9以降が必要です。
クイックスタート
基本的なpytestテスト
import pytest
from deepeval import assert_test
from deepeval.test_case import LLMTestCase
from deepeval.metrics import AnswerRelevancyMetric
def test_chatbot():
metric = AnswerRelevancyMetric(threshold=0.7, model="athropic-claude-sonnet-4-5")
test_case = LLMTestCase(
input="What if these shoes don't fit?",
actual_output="You have 30 days for full refund"
)
assert_test(test_case, [metric])
次のコマンドで実行します:deepeval test run test_chatbot.py
環境のセットアップ
DeepEvalは.env.localを読み込んだ後に.envを自動的に読み込みます。
# .env
OPENAI_API_KEY="sk-..."
主要なワークフロー
RAGの評価
検索フェーズと生成フェーズの両方を評価します。
from deepeval.metrics import (
ContextualPrecisionMetric,
ContextualRecallMetric,
ContextualRelevancyMetric,
AnswerRelevancyMetric,
FaithfulnessMetric
)
# Retrieval metrics
contextual_precision = ContextualPrecisionMetric(threshold=0.7)
contextual_recall = ContextualRecallMetric(threshold=0.7)
contextual_relevancy = ContextualRelevancyMetric(threshold=0.7)
# Generation metrics
answer_relevancy = AnswerRelevancyMetric(threshold=0.7)
faithfulness = FaithfulnessMetric(threshold=0.8)
test_case = LLMTestCase(
input="What are the side effects of aspirin?",
actual_output="Common side effects include stomach upset and nausea.",
expected_output="Aspirin side effects include gastrointestinal issues.",
retrieval_context=[
"Aspirin common side effects: stomach upset, nausea, vomiting.",
"Serious aspirin side effects: gastrointestinal bleeding.",
]
)
evaluate(test_cases=[test_case], metrics=[
contextual_precision, contextual_recall, contextual_relevancy,
answer_relevancy, faithfulness
])
コンポーネントレベルのトレース:
from deepeval.tracing import observe, update_current_span
@observe(metrics=[contextual_relevancy])
def retriever(query: str):
chunks = your_vector_db.search(query)
update_current_span(
test_case=LLMTestCase(input=query, retrieval_context=chunks)
)
return chunks
@observe(metrics=[answer_relevancy, faithfulness])
def generator(query: str, chunks: list):
response = your_llm.generate(query, chunks)
update_current_span(
test_case=LLMTestCase(
input=query,
actual_output=response,
retrieval_context=chunks
)
)
return response
@observe
def rag_pipeline(query: str):
chunks = retriever(query)
return generator(query, chunks)
会話型AIの評価
複数ターンの対話をテストします。
from deepeval.test_case import Turn, ConversationalTestCase
from deepeval.metrics import (
RoleAdherenceMetric,
KnowledgeRetentionMetric,
ConversationCompletenessMetric,
TurnRelevancyMetric
)
convo_test_case = ConversationalTestCase(
chatbot_role="professional, empathetic medical assistant",
turns=[
Turn(role="user", content="I have a persistent cough"),
Turn(role="assistant", content="How long have you had this cough?"),
Turn(role="user", content="About a week now"),
Turn(role="assistant", content="A week-long cough should be evaluated.")
]
)
metrics = [
RoleAdherenceMetric(threshold=0.7),
KnowledgeRetentionMetric(threshold=0.7),
ConversationCompletenessMetric(threshold=0.6),
TurnRelevancyMetric(threshold=0.7)
]
evaluate(test_cases=[convo_test_case], metrics=metrics)
エージェントの評価
ツールの使用とタスクの完了をテストします。
from deepeval.test_case import ToolCall
from deepeval.metrics import (
TaskCompletionMetric,
ToolUseMetric,
ArgumentCorrectnessMetric
)
agent_test_case = ConversationalTestCase(
turns=[
Turn(role="user", content="When did Trump first raise tariffs?"),
Turn(
role="assistant",
content="Let me search for that information.",
tools_called=[
ToolCall(
name="WebSearch",
arguments={"query": "Trump first raised tariffs year"}
)
]
),
Turn(role="assistant", content="Trump first raised tariffs in 2018.")
]
)
evaluate(
test_cases=[agent_test_case],
metrics=[
TaskCompletionMetric(threshold=0.7),
ToolUseMetric(threshold=0.7),
ArgumentCorrectnessMetric(threshold=0.7)
]
)
安全性の評価
有害なコンテンツがないか確認します。
from deepeval.metrics import (
ToxicityMetric,
BiasMetric,
PIILeakageMetric,
HallucinationMetric
)
def safety_gate(output: str, input: str) -> tuple[bool, list]:
"""Returns (passed, reasons) tuple"""
test_case = LLMTestCase(input=input, actual_output=output)
safety_metrics = [
ToxicityMetric(threshold=0.5),
BiasMetric(threshold=0.5),
PIILeakageMetric(threshold=0.5)
]
failures = []
for metric in safety_metrics:
metric.measure(test_case)
if not metric.is_successful():
failures.append(f"{metric.name}: {metric.reason}")
return len(failures) == 0, failures
指標の選択ガイド
RAGの指標
検索フェーズ:
ContextualPrecisionMetric- 関連するチャンクが、関連しないチャンクより上位にランク付けされているかContextualRecallMetric- 必要な情報がすべて検索されているかContextualRelevancyMetric- 検索されたチャンクが入力に関連しているか
生成フェーズ:
AnswerRelevancyMetric- 出力が入力されたクエリに回答しているかFaithfulnessMetric- 出力が検索コンテキストに根拠を置いているか
会話の指標
TurnRelevancyMetric- 各ターンが会話に関連しているかKnowledgeRetentionMetric- ターンをまたいで情報が保持されているかConversationCompletenessMetric- あらゆる側面が網羅されているかRoleAdherenceMetric- チャットボットが割り当てられた役割を維持しているかTopicAdherenceMetric- 会話が話題から逸れていないか
エージェントの指標
TaskCompletionMetric- タスクが正常に完了したかToolUseMetric- 適切なツールが選択されたかArgumentCorrectnessMetric- ツールの引数が正しいかMCPUseMetric- MCPが正しく使用されたか
安全性の指標
ToxicityMetric- 有害なコンテンツの検出BiasMetric- 偏りのある出力の特定HallucinationMetric- 捏造された情報PIILeakageMetric- 個人情報の漏えい
カスタム指標
G-Eval(LLMベース):
from deepeval.metrics import GEval
from deepeval.test_case import LLMTestCaseParams
custom_metric = GEval(
name="Professional Tone",
criteria="Determine if response maintains professional, empathetic tone",
evaluation_params=[LLMTestCaseParams.ACTUAL_OUTPUT],
threshold=0.7,
model="anthropic-claude-sonnet-4-5"
)
BaseMetricのサブクラス:
BaseMetricのサブクラス化と決定論的スコアラー(ROUGE、BLEU、BERTScore)を使ったカスタム指標の作成方法については、完全なガイドであるreferences/custom_metrics.mdを参照してください。
設定
LLMプロバイダーのセットアップ
DeepEvalは、OpenAI、Anthropic Claude、Google Gemini、AWS Bedrock、およびLiteLLM経由で100以上のプロバイダーをサポートしています。 Anthropicのモデルを推奨します。
CLI設定(グローバル):
deepeval set-azure-openai --openai-endpoint=... --openai-api-key=... --deployment-name=...
deepeval set-ollama deepseek-r1:1.5b
Python設定(指標ごと):
from deepeval.models import AnthropicModel, OllamaModel
anthropic_model = AnthropicModel(
model_id=settings.anthropic_model_id,
client_args={"api_key": settings.anthropic_api_key},
temperature=settings.agent_temperature
)
metric = AnswerRelevancyMetric(model=anthropic_model)
プロバイダー設定の完全なガイドについては、references/model_providers.mdを参照してください。
パフォーマンスの最適化
非同期モードはデフォルトで有効です。AsyncConfigとCacheConfigで設定します。
from deepeval import evaluate, AsyncConfig, CacheConfig
evaluate(
test_cases=[...],
metrics=[...],
async_config=AsyncConfig(
run_async=True,
max_concurrent=20, # Reduce if rate limited
throttle_value=0 # Delay between test cases (seconds)
),
cache_config=CacheConfig(
use_cache=True, # Read from cache
write_cache=True # Write to cache
)
)
CLIでの並列化:
deepeval test run -n 4 -c -i # 4 processes, cached, ignore errors
ベストプラクティス:
- 指標は最大5つに制限します(汎用指標を2~3個、カスタム指標を1~2個)
- 利用可能な最新のAnthropic Claude SonnetモデルまたはHaikuモデルを使用します
- レート制限に達する場合は、
max_concurrentを5に減らします - 個別の
measure()呼び出しよりevaluate()関数を使用します
パフォーマンス最適化の詳細なガイドについては、references/async_performance.mdを参照してください。
データセットの管理
データセットの読み込み
from deepeval.dataset import EvaluationDataset, Golden
dataset = EvaluationDataset()
# From CSV
dataset.add_goldens_from_csv_file(
file_path="./test_data.csv",
input_col_name="question",
expected_output_col_name="answer",
context_col_name="context",
context_col_delimiter="|"
)
# From JSON
dataset.add_goldens_from_json_file(
file_path="./test_data.json",
input_key_name="query",
expected_output_key_name="response"
)
合成データの生成
from deepeval.synthesizer import Synthesizer
synthesizer = Synthesizer()
# From documents
goldens = synthesizer.generate_goldens_from_docs(
document_paths=["./docs/knowledge_base.pdf"],
max_goldens_per_document=10,
evolution_types=["REASONING", "MULTICONTEXT", "COMPARATIVE"]
)
# From scratch
goldens = synthesizer.generate_goldens_from_scratch(
subject="customer support for SaaS product",
task="answer user questions about billing",
max_goldens=20
)
進化タイプ: REASONING、MULTICONTEXT、CONCRETISING、CONSTRAINED、COMPARATIVE、HYPOTHETICAL、IN_BREADTH
バージョン管理やクラウド統合を含むデータセットの完全なガイドについては、references/dataset_management.mdを参照してください。
テストケースの種類
シングルターン(LLMTestCase)
from deepeval.test_case import LLMTestCase
test_case = LLMTestCase(
input="What if these shoes don't fit?",
actual_output="You have 30 days for full refund",
expected_output="We offer 30-day full refund",
retrieval_context=["All customers eligible for 30 day refund"],
tools_called=[ToolCall(name="...", arguments={"...": "..."})]
)
マルチターン(ConversationalTestCase)
from deepeval.test_case import Turn, ConversationalTestCase
convo_test_case = ConversationalTestCase(
chatbot_role="helpful customer service agent",
turns=[
Turn(role="user", content="I need help with my order"),
Turn(role="assistant", content="I'd be happy to help"),
Turn(role="user", content="It hasn't arrived yet")
]
)
マルチモーダル(MLLMTestCase)
from deepeval.test_case import MLLMTestCase, MLLMImage
m_test_case = MLLMTestCase(
input=["Describe this image", MLLMImage(url="./photo.png", local=True)],
actual_output=["A red bicycle leaning against a wall"]
)
CI/CD統合
# .github/workflows/test.yml
name: LLM Tests
on: [push, pull_request]
jobs:
evaluate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Install dependencies
run: pip install deepeval
- name: Run evaluations
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: deepeval test run tests/
参考資料
詳細な実装ガイド:
-
references/model_providers.md - OpenAI、Anthropic、Gemini、Bedrock、ローカルモデルの設定に関する完全ガイドです。プロバイダー固有の考慮事項、コスト分析、トラブルシューティングも含まれています。
-
references/custom_metrics.md - BaseMetric のサブクラス化によるカスタムメトリクスの作成に関する完全ガイドです。決定論的なスコアラー(ROUGE、BLEU、BERTScore)と、LLM ベースの評価パターンを含みます。
-
references/async_performance.md - 非同期モード、キャッシュ、並行性の調整、レート制限への対応による評価パフォーマンスの最適化に関する完全ガイドです。
-
references/dataset_management.md - データセットの読み込み、保存、合成データの生成、バージョン管理、Confident AI とのクラウド連携に関する完全ガイドです。
ベストプラクティス
メトリクスの選択
- メトリクスをユースケースに合わせます(RAG システムには検索と生成のメトリクスが必要です)
- まずは必須のメトリクスを2~3個使い、必要に応じて追加します
- 適切なしきい値を使用します(本番環境では0.7~0.8、開発環境では0.5~0.6)
- 相互補完的なメトリクスを組み合わせます(回答の関連性 + 忠実性)
テストケースの設計
- よくあるクエリやエッジケースを網羅する、代表的な例を作成します
- 必要に応じてコンテキストを含めます(RAG では
retrieval_context、G-Eval ではexpected_output) - 大規模なテストにはデータセットを使用します
- テストケースのバージョンを継続的に管理します
評価ワークフロー
- まずコンポーネント単位で評価します。個々の部分には
@observeを使用します - デプロイ前にエンドツーエンドで検証します
deepeval test runを使って CI/CD で自動化します- Confident AI クラウドを使って結果を継続的に追跡します
テストのアンチパターン
避けること:
- 成功するケースだけをテストする
- 非現実的な入力を使用する
- メトリクスの理由を無視する
- 最初からしきい値を高く設定する
- 変更のたびにテストスイート全体を実行する
実施すること:
- エッジケースや障害モードをテストする
- 実際のユーザークエリをテスト入力として使用する
- メトリクスの理由を読み、分析する
- 実測結果に基づいてしきい値を調整する
- 開発中はコンポーネント単位のテストを使用する
- 設定と評価の内容をコードから分離する