跳转到内容

上下文精确率

上下文精确率(Context Precision)是一个评估检索器能力的指标,用于衡量其在检索到的上下文中,为给定查询将相关内容块(chunks)排在不相关内容块之前的能力。具体来说,它评估了检索到的上下文中相关内容块被排在顶部的程度。

它的计算方式是上下文中每个内容块的 precision@k 的平均值。Precision@k 是指在排名 k 处的相关内容块数量与排名 k 处总内容块数量的比率。

\[ \text{上下文精确率@K} = \frac{\sum_{k=1}^{K} \left( \text{精确率@k} \times v_k \right)}{\text{前 } K \text{ 个结果中的相关项总数}} \]
\[ \text{精确率@k} = {\text{真正例@k} \over (\text{真正例@k} + \text{假正例@k})} \]

其中 \(K\)retrieved_contexts 中内容块的总数,而 \(v_k \in \{0, 1\}\) 是在排名 \(k\) 处的相关性指示符。

示例

上下文精确率

ContextPrecision 指标通过将每个上下文与参考答案进行比较,来评估检索到的上下文是否有助于回答问题。当您有参考答案时,请使用此指标。

from openai import AsyncOpenAI
from ragas.llms import llm_factory
from ragas.metrics.collections import ContextPrecision

# Setup LLM
client = AsyncOpenAI()
llm = llm_factory("gpt-4o-mini", client=client)

# Create metric
scorer = ContextPrecision(llm=llm)

# Evaluate
result = await scorer.ascore(
    user_input="Where is the Eiffel Tower located?",
    reference="The Eiffel Tower is located in Paris.",
    retrieved_contexts=[
        "The Eiffel Tower is located in Paris.",
        "The Brandenburg Gate is located in Berlin."
    ]
)
print(f"Context Precision Score: {result.value}")

输出

Context Precision Score: 0.9999999999

同步用法

如果你偏好同步代码,可以使用 .score() 方法来代替 .ascore()

result = scorer.score(
    user_input="Where is the Eiffel Tower located?",
    reference="The Eiffel Tower is located in Paris.",
    retrieved_contexts=[...]
)

上下文利用率

ContextUtilization 指标通过将每个上下文与生成的回答进行比较,来评估检索到的上下文是否有用。当您没有参考答案但有生成的回答时,请使用此指标。

from openai import AsyncOpenAI
from ragas.llms import llm_factory
from ragas.metrics.collections import ContextUtilization

# Setup LLM
client = AsyncOpenAI()
llm = llm_factory("gpt-4o-mini", client=client)

# Create metric
scorer = ContextUtilization(llm=llm)

# Evaluate
result = await scorer.ascore(
    user_input="Where is the Eiffel Tower located?",
    response="The Eiffel Tower is located in Paris.",
    retrieved_contexts=[
        "The Eiffel Tower is located in Paris.",
        "The Brandenburg Gate is located in Berlin."
    ]
)
print(f"Context Utilization Score: {result.value}")

输出

Context Utilization Score: 0.9999999999

请注意,即使一个不相关的内容块出现在数组的第二个位置,上下文精确率也保持不变。但是,如果这个不相关的内容块被放在第一个位置,上下文精确率会降低。

result = await scorer.ascore(
    user_input="Where is the Eiffel Tower located?",
    response="The Eiffel Tower is located in Paris.",
    retrieved_contexts=[
        "The Brandenburg Gate is located in Berlin.",
        "The Eiffel Tower is located in Paris."
    ]
)
print(f"Context Utilization Score: {result.value}")

输出

Context Utilization Score: 0.49999999995

旧版指标 API

以下示例使用旧版指标 API 模式。对于新项目,我们建议使用上面显示的基于集合的 API。

弃用时间表

此 API 将在 0.4 版本中被弃用,并在 1.0 版本中被移除。请迁移到上面显示的基于集合的 API。

使用 SingleTurnSample 的示例

from ragas import SingleTurnSample
from ragas.metrics import LLMContextPrecisionWithoutReference

context_precision = LLMContextPrecisionWithoutReference(llm=evaluator_llm)

