跳转到内容

编写您自己的指标

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

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

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

# dataset
from datasets import load_dataset
from ragas import EvaluationDataset

amnesty_qa = load_dataset("vibrantlabsai/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 langchain_openai import ChatOpenAI
from ragas.embeddings import OpenAIEmbeddings
import openai

evaluator_llm = LangchainLLMWrapper(ChatOpenAI(model="gpt-4o"))
openai_client = openai.OpenAI()
evaluator_embeddings = OpenAIEmbeddings(client=openai_client)

安装 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 openai import OpenAI
from ragas.llms import llm_factory

openai_client = OpenAI(api_key="sk-...")
evaluator_llm = llm_factory("gpt-4o", client=openai_client)

方面评价器 - 简单标准评分

方面评价器 会为您提供的 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 来评估我的指标吗?如果是,则继承 MetricWithLLM 类,而不是 Metric 类。

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

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

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

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

\[ \text{幻觉} = 1 - \text{忠实度} \]
# 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()

输出

user_input retrieved_contexts response reference 幻觉指标 幻觉评分细则 幻觉二元值
0 美国最高法院...的全球影响是什么... [- 2022年,美国最高法院做出判决... 美国最高法院...的全球影响... 美国最高法院...的全球影响... 0.423077 3 0
1 哪些公司是全球温室气体...的主要贡献者... [近年来,人们日益认识到... 根据碳排放大户数据库,主要贡献者... 根据碳排放大户数据库,主要贡献者... 0.862069 3 0
2 美洲哪些私营公司是... [温室气体排放问题已成为... 根据碳排放大户数据库,最大的... 美洲最大的私营公司... 1.000000 3 0
3 大赦国际敦促其支持者采取什么行动... [在奥戈尼九人案中,大赦国际... 大赦国际敦促其支持者... 大赦国际敦促其支持者... 0.400000 3 0
4 大赦国际提出了哪些建议... [近年来,大赦国际一直关注... 大赦国际提出了几项建议... 大赦国际提出的建议... 0.952381 3 0

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