Files
siemens_ragas/docs/rag-eval-engine-flow.md
2026-06-12 14:02:15 +08:00

10 KiB
Raw Blame History

RAG 评测引擎链路说明

1. 这份文档解决什么问题

docs/rag-eval-architecture.md 主要回答“为什么这样分层、模块边界是什么”。
这份文档回答的是另一件事:一次评测在代码里到底是怎么跑起来的

如果你现在对下面这些问题还有点混淆,这份文档就是给你的:

  • rag_eval/ 到底是评测什么的
  • apps/ 在整个架构里扮演什么角色
  • offlineonline 模式的区别是什么
  • dataset、adapter、metrics、reporting 是怎么串起来的

2. 一句话理解整个引擎

这套系统本质上是一条标准化评测流水线:

scenario -> dataset -> normalize -> app adapter -> metrics -> reporting -> run artifacts

也可以拆成更容易理解的话:

  1. 先读取一份评测场景配置
  2. 再读取待评测数据
  3. 把原始数据标准化成统一样本结构
  4. 如果需要,调用你的 RAG 应用补齐 answercontexts
  5. ragas 指标计算分数
  6. 把结果写到本地 run 目录

3. 目录职责

rag_eval/

这是评测引擎本体。它负责:

  • 加载 scenario
  • 加载 dataset
  • 调用 app adapter
  • 执行指标评分
  • 写出结果资产

apps/

这是被评测应用的接入层,不是评测框架本身。

这里放的是“你的 RAG 应用如何被框架调用”的示例或适配代码。例如:

apps/
└── sample_python/
    ├── adapter.py
    └── README.md

apps/sample_python/ 的意义不是提供评测逻辑,而是演示:

  • 如果你的应用是本地 Python 函数
  • 它应该暴露什么接口
  • 返回值要长什么样

scenarios/

这是评测配置层,用 YAML 声明:

  • 评测模式
  • 数据集路径
  • judge / embedding 模型
  • 要跑哪些 metrics
  • 输出目录
  • 是否要调用 httppython adapter

datasets/

这里存放评测输入数据。通常分为:

  • raw/:原始输入
  • normalized/:整理后的标准评测样本

outputs/runs/

这里存放每次评测生成的结果资产,比如:

  • scores.csv
  • invalid.csv
  • summary.md
  • metadata.json

4. 主入口链路

统一主链路最终都会走到:

核心入口函数是 run_scenario(),它负责把所有子模块串起来。

简化后的执行顺序是:

run_scenario()
  -> load_scenario()
  -> build_adapter()
  -> build_metric_pipeline()
  -> Evaluator.evaluate()
  -> write_run_artifacts()

你可以把它理解成整套系统的 orchestration 层。


5. Scenario 链路

scenario 是一次评测任务的“总配置”。

相关代码:

它定义的内容包括:

  • mode: offlineonline
  • dataset
  • judge_model
  • embedding_model
  • metrics
  • output_dir
  • runtime
  • app_adapter

作用可以概括为一句话:
scenario 决定“这次评测要怎么跑”。


6. Dataset 链路

数据进入评测引擎后,不会直接拿原始 CSV 去打分,而是要先标准化。

相关代码:

它做三件事:

  1. 读取 CSV / Excel / JSONL
  2. 校验必要字段
  3. 转成统一内部对象 NormalizedSample

统一样本结构定义在:

最关键字段是:

  • question
  • contexts
  • answer
  • ground_truth

这个统一结构是后续 metrics 和 reporting 能共用一条链路的前提。


7. Offline 和 Online 的真正区别

这是整个系统最关键的分叉点。

Offline 模式

离线模式下dataset 里已经有完整评测字段:

  • question
  • contexts
  • answer
  • ground_truth

所以链路是:

load dataset -> normalize -> score metrics -> write artifacts

这个模式不需要调用你的应用。

Online 模式

在线模式下dataset 往往只有:

  • question
  • 一些 metadata

answercontexts 需要评测时实时调用你的 RAG 应用拿回来。

所以链路会变成:

load dataset -> normalize -> call app adapter -> enrich samples -> score metrics -> write artifacts

