跳到主要内容

Ragas — 架构与原理

30 秒导读: Ragas 是给「RAG / LLM 应用」做评测的工具箱。你给它一批(问题、检索到的资料、模型答案、标准答案),它用一个 LLM 当裁判,把「答得忠不忠于资料」「答得切不切题」这类原本靠人主观打的东西,量化成 0~1 的分数。没有测试集?它还能把你的文档自动造成带标准答案的测试集

1. 这是什么(零基础也能懂)

一句话定义: Ragas 是一个 Python 库,用「LLM 当裁判 + 传统文本指标」给 RAG 和 LLM 应用的输出打分。

它解决谁的什么问题。 假设你做了一个问答机器人:用户问问题 → 系统检索几段资料 → LLM 根据资料生成答案。现在你改了 prompt、换了检索器、调了模型,怎么知道是变好了还是变差了? 人工一条条读太慢、太主观、不可复现。Ragas 把「好不好」拆成几个可计算的维度,每条样本自动出分,于是你能像跑单元测试一样跑评测。

RAG 是什么(术语点破)。 RAG(Retrieval-Augmented Generation,检索增强生成)= 先从知识库检索相关片段,再让 LLM 基于这些片段作答。它的两大失败模式正好对应 Ragas 的核心指标:

失败模式白话对应指标
答案不忠于资料(幻觉)模型编了资料里没有的内容faithfulness(忠实度)
答案跑题答非所问、含糊其辞answer_relevancy(答案相关性)
检索没捞到该捞的关键资料没被检索到context_precision / context_recall

它能做什么(功能):

  • 打分(evaluate): 内置 20+ 指标,覆盖 RAG、Agent(工具调用、目标达成)、文本相似度(BLEU/ROUGE)、自定义规则。
  • 造测试集(testset generation): 喂一堆文档,自动生成「问题 + 标准答案 + 该用哪段资料」的评测数据。
  • 优化指标 prompt(train/align): 用你的人工标注反向调裁判 prompt,让 LLM 裁判更贴近人的判断。
  • 跑实验(@experiment): 把「对一个数据集跑一遍你的应用 + 评测」打包成可复现、可版本化的实验。

用起来什么样。 最小的一次评测(示意,非源码):

# 示意,非源码:演示 Ragas 的基本调用形状
from ragas import evaluate, EvaluationDataset
from ragas.metrics import faithfulness, answer_relevancy

# 一条样本 = 问题 + 检索到的资料 + 模型答案
dataset = EvaluationDataset.from_list([{
"user_input": "谁发明了相对论?",
"retrieved_contexts": ["爱因斯坦提出了相对论。"],
"response": "相对论由爱因斯坦提出。",
}])

result = evaluate(dataset, metrics=[faithfulness, answer_relevancy])
print(result) # {'faithfulness': 1.0, 'answer_relevancy': 0.92}

一句话直觉/类比。 把 Ragas 当成给 AI 答卷的自动阅卷老师:它不只看「答案对不对」,还看「有没有照着给的参考资料答(没瞎编)」「有没有答到点子上」。阅卷标准本身(prompt)也能拿往年人工评分去校准。

2. 顶层全景(它大概怎么转)

Ragas 有两条主线,共享同一套 LLM/Prompt 底座:

┌─────────────────────────────────────────────┐
│ 你的输入 │
│ 文档(docs) 评测样本(dataset) │
└──────┬───────────────────────┬──────────────┘
│ │
主线A:造测试集 │ 主线B:打分 │
▼ ▼
┌────────────────────┐ ┌────────────────────────┐
│ 文档 → 知识图谱 │ │ 每条样本 → 各指标 │
│ (transforms) │ │ metric.single_turn_ │
│ 抽标题/摘要/实体 │ │ ascore(sample) │
│ 连边成图(KG) │ └───────────┬────────────┘
└─────────┬──────────┘ │
▼ ▼
┌────────────────────┐ ┌────────────────────────┐
│ 沿图找「簇」造问题 │ │ Executor 异步并发跑 │
│ 单跳 / 多跳合成器 │ │ 所有(样本×指标)任务 │
└─────────┬──────────┘ └───────────┬────────────┘
▼ ▼
┌──────────────┐ ┌────────────────────┐
│ Testset │ │ EvaluationResult │
│ (问答对+答案) │ │ (每行每指标的分数) │
└──────────────┘ └────────────────────┘
│ │
└─────────┬─────────────────┘

共享底座:llm_factory / PydanticPrompt /
BaseRagasEmbedding / callbacks 追踪

怎么读这张图: 左边是「从文档造测试集」(主线 A),右边是「拿测试集打分」(主线 B);两条线最后都落在同一套 LLM + Prompt + 异步执行的底座上。

部件一句话职责:

