跳过内容

编写自己的指标

虽然 Ragas 内置了许多指标,但您可能需要为您的用例创建自定义指标。本指南将帮助您实现这一目标。

为了本教程的目的,我们假设要构建一个自定义指标来衡量 LLM 应用中的幻觉。虽然我们有一个内置的 Faithfulness 指标,它相似但不完全相同。Faithfulness 衡量生成答案与给定上下文的事实一致性,而 Hallucinations 衡量生成答案中是否存在幻觉。

在我们开始之前,让我们加载数据集并定义 LLM

# dataset
from datasets import load_dataset
from ragas import EvaluationDataset

amnesty_qa = load_dataset("explodinggradients/amnesty_qa", "english_v3")
eval_dataset = EvaluationDataset.from_hf_dataset(amnesty_qa["eval"])
eval_dataset
EvaluationDataset(features=['user_input', 'retrieved_contexts', 'response', 'reference'], len=20)

安装 langchain-openai 软件包

pip install langchain-openai

确保您已准备好 OpenAI 密钥并在您的环境中可用。

import os
os.environ["OPENAI_API_KEY"] = "your-openai-key"
将 LLM 封装在 LangchainLLMWrapper 中,以便与 ragas 一起使用。

from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper
from langchain_openai import ChatOpenAI
from langchain_openai import OpenAIEmbeddings
evaluator_llm = LangchainLLMWrapper(ChatOpenAI(model="gpt-4o"))
evaluator_embeddings = LangchainEmbeddingsWrapper(OpenAIEmbeddings())

安装 langchain-aws 软件包

pip install langchain-aws

然后您必须设置您的 AWS 凭据和配置

config = {
    "credentials_profile_name": "your-profile-name",  # E.g "default"
    "region_name": "your-region-name",  # E.g. "us-east-1"
    "llm": "your-llm-model-id",  # E.g "anthropic.claude-3-5-sonnet-20241022-v2:0"
    "embeddings": "your-embedding-model-id",  # E.g "amazon.titan-embed-text-v2:0"
    "temperature": 0.4,
}

定义您的 LLM 并将其封装在 LangchainLLMWrapper 中,以便与 ragas 一起使用。

from langchain_aws import ChatBedrockConverse
from langchain_aws import BedrockEmbeddings
from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper

evaluator_llm = LangchainLLMWrapper(ChatBedrockConverse(
    credentials_profile_name=config["credentials_profile_name"],
    region_name=config["region_name"],
    base_url=f"https://bedrock-runtime.{config['region_name']}.amazonaws.com",
    model=config["llm"],
    temperature=config["temperature"],
))
evaluator_embeddings = LangchainEmbeddingsWrapper(BedrockEmbeddings(
    credentials_profile_name=config["credentials_profile_name"],
    region_name=config["region_name"],
    model_id=config["embeddings"],
))

如果您想了解如何使用其他 AWS 服务,请参阅 langchain-aws 文档。

Google 提供两种方式来访问其模型:Google AI Studio 和 Google Cloud Vertex AI。Google AI Studio 只需要 Google 账户和 API 密钥,而 Vertex AI 需要 Google Cloud 账户。如果您刚开始使用,请使用 Google AI Studio。

首先,安装所需的软件包(仅安装您根据 API 选择所需的软件包)

# for Google AI Studio
pip install langchain-google-genai
# for Google Cloud Vertex AI
pip install langchain-google-vertexai

然后根据您选择的 API 设置您的凭据

对于 Google AI Studio

import os
os.environ["GOOGLE_API_KEY"] = "your-google-ai-key"  # From https://ai.google.dev/

对于 Google Cloud Vertex AI

# Ensure you have credentials configured (gcloud, workload identity, etc.)
# Or set service account JSON path:
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "path/to/service-account.json"

定义您的配置

config = {
    "model": "gemini-1.5-pro",  # or other model IDs
    "temperature": 0.4,
    "max_tokens": None,
    "top_p": 0.8,
    # For Vertex AI only:
    "project": "your-project-id",  # Required for Vertex AI
    "location": "us-central1",     # Required for Vertex AI
}

初始化 LLM 并将其封装以与 ragas 一起使用

from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper

# Choose the appropriate import based on your API:
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_google_vertexai import ChatVertexAI

# Initialize with Google AI Studio
evaluator_llm = LangchainLLMWrapper(ChatGoogleGenerativeAI(
    model=config["model"],
    temperature=config["temperature"],
    max_tokens=config["max_tokens"],
    top_p=config["top_p"],
))

# Or initialize with Vertex AI
evaluator_llm = LangchainLLMWrapper(ChatVertexAI(
    model=config["model"],
    temperature=config["temperature"],
    max_tokens=config["max_tokens"],
    top_p=config["top_p"],
    project=config["project"],
    location=config["location"],
))

您可以选择配置安全设置

from langchain_google_genai import HarmCategory, HarmBlockThreshold