在线模式比离线模式多出来的核心环节,就是 adapter 调用


8. apps/sample_python/ 到底是干什么的

这个目录是一个 Python adapter 示例

相关文件:

它演示了:如果你的 RAG 应用是本地 Python 代码,那么框架期望你提供一个这样的函数:

def run(question: str, **kwargs) -> dict:
    return {
        "answer": "...",
        "contexts": ["...", "..."],
        "raw_response": {...},
    }

也就是说,apps/sample_python/ 不是评测引擎的一部分,而是“被评测应用”的一个参考接入模板。

它的作用是:

  • 告诉你 Python 类型应用如何接入
  • python adapter 一个最小可运行示例
  • 让你后续把真实 RAG 逻辑替换进去

9. Adapter 链路

adapter 层的目标是:把不同类型的目标应用,统一成同一套输入输出协议。

相关代码:

当前支持两类 adapter

python

适用于本地 Python 应用。
框架会根据 scenario 里的 module:function 动态加载函数,然后调用它。

http

适用于独立 HTTP 服务。
框架会构造请求、解析响应,并映射到统一结构。

无论哪种 adapter最后都要返回统一结果

  • answer
  • contexts
  • raw_response(可选)

这一步很关键,因为 metrics 层不应该关心底层到底是 HTTP 服务还是 Python 函数。


10. Evaluator 链路

评测执行核心在:

Evaluator.evaluate() 大致会做这些事:

  1. 记录开始时间
  2. 加载 dataset
  3. 标准化样本
  4. 如果是 online,先调用 adapter 补齐样本
  5. 调用 metric pipeline 打分
  6. 合并样本字段和评分结果
  7. 返回 EvaluationResult

这里可以把 Evaluator 理解成:

一次评测运行的总执行器


11. Metric Pipeline 链路

相关代码:

这里的职责不是“决定评什么”,而是“把要评的指标真正跑起来”。

具体包括:

  • 初始化 OpenAI client
  • 创建 judge model / embedding model
  • 根据 scenario 装配对应的 ragas metrics
  • 并发执行单样本或批量评分

当前支持的指标包括:

  • faithfulness
  • answer_relevancy
  • context_recall
  • context_precision

所以 metric pipeline 的职责可以总结为:

把标准样本转换成结构化评分结果。


12. Reporting 链路

相关代码:

当评测完成后,结果不会只打印在终端,而是会沉淀成标准资产。

标准输出一般包括:

  • scenario.snapshot.yaml
  • scores.csv
  • invalid.csv
  • summary.md
  • metadata.json

这是整套架构很重要的价值点,因为它让每次 run 都具备:

  • 可复现性
  • 可审计性
  • 可对比性

13. 两条完整链路示意

Offline 完整链路

main.py
  -> run_scenario()
  -> load_scenario()
  -> load_dataset_records()
  -> normalize_records()
  -> build_metric_pipeline()
  -> score_samples()
  -> write_run_artifacts()

特点:

  • 不调用被评测应用
  • 直接对现成样本评分

Online 完整链路

main.py
  -> run_scenario()
  -> load_scenario()
  -> build_adapter()
  -> load_dataset_records()
  -> normalize_records()
  -> adapter.enrich_sample()
  -> build_metric_pipeline()
  -> score_samples()
  -> write_run_artifacts()

特点:

  • 会先调用目标应用
  • 再对实时生成的 answer / contexts 评分

14. 你应该怎么理解这套架构

如果只记一条心智模型,可以记这个:

  • rag_eval/ 负责“怎么评”
  • apps/ 负责“被评的应用怎么接进来”
  • datasets/ 负责“评测输入是什么”
  • scenarios/ 负责“这次评测要怎么配置”
  • reporting/ 负责“结果怎么沉淀”

从工程拆分上看,这个架构的核心价值不是“能跑一次评测”,而是:

  • 可以反复跑
  • 可以换应用跑
  • 可以换数据跑
  • 可以换模型跑
  • 可以把每次实验的资产稳定留住

这也是它和一次性离线脚本的根本区别。