部件干什么在哪个文件
evaluate / aevaluate评测入口:校验列、装配 LLM、把(样本×指标)submit 给执行器src/ragas/evaluation.py
Metric 及子类一个指标:输入一条样本,输出一个分数src/ragas/metrics/base.py
Faithfulness 等具体指标实现某个维度的打分逻辑(拆句→判定→聚合)src/ragas/metrics/_faithfulness.py
PydanticPrompt把指令+少样本+JSON Schema 组成 prompt,解析 LLM 的结构化输出src/ragas/prompt/pydantic_prompt.py
Executor异步并发跑一堆协程任务,带进度条、限并发、可取消src/ragas/executor.py
KnowledgeGraph测试集生成的核心数据结构:节点(文档块)+关系(边)src/ragas/testset/graph.py
TestsetGenerator文档→图→问答对的总指挥src/ragas/testset/synthesizers/generate.py
llm_factory / InstructorLLM统一的 LLM 接口,产出经 Pydantic 校验的结构化输出src/ragas/llms/base.py
experiment 装饰器取代 evaluate() 的新范式:对数据集逐行跑你的函数并落盘src/ragas/experiment.py

主线走一遍(打分,高层不进代码):

  1. 你把样本组成 EvaluationDataset,指定 metrics
  2. evaluate() 校验每个指标要的列都在(validate_required_columns),给没设 LLM 的指标装上默认 gpt-4o-mini
  3. 对每条样本 × 每个指标,executor.submit(metric.single_turn_ascore, sample, ...)
  4. Executor 异步并发跑完所有任务,失败的填 np.nan(除非 raise_exceptions=True)。
  5. 结果按提交顺序排回,拼成 EvaluationResult(每行每指标一个分)。

3. 一个关键认知:Ragas 正在「换代」,有两套指标体系

这是读 Ragas 源码最容易踩的坑,先讲清楚再往下钻。仓库里同时存在两套并行的指标 API:

旧体系(经典)新体系(collections)
基类Metric / MetricWithLLM(dataclass + ABC)SimpleBaseMetric / BaseMetric
打分入口single_turn_ascore(sample)ascore(**kwargs) → 返回 MetricResult
LLM 接口兼容 LangChain LLM + Ragas LLM只收现代 InstructorLLM
跑法evaluate(dataset, metrics)@experiment 装饰器 + 自己调 ascore
状态evaluate()/aevaluate() 已挂 DeprecationWarninggoing-forward 的方向

evaluate()aevaluate() 顶部都明确发出弃用警告,推荐改用 @experiment(src/ragas/evaluation.py:447-453105-111)。新指标的基类 BaseMetric._validate_llm直接拒绝InstructorLLM 的裁判模型(src/ragas/metrics/collections/base.py:118-125)。

本文档两套都讲、并标注各自定位,因为线上代码与文档示例仍大量引用旧体系,而新体系是未来。哪一套最终完全胜出,代码里看不出确定结论——以仓库当前状态为准。

4. 阅读地图(按这个顺序往下读)

  • 01-metrics-engine.md — 先读这章。一条样本怎么被打成分:以 faithfulness(拆句→NLI 判定→比例聚合)和 answer_relevancy(反向生成问题→嵌入相似度)为主线;再讲新旧两套指标基类的差别。
  • 02-prompts-and-optimization.md — Ragas 怎么让 LLM 稳定吐结构化 JSON(PydanticPrompt),怎么用嵌入做动态少样本检索,以及怎么拿人工标注反向优化裁判 prompt(train / align)。
  • 03-testset-generation.md — 信号最强的特色功能:文档 → 知识图谱 → 沿图上的「簇」造单跳/多跳问答对。重点看 KnowledgeGraph.find_n_indirect_clusters 这个图采样算法。
  • 04-execution-and-experiments.md — 底座:Executor 异步并发模型、回调追踪树,以及取代 evaluate()@experiment 范式。

5. 代码地图(导航索引)

主题文件关键符号
评测入口src/ragas/evaluation.pyevaluate, aevaluate, RAGAS_EVALUATION_CHAIN_NAME
指标基类(旧)src/ragas/metrics/base.pyMetric, MetricWithLLM, SingleTurnMetric, Ensember
指标基类(新)src/ragas/metrics/base.pySimpleBaseMetric, SimpleLLMMetric
新体系组件校验src/ragas/metrics/collections/base.pyBaseMetric, _validate_llm
忠实度指标src/ragas/metrics/_faithfulness.pyFaithfulness, NLIStatementPrompt, _compute_score
答案相关性src/ragas/metrics/_answer_relevance.pyResponseRelevancy, calculate_similarity
结构化 Promptsrc/ragas/prompt/pydantic_prompt.pyPydanticPrompt, RagasOutputParser, generate_multiple
动态少样本src/ragas/prompt/dynamic_few_shot.pyDynamicFewShotPrompt, SimpleInMemoryExampleStore
异步执行器src/ragas/executor.pyExecutor, wrap_callable_with_index, aresults
知识图谱src/ragas/testset/graph.pyKnowledgeGraph, find_n_indirect_clusters, Node, Relationship
测试集总指挥src/ragas/testset/synthesizers/generate.pyTestsetGenerator, generate, generate_with_langchain_docs
实验范式src/ragas/experiment.pyexperiment, ExperimentWrapper, version_experiment