- rag_eval/advisor/: new package with rules engine, LLM analyzer, writer - rules.py: 7-metric diagnostic rules (warning/critical thresholds, top-3 low samples) - llm_analyzer.py: Chinese optimization report via judge_model, graceful fallback - writer.py: writes optimization_advice.md + log summary - __init__.py: run_advisor() entry point (no-op when optimization_advisor=False) - Scenario.optimization_advisor: new bool field (default False) - ScenarioModel: same field added, loader.py透传 - RunArtifactPaths.advice_md: new path field - factory.py: build_models() now public; build_metric_pipeline() accepts pre-built llm/embeddings - runner.py: lifts llm, passes to pipeline and advisor; calls run_advisor() at end - siemens online YAML: optimization_advisor: true enabled - tests: 9 rules tests + 6 writer tests, all pass - docs: advisor section added to engine-flow.md and architecture.md Co-Authored-By: Claude <noreply@anthropic.com>
12 KiB
RAG 评测引擎链路说明
1. 这份文档解决什么问题
docs/rag-eval-architecture.md 主要回答“为什么这样分层、模块边界是什么”。
这份文档回答的是另一件事:一次评测在代码里到底是怎么跑起来的。
如果你现在对下面这些问题还有点混淆,这份文档就是给你的:
rag_eval/到底是评测什么的apps/在整个架构里扮演什么角色offline和online模式的区别是什么- dataset、adapter、metrics、reporting 是怎么串起来的
2. 一句话理解整个引擎
这套系统本质上是一条标准化评测流水线:
scenario -> dataset -> normalize -> app adapter -> metrics -> reporting -> run artifacts
也可以拆成更容易理解的话:
- 先读取一份评测场景配置
- 再读取待评测数据
- 把原始数据标准化成统一样本结构
- 如果需要,调用你的 RAG 应用补齐
answer和contexts - 用
ragas指标计算分数 - 把结果写到本地 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
- 输出目录
- 是否要调用
http或pythonadapter
datasets/
这里存放评测输入数据。通常分为:
raw/:原始输入normalized/:整理后的标准评测样本
outputs/ 或 runs/
这里存放每次评测生成的结果资产,比如:
scores.csvinvalid.csvsummary.mdmetadata.json
4. 主入口链路
统一主链路最终都会走到:
核心入口函数是 run_scenario(),它负责把所有子模块串起来。
简化后的执行顺序是:
run_scenario()
-> load_scenario()
-> build_adapter()
-> build_metric_pipeline()
-> Evaluator.evaluate()
-> write_run_artifacts()
你可以把它理解成整套系统的 orchestration 层。
5. Scenario 链路
scenario 是一次评测任务的“总配置”。
相关代码:
它定义的内容包括:
mode:offline或onlinedatasetjudge_modelembedding_modelmetricsoutput_dirruntimeapp_adapter
作用可以概括为一句话:
scenario 决定“这次评测要怎么跑”。
6. Dataset 链路
数据进入评测引擎后,不会直接拿原始 CSV 去打分,而是要先标准化。
相关代码:
它做三件事:
- 读取 CSV / Excel / JSONL
- 校验必要字段
- 转成统一内部对象
NormalizedSample
统一样本结构定义在:
最关键字段是:
questioncontextsanswerground_truth
这个统一结构是后续 metrics 和 reporting 能共用一条链路的前提。
7. Offline 和 Online 的真正区别
这是整个系统最关键的分叉点。
Offline 模式
离线模式下,dataset 里已经有完整评测字段:
questioncontextsanswerground_truth
所以链路是:
load dataset -> normalize -> score metrics -> write artifacts
这个模式不需要调用你的应用。
Online 模式
在线模式下,dataset 往往只有:
question- 一些 metadata
answer 和 contexts 需要评测时实时调用你的 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 类型应用如何接入
- 给
pythonadapter 一个最小可运行示例 - 让你后续把真实 RAG 逻辑替换进去
9. Adapter 链路
adapter 层的目标是:把不同类型的目标应用,统一成同一套输入输出协议。
相关代码:
当前支持两类 adapter:
python
适用于本地 Python 应用。
框架会根据 scenario 里的 module:function 动态加载函数,然后调用它。
http
适用于独立 HTTP 服务。
框架会构造请求、解析响应,并映射到统一结构。
无论哪种 adapter,最后都要返回统一结果:
answercontextsraw_response(可选)
这一步很关键,因为 metrics 层不应该关心底层到底是 HTTP 服务还是 Python 函数。
10. Evaluator 链路
评测执行核心在:
Evaluator.evaluate() 大致会做这些事:
- 记录开始时间
- 加载 dataset
- 标准化样本
- 如果是
online,先调用 adapter 补齐样本 - 调用 metric pipeline 打分
- 合并样本字段和评分结果
- 返回
EvaluationResult
这里可以把 Evaluator 理解成:
一次评测运行的总执行器
11. Metric Pipeline 链路
相关代码:
这里的职责不是“决定评什么”,而是“把要评的指标真正跑起来”。
具体包括:
- 初始化 OpenAI client
- 创建 judge model / embedding model
- 根据 scenario 装配对应的 ragas metrics
- 并发执行单样本或批量评分
当前支持的指标包括:
核心检索 / 生成指标(始终可用):
faithfulnessanswer_relevancycontext_recallcontext_precision
鲁棒性 / 端到端指标(架构设计 §10.2,需数据集含 ground_truth):
noise_sensitivity—— 鲁棒性:对检索噪声的敏感度factual_correctness—— 端到端:回答相对标准答案的事实正确性semantic_similarity—— 端到端:回答与标准答案的语义相似度(基于 embedding,无 LLM 调用)
所有指标都通过同一套装配点接入:registry.py(校验白名单)、factory.py(实例化)、pipeline.py(ascore 入参分发),新增指标只需在这三处对齐即可。
所以 metric pipeline 的职责可以总结为:
把标准样本转换成结构化评分结果。
12. Reporting 链路
相关代码:
当评测完成后,结果不会只打印在终端,而是会沉淀成标准资产。
标准输出一般包括:
scenario.snapshot.yamlscores.csvinvalid.csvsummary.mdmetadata.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/负责“结果怎么沉淀”
从工程拆分上看,这个架构的核心价值不是“能跑一次评测”,而是:
- 可以反复跑
- 可以换应用跑
- 可以换数据跑
- 可以换模型跑
- 可以把每次实验的资产稳定留住
这也是它和一次性离线脚本的根本区别。
15. Optimization Advisor 链路
相关代码:
rag_eval/advisor/__init__.py— 外部入口run_advisor()rag_eval/advisor/rules.py— 规则引擎(纯函数,无 LLM),7 条指标诊断规则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 时生效,默认关闭。
执行链路:
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 目录:
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 生成针对具体内容的中文建议。