Mit watsonx die RAG-Pipeline mit Ragas in Python evaluieren

In diesem Tutorial verwenden wir das Ragas-Framework für die Retrieval-Augmented Generation (RAG)-Evaluierung in Python mit LangChain.

RAG ist eine Technik der Verarbeitung natürlicher Sprache (Natural Language Processing, NLP), die Information Retrieval und generative Modelle kombiniert, um genauere, relevantere und kontextuell bewusstere Antworten zu erhalten. Bei herkömmlichen Sprachgenerierungsaufgaben werden große Sprachmodelle (LLMs) wie GPT-4 (Generative Pre-trained Transformer) von OpenAI oder IBM® Granite Models verwendet, um auf der Grundlage eines Prompts Antworten zu erstellen. Gängige reale Anwendungsfall dieser großen Sprachmodelle sind Chatbots. Diese Modelle haben jedoch Schwierigkeiten, Antworten zu liefern, die kontextbezogen relevant, sachlich korrekt oder aktuell sind.

RAG-Anwendungen umgehen diese Einschränkung, indem sie einen Abrufschritt vor der Antwortgenerierung integrieren. Während der Abfrage werden zusätzliche Textfragmente, die für den Prompt relevant sind, aus einer Wissensdatenbank abgerufen, beispielsweise relevante Dokumente aus einem umfangreichen Textkorpus, der in der Regel in einer Vektordatenbank gespeichert ist. Schließlich wird ein LLM zum Generieren von Antworten verwendet, die auf dem ursprünglichen Prompt basieren und mit dem abgerufenen Kontext ergänzt werden.

Überblick über die RAG-Evaluierung

Es gibt viele verschiedene RAG-Bewertungsframeworks und Bewertungsmetriken. Neben Ragas gibt es noch weitere Frameworks, darunter Unitxt von IBM und Evals von OpenAI. Im Gegensatz zu den anderen Frameworks verwendet Ragas ein weiteres LLM-as-a-judge, um die Leistung einer RAG-Pipeline zu bewerten.

Es stehen mehrere Metriken zur Verfügung, um die Leistung unserer RAG-Pipeline zu messen. Die Metriken, die wir im Open-Source-Framework von Ragas verwenden werden, lassen sich in zwei Teile unterteilen:

  • Generationsbewertung                
    • Die Treue misst, ob alle generierten Antworten aus dem abgerufenen Kontext abgeleitet werden können.
    • Die Antwortrelevanz misst die Relevanz der generierten Antwort auf die Frage.
  • Auswertung des Abrufs   
    • Die Kontextpräzision misst die Rangfolge der relevanten Entitäten im Kontext, die auf der Basis von Fakten ermittelt wurden. Höhere Kontextpräzision bedeutet, dass relevante Elemente für die Bodenwahrheit höher eingestuft werden als „Rauschen“.
    • Kontextabruf misst, inwieweit die vom LLM generierten Antworten auf Benutzeranfragen im abgerufenen Kontext zu finden sind.

Diese Metriken sind als subjektive Näherungen dafür gedacht, wie gut eine RAG-Pipeline relevante Informationen aus ihrer Wissensbasis abruft, um eine Antwort zu formulieren. Es ist wichtig zu beachten, dass es kein Ideal für Daten, Prompts oder LLMs gibt. Selbst ein Kontext mit einer niedrigen Bewertung für context_relevance ist nicht zwangsläufig ein ungünstiger Kontext. Die niedrige Punktzahl kann auf ein gewisses Maß an „Rauschen“ oder weniger relevante Informationen zurückzuführen sein oder einfach darauf, dass die Aufgabe selbst mehrere Interpretationen zulässt. Lärm ist auch nicht unbedingt schlecht. Wir als Menschen erzeugen in unseren Antworten ein gewisses Maß an Rauschen und sind gleichzeitig bei der Beantwortung von Fragen verständlich.

Es gibt auch Verzerrungen, die die Bewertung einer RAG-Pipeline beeinflussen, wie beispielsweise die Präferenz für kürzere oder längere Antworten, auch bekannt als Längenverzerrung. Diese Art von Verzerrung kann dazu führen, dass eine Antwort aufgrund ihrer Länge und nicht aufgrund ihres Inhalts höher bewertet wird als eine andere.

