Files
siemens_ragas/docs/rag-eval-engine-flow.md

463 lines
12 KiB
Markdown
Raw Permalink Normal View History

2026-06-12 14:02:15 +08:00
# RAG 评测引擎链路说明
## 1. 这份文档解决什么问题
`docs/rag-eval-architecture.md` 主要回答“为什么这样分层、模块边界是什么”。
这份文档回答的是另一件事:**一次评测在代码里到底是怎么跑起来的**。
如果你现在对下面这些问题还有点混淆,这份文档就是给你的:
- `rag_eval/` 到底是评测什么的
- `apps/` 在整个架构里扮演什么角色
- `offline``online` 模式的区别是什么
- dataset、adapter、metrics、reporting 是怎么串起来的
---
## 2. 一句话理解整个引擎
这套系统本质上是一条标准化评测流水线:
```text
scenario -> dataset -> normalize -> app adapter -> metrics -> reporting -> run artifacts
```
也可以拆成更容易理解的话:
1. 先读取一份评测场景配置
2. 再读取待评测数据
3. 把原始数据标准化成统一样本结构
4. 如果需要,调用你的 RAG 应用补齐 `answer``contexts`
5.`ragas` 指标计算分数
6. 把结果写到本地 run 目录
---
## 3. 目录职责
### `rag_eval/`
这是**评测引擎本体**。它负责:
- 加载 scenario
- 加载 dataset
- 调用 app adapter
- 执行指标评分
- 写出结果资产
### `apps/`
这是**被评测应用的接入层**,不是评测框架本身。
这里放的是“你的 RAG 应用如何被框架调用”的示例或适配代码。例如:
```text
apps/
└── sample_python/
├── adapter.py
└── README.md
```
`apps/sample_python/` 的意义不是提供评测逻辑,而是演示:
- 如果你的应用是本地 Python 函数
- 它应该暴露什么接口
- 返回值要长什么样
### `scenarios/`
这是评测配置层,用 YAML 声明:
- 评测模式
- 数据集路径
- judge / embedding 模型
- 要跑哪些 metrics
- 输出目录
- 是否要调用 `http``python` adapter
### `datasets/`
这里存放评测输入数据。通常分为:
- `raw/`:原始输入
- `normalized/`:整理后的标准评测样本
### `outputs/` 或 `runs/`
这里存放每次评测生成的结果资产,比如:
- `scores.csv`
- `invalid.csv`
- `summary.md`
- `metadata.json`
---
## 4. 主入口链路
统一主链路最终都会走到:
- [rag_eval/execution/runner.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/execution/runner.py:1)
核心入口函数是 `run_scenario()`,它负责把所有子模块串起来。
简化后的执行顺序是:
```text
run_scenario()
-> load_scenario()
-> build_adapter()
-> build_metric_pipeline()
-> Evaluator.evaluate()
-> write_run_artifacts()
```
你可以把它理解成整套系统的 orchestration 层。
---
## 5. Scenario 链路
scenario 是一次评测任务的“总配置”。
相关代码:
- [rag_eval/config/loader.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/config/loader.py:1)
- [rag_eval/config/schema.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/config/schema.py:1)
- [rag_eval/config/validators.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/config/validators.py:1)
它定义的内容包括:
- `mode`: `offline``online`
- `dataset`
- `judge_model`
- `embedding_model`
- `metrics`
- `output_dir`
- `runtime`
- `app_adapter`
作用可以概括为一句话:
**scenario 决定“这次评测要怎么跑”。**
---
## 6. Dataset 链路
数据进入评测引擎后,不会直接拿原始 CSV 去打分,而是要先标准化。
相关代码:
- [rag_eval/datasets/loader.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/datasets/loader.py:1)
- [rag_eval/datasets/validators.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/datasets/validators.py:1)
- [rag_eval/datasets/normalizers.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/datasets/normalizers.py:1)
它做三件事:
1. 读取 CSV / Excel / JSONL
2. 校验必要字段
3. 转成统一内部对象 `NormalizedSample`
统一样本结构定义在:
- [rag_eval/shared/models.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/shared/models.py:1)
最关键字段是:
- `question`
- `contexts`
- `answer`
- `ground_truth`
这个统一结构是后续 metrics 和 reporting 能共用一条链路的前提。
---
## 7. Offline 和 Online 的真正区别
这是整个系统最关键的分叉点。
### Offline 模式
离线模式下dataset 里已经有完整评测字段:
- `question`
- `contexts`
- `answer`
- `ground_truth`
所以链路是:
```text
load dataset -> normalize -> score metrics -> write artifacts
```
这个模式不需要调用你的应用。
### Online 模式
在线模式下dataset 往往只有:
- `question`
- 一些 metadata
`answer``contexts` 需要评测时实时调用你的 RAG 应用拿回来。
所以链路会变成:
```text
load dataset -> normalize -> call app adapter -> enrich samples -> score metrics -> write artifacts
```
在线模式比离线模式多出来的核心环节,就是 **adapter 调用**
---
## 8. `apps/sample_python/` 到底是干什么的
这个目录是一个 **Python adapter 示例**
相关文件:
- [apps/sample_python/adapter.py](/C:/Users/A200477427/Learnings/ragas-template/apps/sample_python/adapter.py:1)
- [apps/sample_python/README.md](/C:/Users/A200477427/Learnings/ragas-template/apps/sample_python/README.md:1)
它演示了:如果你的 RAG 应用是本地 Python 代码,那么框架期望你提供一个这样的函数:
```python
def run(question: str, **kwargs) -> dict:
return {
"answer": "...",
"contexts": ["...", "..."],
"raw_response": {...},
}
```
也就是说,`apps/sample_python/` 不是评测引擎的一部分,而是“被评测应用”的一个参考接入模板。
它的作用是:
- 告诉你 Python 类型应用如何接入
-`python` adapter 一个最小可运行示例
- 让你后续把真实 RAG 逻辑替换进去
---
## 9. Adapter 链路
adapter 层的目标是:**把不同类型的目标应用,统一成同一套输入输出协议。**
相关代码:
- [rag_eval/adapters/base.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/adapters/base.py:1)
- [rag_eval/adapters/http.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/adapters/http.py:1)
- [rag_eval/adapters/python.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/adapters/python.py:1)
当前支持两类 adapter
### `python`
适用于本地 Python 应用。
框架会根据 scenario 里的 `module:function` 动态加载函数,然后调用它。
### `http`
适用于独立 HTTP 服务。
框架会构造请求、解析响应,并映射到统一结构。
无论哪种 adapter最后都要返回统一结果
- `answer`
- `contexts`
- `raw_response`(可选)
这一步很关键,因为 metrics 层不应该关心底层到底是 HTTP 服务还是 Python 函数。
---
## 10. Evaluator 链路
评测执行核心在:
- [rag_eval/execution/evaluator.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/execution/evaluator.py:1)
`Evaluator.evaluate()` 大致会做这些事:
1. 记录开始时间
2. 加载 dataset
3. 标准化样本
4. 如果是 `online`,先调用 adapter 补齐样本
5. 调用 metric pipeline 打分
6. 合并样本字段和评分结果
7. 返回 `EvaluationResult`
这里可以把 `Evaluator` 理解成:
**一次评测运行的总执行器**
---
## 11. Metric Pipeline 链路
相关代码:
- [rag_eval/metrics/factory.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/metrics/factory.py:1)
- [rag_eval/metrics/pipeline.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/metrics/pipeline.py:1)
- [rag_eval/metrics/registry.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/metrics/registry.py:1)
这里的职责不是“决定评什么”,而是“把要评的指标真正跑起来”。
具体包括:
- 初始化 OpenAI client
- 创建 judge model / embedding model
- 根据 scenario 装配对应的 ragas metrics
- 并发执行单样本或批量评分
当前支持的指标包括:
核心检索 / 生成指标(始终可用):
2026-06-12 14:02:15 +08:00
- `faithfulness`
- `answer_relevancy`
- `context_recall`
- `context_precision`
鲁棒性 / 端到端指标(架构设计 §10.2,需数据集含 `ground_truth`
- `noise_sensitivity` —— 鲁棒性:对检索噪声的敏感度
- `factual_correctness` —— 端到端:回答相对标准答案的事实正确性
- `semantic_similarity` —— 端到端:回答与标准答案的语义相似度(基于 embedding无 LLM 调用)
所有指标都通过同一套装配点接入:`registry.py`(校验白名单)、`factory.py`(实例化)、`pipeline.py``ascore` 入参分发),新增指标只需在这三处对齐即可。
2026-06-12 14:02:15 +08:00
所以 metric pipeline 的职责可以总结为:
**把标准样本转换成结构化评分结果。**
---
## 12. Reporting 链路
相关代码:
- [rag_eval/reporting/artifacts.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/reporting/artifacts.py:1)
- [rag_eval/reporting/summary.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/reporting/summary.py:1)
- [rag_eval/reporting/writers.py](/C:/Users/A200477427/Learnings/ragas-template/rag_eval/reporting/writers.py:1)
当评测完成后,结果不会只打印在终端,而是会沉淀成标准资产。
标准输出一般包括:
- `scenario.snapshot.yaml`
- `scores.csv`
- `invalid.csv`
- `summary.md`
- `metadata.json`
这是整套架构很重要的价值点,因为它让每次 run 都具备:
- 可复现性
- 可审计性
- 可对比性
---
## 13. 两条完整链路示意
### Offline 完整链路
```text
main.py
-> run_scenario()
-> load_scenario()
-> load_dataset_records()
-> normalize_records()
-> build_metric_pipeline()
-> score_samples()
-> write_run_artifacts()
```
特点:
- 不调用被评测应用
- 直接对现成样本评分
### Online 完整链路
```text
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/` 负责“结果怎么沉淀”
从工程拆分上看,这个架构的核心价值不是“能跑一次评测”,而是:
- 可以反复跑
- 可以换应用跑
- 可以换数据跑
- 可以换模型跑
- 可以把每次实验的资产稳定留住
这也是它和一次性离线脚本的根本区别。
---
## 15. Optimization Advisor 链路
相关代码:
- `rag_eval/advisor/__init__.py` — 外部入口 `run_advisor()`
- `rag_eval/advisor/rules.py` — 规则引擎(纯函数,无 LLM7 条指标诊断规则
- `rag_eval/advisor/llm_analyzer.py` — LLM 分析器(复用 judge_model llm 实例,失败自动降级)
- `rag_eval/advisor/writer.py` — 写出 `optimization_advice.md` + 日志摘要
Advisor 在 `write_run_artifacts()` 之后触发,仅当场景配置 `optimization_advisor: true` 时生效,默认关闭。
执行链路:
```text
run_advisor(result, scenario, llm)
-> rules.diagnose(score_rows, metrics) # 识别异常指标,选取 top-3 低分样本
-> llm_analyzer.analyze(diagnoses, llm) # LLM 生成中文建议(失败自动降级为纯规则报告)
-> writer.write_advice(...) # 写 optimization_advice.md + 日志摘要
```
输出产物追加在现有 run 目录:
```text
outputs/online/siemens-pdf-question-bank/<run_id>/
scenario.snapshot.yaml
scores.csv
invalid.csv
summary.md
metadata.json
optimization_advice.md <- 新增optimization_advisor: true 时生成
```
规则引擎对 7 个指标各自设 warning / critical 双档阈值,`noise_sensitivity` 为"越低越好"(方向相反)。所有诊断均附带 top-3 低分样本,喂给 LLM 生成针对具体内容的中文建议。