safety_settings = {
    HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_NONE,
    # Add other safety settings as needed
}

# Apply to your LLM initialization
evaluator_llm = LangchainLLMWrapper(ChatGoogleGenerativeAI(
    model=config["model"],
    temperature=config["temperature"],
    safety_settings=safety_settings,
))

初始化嵌入并将其封装以与 ragas 一起使用(选择以下之一)

# Google AI Studio Embeddings
from langchain_google_genai import GoogleGenerativeAIEmbeddings

evaluator_embeddings = LangchainEmbeddingsWrapper(GoogleGenerativeAIEmbeddings(
    model="models/embedding-001",  # Google's text embedding model
    task_type="retrieval_document"  # Optional: specify the task type
))
# Vertex AI Embeddings
from langchain_google_vertexai import VertexAIEmbeddings

evaluator_embeddings = LangchainEmbeddingsWrapper(VertexAIEmbeddings(
    model_name="textembedding-gecko@001",  # or other available model
    project=config["project"],  # Your GCP project ID
    location=config["location"]  # Your GCP location
))

有关可用模型、功能和配置的更多信息,请参阅:Google AI Studio 文档Google Cloud Vertex AI 文档LangChain Google AI 集成LangChain Vertex AI 集成

安装 langchain-openai 软件包

pip install langchain-openai

确保您已准备好 Azure OpenAI 密钥并在您的环境中可用。

import os
os.environ["AZURE_OPENAI_API_KEY"] = "your-azure-openai-key"

# other configuration
azure_config = {
    "base_url": "",  # your endpoint
    "model_deployment": "",  # your model deployment name
    "model_name": "",  # your model name
    "embedding_deployment": "",  # your embedding deployment name
    "embedding_name": "",  # your embedding name
}

定义您的 LLM 并将其封装在 LangchainLLMWrapper 中,以便与 ragas 一起使用。

from langchain_openai import AzureChatOpenAI
from langchain_openai import AzureOpenAIEmbeddings
from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper
evaluator_llm = LangchainLLMWrapper(AzureChatOpenAI(
    openai_api_version="2023-05-15",
    azure_endpoint=azure_config["base_url"],
    azure_deployment=azure_config["model_deployment"],
    model=azure_config["model_name"],
    validate_base_url=False,
))

# init the embeddings for answer_relevancy, answer_correctness and answer_similarity
evaluator_embeddings = LangchainEmbeddingsWrapper(AzureOpenAIEmbeddings(
    openai_api_version="2023-05-15",
    azure_endpoint=azure_config["base_url"],
    azure_deployment=azure_config["embedding_deployment"],
    model=azure_config["embedding_name"],
))

如果您想了解如何使用其他 Azure 服务,请参阅 langchain-azure 文档。

如果您使用不同的 LLM 提供商并通过 Langchain 与其交互,您可以将您的 LLM 封装在 LangchainLLMWrapper 中,以便与 ragas 一起使用。

from ragas.llms import LangchainLLMWrapper
evaluator_llm = LangchainLLMWrapper(your_llm_instance)

如需更详细的指南,请查阅自定义模型指南

如果您使用 LlamaIndex,您可以使用 LlamaIndexLLMWrapper 将您的 LLM 封装起来,以便与 ragas 一起使用。

from ragas.llms import LlamaIndexLLMWrapper
evaluator_llm = LlamaIndexLLMWrapper(your_llm_instance)

有关如何使用 LlamaIndex 的更多信息,请参阅LlamaIndex 集成指南

如果您仍然无法将 Ragas 与您喜欢的 LLM 提供商一起使用,请在此问题上留言告知我们,我们将为其添加支持 🙂。

from ragas.llms import llm_factory

evaluator_llm = llm_factory("gpt-4o")

方面评估 - 简单标准评分

Aspect Critic 会根据您提供的 definition 输出一个二进制分数。一个简单的通过/失败指标可以为衡量目标带来清晰度和重点,并且比从头构建更复杂的指标更好地分配精力,尤其是在刚开始时。

查阅这些资源,了解更多关于拥有简单通过/失败指标的有效性

现在,让我们使用 Ragas 创建一个简单的通过/失败指标来衡量数据集中的幻觉。

from ragas.metrics import AspectCritic

# you can init the metric with the evaluator llm
hallucinations_binary = AspectCritic(
    name="hallucinations_binary",
    definition="Did the model hallucinate or add any information that was not present in the retrieved context?",
    llm=evaluator_llm,
)

await hallucinations_binary.single_turn_ascore(eval_dataset[0])
输出
0

领域特定指标或基于评分标准的指标

这里我们将构建一个基于评分标准的指标,该指标根据我们提供的评分标准以 1 到 5 的等级评估数据。您可以在此处阅读有关基于评分标准的指标的更多信息

对于我们构建幻觉指标的示例,我们将使用以下评分标准

