忠实度是指答案应基于给定的上下文。这对于避免幻觉至关重要,同时也能确保检索到的上下文可作为生成答案的依据。实际上,检索增强生成(RAG)系统常用于对生成文本与事实来源的一致性要求很高的应用场景,例如在信息不断更新的法律等领域。
如果答案 中的主张能够从上下文 中推断出来,我们就认为该答案忠实于上下文 。为了评估忠实度,我们首先使用大语言模型(LLM)提取一组陈述 。这一步的目的是将较长的句子分解为更简短、更聚焦的断言/陈述 statement 。我们在这一步使用以下提示词:
1 2 3 给定一个问题和答案,从给定答案的每个句子中创建一个或多个陈述。 问题:[问题] 答案:[答案]
其中,[问题]和[答案]指的是给定的问题和答案。对于集合 中的每个陈述 ,大语言模型会使用验证函数 来判断 是否能从 中推断出来。这个验证步骤使用以下提示词:
1 2 3 4 考虑给定的上下文和以下陈述,然后判断这些陈述是否能从上下文中的信息得到支持。在得出结论(是/否)之前,对每个陈述进行简要解释。最后按照给定的格式依次给出每个陈述的最终结论。不要偏离指定的格式。 陈述:[陈述1] …… 陈述:[陈述n]
最终的忠实度得分 的计算方式为 ,其中 是根据大语言模型判断得到支持的陈述数量, 是陈述的总数。
这是测试数据
1 2 3 4 5 6 answer = "美国最高法院关于堕胎的裁决具有重要的全球影响。该裁决导致在堕胎访问受到限制的州,三分之一的生育年龄女性和女孩无法获得堕胎服务。那些州的母婴健康支持也较弱,母亲死亡率较高,儿童贫困率也较高。此外,裁决的影响超出了国界,由于美国在全球的地缘政治和文化影响力,这一裁决也产生了跨国影响。全球的组织和活动家担心这一裁决可能会激励其他国家出台反堕胎的立法和政策。裁决还妨碍了某些非洲国家的进步法律改革和堕胎指南的实施。此外,该裁决在国际政策领域造成了寒蝉效应,使得反堕胎的力量能够削弱人权保护。" docs = [ "- 2022年,美国最高法院作出裁决,推翻了50年的判例法,取消了宪法堕胎权。\n- 这一裁决产生了巨大影响:三分之一的生育年龄女性和女孩现在生活在堕胎服务几乎完全无法获得的州。\n- 这些堕胎法律最为严格的州,母婴健康支持最为薄弱,母亲死亡率较高,儿童贫困率较高。\n- 美国最高法院的裁决还通过美国在全球的地缘政治和文化影响力,超越国界产生了影响。\n- 全球的SRR组织和活动家对这一裁决可能为其他国家的反堕胎立法和政策攻击铺路表示担忧。\n- 观察者还注意到该裁决对某些非洲国家的进步法律改革产生了影响,导致堕胎指导方针的 adoption 和执行停滞不前。\n- 该裁决在国际政策领域产生了寒蝉效应,助长了反堕胎的国家和非国家行为体破坏人权保护的势头。" , "美国最高法院的堕胎裁决不仅在国内引发了激烈的辩论和讨论,也在全球范围内引发了广泛关注。许多国家将美国视为法律和社会问题的领导者,因此这一裁决可能会影响其他国家对堕胎的政策和态度。" , "这一裁决还可能对国际组织和非政府组织(NGO)产生影响,尤其是那些致力于生育权和妇女健康问题的团体。根据裁决的结果,可能会出现资金、倡导工作和与美国同行的合作发生变化,进而在全球范围内引发生育正义斗争的连锁反应。" ]
实现介绍 指标原理: 忠实度指标用于评估生成回答是否忠于提供的上下文信息。其核心思想是:
从回答中提取陈述 :将回答拆解为多个可验证的原子化陈述。
在上下文中验证陈述 :检查这些陈述是否可以从上下文信息推导得出。
计算忠实度得分 :忠实度得分是可验证陈述的比例。
背景原因: 生成式模型可能会生成幻觉,即回答中包含超出提供上下文的信息。忠实度指标可以帮助检测这种情况,确保模型回答与上下文一致,提高模型的可靠性。
实现流程:
解析回答 :使用 LLM 提取回答中的关键陈述。
验证陈述 :使用 LLM 判断每个陈述是否可以在上下文中得到支持。
计算评分 :统计可验证陈述的比例,作为最终得分。
解析回答 create statements 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 from typing import List from langchain_core.documents import Documentfrom langchain_openai import ChatOpenAIfrom langchain_core.prompts import PromptTemplatefrom langchain_core.output_parsers import PydanticOutputParserfrom pydantic import BaseModel, Field''' 输出格式形如: { "sentence_and_statements": [ # 这是第一个句子和它可拆分的内容陈述 { "origin_sentence": 回答中某个句子的原始内容,为了保证连贯性让模型输出, "statements":[ { "description":这是内容陈述1的具体内容。 }, { "description":这是内容陈述2的具体内容。 }, ... ] }, ... ] } ''' class Statement (BaseModel ): description: str = Field(description="这是内容陈述的具体内容。" ) class Sentence_And_Statement (BaseModel ): origin_sentence: str = Field(description="这是回答的某个句子。" ) statements: List [Statement] = Field(description="这是由上述句子中提取的一组内容陈述。" ) class Sentence_And_Statement_List (BaseModel ): sentence_and_statements: List [Sentence_And_Statement] = Field(description="这是由文本中提取的每组句子和对应的内容陈述。" ) statement_output_parser = PydanticOutputParser(pydantic_object=Sentence_And_Statement_List) llm = ChatOpenAI( base_url='http://localhost:5551/v1' , api_key='EMPTY' , model_name='Qwen2.5-7B-Instruct' , temperature=0.5 , ) create_statement_prompt = ( "给定一个包含若干句子的文本,分析每个句子并将每个句子分解为一个或多个原子化的完全可理解的内容陈述,同时确保每个语句中不使用代词,且每个对象都需要具体,在其所在陈述中可理解。\n" "输出格式:\n{output_format_instructions}\n\n" "[文本-开始]:\n{context}\n[文本-结束]\n" ) create_statement_prompt = PromptTemplate( template=create_statement_prompt, partial_variables={ "output_format_instructions" :statement_output_parser.get_format_instructions() } ) create_statement_chain = create_statement_prompt | llm | statement_output_parser
1 create_statement_prompt.pretty_print()
给定一个包含若干句子的文本,分析每个句子并将每个句子分解为一个或多个原子化的完全可理解的内容陈述,同时确保每个语句中不使用代词,且每个对象都需要具体,在其所在陈述中可理解。
输出格式:
The output should be formatted as a JSON instance that conforms to the JSON schema below.
As an example, for the schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}
the object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema. The object {"properties": {"foo": ["bar", "baz"]}} is not well-formatted.
Here is the output schema:
1 {"$defs": {"Sentence_And_Statement": {"properties": {"origin_sentence": {"description": "这是回答的某个句子。", "title": "Origin Sentence", "type": "string"}, "statements": {"description": "这是由上述句子中提取的一组内容陈述。", "items": {"$ref": "#/$defs/Statement"}, "title": "Statements", "type": "array"}}, "required": ["origin_sentence", "statements"], "title": "Sentence_And_Statement", "type": "object"}, "Statement": {"properties": {"description": {"description": "这是内容陈述的具体内容。", "title": "Description", "type": "string"}}, "required": ["description"], "title": "Statement", "type": "object"}}, "properties": {"sentence_and_statements": {"description": "这是由文本中提取的每组句子和对应的内容陈述。", "items": {"$ref": "#/$defs/Sentence_And_Statement"}, "title": "Sentence And Statements", "type": "array"}}, "required": ["sentence_and_statements"]}
[文本-开始]:
[33;1m[1;3m{context}[0m
[文本-结束]
1 statement_list = create_statement_chain.invoke({"context" :answer})
1 statements = sum ([item.statements for item in statement_list.sentence_and_statements], [])
[Statement(description='美国最高法院关于堕胎的裁决具有重要的全球影响。'),
Statement(description='在堕胎访问受到限制的州,三分之一的生育年龄女性和女孩无法获得堕胎服务。'),
Statement(description='那些州的母婴健康支持较弱。'),
Statement(description='那些州的母亲死亡率较高。'),
Statement(description='那些州的儿童贫困率较高。'),
Statement(description='裁决的影响超出了国界。'),
Statement(description='由于美国在全球的地缘政治和文化影响力,这一裁决也产生了跨国影响。'),
Statement(description='全球的组织和活动家担心这一裁决可能会激励其他国家出台反堕胎的立法和政策。'),
Statement(description='裁决妨碍了某些非洲国家的进步法律改革和堕胎指南的实施。'),
Statement(description='该裁决在国际政策领域造成了寒蝉效应,使得反堕胎的力量能够削弱人权保护。')]
这是测试数据的提取结果
1 2 3 4 5 6 7 8 9 10 [Statement(description='美国最高法院关于堕胎的裁决具有重要的全球影响。'), Statement(description='在堕胎访问受到限制的州,三分之一的生育年龄女性和女孩无法获得堕胎服务。'), Statement(description='那些州的母婴健康支持较弱。'), Statement(description='那些州的母亲死亡率较高。'), Statement(description='那些州的儿童贫困率较高。'), Statement(description='裁决的影响超出了国界。'), Statement(description='由于美国在全球的地缘政治和文化影响力,这一裁决也产生了跨国影响。'), Statement(description='全球的组织和活动家担心这一裁决可能会激励其他国家出台反堕胎的立法和政策。'), Statement(description='裁决妨碍了某些非洲国家的进步法律改革和堕胎指南的实施。'), Statement(description='该裁决在国际政策领域造成了寒蝉效应,使得反堕胎的力量能够削弱人权保护。')]
验证陈述 statement verdict 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 ''' 输出格式形如: { "statement_verdications": [ # 这是第一个内容陈述和它的验证结果 { "statement": 某个内容陈述,为了保证模型不会中途乱输出, "verdication_reasoning":这是判断陈述是否可以由上下文推断时的思考内容 "verdication_result":陈述可信度,如果可以根据上下文直接推断该出陈述,则为1,否则为0。 }, ... ] } ''' class Statement_Verdication (BaseModel ): statement: str = Field(description="这是内容陈述的内容,你直接复制原始内容。" ) verdication_reasoning: str = Field(description="这是判断陈述是否可以由上下文推断时的思考内容" ) verdication_result: int = Field(description="陈述可信度,如果可以根据上下文直接推断该出陈述,则为1,否则为0。" ) class Statement_Verdication_List (BaseModel ): statement_verdications: List [Statement_Verdication] = Field(description="这是一组内容陈述的是否可由上下文推断出的结果。" ) verdict_statement_parser = PydanticOutputParser(pydantic_object=Statement_Verdication_List) verdict_statement_prompt = ( "你的任务是根据给定的上下文判断一系列内容陈述的可信度。对于每个陈述,如果可以根据上下文直接推断该出陈述,则返回1,否则返回0。\n" "输出格式:\n{output_format_instructions}\n\n" "[上下文-开始]:\n{context}\n[上下文-结束]\n" "[内容陈述-开始]:\n{statements}\n[内容陈述-结束]" ) verdict_statement_prompt = PromptTemplate( template=verdict_statement_prompt, partial_variables={ "output_format_instructions" :verdict_statement_parser.get_format_instructions() } ) verdict_statement_chain = verdict_statement_prompt | llm | verdict_statement_parser
1 verdict_statement_prompt.pretty_print()
你的任务是根据给定的上下文判断一系列内容陈述的可信度。对于每个陈述,如果可以根据上下文直接推断该出陈述,则返回1,否则返回0。
输出格式:
The output should be formatted as a JSON instance that conforms to the JSON schema below.
As an example, for the schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}
the object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema. The object {"properties": {"foo": ["bar", "baz"]}} is not well-formatted.
Here is the output schema:
1 {"$defs": {"Statement_Verdication": {"properties": {"statement": {"description": "这是内容陈述的内容,你直接复制原始内容。", "title": "Statement", "type": "string"}, "verdication_reasoning": {"description": "这是判断陈述是否可以由上下文推断时的思考内容", "title": "Verdication Reasoning", "type": "string"}, "verdication_result": {"description": "陈述可信度,如果可以根据上下文直接推断该出陈述,则为1,否则为0。", "title": "Verdication Result", "type": "integer"}}, "required": ["statement", "verdication_reasoning", "verdication_result"], "title": "Statement_Verdication", "type": "object"}}, "properties": {"statement_verdications": {"description": "这是一组内容陈述的是否可由上下文推断出的结果。", "items": {"$ref": "#/$defs/Statement_Verdication"}, "title": "Statement Verdications", "type": "array"}}, "required": ["statement_verdications"]}
[上下文-开始]:
[33;1m[1;3m{context}[0m
[上下文-结束]
[内容陈述-开始]:
[33;1m[1;3m{statements}[0m
[内容陈述-结束]
1 2 3 4 5 6 verdict_results = verdict_statement_chain.invoke( { "context" :'\n' .join(docs), "statements" :'\n' .join([f'{indice+1 } . {item.description} ' for indice, item in enumerate (statements)]) } )
1 verdict_results.statement_verdications
[Statement_Verdication(statement='美国最高法院关于堕胎的裁决具有重要的全球影响。', verdication_reasoning='上下文明确提到这一裁决‘超越国界产生了影响’并且‘在全球范围内引发了广泛关注’。', verdication_result=1),
Statement_Verdication(statement='在堕胎访问受到限制的州,三分之一的生育年龄女性和女孩无法获得堕胎服务。', verdication_reasoning='上下文直接提到‘三分之一的生育年龄女性和女孩现在生活在堕胎服务几乎完全无法获得的州’。', verdication_result=1),
Statement_Verdication(statement='那些州的母婴健康支持较弱。', verdication_reasoning='上下文明确指出‘这些堕胎法律最为严格的州,母婴健康支持最为薄弱’。', verdication_result=1),
Statement_Verdication(statement='那些州的母亲死亡率较高。', verdication_reasoning='上下文提到‘母亲死亡率较高’。', verdication_result=1),
Statement_Verdication(statement='那些州的儿童贫困率较高。', verdication_reasoning='上下文提到‘儿童贫困率较高’。', verdication_result=1),
Statement_Verdication(statement='裁决的影响超出了国界。', verdication_reasoning='上下文明确提到‘这一裁决通过美国在全球的地缘政治和文化影响力,超越国界产生了影响’。', verdication_result=1),
Statement_Verdication(statement='由于美国在全球的地缘政治和文化影响力,这一裁决也产生了跨国影响。', verdication_reasoning='上下文提到‘这一裁决通过美国在全球的地缘政治和文化影响力,超越国界产生了影响’。', verdication_result=1),
Statement_Verdication(statement='全球的组织和活动家担心这一裁决可能会激励其他国家出台反堕胎的立法和政策。', verdication_reasoning='上下文提到‘全球的SRR组织和活动家对这一裁决可能为其他国家的反堕胎立法和政策攻击铺路表示担忧’。', verdication_result=1),
Statement_Verdication(statement='裁决妨碍了某些非洲国家的进步法律改革和堕胎指南的实施。', verdication_reasoning='上下文提到‘观察者还注意到该裁决对某些非洲国家的进步法律改革产生了影响,导致堕胎指导方针的 adoption 和执行停滞不前’。', verdication_result=1),
Statement_Verdication(statement='该裁决在国际政策领域造成了寒蝉效应,使得反堕胎的力量能够削弱人权保护。', verdication_reasoning='上下文提到‘该裁决在国际政策领域产生了寒蝉效应,助长了反堕胎的国家和非国家行为体破坏人权保护的势头’。', verdication_result=1)]
以下是测试数据的验证结果,主要看verdication_result字段
1 2 3 4 5 6 7 8 9 10 [Statement_Verdication(statement='美国最高法院关于堕胎的裁决具有重要的全球影响。', verdication_reasoning='上下文明确提到这一裁决‘超越国界产生了影响’并且‘在全球范围内引发了广泛关注’。', verdication_result=1), Statement_Verdication(statement='在堕胎访问受到限制的州,三分之一的生育年龄女性和女孩无法获得堕胎服务。', verdication_reasoning='上下文直接提到‘三分之一的生育年龄女性和女孩现在生活在堕胎服务几乎完全无法获得的州’。', verdication_result=1), Statement_Verdication(statement='那些州的母婴健康支持较弱。', verdication_reasoning='上下文明确指出‘这些堕胎法律最为严格的州,母婴健康支持最为薄弱’。', verdication_result=1), Statement_Verdication(statement='那些州的母亲死亡率较高。', verdication_reasoning='上下文提到‘母亲死亡率较高’。', verdication_result=1), Statement_Verdication(statement='那些州的儿童贫困率较高。', verdication_reasoning='上下文提到‘儿童贫困率较高’。', verdication_result=1), Statement_Verdication(statement='裁决的影响超出了国界。', verdication_reasoning='上下文明确提到‘这一裁决通过美国在全球的地缘政治和文化影响力,超越国界产生了影响’。', verdication_result=1), Statement_Verdication(statement='由于美国在全球的地缘政治和文化影响力,这一裁决也产生了跨国影响。', verdication_reasoning='上下文提到‘这一裁决通过美国在全球的地缘政治和文化影响力,超越国界产生了影响’。', verdication_result=1), Statement_Verdication(statement='全球的组织和活动家担心这一裁决可能会激励其他国家出台反堕胎的立法和政策。', verdication_reasoning='上下文提到‘全球的SRR组织和活动家对这一裁决可能为其他国家的反堕胎立法和政策攻击铺路表示担忧’。', verdication_result=1), Statement_Verdication(statement='裁决妨碍了某些非洲国家的进步法律改革和堕胎指南的实施。', verdication_reasoning='上下文提到‘观察者还注意到该裁决对某些非洲国家的进步法律改革产生了影响,导致堕胎指导方针的 adoption 和执行停滞不前’。', verdication_result=1), Statement_Verdication(statement='该裁决在国际政策领域造成了寒蝉效应,使得反堕胎的力量能够削弱人权保护。', verdication_reasoning='上下文提到‘该裁决在国际政策领域产生了寒蝉效应,助长了反堕胎的国家和非国家行为体破坏人权保护的势头’。', verdication_result=1)]
1 2 3 4 5 verdications = verdict_results.statement_verdications num_faithful_statements = sum ([item.verdication_result for item in verdications]) num_statements = len (verdications) score = num_faithful_statements / num_statements print (score)
1.0
完整代码 继承 Runnable, 可像langchain实例一样invoke调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 """ ## 忠实度指标(Faithfulness Metric)教程 ### 指标原理 忠实度指标用于评估生成回答是否忠于提供的上下文信息。其核心思想是: 1. **从回答中提取陈述**:将回答拆解为多个可验证的原子化陈述。 2. **在上下文中验证陈述**:检查这些陈述是否可以从上下文信息推导得出。 3. **计算忠实度得分**:忠实度得分是可验证陈述的比例。 ### 背景原因 生成式模型可能会生成幻觉,即回答中包含超出提供上下文的信息。忠实度指标可以帮助检测这种情况,确保模型回答与上下文一致,提高模型的可靠性。 ### 实现流程 1. **解析回答**:使用 LLM 提取回答中的关键陈述。 2. **验证陈述**:使用 LLM 判断每个陈述是否可以在上下文中得到支持。 3. **计算评分**:统计可验证陈述的比例,作为最终得分。 """ import jsonimport numpy as npimport asynciofrom typing import List , Dict from langchain.schema.runnable import Runnablefrom langchain_openai import ChatOpenAIfrom langchain_core.prompts import PromptTemplatefrom langchain_core.output_parsers import PydanticOutputParserfrom pydantic import BaseModel, Fieldclass Statement (BaseModel ): description: str = Field(description="这是内容陈述的具体内容。" ) class Sentence_And_Statement (BaseModel ): origin_sentence: str = Field(description="这是回答的某个句子。" ) statements: List [Statement] = Field(description="这是由上述句子中提取的一组内容陈述。" ) class Sentence_And_Statement_List (BaseModel ): sentence_and_statements: List [Sentence_And_Statement] = Field(description="这是由文本中提取的每组句子和对应的内容陈述。" ) class Statement_Verdication (BaseModel ): statement: str = Field(description="这是内容陈述的内容,你直接复制原始内容。" ) verdication_reasoning: str = Field(description="这是判断陈述是否可以由上下文推断时的思考内容" ) verdication_result: int = Field(description="陈述可信度,如果可以根据上下文直接推断该出陈述,则为1,否则为0。" ) class Statement_Verdication_List (BaseModel ): statement_verdications: List [Statement_Verdication] = Field(description="这是一组内容陈述的是否可由上下文推断出的结果。" ) class Faithfulness (Runnable ): """ 评估回答的忠实度,确保回答中的信息能够由提供的上下文支持。 该类支持同步和异步评估。 """ def __init__ (self, llm: ChatOpenAI ): self .llm = llm self .statement_output_parser = PydanticOutputParser(pydantic_object=Sentence_And_Statement_List) self .verdict_statement_parser = PydanticOutputParser(pydantic_object=Statement_Verdication_List) create_statement_prompt = ( "给定一个包含若干句子的文本,分析每个句子并将每个句子分解为一个或多个原子化的完全可理解的内容陈述,同时确保每个语句中不使用代词,且每个对象都需要具体,在其所在陈述中可理解。\n" "输出格式:\n{output_format_instructions}\n\n" "[文本-开始]:\n{context}\n[文本-结束]\n" ) self .create_statement_prompt = PromptTemplate( template=create_statement_prompt, partial_variables={"output_format_instructions" : self .statement_output_parser.get_format_instructions()} ) self .create_statement_chain = self .create_statement_prompt | self .llm | self .statement_output_parser verdict_statement_prompt = ( "你的任务是根据给定的上下文判断一系列内容陈述的可信度。对于每个陈述,如果可以根据上下文直接推断该出陈述,则返回1,否则返回0。\n" "输出格式:\n{output_format_instructions}\n\n" "[上下文-开始]:\n{context}\n[上下文-结束]\n" "[内容陈述-开始]:\n{statements}\n[内容陈述-结束]" ) self .verdict_statement_prompt = PromptTemplate( template=verdict_statement_prompt, partial_variables={"output_format_instructions" : self .verdict_statement_parser.get_format_instructions()} ) self .verdict_statement_chain = self .verdict_statement_prompt | self .llm | self .verdict_statement_parser def create_statements (self, context: str ): statement_list = self .create_statement_chain.invoke({"context" : context}) return sum ([item.statements for item in statement_list.sentence_and_statements], []) def verdict_statements (self, context: str , statements: List [Statement] ): verdict_result = self .verdict_statement_chain.invoke({ "context" : context, "statements" : '\n' .join([f'{i+1 } . {item.description} ' for i, item in enumerate (statements)]) }) return verdict_result.statement_verdications def compute_score (self, verdicts ): num_faithful_statements = sum ([item.verdication_result for item in verdicts]) num_statements = len (verdicts) return num_faithful_statements / num_statements if num_statements else np.nan def invoke (self, inputs: Dict [str , List [str ]] ) -> float : """ 评估回答的忠实度。 :param inputs: 包含 `answer` (回答) 和 `document_list` (上下文列表) 的字典。 :return: 计算的忠实度得分。 """ answer = inputs["answer" ] document_list = inputs["document_list" ] statements = self .create_statements(answer) context = '\n' .join(document_list) verdicts = self .verdict_statements(context, statements) return self .compute_score(verdicts) async def ainvoke (self, inputs: Dict [str , List [str ]] ) -> float : """ 异步评估回答的忠实度。 :param inputs: 包含 `answer` (回答) 和 `document_list` (上下文列表) 的字典。 :return: 计算的忠实度得分。 """ answer = inputs["answer" ] document_list = inputs["document_list" ] statements = await asyncio.to_thread(self .create_statements, answer) context = '\n' .join(document_list) verdicts = await asyncio.to_thread(self .verdict_statements, context, statements) return self .compute_score(verdicts)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 llm = ChatOpenAI( base_url='http://localhost:5551/v1' , api_key='EMPTY' , model_name='Qwen2.5-7B-Instruct' , temperature=0.5 , ) tool = Faithfulness(llm) inputs = { "answer" :answer, "document_list" :docs, } score = tool.invoke(inputs) print (score)