RAG评测框架

为了系统化地评测RAG系统,业界出现了一些非常实用的开源自动化评测框架,这些框架通常会从以下几个维度进行评估:

  • 召回质量 (Retrieval Quality): RAG系统是否检索到了正确且相关的文档片段?
  • 答案忠实度 (Faithfulness): 生成的答案是否完全基于检索到的上下文,没有“胡编乱造”(幻觉)?
  • 答案相关性 (Answer Relevance): 生成的答案是否准确地回答了用户的问题?
  • 上下文利用率/效率 (Context Utilization/Efficiency): 大模型是否有效地利用了所有提供给它的上下文信息?(这与我们之前提到的“Lost in the Middle”和“知识浓度”密切相关)

这里介绍几个当前比较流行且功能强大的RAG评测框架:

Ragas

这是领域里非常出名的一个框架,它的核心思想是“让大模型来帮助你评估RAG系统”。在评测时,Ragas 会调用一个大模型作为评测专家来阅读你的问题、RAG检索到的上下文和生成的答案,然后根据预设的指标给出分数。Ragas的评估指标高度契合RAG系统的痛点,主要包括:

  • 整体回答质量的评估:
    • Answer Correctness,用于评估 RAG 应用生成答案的准确度。
  • 生成环节的评估:
    • Answer Relevancy,用于评估 RAG 应用生成的答案是否与问题相关。
    • Faithfulness,用于评估 RAG 应用生成的答案和检索到的参考资料的事实一致性。
  • 召回阶段的评估:
    • Context Precision,用于评估 contexts 中与准确答案相关的条目是否排名靠前、占比高(信噪比)。
    • Context Recall,用于评估有多少相关参考资料被检索到,越高的得分意味着更少的相关参考资料被遗漏。

该框架提供了Python库,只需几行代码就能集成到你的RAG工作流中,也是本章后续介绍的重点。

TruLens

这个框架专注于评估的可观测性,它不仅仅告诉你RAG哪里可能有问题,它还能帮你追溯RAG的整个运行过程。包括每次运行的输入、输出、中间步骤、调用的大模型、检索召回的上下文等等,并提供一系列“反馈函数”来自动化评估这些运行。 TruLens 框架可以与LangChain、LlamaIndex等框架无缝集成,并提供了一套可视化工具,展示每次RAG调用的详细过程。同时,TruLens 提供了细粒度的反馈函数,从多个角度评估RAG性能,帮助你快速定位问题。其主要评估指标包括:

  • Groundedness:生成的答案是否是来自于检索召回的知识
  • Answer Relevance:生成的答案是否与问题相关
  • Context Relevance:评估召回的知识是否跟问题相关。

你也可以访问 TruLens官网了解其他评估指标如(User sentiment、Fairness and bias)等等。

DeepEval

DeepEval 则将传统软件开发的测试理念引入到RAG应用中。它鼓励你采用单元测试和测试驱动开发(TDD)的思想,在RAG功能开发前就编写评估测试,确保应用性能从一开始就符合预期。 为此,DeepEval提供了一个专门的测试框架,让你能够像编写传统软件的单元测试一样,为RAG系统创建LLM评估测试。它支持为每个测试用例设置明确的通过/失败(Pass/Fail)阈值,这使得DeepEval能轻松集成到你的持续集成/持续部署(CI/CD)流程中,从而实现自动化回归测试。 DeepEval 的主要评测指标类似Ragas,也支持Faithfulness, Answer Relevance, Context Relevance, Context Recall等。

你可以访问DeepEval官网了解更多内容。

自定义评测框架

除了前面介绍的Ragas、TruLens、DeepEval等专业评测框架,你可能也接触过其他的开源评测工具,比如LlamaIndex和LangChain这些主流RAG开发框架本身也有内置评估工具。这些评估工具能让你在构建RAG流程的同时,方便地进行性能评估,实现无缝衔接。

但是,在某些特定场景下,你可能需要更灵活、更贴合业务的评估方式,这时你也可以选择自定义评测框架。

对于评测一个智能客服系统而言,你不仅仅想知道RAG有没有“瞎说”(Faithfulness)或者答案是否“相关”(Relevance),你更想知道它是否符合你业务的特定规则,或者提供的答案是否真正解决了用户的痛点。

  • 案例一:当用户询问“报销的流程是什么?”,你们的业务专家可能会要求“好的报销答案,必须明确包含报销单链接和二级主管审批信息。”或者“好的答案,必须引导用户到费用系统提交报销申请。”,这样才能满足“流程合规”的要求。
  • 案例二:当用户询问“订单延迟了怎么办?”,更好的回答可能是先要“安抚用户的情绪,再给出物流状态,预期送达时间、延误原因(如果已知)、以及后续处理(如退款/投诉)的指引。”而不仅仅是回答“您的订单正在派送中,请耐心等待”。

因此,你可以把“流程可操作性”、“政策合规性”、“情绪安抚度”、“问题解决完备性”等指标,加入你的自定义评测框架。

请注意:领域专家的深度参与是评测系统乃至AI应用成功的关键。使用自动化评测框架并非要让机器彻底取代人工判断,而是旨在为评测提效。前面介绍的许多自动化框架(如Ragas)会利用大模型来充当“评委”,对RAG表现进行初步判断。然而,只有领域专家才能提供那些最宝贵的、真正反映业务需求的高价值“正确答案”(Ground Truth),并对用户提问和RAG回答的正确性进行权威性的审定。

因此,我们必须让领域专家深度参与到评测集的构建和系统性评估中。自动化评测的真正价值,在于它能将专家提供的这些宝贵Ground Truth或评估标准,转化为大规模、可重复的日常评测任务,从而解放专家的时间,让他们聚焦于更具挑战性的问题分析和优化策略制定,而非陷入重复性的判断劳动中。

  1. 1. 使用 Ragas 来评估应用表现

你可以使用Ragas来做全链路评测,这只需要在你的Python项目中加入几行代码。

评估 RAG 应用回答质量