rubric = {
    "score1_description": "There is no hallucination in the response. All the information in the response is present in the retrieved context.",
    "score2_description": "There are no factual statements that are not present in the retrieved context but the response is not fully accurate and lacks important details.",
    "score3_description": "There are many factual statements that are not present in the retrieved context.",
    "score4_description": "The response contains some factual errors and lacks important details.",
    "score5_description": "The model adds new information and statements that contradict the retrieved context.",
}

现在,让我们使用评分标准和评估器 LLM 初始化指标并评估数据集。

from ragas.metrics import RubricsScore

hallucinations_rubric = RubricsScore(
    name="hallucinations_rubric", llm=evaluator_llm, rubrics=rubric
)

await hallucinations_rubric.single_turn_ascore(eval_dataset[0])
输出
3

自定义指标

如果您的用例不属于这两类,您可以通过继承 Ragas 中的基础 Metric 类来构建自定义指标,但在那之前您必须问自己以下问题

  1. 我是否正在尝试构建单轮或多轮指标?如果是,则根据您评估的是单轮还是多轮交互来继承 Metric 类以及 SingleTurnMetricMultiTurnMetric

  2. 我是否需要使用 LLM 来评估我的指标?如果是,则不继承 Metric 类,而是继承 MetricWithLLM 类。

  3. 我是否需要使用嵌入来评估我的指标?如果是,则不继承 Metric 类,而是继承 MetricWithEmbeddings 类。

  4. 我是否需要同时使用 LLM 和嵌入来评估我的指标?如果是,则同时继承 MetricWithLLM 和 MetricWithEmbeddings 类。

对于我们的示例,我们需要使用 LLM 来评估我们的指标,因此我们将继承 MetricWithLLM 类;并且我们目前只处理单轮交互,因此我们将继承 SingleTurnMetric 类。

至于实现,我们将使用 Faithfulness 指标来评估我们的指标,并使用以下公式衡量幻觉

\[ \text{幻觉} = 1 - \text{Faithfulness} \]
# we are going to create a dataclass that subclasses `MetricWithLLM` and `SingleTurnMetric`
from dataclasses import dataclass, field

# import the base classes
from ragas.metrics.base import MetricWithLLM, SingleTurnMetric, MetricType
from ragas.metrics import Faithfulness

# import types
import typing as t
from ragas.callbacks import Callbacks
from ragas.dataset_schema import SingleTurnSample


@dataclass
class HallucinationsMetric(MetricWithLLM, SingleTurnMetric):
    # name of the metric
    name: str = "hallucinations_metric"
    # we need to define the required columns for the metric
    _required_columns: t.Dict[MetricType, t.Set[str]] = field(
        default_factory=lambda: {
            MetricType.SINGLE_TURN: {"user_input", "response", "retrieved_contexts"}
        }
    )

    def __post_init__(self):
        # init the faithfulness metric
        self.faithfulness_metric = Faithfulness(llm=self.llm)

    async def _single_turn_ascore(
        self, sample: SingleTurnSample, callbacks: Callbacks
    ) -> float:
        faithfulness_score = await self.faithfulness_metric.single_turn_ascore(
            sample, callbacks
        )
        return 1 - faithfulness_score
hallucinations_metric = HallucinationsMetric(llm=evaluator_llm)

await hallucinations_metric.single_turn_ascore(eval_dataset[0])

输出

0.5

现在,让我们使用我们创建的指标评估整个数据集。

from ragas import evaluate

results = evaluate(
    eval_dataset,
    metrics=[hallucinations_metric, hallucinations_rubric, hallucinations_binary],
)

Output
{'hallucinations_metric': 0.5932, 'hallucinations_rubric': 3.1500, 'hallucinations_binary': 0.1000}
```python
results_df = results.to_pandas()
results_df.head()

输出

用户输入 检索到的上下文 响应 参考 幻觉指标 幻觉评分标准 幻觉二进制
0 美国最高法院的全球影响是... [- 2022 年,美国最高法院下达了... 美国最高法院的全球影响... 美国最高法院的全球影响... 0.423077 3 0
1 哪些公司是全球主要的贡献者... [近年来,有越来越多的压力... 根据 Carbon Majors 数据库,主要... 根据 Carbon Majors 数据库,主要... 0.862069 3 0
2 美洲地区哪些私营公司是... [温室气体排放问题已成为... 根据 Carbon Majors 数据库,最大... 美洲地区最大的私营公司... 1.000000 3 0
3 大赦国际敦促其支持者采取了什么行动... [在 Ogoni 9 一案中,大赦国际... 大赦国际敦促其支持者... 大赦国际敦促其支持者... 0.400000 3 0
4 大赦国际提出了哪些建议... [近年来,大赦国际一直专注于... 大赦国际提出了几项建议... 大赦国际提出的建议... 0.952381 3 0

如果您想了解更多关于如何构建自定义指标的信息,您可以阅读自定义指标高级指南