mcpField
D
deepeval

deepeval

github.com/sammcj测试与质量16778 次安装1 天前更新
代码仓库

关于 deepeval

DeepEval 是面向 LLM 应用开发者的 pytest 测试框架,可评估 RAG、对话、Agent 和安全性,并支持自定义指标与组件级追踪。

主要功能

  1. 01覆盖 RAG、对话、Agent 与安全评估
  2. 02支持自定义及多模态测试用例
  3. 03提供组件级追踪与评估
  4. 04支持异步执行、缓存和并行化
  5. 05可生成合成评估数据集

适用场景

  1. 01在 CI/CD 中运行 LLM 应用测试
  2. 02检查 RAG 检索与生成质量
  3. 03评估多轮对话和 Agent 工具调用
  4. 04识别有害内容、偏见及隐私泄漏

MCP 相关

DeepEval 提供 MCPUseMetric,用于评估 Agent 是否正确使用 MCP。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sammcj/agentic-coding --skill deepeval

安装后在 Claude Code 中输入/deepeval确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
async_performance.md
custom_metrics.md
dataset_management.md
model_providers.md

详细介绍

DeepEval

概述

DeepEval 是一个基于 pytest 的框架,用于测试大模型应用。它提供 50 多种评估指标,涵盖 RAG 流程、对话式 AI、Agent、安全性和自定义标准。DeepEval 通过 pytest 集成到开发工作流中,支持多个大模型提供商,并通过 @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)
Agent 评估

测试工具使用和任务完成情况:

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 - 对话始终围绕主题
Agent 指标
  • TaskCompletionMetric - 成功完成任务
  • ToolUseMetric - 选择了正确的工具
  • ArgumentCorrectnessMetric - 工具参数正确
  • MCPUseMetric - 正确使用 MCP
安全性指标
  • ToxicityMetric - 检测有害内容
  • BiasMetric - 识别有偏见的输出
  • HallucinationMetric - 检测捏造的信息
  • PIILeakageMetric - 检测个人信息泄露
自定义指标

G-Eval(基于大模型):

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。

配置

大模型提供商设置

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
  • 优先使用 evaluate() 函数,而不是单独调用 measure()

有关详细的性能优化指南,请参阅 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)和基于大模型的评估模式。

  • 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
  • 部署前进行端到端验证
  • 在 CI/CD 中使用 deepeval test run 实现自动化
  • 使用 Confident AI 云跟踪结果随时间的变化
测试反模式

避免:

  • 只测试顺利路径
  • 使用不切实际的输入
  • 忽略指标原因
  • 一开始就设置过高的阈值
  • 每次变更都运行完整测试套件

建议:

  • 测试边缘情况和故障模式
  • 使用真实用户查询作为测试输入
  • 阅读并分析指标原因
  • 根据实测结果调整阈值
  • 在开发期间使用组件级测试
  • 将配置和评估内容与代码分开

评论

支持 Markdown