BatchEvalRunner 是在主流RAG评估框架 LlamaIndex 中,用于高效批量运行多项评估任务的核心工具。它的核心职责就是系统化地测试你的 RAG 系统。

🚀 为什么需要它?

  • 自动化与批量化:自动化评估整个测试集,一次性回答成百上千个问题,避免低效的手动点测
  • 并行化加速:利用异步机制,如设置 workers=8 启用8个并发任务,能极大缩短整体评估时间
  • 指标集成:可一站式配置并运行所有评估(如答案忠实度、相关性),输出结构化数据进行统一汇总

⚙️ 如何使用它?

1. 准备评估器 (Evaluators)

首先,选择一个LLM作为“评委”(如GPT-4),用它来实例化具体的评估器(如 FaithfulnessEvaluator

python

from llama_index.llms.openai import OpenAI
from llama_index.core.evaluation import FaithfulnessEvaluator, RelevancyEvaluator

# 初始化评委模型,temperature=0确保评估结果一致性
gpt4 = OpenAI(temperature=0, model="gpt-4")
# 实例化忠实度评估器
faithfulness_evaluator = FaithfulnessEvaluator(llm=gpt4)
# 实例化相关性评估器
relevancy_evaluator = RelevancyEvaluator(llm=gpt4)

2. 创建并运行 Runner

将评估器以字典形式传入BatchEvalRunner,并调用其 aevaluate_queries 方法(注意:这是一个异步方法)

python

import asyncio
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core.evaluation import FaithfulnessEvaluator, RelevancyEvaluator, BatchEvalRunner

from 加载模型 import get_llm


async def main():
    # 1. 初始化模型设置 (全局配置)
    llm, embed_model = get_llm()

    # 2. 准备索引
    print("正在构建索引...")
    documents = SimpleDirectoryReader(input_files=[r".\data\小说.txt"]).load_data()
    index = VectorStoreIndex.from_documents(documents)
    query_engine = index.as_query_engine()

    # 3. 初始化评估器
    # 建议:评估模型可以选比生成模型更强的(如 GPT-4),结果更客观
    """
        忠实度:答案是否忠于检索上下文(有没有凭空捏造)。
        答案相关性:答案是否针对用户所问的问题(有没有答非所问)。
    """
    faith_evaluator = FaithfulnessEvaluator(llm=llm)  # 忠实度评估器
    rel_evaluator = RelevancyEvaluator(llm=llm)  # 答案相关性评估器

    # 4. 批量查询与评估 (核心优化点)
    queries = [
        "萧炎的爸爸是谁?",  # 基础题(预期:1.0)
        "萧炎最喜欢的现代流行歌手是谁?",  # 跨时空无关(预期:Faithfulness 应该为 1.0,但回答应为“不知道”)
        "萧炎在第一章里一共喝了几杯咖啡?",  # 逻辑陷阱(玄幻小说没咖啡,看它是否产生幻觉)
        "作者天蚕土豆的家庭住址在哪里?",  # 外部元数据(文档里没写作者隐私,看它是否拒绝)
        "萧炎用什么牌子的智能手机和药老联系?"  # 严重干扰项
    ]

    print(f"\n开始批量执行 {len(queries)} 组评估...")

    # 使用 BatchEvalRunner 进行并行异步评估
    # 相比于 for 循环逐个评估,BatchEvalRunner 能显著提高 Token 利用率和执行速度
    runner = BatchEvalRunner(
        {
            "faithfulness": faith_evaluator,
            "relevancy": rel_evaluator,
        },
        show_progress=True,
        workers=4  # 根据 API 限制调整并发数
    )

    # aevaluate_queries 会自动执行:查询 -> 获取 Response -> 调用各评估器
    eval_results = await runner.aevaluate_queries(
        query_engine,
        queries=queries
    )

    # 5. 格式化结果输出
    print("\n" + "=" * 50)
    print("评估报告汇总")
    print("=" * 50)

    for query in queries:
        print(f"查询问题: {query}")

        print("RAG最终的回复:", query_engine.query(query).response)

        # 提取各个维度的结果
        f_res = eval_results["faithfulness"][queries.index(query)]
        r_res = eval_results["relevancy"][queries.index(query)]

        # 打印详细打分
        print(f"  [忠实度 Faithfulness]: {'通过' if f_res.passing else '❌ 失败'} (得分: {f_res.score:.2f})")
        if not f_res.passing:
            print(f"    └─ 反馈: {f_res.feedback}")

        print(f"  [相关性 Relevancy   ]: {'通过' if r_res.passing else '❌ 失败'} (得分: {r_res.score:.2f})")
        if not r_res.passing:
            print(f"    └─ 反馈: {r_res.feedback}")

    print("\n" + "=" * 50)


if __name__ == "__main__":
    asyncio.run(main())

注意:因为 aevaluate_queries 是异步方法,如果不在Jupyter Notebook环境下运行,你需要把它包裹在一个异步函数中,并用 asyncio.run() 来执行。

⚡ 关键特性:异步与并发

BatchEvalRunner 核心优势在于其异步(Async)并发架构

  • 高并发:通过workers参数控制并发数,最大化利用你的API额度,显著缩短评估时间。
  • 常见问题与解决:如果你在同步环境(如常规Python脚本)中使用 await runner.aevaluate_queries(),会遇到 SyntaxError: 'await' outside function 错误。解决方案是创建一个异步协程来调用它。

🆚 BatchEvalRunner vs. 其他框架

  • Langfuse: 使用 BatchEvaluationRunner 对Langfuse平台中已有的生产日志(Traces/Observations)进行事后批量分析
  • Ragas: 没有直接的Runner,核心入口是 evaluate() 和 aevaluate() 函数,能够批量运行 EvaluationDataset

💡 典型应用场景

  • 回归测试:将评估流程(CI/CD),每次代码变更后自动运行,通过指标变化检测性能下降(即“回归”)
  • 迭代优化:对测试集运行BatchEvalRunner生成详细评估报告,通过分析具体的低分案例来定位问题环节,进行针对性优化。

💎 总结

BatchEvalRunner是RAG应用从“能跑”迈向“好用”的关键一步,它帮助你建立量化的评估体系,是确保应用可靠迭代的重要一环。

希望这些介绍能帮你更好地理解它。如果想了解更具体的配置,比如如何集成你自己的数据集,可以随时再问我。