Aus diesen Gründen empfiehlt es sich, mehrere Bewertungen durchzuführen. Diese Übung kann durchgeführt werden, indem die Promptvorlage, die Metriken, die Auswertungssequenz und vieles mehr geändert werden. Wenn Sie Ihren eigenen Datensatz für Ihre RAG-Pipeline erstellen, wird empfohlen, unterschiedliche Modelle für das LLM zur Generierung der Antworten und das LLM zur Bewertung der Antworten zu verwenden. Wenn für beide dasselbe Modell verwendet wird, besteht ein höheres Risiko für Verzerrungen bei der Selbstbewertung. Da diese Bewertungskriterien subjektiv sind, sollten die Ergebnisse dieser Rahmenwerke zusätzlich von menschlichen Gutachtern überprüft werden.

In diesem Tutorial erstellen wir kein RAG-System. Stattdessen verwenden wir Ragas, um die Ausgabe eines zuvor erstellten RAG-Systems auszuwerten. Weitere Informationen zum Aufbau Ihres RAG-Systems mit LangChain finden Sie in unserem ausführlichen RAG-Tutorial.

Voraussetzungen

Sie benötigen ein IBM® Cloud-Konto, um ein watsonx.ai-Projekt zu erstellen. Hier können Sie sich kostenlos registrieren.

Schritte

Schritt 1. Einrichten Ihrer Umgebung

Sie können zwar aus mehreren Tools wählen, aber dieses Tutorial führt Sie durch die Einrichtung eines IBM Kontos für die Verwendung eines Jupyter Notebook.

  1. Melden Sie sich bei watsonx.ai mit Ihrem IBM Cloud-Konto an.

  2. Erstellen Sie ein watsonx.ai-Projekt.

    Sie können Ihre Projekt-ID in Ihrem Projekt abrufen. Klicken Sie auf die Registerkarte Verwalten. Kopieren Sie anschließend die Projekt-ID aus dem Abschnitt Details auf der Seite Allgemein. Diese ID benötigen Sie für dieses Tutorial.
     

  3. Erstellen Sie ein Jupyter Notebook.

    Dieser Schritt öffnet eine Notebook-Umgebung, in der Sie den Code aus diesem Tutorial kopieren können, um eine eigene RAG-Auswertung durchzuführen. Alternativ können Sie dieses Notebook auf Ihr lokales System herunterladen und als Asset in Ihr watsonx.ai-Projekt hochladen. Weitere Granite-Tutorials finden Sie in der IBM Granite-Community. Dieses Jupyter Notebook ist auch auf GitHub verfügbar.

Schritt 2. Richten Sie eine watsonx.ai-Laufzeit-Instanz und einen API-Schlüssel ein

  1. Erstellen Sie eine watsonx.ai Runtime-Service-Instanz (wählen Sie Ihre entsprechende Region aus und wählen Sie den Lite-Plan, der eine kostenlose Instanz ist).

  2. Generieren Sie einen API-Schlüssel.

  3. Verknüpfen Sie die Instanz des watsonx.ai-Runtime-Service mit dem Projekt, das Sie in watsonx.ai erstellt haben.

Schritt 3. Installieren und importieren Sie relevante Bibliotheken und richten Sie Ihre Zugangsdaten ein.

Für dieses Tutorial benötigen wir einige Bibliotheken und Module. Stellen Sie sicher, dass Sie die aufgelisteten importieren, und wenn sie nicht installiert sind, behebt eine schnelle Pip-Installation das Problem. Dieses Tutorial wurde mit Python 3.11.9 erstellt.

#installations
%pip install -q langchain_community
%pip install -q "ragas==0.2.1"
%pip install -q langchain_ibm
%pip install -q ibm_watson_machine_learning
%pip install -q ibm_watsonx_ai
%pip install -q langchain_core
%pip install -q nltk import os

from langchain_community.llms import WatsonxLLM as _WatsonxLLM
from langchain_ibm import WatsonxEmbeddings
from langchain.callbacks.manager import CallbackManagerForLLMRun
from langchain.schema import LLMResult
from ragas import evaluate
from ragas.llms import LangchainLLMWrapper
from ragas.metrics import answer_relevancy, context_precision, context_recall, faithfulness
from typing import List, Optional, Any
from datasets import load_dataset
from ibm_watson_machine_learning.metanames import GenTextParamsMetaNames as GenParams
from ibm_watsonx_ai.foundation_models.utils.enums import EmbeddingTypes