在评估 RAG 应用整体回答质量时,使用 Ragas 的 Answer Correctness 是一个很好的指标。为了计算这个指标,你需要准备以下两种数据来评测 RAG 应用产生的 answer 质量:

  1. 1. question(输入给 RAG 应用的问题)

  2. 2. ground_truth(你预先知道的正确的答案)

为了便于展示不同回答的评测指标差异,我们针对问题「张伟是哪个部门的」准备了三组 RAG 应用回答:

计算Answer Correctness

我们就可以运行下面的代码,来计算回答准确度(即 Answer Correctness)的得分。


  1. from langchain_community.llms.tongyi import Tongyi

  2. from langchain_community.embeddings import DashScopeEmbeddings

  3. from datasets import Dataset

  4. from ragas import evaluate

  5. from ragas.metrics import answer_correctness

  6. data_samples = {'question': ['张伟是哪个部门的?',

  7.                              '张伟是哪个部门的?',

  8.                              '张伟是哪个部门的?'],

  9.                 'answer': ['根据提供的信息,没有提到张伟所在的部门。如果您能提供更多关于张伟的信息,我可能能够帮助您找到答案。',

  10.                            '张伟是人事部门的',

  11.                            '张伟是教研部的'],

  12.                 'ground_truth':['张伟是教研部的成员',

  13.                                 '张伟是教研部的成员',

  14.                                 '张伟是教研部的成员']}

  15. dataset = Dataset.from_dict(data_samples)

  16. score = evaluate(dataset = dataset,

  17.                  metrics=[answer_correctness],

  18.                  llm=Tongyi(model_name="qwen-plus-0919"),

  19.                  embeddings=DashScopeEmbeddings(model="text-embedding-v3"))

  20. score.to_pandas()

可以看到,Ragas 的 Answer Correctness 指标准确的反映出了三种回答的表现,越符合事实的answer得分越高。

了解 answer correctness 的计算过程

从直观感受上 Answer correctness 的打分确实与你的预期相符。它在打分过程使用到了大模型(代码中的llm=Tongyi(model_name="qwen-plus"))与 embedding 模型(代码中的embeddings=DashScopeEmbeddings(model="text-embedding-v3")),由 answer 和 ground_truth 的语义相似度和事实准确度计算得出。

  • 语义相似度

语义相似度是通过 embedding 模型得到 answer 和 ground_truth 的文本向量,然后计算两个文本向量的相似度。向量相似度的计算有许多种方法,如余弦相似度、欧氏距离、曼哈顿距离等, Ragas 使用了最常用的余弦相似度。

  • 事实准确度

事实准确度是衡量 answer 与 ground_truth 在事实描述上差异的指标。比如以下两个描述:

  • answer:张伟是教研部负责大模型课程的同事。
  • ground_truth:张伟是教研部负责大数据方向的同事。

answer 和 ground_truth 在事实描述上存在差异(工作方向),但也存在一致的地方(工作部门)。这样的差异很难通过大模型或 embedding 模型的简单调用来量化。Ragas 通过大模型将 answer 与 ground_truth 分别生成各自的观点列表,并对观点列表中的元素进行比较与计算。

下图可以帮助你理解 Ragas 衡量事实准确度的方法:

  1. 1. 通过大模型将answer、ground_truth分别生成各自的观点列表。比如:

    • 生成 answer 的观点列表: 张伟是教研部负责大模型课程的同事。 ---> ["张伟是教研部的", "张伟负责大模型课程"]
    • 生成 ground_truth 的观点列表:张伟是教研部负责大数据方向的同事。---> ["张伟是教研部的", "张伟负责大数据方向"]
  2. 2. 遍历answer与ground_truth列表,并初始化三个列表,TP、FP与FN。

    • 如果该观点在 answer 的观点列表中找不到依据,则将该陈述添加到FN列表中。比如:「张伟负责大数据方向」。
    • 如果该观点与ground_truth的观点相匹配,则将该观点添加到TP列表中。比如:「张伟是教研部的」。
    • 如果该观点在 ground_truth 的观点列表中找不到依据,则将该观点添加到FP列表中。比如:「张伟负责大模型课程」。
    • 对于由answer生成的观点:
    • 对于ground_truth生成的观点:
  1. 该步骤的判断过程均由大模型提供。
  1. 4. 统计TP、FP与FN列表的元素个数,并按照以下方式计算f1 score分数:

f1 score = tp / (tp + 0.5 * (fp + fn)) if tp > 0 else 0

以上文为例:f1 score = 1/(1+0.5*(1+1)) = 0.5。

得到语义相似度和事实准确度的分数后,对两者加权求和,即可得到最终的 Answer Correctness 的分数。

Answer Correctness 得分 = 0.25 * 语义相似度得分 + 0.75 * 事实准确度得分

评估检索召回效果

Ragas 中的 context precision 和 context recall 指标可以用于评估 RAG 应用中的检索的召回效果。

  • Context precision 会评估检索召回的参考信息(contexts)中与准确答案相关的条目是否排名靠前、占比高(信噪比),侧重相关性。
  • Context recall 则会评估 contexts 与 ground_truth 的事实一致性程度,侧重事实准确度。

实际应用时,可以将两者结合使用。

为了计算这些指标,你需要准备的数据集应该包括以下信息:

  • question,输入给 RAG 应用的问题。
  • contexts,检索召回的参考信息。
  • ground_truth,你预先知道的正确的答案。

计算 context precision 和 context recall

继续使用「张伟是哪个部门」这个问题,准备三组数据,运行下面的代码,来同时计算 context precision 和 context recall 的得分。

  1. from langchain_community.llms.tongyi import Tongyi

  2. from datasets import Dataset

  3. from ragas import evaluate

  4. from ragas.metrics import context_recall,context_precision

  5. data_samples = {

  6.     'question': [

  7.         '张伟是哪个部门的?',

  8.         '张伟是哪个部门的?',

  9.         '张伟是哪个部门的?'

  10.     ],

  11.     'answer': [

  12.         '根据提供的信息,没有提到张伟所在的部门。如果您能提供更多关于张伟的信息,我可能能够帮助您找到答案。',

  13.         '张伟是人事部门的',

  14.         '张伟是教研部的'

  15.     ],

  16.     'ground_truth':[

  17.         '张伟是教研部的成员',

  18.         '张伟是教研部的成员',

  19.         '张伟是教研部的成员'

  20.     ],

  21.     'contexts' : [

  22.         ['提供⾏政管理与协调⽀持,优化⾏政⼯作流程。 ', '绩效管理部 韩杉 李⻜ I902 041 ⼈⼒资源'],

  23.         ['李凯 教研部主任 ', '牛顿发现了万有引力'],

  24.         ['牛顿发现了万有引力', '张伟 教研部工程师,他最近在负责课程研发'],

  25.     ],

  26. }

  27. dataset = Dataset.from_dict(data_samples)

  28. score = evaluate(

  29.     dataset = dataset,

  30.     metrics=[context_recall, context_precision],

  31.     llm=Tongyi(model_name="qwen-plus-0919"))

  32. score.to_pandas()

