Context Precision(上下文精确率)
Context Precision 是一项指标,用于评估检索器在给定查询下,将相关 chunk 排在无关 chunk 之前的能力。具体来说,它衡量检索到的上下文中,相关 chunk 被放在排序顶部的程度。
它计算为上下文中每个 chunk 的 precision@k 的均值。Precision@k 是排名 k 处相关 chunk 数量与排名 k 处 chunk 总数之比。
[ \text{Context Precision@K} = \frac{\sum_{k=1}^{K} \left( \text{Precision@k} \times v_k \right)}{\text{Total number of relevant items in the top } K \text{ results}} ]
[ \text{Precision@k} = {\text{true positives@k} \over (\text{true positives@k} + \text{false positives@k})} ]
其中 (K) 是 retrieved_contexts 中的 chunk 总数,(v_k \in {0, 1}) 是排名 (k) 处的相关性指示。
示例
Context Precision
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=[...]
)
Context Utilization
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
注意,即使无关 chunk 出现在数组的第二位,context precision 仍保持不变。然而,如果这个无关 chunk 被放到第一位,context precision 就会下降:
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
旧版 Metrics API
以下示例使用旧版 metrics API 模式。对于新项目,我们建议使用上文所示的 collections-based API。
弃用时间表
此 API 将在 0.4 版本中弃用,并在 1.0 版本中移除。请迁移到上文所示的 collections-based 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
无 reference 的 Context Precision
LLMContextPrecisionWithoutReference 指标可以在没有参考答案的情况下使用。为了估计检索到的上下文是否相关,此方法使用 LLM 将 retrieved_contexts 中的每个 chunk 与 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
有 reference 的 Context Precision
当你同时拥有检索到的上下文以及与 user_input 关联的参考回答时,可以使用 LLMContextPrecisionWithReference 指标。为了估计检索到的上下文是否相关,此方法使用 LLM 将 retrieved_contexts 中的每个 chunk 与 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 的 Context Precision
此指标使用非 LLM 方法(例如 Levenshtein distance measure)来判断检索到的上下文是否相关。
有 reference contexts 的 Context Precision
NonLLMContextPrecisionWithReference 指标适用于同时拥有检索上下文和参考上下文的 user_input 场景。为了判断检索到的上下文是否相关,此方法使用非 LLM 相似度度量,将 retrieved_contexts 中的每个检索上下文或 chunk 与 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 的 Context Precision
IDBasedContextPrecision 通过比较检索上下文的 ID 与参考上下文 ID,提供一种直接且高效的精确率度量方式。当你的文档有唯一 ID 体系,并希望在不比较实际内容的情况下评估检索性能时,此指标特别有用。
该指标使用 retrieved_context_ids 和 reference_context_ids 计算精确率,取值范围为 0 到 1。值越高表示性能越好。它同时支持字符串和整数 ID。
基于 ID 的 context precision 计算公式如下:
[ \text{ID-Based Context Precision} = \frac{\text{Number of retrieved context IDs found in reference context IDs}}{\text{Total number of retrieved context IDs}} ]
示例
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%。