Richten Sie Ihre Anmeldedaten ein. Eingabe Ihren API-Schlüssel und Ihre Projekt-ID als Zeichenfolgen ein. Verwenden Sie je nach Ihrer Provisioning Services Instanz eine der aufgeführten Regionen als Ihre watsonx-URL:

  • Dallas: https://us-south.ml.cloud.ibm.com
  • London: https://eu-gb.ml.cloud.ibm.com
  • Frankfurt: https://eu-de.ml.cloud.ibm.com
  • Tokio: https://jp-tok.ml.cloud.ibm.com
os.environ["WATSONX_APIKEY"] = <API_KEY>
os.environ["WATSONX_PROJECT_ID"] = <PROJECT_ID>
os.environ["WATSONX_URL"] = "https://us-south.ml.cloud.ibm.com"

Schritt 4. Laden des Datensatzes

Die Bewertung von Ragas erfordert einen Datensatz, der RAG-Pipeline-Ausführungen mehrerer verschiedener Prompts enthält. Zusätzlich zu den Fragen selbst muss der Datensatz die erwarteten Antworten, die als „Ground Truths“ bezeichnet werden, die vom LLM generierten Antworten und die Liste der Kontextelemente enthalten, die von der RAG-Pipeline bei der Beantwortung jeder Frage abgerufen wurden. Sie können Ihren eigenen End-to-End-Datensatz erstellen, aber für die Zwecke dieses Tutorials ist der Datensatz, den wir in diesem Tutorial verwenden, auf Hugging Face verfügbar. Laden wir den Datensatz.

amnesty_qa = load_dataset(“explodinggradients/amnesty_qa”, “english_v2”)
amnesty_qa

Ausgabe:

Repo card metadata block was not found. Setting CardData to empty.
DatasetDict({
    eval: Dataset({
        features: [‘question’, ‘ground_truth’, ‘answer’, ‘contexts’],
        num_rows: 20
    })
})

Die Daten werden als DatasetDict geladen und die Funktionen, die uns interessieren, liegen innerhalb der „eval“-Aufteilung.

dataset = amnesty_qa[“eval”]
dataset

Output:

Dataset({
    features: [‘question’, ‘ground_truth’, ‘answer’, ‘contexts’],
    num_rows: 20
})

Laden Sie nun die Daten in einen Pandas-Datenrahmen. Ein Beispiel für einen Eintrag in diesem Datensatz finden Sie in der HuggingFace-Dokumentation.

df = dataset.to_pandas()        

Datensätze für die RAG-Bewertung können auf verschiedene Arten erstellt werden. Ein wesentliches Element für die Erstellung dieses Datensatzes war die externe Wissensbasis, die einem LLM zur Verfügung gestellt wurde. Dieses Wissen kann aus einer gescrapten Webseite, einer einfachen Textdatei, einem importierten Dokument und vielem mehr gewonnen werden. In diesem Fall werden Berichte von Amnesty International verwendet. Der Inhalt des Datensatzes könnte durchgängig erstellt worden sein oder mithilfe eines Ansatzes zur Generierung synthetischer Daten, wie beispielsweise dem TestsetGenerator von Ragas. Die Verwendung von TestsetGenerator erfordert die geladenen Dokumente, einen Generator-LLM, einen Kritiker-LLM und ein Einbettungsmodell.