由上面的数据可以看到:

  • 最后一行数据的回答是准确的
  • 过程中检索到的参考资料(contexts)中也包含了正确答案的观点,即「张伟是教研部的」。这一情况体现在了 context recall 得分为 1。
  • 但是 contexts 中并不是每一条都是和问题及答案相关的,比如「牛顿发现了万有引力」。这一情况体现在了 context precision 得分为 0.5。

了解 context recall 和 context precision 的计算过程

  • Context recall

你已经从上文了解到 context recall 是衡量 contexts 与 ground_truth 是否一致的指标。

在Ragas 中,context recall 用来描述 ground_truth 中有多少比例的观点可以得到 contexts 的支持,计算过程如下:

  1. 1. 由大模型将 ground_truth 分解成 n 个观点(statements)。

  2. 2. 比如,可以由ground_truth「张伟是教研部的成员」生成观点列表 [张伟是教研部的"]。

  3. 3. 由大模型判断每个观点能在检索到的参考资料(contexts)中找到依据,或者说 context 是否能支撑 ground_truth 的观点。

  4. 4. 比如,这个观点在第三行数据的 contexts 中能找到依据「张伟 教研部工程师,他最近在负责课程研发」。

  5. 5. 然后 ground_truth 观点列表中,能在 contexts 中找到依据的观点占比,作为 context_recall 分数。

  6. 6. 这里的得分为 1 = 1/1。

  • Context precision

在Ragas 中,context precision 不仅衡量了 contexts 中有多少比例的 context 与 ground_truth 相关,还衡量了 contexts 中 context 的排名情况。计算过程比较复杂:

  1. 1. 按顺序读取 contexts 中的 context(i) ,根据 question 与 ground_truth,判断 context(i) 是否相关。相关为 1 分,否则为 0 分。

  2. 2. 比如上面第三行数据中,context(1)(牛顿发现了万有引力) 是不相关的,context(2) 相关。

  3. 3. 对于每一个 context,以该 context 及之前 context 的分数之和作为分子,context 所处排位作为分母,计算 precision 分。

  4. 4. 对于上面第三行数据,context(1) precision 分为 0/1 = 0,context(2) precision 分为 1/2 = 0.5。

  5. 5. 对每一个 context 的 precision 分求和,除以相关的 context 个数,得到 context_precision。

  6. 6. 对于上面第三行数据,context_precision = (0 + 0.5) / 1 = 0.5。

如果你暂时无法理解上面的计算过程也没有关系,你只需知道该指标衡量了 contexts 中 context 的排名情况。如果你感兴趣,我们鼓励你去阅读 Ragas 的源码。

Ragas 还提供了很多其他的指标,这里就不一一介绍,你可以访问 Ragas 的文档来查看更多指标的适用场景和工作原理。

Ragas 支持的指标可以访问:https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/

如何根据 Ragas 指标进行优化

做评测的最终目的不是为了拿到分数,而是根据这些分数确定优化的方向。你已经学习到了answer correctness、context recall、context precision三个指标的概念与计算方法,当你观察到某几个指标的分数较低时,应该制定相应的优化措施。

上下文是 RAG 的生命线

当用户提出一个问题时,大模型通过阅读理解你提供的 上下文(Context) 来给出回答。上下文决定了大模型能否给出准确、完整的答案。如果上下文缺失重要知识点,或存在错误、无关的内容,大模型就无法给出正确的结论。正如你在前面看到的问题一样:如果上下文(Context)里缺少了“张伟部门”的内容,大模型自然无法给出正确答案。

于是,为了不丢失有效知识,有人提出把全部可用资料“一股脑全部灌给大模型”,让大模型来做甄别,结果产生了一个更复杂的问题:即使某个关键线索确实存在于你提供的大量资料中,但如果它被埋藏在海量的无关信息里,大模型也很可能会“视而不见”,这便是 RAG 系统中常说的“Lost in the Middle”现象。试想,关于“张伟部门”的有效信息,可能只是一句简单的“张伟,技术部,工号XXXX”,如果这句话被夹杂在几百页的员工考勤记录、会议纪要甚至公司食堂菜单里,大模型很可能就会在这些冗余信息中迷失,导致最终无法给出正确的答案。它的“注意力”被分散了,关键信息被“淹没”了。

所以,RAG 精度的瓶颈,往往不在于大模型本身是否足够“聪明”,而在于你提供给它的上下文(Context)的“知识浓度”。一个高质量的上下文,理应具有较高的知识浓度,意味着其中的相关信息密度高、噪音少、与问题直接关联。能让大模型准确地专注问题核心,得出正确结论。因此,你提供的上下文质量,直接决定了 RAG 系统的上限。

在 Ragas 中 Context Recall 和 Context Precision 就是来衡量召回的上下文的有效性的。你可以通过分析这两个指标来确认你的RAG系统召回上下文的质量有没有提升。

优化context recall

context recall指标评测的是RAG应用在检索阶段的表现。如果该指标得分较低,你可以尝试从以下方面进行优化:

  • 扩充知识库

知识库是RAG应用的源头,如果知识库的内容不够完备,则会导致召回的参考信息不充分,从而影响context recall。你可以对比知识库的内容与测试样本,观察知识库的内容是否可以支持每一条测试样本(这个过程你也可以借助大模型来完成)。如果你发现某些测试样本缺少相关知识,则需要对知识库进行补充。

  • 更换embedding模型

如果你的知识库内容已经很完备,则可以考虑更换embedding模型。好的embedding模型可以理解文本的深层次语义,如果两句话深层次相关,那么即使“看上去”不相关,也可以获得较高的相似度分数。比如提问是“负责课程研发的是谁?”,知识库对应文本段是“张伟是教研部的成员”,尽管重合的词汇较少,但优秀的embedding模型仍然可以为这两句话打出较高的相似度分数,从而将“张伟是教研部的成员”这一文本段召回。

  • query改写

作为开发者,对用户的提问方式做过多要求是不现实的,因此你可能会得到这样缺少信息的问题:“教研部”、“请假”、“项目管理”。如果直接将这样的问题输入RAG应用中,大概率无法召回有效的文本段。你可以通过对员工常见问题的梳理来设计一个prompt模板,使用大模型来改写query,提升召回的准确率。

context precision

与context recall一样,context precision指标评测的也是RAG应用在检索阶段的表现,但是更注重相关的文本段是否具有靠前的排名。如果该指标得分较低,你可以尝试context recall中的优化措施,并且可以尝试在检索阶段加入rerank(重排序),来提升相关文本段的排名。

answer correctness

answer correctness指标评测的是RAG系统整体的综合指标。如果该指标得分较低,而前两项分数较高,说明RAG系统在检索阶段表现良好,但是生成阶段出了问题。

你可以尝试前边教程学到的方法,如优化prompt、调整大模型生成的超参数(如temperature)等,你也可以更换性能更加强劲的大模型,甚至对大模型进行微调(后边的教程会介绍)等方法来提升生成答案的准确度。

扩展: 替换Ragas 的提示词模板为中文

Ragas 的许多评测指标是基于大模型来实现的。与 LlamaIndex 一样,Ragas 的默认提示词模板是英文的,同时允许自定义修改。你可以将 Ragas 各指标的默认提示词翻译成中文,使得评测的结果更符合中文问答场景。

我们在ragas_prompt文件夹中提供了中文的提示词模板chinese_prompt.py,你可以参考以下代码将中文提示词适配到 Ragas 的不同指标中。

Ragas 会在提示词中向大模型提供一些示例,来帮助大模型理解应该如何进行判断、生成观点列表等操作,因此你也可以更改示例来适配到你的业务场景。


  1. # 导入中文提示词模板

  2. from ragas_prompt.chinese_prompt import ContextRecall,ContextPrecision,AnswerCorrectness

  3. # 进行各指标的自定义 prompt 设置

  4. context_recall.context_recall_prompt.instruction = ContextRecall.context_recall_prompt["instruction"]

  5. context_recall.context_recall_prompt.output_format_instruction = ContextRecall.context_recall_prompt["output_format_instruction"]

  6. context_recall.context_recall_prompt.examples = ContextRecall.context_recall_prompt["examples"]

  7. context_precision.context_precision_prompt.instruction = ContextPrecision.context_precision_prompt["instruction"]

  8. context_precision.context_precision_prompt.output_format_instruction = ContextPrecision.context_precision_prompt["output_format_instruction"]

  9. context_precision.context_precision_prompt.examples = ContextPrecision.context_precision_prompt["examples"]

  10. answer_correctness.correctness_prompt.instruction = AnswerCorrectness.correctness_prompt["instruction"]

  11. answer_correctness.correctness_prompt.output_format_instruction = AnswerCorrectness.correctness_prompt["output_format_instruction"]

  12. answer_correctness.correctness_prompt.examples = AnswerCorrectness.correctness_prompt["examples"]

  13. data_samples = {

  14.     'question': [

  15.         '张伟是哪个部门的?',

  16.         '张伟是哪个部门的?',

  17.         '张伟是哪个部门的?'

  18.     ],

  19.     'answer': [

  20.         '根据提供的信息,没有提到张伟所在的部门。如果您能提供更多关于张伟的信息,我可能能够帮助您找到答案。',

  21.         '张伟是人事部门的',

  22.         '张伟是教研部的'

  23.     ],

  24.     'ground_truth':[

  25.         '张伟是教研部的成员',

  26.         '张伟是教研部的成员',

  27.         '张伟是教研部的成员'

  28.     ],

  29.     'contexts' : [

  30.         ['提供⾏政管理与协调⽀持,优化⾏政⼯作流程。 ', '绩效管理部 韩杉 李⻜ I902 041 ⼈⼒资源'],

  31.         ['李凯 教研部主任 ', '牛顿发现了万有引力'],

  32.         ['牛顿发现了万有引力', '张伟 教研部工程师,他最近在负责课程研发'],

  33.     ],

  34. }

  35. dataset = Dataset.from_dict(data_samples)

  36. score = evaluate(

  37.     dataset = dataset,

  38.     metrics=[answer_correctness,context_recall,context_precision],

  39.     llm=Tongyi(model_name="qwen-plus-0919"),

  40.     embeddings=DashScopeEmbeddings(model="text-embedding-v3"))

  41. score.to_pandas()

用中文提示词之后,再次评测RAG应用的结果是:

附:中文提示词模板:

  1. class AnswerRelavency:

  2.     question_generation_prompt = {

  3.         "instruction": "生成一个与给定答案相关的问题,并识别该答案是否模棱两可。如果答案模棱两可,则给它标记为 1;如果答案明确,则标记为 0。模棱两可的答案是指那些含糊其辞、回避或不明确的回答。例如,“我不知道”或“我不确定”都是模棱两可的答案。",

  4.         "output_format_instruction": "输出应为符合以下 JSON schema 的格式良好的 JSON 实例。\n\n例如,对于 schema {\"properties\": {\"foo\": {\"title\": \"Foo\", \"description\": \"a list of strings\", \"type\": \"array\", \"items\": {\"type\": \"string\"}}}, \"required\": [\"foo\"]}\n,对象 {\"foo\": [\"bar\", \"baz\"]} 是符合此 schema 的格式良好的实例。对象  {\"properties\": {\"foo\": [\"bar\", \"baz\"]}} 则不符合格式。\n\n以下是输出的 JSON schema:\n```\n{\"type\": \"object\", \"properties\": {\"question\": {\"title\": \"Question\", \"type\": \"string\"}, \"noncommittal\": {\"title\": \"Noncommittal\", \"type\": \"integer\"}}, \"required\": [\"question\", \"noncommittal\"]}\n```\n\n不要返回任何前言或解释,只返回用三个反引号(```)包围的纯 JSON 字符串。",

  5.         "examples": [

  6.             {

  7.                 "answer": "阿尔伯特·爱因斯坦出生在德国。",

  8.                 "context": "阿尔伯特·爱因斯坦是一位德国出生的理论物理学家,被广泛认为是有史以来最伟大和最有影响力的科学家之一。",

  9.                 "output": {

  10.                     "question": "阿尔伯特·爱因斯坦出生在哪里?",

  11.                     "noncommittal": 0

  12.                 }

  13.             },

  14.             {

  15.                 "answer": "它可以根据环境温度改变皮肤颜色。",

  16.                 "context": "最近的一项科学研究在亚马逊雨林中发现了一种新物种的青蛙,这种青蛙具有根据环境温度改变皮肤颜色的独特能力。",

  17.                 "output": {

  18.                     "question": "新发现的青蛙物种有什么独特的能力?",

  19.                     "noncommittal": 0

  20.                 }

  21.             },

  22.             {

  23.                 "answer": "珠穆朗玛峰",

  24.                 "context": "地球上从海平面计算的最高山峰,是位于喜马拉雅山脉的一座著名山峰。",

  25.                 "output": {

  26.                     "question": "地球上最高的山是什么?",

  27.                     "noncommittal": 0

  28.                 }

  29.             },

  30.             {

  31.                 "answer": "我不知道2023年发明的智能手机的突破性功能,因为我对2022年之后的信息不了解。",

  32.                 "context": "在2023年,一项突破性的发明被宣布:一款电池续航时间为一个月的智能手机,彻底改变了人们使用移动技术的方式。",

  33.                 "output": {

  34.                     "question": "2023年发明的智能手机的突破性功能是什么?",

  35.                     "noncommittal": 1

  36.                 }

  37.             }

  38.         ]

  39.     }

  40. classFaithfulness:

  41.     nli_statements_message_prompt = {

  42.         "instruction": "你的任务是根据给定的上下文判断一系列陈述的真实性。对于每个陈述,如果可以根据上下文直接推断出该陈述,则必须返回判定结果 1;如果不能根据上下文直接推断出该陈述,则必须返回判定结果 0。",

  43.         "output_format_instruction": "输出应为符合以下 JSON 模式的格式良好的 JSON 实例。\n\n例如,对于模式 {\"properties\": {\"foo\": {\"title\": \"Foo\", \"description\": \"a list of strings\", \"type\": \"array\", \"items\": {\"type\": \"string\"}}}, \"required\": [\"foo\"]}\n对象 {\"foo\": [\"bar\", \"baz\"]} 是该模式的格式良好的实例。对象 {\"properties\": {\"foo\": [\"bar\", \"baz\"]}} 格式不正确。\n\n输出的 JSON 模式如下:\n```\n{\"type\": \"array\", \"items\": {\"$ref\": \"#/definitions/StatementFaithfulnessAnswer\"}, \"definitions\": {\"StatementFaithfulnessAnswer\": {\"title\": \"StatementFaithfulnessAnswer\", \"type\": \"object\", \"properties\": {\"statement\": {\"title\": \"Statement\", \"description\": \"the original statement, word-by-word\", \"type\": \"string\"}, \"reason\": {\"title\": \"Reason\", \"description\": \"verdict理由\", \"type\": \"string\"}, \"verdict\": {\"title\": \"Verdict\", \"description\": \"faithfulness的verdict(0/1)。\", \"type\": \"integer\"}}, \"required\": [\"statement\", \"reason\", \"verdict\"]}}}\n```\n\n不返回任何前言或解释,仅返回由三个反引号(“```”)包围的纯 JSON 字符串。",

  44.         "examples": [

  45.             {

  46.                 "context": "John 是 XYZ 大学的一名学生。他正在攻读计算机科学学位。这个学期他选修了几门课程,包括数据结构、算法和数据库管理。John 是一个勤奋的学生,他花费了大量时间来学习和完成作业。他经常在图书馆熬夜做项目。",

  47.                 "statements": [

  48.                     "John 主修生物学。",

  49.                     "John 正在上人工智能课程。",

  50.                     "John 是一个敬业的学生。",

  51.                     "John 有一份兼职工作。"

  52.                 ],

  53.                 "answer": [

  54.                     {

  55.                         "statement": "John 主修生物学。",

  56.                         "reason": "John 的专业明确提到是计算机科学。没有任何信息表明他主修生物学。",

  57.                         "verdict": 0

  58.                     },

  59.                     {

  60.                         "statement": "John 正在上人工智能课程。",

  61.                         "reason": "上下文提到了 John 当前选修的课程,但没有提到人工智能。因此,不能推断出 John 正在上人工智能课程。",

  62.                         "verdict": 0

  63.                     },

  64.                     {

  65.                         "statement": "John 是一个敬业的学生。",

  66.                         "reason": "上下文提到他花费了大量时间来学习和完成作业。此外,还提到他经常在图书馆熬夜做项目,这表明他很敬业。",

  67.                         "verdict": 1

  68.                     },

  69.                     {

  70.                         "statement": "John 有一份兼职工作。",

  71.                         "reason": "上下文并没有提供有关 John 有兼职工作的任何信息。",

  72.                         "verdict": 0

  73.                     }

  74.                 ]

  75.             },

  76.             {

  77.                 "context": "光合作用是植物、藻类和某些细菌将光能转化为化学能的过程。",

  78.                 "statements": [

  79.                     "阿尔伯特·爱因斯坦是个天才。"

  80.                 ],

  81.                 "answer": [

  82.                     {

  83.                         "statement": "阿尔伯特·爱因斯坦是个天才。",

  84.                         "reason": "上下文和陈述是无关的",

  85.                         "verdict": 0

  86.                     }

  87.                 ]

  88.             }

  89.         ]

  90.     }

  91.     statement_prompt = {

  92.         "instruction": "给定一个问题、一个答案和答案中的句子,分析在'sentences'中给出的每个句子的复杂性,并将每个句子分解成一个或多个完全可理解的陈述,同时确保每个陈述中不使用代词。将输出格式化为JSON。",

  93.         "output_format_instruction": "输出应为符合以下 JSON 模式的格式良好的 JSON 实例。\n\n例如,对于模式 {\"properties\": {\"foo\": {\"title\": \"Foo\", \"description\": \"a list of strings\", \"type\": \"array\", \"items\": {\"type\": \"string\"}}}, \"required\": [\"foo\"]}\n对象 {\"foo\": [\"bar\", \"baz\"]} 是该模式的格式良好的实例。对象 {\"properties\": {\"foo\": [\"bar\", \"baz\"]}} 格式不正确。\n\n输出的 JSON 模式如下:\n```\n{\"type\": \"array\", \"items\": {\"$ref\": \"#/definitions/Statements\"}, \"definitions\": {\"Statements\": {\"title\": \"Statements\", \"type\": \"object\", \"properties\": {\"sentence_index\": {\"title\": \"Sentence Index\", \"description\": \"Index of the sentence from the statement list\", \"type\": \"integer\"}, \"simpler_statements\": {\"title\": \"Simpler Statements\", \"description\": \"the simpler statements\", \"type\": \"array\", \"items\": {\"type\": \"string\"}}}, \"required\": [\"sentence_index\", \"simpler_statements\"]}}}\n```\n\n不返回任何前言或解释,只返回一个由三重反引号(“```”)包围的纯 JSON 字符串。",

  94.         "examples": [

  95.             {

  96.                 "question": "阿尔伯特·爱因斯坦是谁,他以什么闻名?",

  97.                 "answer": "他是一位德国出生的理论物理学家,被广泛认为是有史以来最伟大和最有影响力的物理学家之一。他最出名的是发展了相对论理论,他还为量子力学理论的发展做出了重要贡献。",

  98.                 "sentences": "\n        0:他是一位德国出生的理论物理学家,被广泛认为是有史以来最伟大和最有影响力的物理学家之一。\n        1:他最出名的是发展了相对论理论,他还为量子力学理论的发展做出了重要贡献。\n        ",

  99.                 "analysis": [

  100.                     {

  101.                         "sentence_index": 0,

  102.                         "simpler_statements": [

  103.                             "阿尔伯特·爱因斯坦是一位德国出生的理论物理学家。",

  104.                             "阿尔伯特·爱因斯坦被认为是有史以来最伟大和最有影响力的物理学家之一。"

  105.                         ]

  106.                     },

  107.                     {

  108.                         "sentence_index": 1,

  109.                         "simpler_statements": [

  110.                             "阿尔伯特·爱因斯坦最出名的是发展了相对论理论。",

  111.                             "阿尔伯特·爱因斯坦还为量子力学理论的发展做出了重要贡献。"

  112.                         ]

  113.                     }

  114.                 ]

  115.             }

  116.         ]

  117.     }

  118. classContextRecall:

  119.     context_recall_prompt = {

  120.         "instruction": "给定一个上下文和一个答案,分析答案中的每个句子,并判断该句子是否可以归因于给定的上下文。 仅使用 \"Yes\" (1) 或者 \"No\" (0) 作为二元分类。输出带理由的 json。",

  121.         "output_format_instruction": "输出应该是格式良好的 JSON 实例,符合下面的 JSON 模式。\n\n例如,对于架构 {\"properties\": {\"foo\": {\"title\": \"Foo\", \"description\": \"a list of strings\", \"type\": \"array\", \"items\": {\"type\": \"string\"}}}, \"required\": [\"foo\"]}\n对象 {\"foo\": [\"bar\", \"baz\"]} 是格式良好的架构实例。 对象 {\"properties\": {\"foo\": [\"bar\", \"baz\"]}} 格式不正确。\n\n以下是输出 JSON 模式:\n```\n{\"type\": \"array\", \"items\": {\"$ref\": \"#/definitions/ContextRecallClassificationAnswer\"}, \"definitions\": {\"ContextRecallClassificationAnswer\": {\"title\": \"ContextRecallClassificationAnswer\", \"type\": \"object\", \"properties\": {\"statement\": {\"title\": \"Statement\", \"type\": \"string\"}, \"attributed\": {\"title\": \"Attributed\", \"type\": \"integer\"}, \"reason\": {\"title\": \"Reason\", \"type\": \"string\"}}, \"required\": [\"statement\", \"attributed\", \"reason\"]}}}\n```\n\n不要返回任何前言或解释,只返回一个由三重反引号(```)包围的纯 JSON 字符串。",

  122.         "examples": [

  123.             {

  124.                 "question": "你能告诉我关于阿尔伯特·爱因斯坦的什么信息吗?",

  125.                 "context": "阿尔伯特·爱因斯坦(1879年3月14日 - 1955年4月18日)是一位德国出生的理论物理学家,被广泛认为是有史以来最伟大和最有影响力的科学家之一。他最出名的是发展了相对论理论,他还为量子力学做出了重要贡献,因此在20世纪前几十年现代物理学完成的科学理解自然的革命性重塑中,他是一个核心人物。他的质能等效公式E = mc²,源自相对论理论,被称为‘世界上最著名的方程’。他因‘对理论物理的贡献,特别是发现光电效应定律’而获得了1921年诺贝尔物理学奖,这是量子理论发展的关键一步。他的工作也因其对科学哲学的影响而闻名。在1999年英国《物理世界》杂志对世界130位顶级物理学家的民意调查中,爱因斯坦被评为有史以来最伟大的物理学家。他的智力成就和原创性使得爱因斯坦成为天才的代名词。",

  126.                 "answer": "阿尔伯特·爱因斯坦出生于1879年3月14日,是一位德国出生的理论物理学家,被广泛认为是有史以来最伟大和最有影响力的科学家之一。他因对理论物理的贡献而获得了1921年诺贝尔物理学奖。他在1905年发表了4篇论文。爱因斯坦于1895年搬到了瑞士。",

  127.                 "classification": [

  128.                     {

  129.                         "statement": "阿尔伯特·爱因斯坦出生于1879年3月14日,是一位德国出生的理论物理学家,被广泛认为是有史以来最伟大和最有影响力的科学家之一。",

  130.                         "attributed": 1,

  131.                         "reason": "爱因斯坦的出生日期在上下文中明确提到。"

  132.                     },

  133.                     {

  134.                         "statement": "他因对理论物理的贡献而获得了1921年诺贝尔物理学奖。",

  135.                         "attributed": 1,

  136.                         "reason": "上下文中有确切的句子提到这一点。"

  137.                     },

  138.                     {

  139.                         "statement": "他在1905年发表了4篇论文。",

  140.                         "attributed": 0,

  141.                         "reason": "上下文中没有提到他写的论文。"

  142.                     },

  143.                     {

  144.                         "statement": "爱因斯坦于1895年搬到了瑞士。",

  145.                         "attributed": 0,

  146.                         "reason": "上下文中没有支持这一点的证据。"

  147.                     }

  148.                 ]

  149.             },

  150.             {

  151.                 "question": "谁赢得了2020年国际板球理事会世界杯?",

  152.                 "context": "2022年国际板球理事会男子T20世界杯于2022年10月16日至11月13日在澳大利亚举行,这是该赛事的第八届比赛。原计划于2020年举行,但由于COVID-19疫情被推迟。英格兰队在决赛中击败巴基斯坦队,以五个小门的优势赢得了他们的第二个国际板球理事会男子T20世界杯冠军。",

  153.                 "answer": "英格兰",

  154.                 "classification": [

  155.                     {

  156.                         "statement": "英格兰赢得了2022年国际板球理事会男子T20世界杯。",

  157.                         "attributed": 1,

  158.                         "reason": "从上下文中可以清楚地看出英格兰击败了巴基斯坦赢得了世界杯。"

  159.                     }

  160.                 ]

  161.             },

  162.             {

  163.                 "question": "太阳的主要燃料是什么?",

  164.                 "context": "NULL",

  165.                 "answer": "氢",

  166.                 "classification": [

  167.                     {

  168.                         "statement": "太阳的主要燃料是氢。",

  169.                         "attributed": 0,

  170.                         "reason": "上下文中没有任何信息。"

  171.                     }

  172.                 ]

  173.             }

  174.         ]

  175.     }

  176. classContextPrecision:

  177.     context_precision_prompt = {

  178.         "instruction": "给定问题、答案和上下文,验证上下文是否有助于得出给定的答案。 如果有 JSON 输出,则判定为 \"1\",如果没有,则判定为 \"0\"",

  179.         "output_format_instruction": "输出应该是格式良好的 JSON 实例,符合下面的 JSON 模式。\n\n例如,对于架构 {\"properties\": {\"foo\": {\"title\": \"Foo\", \"description\": \"a list of strings\", \"type\": \"array\", \"items\": {\"type\": \"string\"}}}, \"required\": [\"foo\"]}\n对象 {\"foo\": [\"bar\", \"baz\"]} 是格式良好的架构实例。 对象 {\"properties\": {\"foo\": [\"bar\", \"baz\"]}} 格式不正确。\n\n以下是输出 JSON 模式:\n```\n{\"description\": \"Answer for the verification task wether the context was useful.\", \"type\": \"object\", \"properties\": {\"reason\": {\"title\": \"Reason\", \"description\": \"Reason for verification\", \"type\": \"string\"}, \"verdict\": {\"title\": \"Verdict\", \"description\": \"Binary (0/1) verdict of verification\", \"type\": \"integer\"}}, \"required\": [\"reason\", \"verdict\"]}\n```\n\n不要返回任何前言或解释,只返回一个由三重反引号(```)包围的纯 JSON 字符串。",

  180.         "examples": [

  181.             {

  182.                 "question": "你能告诉我关于阿尔伯特·爱因斯坦的什么信息吗?",

  183.                 "context": "阿尔伯特·爱因斯坦(1879年3月14日 – 1955年4月18日)是一位德国出生的理论物理学家,被广泛认为是有史以来最伟大和最有影响力的科学家之一。他最出名的是发展了相对论理论,他还为量子力学做出了重要贡献,因此在20世纪前几十年现代物理学完成的科学理解自然的革命性重塑中,他是一个核心人物。他的质能等效公式E = mc²,源自相对论理论,被称为“世界上最著名的方程”。他因“对理论物理的贡献,特别是发现光电效应定律”而获得了1921年诺贝尔物理学奖,这是量子理论发展的关键一步。他的工作也因其对科学哲学的影响而闻名。在1999年英国《物理世界》杂志对世界130位顶级物理学家的民意调查中,爱因斯坦被评为有史以来最伟大的物理学家。他的智力成就和原创性使得爱因斯坦成为天才的代名词。",

  184.                 "answer": "阿尔伯特·爱因斯坦出生于1879年3月14日,是德国出生的理论物理学家,被广泛认为是有史以来最伟大和最有影响力的科学家之一。他因对理论物理的贡献获得了1921年诺贝尔物理学奖。他在1905年发表了4篇论文。爱因斯坦于1895年搬到了瑞士。",

  185.                 "verification": {

  186.                     "reason": "提供的上下文确实有助于得出给定的回答。上下文包括关于阿尔伯特·爱因斯坦的生活和贡献的关键信息,这些信息在回答中得以体现。",

  187.                     "verdict": 1

  188.                 }

  189.             },

  190.             {

  191.                 "question": "谁赢得了2020年国际板球理事会世界杯?",

  192.                 "context": "2022年国际板球理事会男子T20世界杯于2022年10月16日至11月13日在澳大利亚举行,这是该赛事的第八届比赛。原计划于2020年举行,但由于COVID-19疫情被推迟。英格兰队在决赛中击败巴基斯坦队,以五个小门的优势赢得了他们的第二个国际板球理事会男子T20世界杯冠军。",

  193.                 "answer": "英格兰",

  194.                 "verification": {

  195.                     "reason": "上下文有助于澄清2020年国际板球理事会世界杯的情况,并指出英格兰是原定于2020年举行但实际在2022年进行的比赛的冠军。",

  196.                     "verdict": 1

  197.                 }

  198.             },

  199.             {

  200.                 "question": "世界上最高的山是什么?",

  201.                 "context": "安第斯山脉是世界上最长的大陆山脉,位于南美洲。它横跨七个国家,拥有西半球许多最高的山峰。该山脉以其多样的生态系统而闻名,包括高海拔的安第斯高原和亚马逊雨林。",

  202.                 "answer": "珠穆朗玛峰。",

  203.                 "verification": {

  204.                     "reason": "提供的上下文讨论了安第斯山脉,虽然令人印象深刻,但不包括珠穆朗玛峰或直接与关于世界最高山峰的问题相关。",

  205.                     "verdict": 0

  206.                 }

  207.             }

  208.         ]

  209.     }

  210. classAnswerCorrectness:

  211.     correctness_prompt = {

  212.         "instruction": "给定ground_truth和answer分解后的陈述,分析每个陈述并将它们归类为以下类别之一:\n\n- TP(真正例):answer中存在的陈述,并且直接得到ground_truth中的一个或多个陈述的支持,\n- FP(假正例):answer中存在但未得到ground_truth中任何陈述直接支持的陈述,\n- FN(假负例):在ground_truth中存在但answer中不存在的陈述。\n\n每个陈述只能属于TP、FP、FN其中一个类别。请提供你分类的原因。",

  213.         "output_format_instruction": "输出应该是格式正确的 JSON 实例,符合下面的 JSON 模式。\n\n例如,对于架构 {\"properties\": {\"foo\": {\"title\": \"Foo\", \"description\": \"a list of strings\", \"type\": \"array\", \"items\": {\"type\": \"string\"}}}, \"required\": [\"foo\"]}\n对象 {\"foo\": [\"bar\", \"baz\"]} 是格式良好的架构实例。 对象 {\"properties\": {\"foo\": [\"bar\", \"baz\"]}} 格式不正确。\n\n以下是输出 JSON 模式:\n```\n{\"type\": \"object\", \"properties\": {\"TP\": {\"title\": \"Tp\", \"type\": \"array\", \"items\": {\"type\": \"object\"}}, \"FP\": {\"title\": \"Fp\", \"type\": \"array\", \"items\": {\"type\": \"object\"}}, \"FN\": {\"title\": \"Fn\", \"type\": \"array\", \"items\": {\"type\": \"object\"}}}, \"required\": [\"TP\", \"FP\", \"FN\"]}\n```\n\n不要返回任何前言或解释,只返回一个由三重反引号(```)包围的纯 JSON 字符串。",

  214.         "examples": [

  215.             {

  216.                 "question": "太阳的动力来源是什么,它的主要功能是什么?",

  217.                 "answer": ["太阳的动力来源是核裂变,类似于地球上的核反应堆。", "太阳的主要功能是为太阳系提供光。"],

  218.                 "ground_truth": ["太阳的动力来源是核聚变,氢原子聚变形成氦。", "太阳核心的这种聚变过程释放出巨大的能量。", "太阳的能量提供了热和光,这是地球生命必需的。", "太阳的光在地球的气候系统中起着关键作用。", "阳光有助于驱动天气和海洋洋流。"],

  219.                 "classification": {

  220.                     "TP": [

  221.                         {

  222.                             "statement": "太阳的主要功能是为太阳系提供光。",

  223.                             "reason": "这个陈述在某种程度上得到了地面真相的支持,地面真相提到了太阳提供光及其作用,尽管它更广泛地关注太阳的能量。"

  224.                         }

  225.                     ],

  226.                     "FP": [

  227.                         {

  228.                             "statement": "太阳的动力来源是核裂变,类似于地球上的核反应堆。",

  229.                             "reason": "该陈述是不正确的,与地面真相相矛盾,地面真相表明太阳的动力来源是核聚变。"

  230.                         }

  231.                     ],

  232.                     "FN": [

  233.                         {

  234.                             "statement": "太阳的动力来源是核聚变,氢原子聚变形成氦。",

  235.                             "reason": "这个对太阳动力来源的准确描述没有包含在答案中。"

  236.                         },

  237.                         {

  238.                             "statement": "太阳核心的这种聚变过程释放出巨大的能量。",

  239.                             "reason": "这个过程及其重要性没有在答案中提到。"

  240.                         },

  241.                         {

  242.                             "statement": "太阳的能量提供了热和光,这是地球生命必需的。",

  243.                             "reason": "答案中只提到光,忽略了热及其对生命的必要性,这是地面真相涵盖的内容。"

  244.                         },

  245.                         {

  246.                             "statement": "太阳的光在地球的气候系统中起着关键作用。",

  247.                             "reason": "太阳光对地球气候系统的更广泛影响没有在答案中提到。"

  248.                         },

  249.                         {

  250.                             "statement": "阳光有助于驱动天气和海洋洋流。",

  251.                             "reason": "阳光对天气模式和海洋洋流的影响在答案中被遗漏了。"

  252.                         }

  253.                     ]

  254.                 }

  255.             },

  256.             {

  257.                 "question": "水的沸点是多少?",

  258.                 "answer": ["水的沸点是在海平面上100摄氏度。"],

  259.                 "ground_truth": ["水的沸点是在海平面上100摄氏度(212华氏度)。", "水的沸点会随着海拔的变化而改变。"],

  260.                 "classification": {

  261.                     "TP": [

  262.                         {

  263.                             "statement": "水的沸点是在海平面上100摄氏度。",

  264.                             "reason": "这个陈述直接得到了地面真相的支持,地面真相明确指出水的沸点是在海平面上100摄氏度。"

  265.                         }

  266.                     ],

  267.                     "FP": [],

  268.                     "FN": [

  269.                         {

  270.                             "statement": "水的沸点会随着海拔的变化而改变。",

  271.                             "reason": "关于水的沸点会随着海拔变化而改变的附加信息没有在答案中提到。"

  272.                         }

  273.                     ]

  274.                 }

  275.             }

  276.         ]

  277.     }

感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取   

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