continuous-eval

relari-aiApache-2.0活跃维护

面向 LLM 应用的数据驱动评估框架,提供多种指标,重点覆盖 RAG 与信息检索场景,帮助在开发中持续量化效果。

Data-Driven Evaluation for LLM-Powered Applications

v0.3.14发布于 2025-01-10 19:54 UTC519star39fork同步于 2026-11-07 07:29 UTC

怎么上手

由 README 提炼,执行前请确认
python3 -m pip install continuous-eval
硬件要求按 README 说明

README 未说明

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

按模块评估 LLM 应用的开源 Python 包,用确定性与 LLM 指标量化 RAG、Agent、代码生成等流水线各环节

面向 LLM 应用的数据驱动评估框架,提供多种指标,重点覆盖 RAG 与信息检索场景,帮助在开发中持续量化效果。

核心能力

  • 按 pipeline 模块分别配置指标与测试
  • 内置 RAG、代码生成、Agent 工具调用、分类等指标库
  • 混合确定性、语义与 LLM 打分三类指标
  • 用 CustomMetric 以 LLM-as-a-Judge 自定义评分标准
  • 支持多模块 Pipeline 并输出 mermaid 结构图

容易踩的坑

跑 LLM 类指标需在 .env 中配置至少一个 LLM API 密钥;示例数据需通过 example_data_downloader 额外下载;脚本必须放在 if name == "main" 保护下运行,否则多进程并行会出问题

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.3.14
  1. v0.3.14最新正式版2025-01-10 · 2025-01-10 19:54 UTC
  2. v0.3.132024-08-04 · 2024-08-04 23:02 UTC
    查看更新说明
  3. v0.3.112024-06-18 · 2024-06-18 18:44 UTC
    查看更新说明

    What's Changed

    New Contributors

    Full Changelog: https://github.com/relari-ai/continuous-eval/compare/v0.3.10...v0.3.11

  4. v0.3.102024-06-02 · 2024-06-02 16:12 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/relari-ai/continuous-eval/compare/v0.3.9...v0.3.10

  5. v0.3.92024-05-23 · 2024-05-23 19:53 UTC
    查看更新说明

    What's Changed

    New Contributors

    Full Changelog: https://github.com/relari-ai/continuous-eval/compare/v0.3.7...v0.3.9

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    https://pypi.python.org/pypi/continuous-eval/ https://GitHub.com/relari-ai/continuous-eval/releases https://github.com/Naereen/badges/ https://pypi.python.org/pypi/continuous-eval/

    Overview

    continuous-eval is an open-source package created for data-driven evaluation of LLM-powered application.

    How is continuous-eval different?

    • Modularized Evaluation: Measure each module in the pipeline with tailored metrics.

    • Comprehensive Metric Library: Covers Retrieval-Augmented Generation (RAG), Code Generation, Agent Tool Use, Classification and a variety of other LLM use cases. Mix and match Deterministic, Semantic and LLM-based metrics.

    • Probabilistic Evaluation: Evaluate your pipeline with probabilistic metrics

    Getting Started

    This code is provided as a PyPi package. To install it, run the following command:

    python3 -m pip install continuous-eval
    

    if you want to install from source:

    git clone https://github.com/relari-ai/continuous-eval.git && cd continuous-eval
    poetry install --all-extras
    

    To run LLM-based metrics, the code requires at least one of the LLM API keys in .env. Take a look at the example env file .env.example.

    Run a single metric

    Here's how you run a single metric on a datum. Check all available metrics here: link

    from continuous_eval.metrics.retrieval import PrecisionRecallF1
    
    datum = {
        "question": "What is the capital of France?",
        "retrieved_context": [
            "Paris is the capital of France and its largest city.",
            "Lyon is a major city in France.",
        ],
        "ground_truth_context": ["Paris is the capital of France."],
        "answer": "Paris",
        "ground_truths": ["Paris"],
    }
    
    metric = PrecisionRecallF1()
    
    print(metric(**datum))
    

    Run an evaluation

    If you want to run an evaluation on a dataset, you can use the EvaluationRunner class.

    from time import perf_counter
    
    from continuous_eval.data_downloader import example_data_downloader
    from continuous_eval.eval import EvaluationRunner, SingleModulePipeline
    from continuous_eval.eval.tests import GreaterOrEqualThan
    from continuous_eval.metrics.retrieval import (
        PrecisionRecallF1,
        RankedRetrievalMetrics,
    )
    
    
    def main():
        # Let's download the retrieval dataset example
        dataset = example_data_downloader("retrieval")
    
        # Setup evaluation pipeline (i.e., dataset, metrics and tests)
        pipeline = SingleModulePipeline(
            dataset=dataset,
            eval=[
                PrecisionRecallF1().use(
                    retrieved_context=dataset.retrieved_contexts,
                    ground_truth_context=dataset.ground_truth_contexts,
                ),
                RankedRetrievalMetrics().use(
                    retrieved_context=dataset.retrieved_contexts,
                    ground_truth_context=dataset.ground_truth_contexts,
                ),
            ],
            tests=[
                GreaterOrEqualThan(
                    test_name="Recall", metric_name="context_recall", min_value=0.8
                ),
            ],
        )
    
        # Start the evaluation manager and run the metrics (and tests)
        tic = perf_counter()
        runner = EvaluationRunner(pipeline)
        eval_results = runner.evaluate()
        toc = perf_counter()
        print("Evaluation results:")
        print(eval_results.aggregate())
        print(f"Elapsed time: {toc - tic:.2f} seconds\n")
    
        print("Running tests...")
        test_results = runner.test(eval_results)
        print(test_results)
    
    
    if __name__ == "__main__":
        # It is important to run this script in a new process to avoid
        # multiprocessing issues
        main()
    

    Run evaluation on a pipeline (modular evaluation)

    Sometimes the system is composed of multiple modules, each with its own metrics and tests. Continuous-eval supports this use case by allowing you to define modules in your pipeline and select corresponding metrics.

    from typing import Any, Dict, List
    
    from continuous_eval.data_downloader import example_data_downloader
    from continuous_eval.eval import (
        Dataset,
        EvaluationRunner,
        Module,
        ModuleOutput,
        Pipeline,
    )
    from continuous_eval.eval.result_types import PipelineResults
    from continuous_eval.metrics.generation.text import AnswerCorrectness
    from continuous_eval.metrics.retrieval import PrecisionRecallF1, RankedRetrievalMetrics
    
    
    def page_content(docs: List[Dict[str, Any]]) -> List[str]:
        # Extract the content of the retrieved documents from the pipeline results
        return [doc["page_content"] for doc in docs]
    
    
    def main():
        dataset: Dataset = example_data_downloader("graham_essays/small/dataset")
        results: Dict = example_data_downloader("graham_essays/small/results")
    
        # Simple 3-step RAG pipeline with Retriever->Reranker->Generation
        retriever = Module(
            name="retriever",
            input=dataset.question,
            output=List[str],
            eval=[
                PrecisionRecallF1().use(
                    retrieved_context=ModuleOutput(page_content),  # specify how to extract what we need (i.e., page_content)
                    ground_truth_context=dataset.ground_truth_context,
                ),
            ],
        )
    
        reranker = Module(
            name="reranker",
            input=retriever,
            output=List[Dict[str, str]],
            eval=[
                RankedRetrievalMetrics().use(
                    retrieved_context=ModuleOutput(page_content),
                    ground_truth_context=dataset.ground_truth_context,
                ),
            ],
        )
    
        llm = Module(
            name="llm",
            input=reranker,
            output=str,
            eval=[
                AnswerCorrectness().use(
                    question=dataset.question,
                    answer=ModuleOutput(),
                    ground_truth_answers=dataset.ground_truth_answers,
                ),
            ],
        )
    
        pipeline = Pipeline([retriever, reranker, llm], dataset=dataset)
        print(pipeline.graph_repr())  # visualize the pipeline in marmaid format
    
        runner = EvaluationRunner(pipeline)
        eval_results = runner.evaluate(PipelineResults.from_dict(results))
        print(eval_results.aggregate())
    
    
    if __name__ == "__main__":
        main()
    

    Note: it is important to wrap your code in a main function (with the if __name__ == "__main__": guard) to make sure the parallelization works properly.

    Custom Metrics

    There are several ways to create custom metrics, see the Custom Metrics section in the docs.

    The simplest way is to leverage the CustomMetric class to create a LLM-as-a-Judge.

    from continuous_eval.metrics.base.metric import Arg, Field
    from continuous_eval.metrics.custom import CustomMetric
    from typing import List
    
    criteria = "Check that the generated answer does not contain PII or other sensitive information."
    rubric = """Use the following rubric to assign a score to the answer based on its conciseness:
    - Yes: The answer contains PII or other sensitive information.
    - No: The answer does not contain PII or other sensitive information.
    """
    
    metric = CustomMetric(
        name="PIICheck",
        criteria=criteria,
        rubric=rubric,
        arguments={"answer": Arg(type=str, description="The answer to evaluate.")},
        response_format={
            "reasoning": Field(
                type=str,
                description="The reasoning for the score given to the answer",
            ),
            "score": Field(
                type=str, description="The score of the answer: Yes or No"
            ),
            "identifies": Field(
                type=List[str],
                description="The PII or other sensitive information identified in the answer",
            ),
        },
    )
    
    # Let's calculate the metric for the first datum
    print(metric(answer="John Doe resides at 123 Main Street, Springfield."))
    

    💡 Contributing

    Interested in contributing? See our Contribution Guide for more details.

    Resources

    License

    This project is licensed under the Apache 2.0 - see the LICENSE file for details.

    Open Analytics

    We monitor basic anonymous usage statistics to understand our users' preferences, inform new features, and identify areas that might need improvement. You can take a look at exactly what we track in the telemetry code

    To disable usage-tracking you set the CONTINUOUS_EVAL_DO_NOT_TRACK flag to true.