Der End-to-End-Ansatz umfasst wiederum mehrere Schritte. Nehmen wir an, dass dieser Ansatz für die Erstellung dieses Datensatzes gewählt wurde. Dies bedeutet, dass entweder ein LLM oder ein menschlicher Benutzer die in der Spalte „Fragen” gespeicherten Fragen generiert hat. Um die Ground Truths für jede Frage zu generieren, kann der Benutzer diese manuell erstellt oder mithilfe eines LLM mit der entsprechenden Prompt-Vorlage generiert haben. Diese Antworten werden als ideale Antworten angesehen und in der Spalte „ground_truth“ gespeichert. Zuletzt wurde eine RAG-Pipeline verwendet, um die Antworten zu generieren, die in der Antwortspalte angezeigt werden. Beim Aufbau der RAG-Pipeline wurde die externe Wissensbasis vektorisiert. Bei der Abfrage des RAG-Systems wurden dann die relevanten Textabschnitte, die das LLM zur Generierung der einzelnen Antworten verwendet hatte, mithilfe eines Ähnlichkeitsalgorithmus wie dem Top-k-Retrieval-Algorithmus aus dem Vektorspeicher abgerufen. Diese Datensätze wurden in der Spalte „Kontext“ gespeichert.

Schritt 5. Legen Sie die Modelle für die Bewertung und das Einbetten fest

In diesem Tutorial verwenden wir ein IBM Granite-Modell als Beurteilung.

Ragas verwendet standardmäßig Open KI-Modelle. WatsonxLLM: Der Wrapper für IBM watsonx.ai Foundation Models. Ein Ragas-kompatibler watsonxLLM-Wrapper ist derzeit in Arbeit und nicht verfügbar. Um Ragas mit den Granite-Modellen verwenden zu können, müssen wir die Eigenschaften des Wrappers ändern.

class WatsonxLLM(_WatsonxLLM):
    temperature: float = 0.05
    “””
    A workaround for interface incompatibility: Ragas expected all LLMs to
    have a `temperature` property whereas WatsonxLLM does not define it.
    “””

    def _generate(
        self,
        prompts: List[str],
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        stream: Optional[bool] = None,
        **kwargs: Any,
    ) -> LLMResult:
        “””
        A workaround for interface incompatibility: Ragas expected the
        `token_usage` property of the LLM result be of a particular shape.
        WatsonX returns it in a slightly different shape.
        “””
        result: LLMResult = super()._generate(prompts, stop, run_manager, stream, **kwargs)
        if not result.llm_output or “token_usage” not in result.llm_output:
            return result
        usage = result.llm_output[“token_usage”]
        if not isinstance(usage, dict):
            return result
        result.llm_output[“token_usage”] = {
            “prompt_tokens”: usage[“input_token_count”],
            “completion_tokens”: usage[“generated_token_count”],
            “total_tokens”: usage[“input_token_count”] + usage[“generated_token_count”],
        }
    return result

Für dieses Tutorial empfehlen wir die Verwendung des IBM Granite-3.0-8B-Instruct-Modell als LLM, um ähnliche Ergebnisse zu erzielen. Es steht Ihnen frei, ein beliebiges KI-Modell Ihrer Wahl zum Vergleich mit diesem Benchmark zu verwenden und das für Ihre Anwendung am besten geeignete auszuwählen. Die über watsonx.ai verfügbaren Foundation Models finden Sie hier. Der Zweck dieser Modelle in LLM-Anwendungen besteht darin, als Entscheidungsmaschine zu fungieren, die festlegt, welche Maßnahmen zu ergreifen und welche Antworten zu geben sind. Um den WatsonxLLM-Wrapper mit Ragas zu verwenden, ist es erforderlich, einen LangchainLLMWrapper einzusetzen.

watsonx_llm = LangchainLLMWrapper(
    langchain_llm = WatsonxLLM(
        model_id = “ibm/granite-3-8b-instruct”,
        url = os.getenv(“WATSONX_URL”),
        apikey = os.getenv(“WATSONX_APIKEY”),
        project_id = os.getenv(“WATSONX_PROJECT_ID”),
        params = {
            GenParams.MAX_NEW_TOKENS: 200,
            GenParams.MIN_NEW_TOKENS: 1,
            GenParams.STOP_SEQUENCES: [“<|endoftext|>“],
            GenParams.TEMPERATURE: 0.2,
            GenParams.TOP_K: 50,
            GenParams.TOP_P: 1,
        }
    )
)

Als Bewertungsmodell kommt das Granite-Modell zum Einsatz. Wir werden kein Modell zum Generieren von Antworten verwenden, da die Antworten bereits im Datensatz gespeichert sind.