sample = SingleTurnSample(
    user_input="Where is the Eiffel Tower located?",
    response="The Eiffel Tower is located in Paris.",
    retrieved_contexts=["The Eiffel Tower is located in Paris."],
)

await context_precision.single_turn_ascore(sample)

输出

0.9999999999

无参考答案的上下文精确率

LLMContextPrecisionWithoutReference 指标可以在没有参考答案的情况下使用。为了评估检索到的上下文是否相关,此方法使用 LLM 将 retrieved_contexts 中的每个内容块与 response 进行比较。

示例

from ragas import SingleTurnSample
from ragas.metrics import LLMContextPrecisionWithoutReference

context_precision = LLMContextPrecisionWithoutReference(llm=evaluator_llm)

sample = SingleTurnSample(
    user_input="Where is the Eiffel Tower located?",
    response="The Eiffel Tower is located in Paris.",
    retrieved_contexts=["The Eiffel Tower is located in Paris."],
)

await context_precision.single_turn_ascore(sample)

输出

0.9999999999

带参考答案的上下文精确率

当您既有检索到的上下文,又有与 user_input 关联的参考回答时,可以使用 LLMContextPrecisionWithReference 指标。为了评估检索到的上下文是否相关,此方法使用 LLM 将 retrieved_contexts 中的每个内容块与 reference 进行比较。

示例

from ragas import SingleTurnSample
from ragas.metrics import LLMContextPrecisionWithReference

context_precision = LLMContextPrecisionWithReference(llm=evaluator_llm)

sample = SingleTurnSample(
    user_input="Where is the Eiffel Tower located?",
    reference="The Eiffel Tower is located in Paris.",
    retrieved_contexts=["The Eiffel Tower is located in Paris."],
)

await context_precision.single_turn_ascore(sample)

输出

0.9999999999

非基于 LLM 的上下文精确率

该指标使用非基于 LLM 的方法(例如莱文斯坦距离度量)来确定检索到的上下文是否相关。

带参考上下文的上下文精确率

NonLLMContextPrecisionWithReference 指标专为同时提供检索到的上下文和与 user_input 相关的参考上下文的场景设计。为了确定检索到的上下文是否相关,此方法使用非基于 LLM 的相似性度量,将 retrieved_contexts 中的每个检索到的上下文或内容块与 reference_contexts 中的每个上下文进行比较。

请注意,此指标需要安装 rapidfuzz 包:pip install rapidfuzz

示例

from ragas import SingleTurnSample
from ragas.metrics import NonLLMContextPrecisionWithReference

context_precision = NonLLMContextPrecisionWithReference()

sample = SingleTurnSample(
    retrieved_contexts=["The Eiffel Tower is located in Paris."],
    reference_contexts=["Paris is the capital of France.", "The Eiffel Tower is one of the most famous landmarks in Paris."]
)

await context_precision.single_turn_ascore(sample)

输出

0.9999999999

基于 ID 的上下文精确率

IDBasedContextPrecision 通过比较检索到的上下文 ID 与参考上下文 ID,提供了一种直接高效的精确率测量方法。当您的文档有唯一的 ID 系统,并希望在不比较实际内容的情况下评估检索性能时,此指标尤其有用。

该指标使用 retrieved_context_ids 和 reference_context_ids 计算精确率,其值范围在 0 到 1 之间。值越高表示性能越好。它支持字符串和整数类型的 ID。

计算基于 ID 的上下文精确率的公式如下

\[ \text{基于 ID 的上下文精确率} = \frac{\text{在参考上下文 ID 中找到的检索上下文 ID 数量}}{\text{检索到的上下文 ID 总数}} \]

示例

from ragas import SingleTurnSample
from ragas.metrics import IDBasedContextPrecision

sample = SingleTurnSample(
    retrieved_context_ids=["doc_1", "doc_2", "doc_3", "doc_4"],
    reference_context_ids=["doc_1", "doc_4", "doc_5", "doc_6"]
)

id_precision = IDBasedContextPrecision()
await id_precision.single_turn_ascore(sample)

输出

0.5

在此示例中,在 4 个检索到的上下文 ID 中,只有 2 个("doc_1" 和 "doc_4")在参考上下文 ID 中找到,因此精确率分数为 0.5 或 50%。