Das von uns verwendete Einbettungsmodell ist ein IBM Slate-Modell über einen watsonx.ai LangChain-Wrapper. Wenn kein Einbettungsmodell definiert ist, verwendet Ragas standardmäßig OpenAI-Einbettungen. Das Einbettungsmodell ist für die Auswertung unerlässlich, da es dazu dient, die Daten aus den einzelnen Spalten einzubetten und den Abstand zwischen ihnen zu messen.

watsonx_embeddings = WatsonxEmbeddings(
    model_id = EmbeddingTypes.IBM_SLATE_30M_ENG.value,
    url = os.getenv(“WATSONX_URL”),
    apikey = os.getenv(“WATSONX_APIKEY”),
    project_id = os.getenv(“WATSONX_PROJECT_ID”)
)

Schritt 6. Generieren einer Bewertung mit Ragas

Schließlich können wir nun die Ragas-Auswertung für den Datensatz durchführen. Hier übergeben wir den Datensatz, die Metriken zur Auswertung, das LLM und das Einbetten als Parameter.

Wenn Warnmeldungen erscheinen, ignorieren Sie diese, lassen Sie die Auswertung abschließen und drucken Sie das Ergebnis wie gezeigt aus.

result = evaluate(
    amnesty_qa[“eval”],
    metrics=[
        context_precision,
        faithfulness,
        answer_relevancy,
        context_recall,
    ],
    llm=watsonx_llm,
    embeddings=watsonx_embeddings)
print(result)

Ausgabe:

{‘context_precision’: 0.9444, ‘faithfulness’: 0.6000, ‘answer_relevancy’: 0.6917, ‘context_recall’: 0.8333}

Und das war’s. Eine Evaluierung der RAG-Pipeline wurde abgeschlossen. Wie bereits erwähnt, können Sie mehrere Bewertungen durchführen, verschiedene Modelle ausprobieren und Parameter ändern. Je mehr Bewertungen durchgeführt werden, desto umfassender können wir die Genauigkeit und Effektivität eines LLM-Systems unter Verwendung von RAG beurteilen.

Zusammenfassung 

In diesem Tutorial haben Sie Ragas zur Bewertung Ihrer RAG-Pipeline eingesetzt. Ihre Ausgabe umfasste die Metriken context_ Precision , Treue , Answer_relevancy und Context_recall . Das zur Bewertung verwendete LLM war ein IBM Granite-Modell und das verwendete Einbetten-Modell war ein IBM Slate-Modell, auf das über die watsonx.ai-Einbettungs-API zugegriffen wurde.

Die durchgeführte Bewertung ist wichtig, da sie auf zukünftige generative KI-Workflows angewendet werden kann, um die Leistung Ihrer RAG-Systeme zu bewerten und zu verbessern.

Wir empfehlen Ihnen, die Ragas-Dokumentationsseite zu besuchen, um weitere Informationen zu den Metriken und dem Bewertungsprozess zu erhalten.

Weiterführende Lösungen
IBM watsonx.ai

Trainieren, validieren, optimieren und implementieren Sie generative KI, Foundation Models und maschinelle Lernfunktionen mit IBM watsonx.ai, einem Studio der nächsten Generation für AI Builder in Unternehmen. Erstellen Sie KI-Anwendungen mit einem Bruchteil der Zeit und Daten.

Entdecken sie watsonx.ai
Lösungen im Bereich künstlicher Intelligenz

Setzen Sie KI in Ihrem Unternehmen ein – mit branchenführendem Fachwissen im Bereich KI und dem Lösungsportfolio von IBM an Ihrer Seite.

Erkunden Sie KI-Lösungen
KI-Services

Erfinden Sie kritische Workflows und Abläufe neu, indem Sie KI einsetzen, um Erfahrungen, Entscheidungsfindung in Echtzeit und den geschäftlichen Nutzen zu maximieren.

KI-Services entdecken
Machen Sie den nächsten Schritt

Profitieren Sie von einem einheitlichen Zugriff auf Funktionen, die den gesamten Lebenszyklus der KI-Entwicklung abdecken. Erstellen Sie leistungsstarke KI-Lösungen mit benutzerfreundlichen Oberflächen, Workflows und Zugriff auf branchenübliche APIs und SDKs.

watsonx.ai erkunden Buchen Sie eine Live-Demo