LLM-Agentenorchestrierung: Schritt-für-Schritt-Anleitung mit LangChain und Granite

Autor

Vrunda Gadesha

AI Advocate | Technical Content Author

LLM-Agenten-Orchestrierung ist der Prozess der Verwaltung und Koordination der Interaktionen zwischen einem Large Language Model (LLM) und verschiedenen Tools, APIs oder Prozessen zur Ausführung komplexer Aufgaben innerhalb von KI-Systemen. Dabei geht es um die Strukturierung von Workflows, bei denen ein KI-Agent, der von künstlicher Intelligenz unterstützt wird, als zentraler Entscheidungsträger oder Reasoning Engine fungiert und seine Aktionen auf der Grundlage von Eingaben, Kontext und Ausgaben externer Systeme orchestriert. Mithilfe eines Frameworks können LLMs nahtlos in APIs, Datenbanken und andere KI-Anwendungen integriert werden, wodurch Funktionen wie Chatbots und Automatisierung ermöglicht werden. Open-Source-Agenten-Frameworks verbessern die Anpassungsfähigkeit dieser Systeme weiter und machen LLMs in realen Szenarien effektiver.

Viele Menschen missverstehen den Unterschied zwischen LLM-Orchestrierung und LLM-Agenten-Orchestrierung. Die folgende Abbildung verdeutlicht die wichtigsten Unterschiede:

Diagramm mit dem wichtigsten Unterschied zwischen LLM-Orchestrierung und LLM-Agenten-Orchestrierung Wichtigster Unterschied zwischen LLM-Orchestrierung und LLM-Agenten-Orchestrierung

In diesem Tutorial lernen Sie, wie Sie mithilfe von IBM Granite-Modellen und LangChain einen autonomen Agenten erstellen, der auf Large Language Models (LLMs) basiert. Wir werden erkunden, wie Agenten Schlüsselkomponenten wie Gedächtnis, Planung und Maßnahmen nutzen, um intelligente Aufgaben auszuführen. Außerdem implementieren Sie ein praktisches System, das Text aus einem Buch verarbeitet, Abfragen dynamisch beantwortet und seine Leistung anhand von Metriken wie BLEU, Präzision, Rückruf und F1-Score bewertet.

Framework für LLM-basierte autonome Agenten

Das in Abbildung 1 dargestellte Framework bietet ein ganzheitliches Design für autonome Agenten, die auf Large Language Models (LLM) basieren, und betont das Zusammenspiel der wichtigsten Komponenten: Profil, Gedächtnis, Planung und Aktion. Jede Komponente steht für eine entscheidende Phase beim Aufbau eines autonomen Agenten, der zu Reasoning, Entscheidungsfindung und zur Interaktion mit dynamischen Umgebungen fähig ist.1

Framework für LLM-basierte autonome Agenten Framework für LLM-basierte autonome Agenten

1. Profil: Definition der Identität des Agenten

Das Profil verleiht dem Agenten seine Identität, indem es Informationen wie demografische Daten, Persönlichkeitsmerkmale und sozialen Kontext einbettet. Dieser Prozess gewährleistet, dass der Agent auf personalisierte Weise interagieren kann. Profile können manuell erstellt, mit KI-Modellen wie IBM Granite-Modellen oder dem GPT (Generative Pretrained Transformer) von OpenAI generiert oder mit bestimmten Datensätzen abgeglichen werden, um die Aufgabenanforderungen zu erfüllen. Durch die Nutzung von Prompt Engineering können Profile dynamisch verfeinert werden, um die Antworten zu optimieren. Darüber hinaus hilft das Profil innerhalb der Multiagenten-Orchestrierung bei der Definition von Rollen und Verhaltensweisen und gewährleistet eine nahtlose Koordination zwischen KI-Algorithmen und Systemen zur Entscheidungsfindung.

2. Gedächtnis: Speichern und Verwenden von Kontext

Der Speicher hilft dem Agenten, vergangene Interaktionen zu behalten und abzurufen, und ermöglicht so kontextbezogene Antworten. Er kann einheitlich (alle Daten an einem Ort) oder hybrid (strukturiert und unstrukturiert) sein. Vorgänge wie Lesen, Schreiben und Reflexion ermöglichen es dem Agenten, aus Erfahrung zu lernen und einheitliche, fundierte Ausgaben zu liefern. Ein gut strukturierter Speicher verbessert die Multi-Agenten-Orchestrierung, indem er sicherstellt, dass verschiedene Agenten, einschließlich spezialisierter Agenten, die für eine bestimmte Aufgabe entwickelt wurden, relevante Daten effizient teilen und abrufen können. In Frameworks wie AutoGen und Crew KI spielt dar Speicher eine entscheidende Rolle bei der Aufrechterhaltung der Kontinuität innerhalb des Ökosystems der zusammenarbeitenden Agenten, wodurch eine reibungslose Koordination und eine optimierte Aufgabenausführung gewährleistet werden.

3. Planung: Strategische Maßnahmen

Mit der Planungskomponente kann der Agent Strategien zur Zielerreichung entwickeln. Er kann vordefinierten Schritten folgen oder sich dynamisch an das Feedback der Umgebung, des Menschen oder des LLM selbst anpassen. Durch die Integration von KI-Algorithmen und die Nutzung einer Wissensdatenbank kann die Planung optimiert werden, um die Effizienz des Reasoning und die Genauigkeit der Problemlösung zu verbessern. Bei LLM-Anwendungen spielt die Planung eine entscheidende Rolle, wenn es darum geht, sicherzustellen, dass das natürliche Sprachverständnis und die Entscheidungsfindung mit den Zielen des Agenten in Einklang stehen. Darüber hinaus verbessern Retrieval-Augmented-Techniken die Fähigkeit des Agenten, dynamisch auf relevante Informationen zuzugreifen und so die Antwortgenauigkeit zu verbessern. Diese Flexibilität stellt sicher, dass der Agent auch bei sich ändernden Szenarien effektiv bleibt. Dies gilt insbesondere bei der Multi-Agenten-Orchestrierung, bei der verschiedene Agenten ihre Pläne koordinieren, um komplexe Ziele zu erreichen und gleichzeitig die Skalierbarkeit für die Bewältigung großer und vielfältiger Aufgaben aufrechtzuerhalten.

4. Aktion: Ausführung von Entscheidungen

Der Agent interagiert mit der Welt in Form von Aktionen, sei es durch das Erledigen von Aufgaben, das Sammeln von Informationen oder durch Kommunikation. Er nutzt Gedächtnis und Planung zur Steuerung der Ausführung, setzt bei Bedarf Tools ein und passt seinen internen Zustand auf der Grundlage der Ergebnisse an, um sich kontinuierlich zu verbessern. Die Optimierung des Algorithmus für die Ausführung der Maßnahmen sorgt für Effizienz, insbesondere bei der Integration von GPT-gestützten Reasoning-Modellen und generativen KI-Techniken zur Entscheidungsfindung in Echtzeit.

Durch die Kombination dieser Komponenten verwandelt das Framework LLMs in anpassungsfähige Agenten, die in der Lage sind, autonom zu denken, zu lernen und Aufgaben auszuführen. Durch seinen modularen Aufbau ist es ideal für Anwendungen wie Kundenservice, Forschungsunterstützung und kreative Problemlösung.

Anwendungsfall: Aufbau eines abfragbaren Wissensagenten

In diesem Tutorial wird die Erstellung eines abfragefähigen Wissensagenten gezeigt, der darauf ausgelegt ist, große Textdokumente (wie Bücher) zu verarbeiten und Benutzeranfragen korrekt zu beantworten. Unter Verwendung von IBM Granite-Modellen und LangChain wird der Agent nach den Prinzipien gebaut, die im Framework für LLM-basierte autonome Agenten beschrieben sind. Die Komponenten des Frameworks fügen sich nahtlos in den Workflow des Agenten ein, um Anpassungsfähigkeit und intelligente Antworten zu gewährleisten.

Sehen wir uns an, wie das Framework in unserem Anwendungsfall angewendet wird.

Anwendung des Frameworks Anwendung des Frameworks

Profil: Der Agent ist mit einem „Wissensassistenten“-Profil konzipiert, das sich auf Zusammenfassungen, die Beantwortung von Fragen und Argumentationsaufgaben konzentriert. Sein Kontext ist personalisiert, um ein bestimmtes Dokument zu verarbeiten (z. B. Die Abenteuer des Sherlock Holmes).

Speicher: Der Agent nutzt einen hybriden Speicher, indem er Teile des Buches in einen FAISS-Vektorspeicher einbettet. Diese Fähigkeit ermöglicht es, relevanten Kontext dynamisch während Abfragen abzurufen. Speicheroperationen wie Lesen (Abrufen) und Schreiben (Aktualisieren von Einbettungen) stellen sicher, dass sich der Agent im Laufe der Zeit an neue Abfragen anpassen kann.

Planung: Die Lösung von Anfragen erfolgt über Single-Path-Reasoning. Der Agent ruft relevante Textabschnitte ab, generiert Antworten mithilfe das LLM Granite von IBM und prüft die Ausgabe auf Korrektheit. Eine Planung ohne Feedback sorgt für Einfachheit, während die Modularität des Systems die Integration von Feedbackschleifen in zukünftige Iterationen ermöglicht.

Aktion: Der Agent führt die Lösung von Anfragen aus, indem er Speicherabruf und LLM-Verarbeitung integriert. Er erledigt Aufgaben wie das Generieren von Antworten, das Berechnen von Metriken (BLEU, Präzision, Rückruf und F1-Score) und das Visualisieren von Ergebnissen für die Interpretation durch den Benutzer. Diese Ausgaben spiegeln die Funktion des Agenten wider, auf der Grundlage von Reasoning und Planung intelligent zu handeln.

Voraussetzungen

Sie benötigen ein IBM Cloud-Konto, um ein watsonx.ai-Projekt zu erstellen.

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 mit Ihrem IBM Cloud-Konto bei watsonx.ai an.
  2. 2. Erstellen Sie ein watsonx.ai-Projekt. Sie können Ihre Projekt-ID in Ihrem Projekt abrufen. Klicken Sie auf die Registerkarte Verwalten. Dann kopieren Sie die Projekt-ID aus dem Abschnitt Details der Seite Allgemein. Sie benötigen diese ID für dieses Tutorial.
  3. 3. Erstellen Sie ein Jupyter Notebook.

Dieser Schritt öffnet eine Notebook-Umgebung, in die Sie den Code aus diesem Tutorial kopieren können. 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 Tutorial ist auch auf GitHub verfügbar.

Schritt 2. Einrichtung von watsonx.ai Runtime Service und API-Schlüssel

  1. Erstellen Sie eine Instanz des watsonx.ai Runtime Service (wählen Sie den Lite-Plan als kostenlose Instanz).
  2. Generieren Sie einen Schlüssel für eine Programmierschnittstelle (API).
  3. Verknüpfen Sie den watsonx.ai Runtime Service mit dem Projekt, das Sie in watsonx.ai erstellt haben.

Schritt 3. Installation der Pakete

Um mit dem LangChain-Framework zu arbeiten und IBM WatsonxLLM zu integrieren, müssen wir einige wichtige Bibliotheken installieren. Beginnen wir mit der Installation der erforderlichen Pakete:

Hinweis: Wenn Sie eine alte Version vonpip , Sie können folgenden Befehl verwenden:pip install --upgrade pip , um ein Upgrade durchzuführen, um die neuesten Pakete einfach zu installieren, die möglicherweise nicht mit älteren Versionen kompatibel sind. Wenn Sie jedoch bereits die neueste Version verwenden oder Ihre Pakete kürzlich aktualisiert haben, können Sie diesen Befehl überspringen.

!pip install --upgrade pip
!pip install langchain faiss-cpu pandas sentence-transformers
%pip install langchain
!pip install langchain-ibm

In der vorhergehenden Codezelle ist

  • LangChain  das Kern-Framework für die Erstellung von Anwendungen mit Sprachmodellen.
  • faiss-cpu  dient der effizienten Ähnlichkeitssuche, die beim Erstellen und Abfragen von Vektorindizes verwendet wird.
  • pandas  dient der Datenmanipulation und -analyse.
  • sentence-transformers  dient dazu, Einbettungen für die semantische Suche zu generieren.
  • langchain-ibm  dient der Integration von IBM watsonxLLM (in diesem Tutorial granite-3-8b-instruct) mit LangChain.

Dieser Schritt stellt sicher, dass Ihre Umgebung für die anstehenden Aufgaben bereit ist.

Schritt 4. Importieren erforderlicher Bibliotheken

Nachdem wir nun die erforderlichen Bibliotheken installiert haben, importieren wir die für dieses Tutorial erforderlichen Module:

import os
from langchain_ibm import WatsonxLLM
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
from langchain.text_splitter import RecursiveCharacterTextSplitter
import pandas as pd
import getpass

In der vorhergehenden Codezelle ist

  • os  bietet eine Möglichkeit zur Interaktion mit dem Betriebssystem (z. B. Zugriff auf Umgebungsvariablen).
  • langchain_ibm.WatsonxLLM  ermöglicht es uns, das IBM Watson Granite LLM nahtlos innerhalb des LangChain-Frameworks zu verwenden.
  • langchain.embeddings.HuggingFaceEmbeddings  generiert Einbettungen für Text unter Verwendung von HuggingFace-Modellen, die für die semantische Suche unerlässlich sind.
  • langchain.vectorstores.FAISS  ist eine Bibliothek zur effizienten Vektor-Speicher und Ähnlichkeitssuche, die es uns ermöglicht, einen Vektorindex zu erstellen und abzufragen.
  • RecursiveCharacterTextSplitter  hilft bei der Aufteilung großer Textblöcke in kleinere Teile, was für die effiziente Verarbeitung von Dokumenten entscheidend ist.
  • pandas  ist eine leistungsstarke Bibliothek für die Datenanalyse und -bearbeitung, die hier zur Verarbeitung von Tabellendaten verwendet wird.
  • getpass  ist eine sichere Möglichkeit, sensible Eingaben wie API-Schlüssel zu erfassen, ohne sie auf dem Bildschirm anzuzeigen.

In diesem Schritt werden alle Werkzeuge und Module eingerichtet, die wir benötigen, um Text zu verarbeiten, Einbettungen zu erstellen, sie in einer Vektordatenbank zu speichern und mit WatsonxLLM von IBM zu interagieren.

Schritt 5. Einrichten von Zugangsdaten

Dieser Code richtet die Anmeldedaten für den Zugriff auf die IBM Watson Machine Learning (WML) API ein und stellt sicher, dass die Projekt-ID korrekt konfiguriert ist.

  • A dictionaryZugangsdaten is created with theWML service URL undAPI-Schlüssel Der API-Schlüssel wird sicher mithilfe von „getpass.getpass“ erfasst, um die Offenlegung sensibler Informationen zu vermeiden.
  • Der Code versucht, die PROJECT_ID  mithilfe von os.environ aus Umgebungsvariablen abzurufen . Wenn die PROJECT_ID  nicht gefunden wird, wird der Benutzer aufgefordert, sie manuell über die Eingabe einzugeben.
# Set up credentials
credentials = {
      "url": "https://us-south.ml.cloud.ibm.com", # Replace with the correct region if needed
      "apikey": getpass.getpass("Please enter your WML API key (hit enter): ")
     }
# Set up project_id
try:
     project_id = os.environ["PROJECT_ID"]
except KeyError:
     project_id = input("Please enter your project_id (hit enter): ")

Schritt 6. Initialisieren eines Large Language Models

Dieser Code initialisiert das IBM watsonxLLM zur Verwendung in der Anwendung:

  1. Dieser Code erstellt eine Instanz von WatsonxLLM , indem er das Modellibm/granite-3-8b-instruct verwendet, das für anweisungsbasierte generative KI-Aufgaben entwickelt wurde.
  2. Derurl ,API-Schlüssel  undproject_id -Werte der zuvor eingerichteten Zugangsdaten werden zur Authentifizierung und Verbindung zum IBM watsonxLLM-Service weitergegeben.
  3. Konfiguriert den Parametermax_new_tokens , um die Anzahl der Token zu begrenzen, die das Modell je Antwort generiert (in diesem Fall 150 Token).

In diesem Schritt wird WatsonxLLM für die Generierung von Antworten im Workflow vorbereitet.

# Initialize the IBM Granite LLM
llm = WatsonxLLM(
      model_id="ibm/granite-3-8b-instruct",
      url=credentials["url"],
      apikey=credentials["apikey"],
      project_id=project_id,
      params={
           "max_new_tokens": 150
      }
)

Schritt 7. Definieren einer Funktion zum Extrahieren von Text aus einer Datei

Um den Text aus einem Dokument zu verarbeiten, benötigen wir eine Funktion, die seinen Inhalt lesen und extrahieren kann. Die folgende Funktion ist für die Verarbeitung von einfachen Textdateien konzipiert:

def extract_text_from_txt(file_path):
      """Extracts text from a plain text file."""
           with open(file_path, "r", encoding="utf-8") as file:
           text = file.read()
return text

Diese Funktion,extract_text_from_txt , wurde entwickelt, um den Inhalt einer einfachen Textdatei zu lesen und zu extrahieren. Sie akzeptiert den Dateipfad als Argument und öffnet die Datei im Lesemodus mitUTF-8-Kodierung , um sicherzustellen, dass Sonderzeichen korrekt verarbeitet werden.

Der gesamte Inhalt der Datei wird in eine Variable mit dem NamenText eingelesen, die dann zurückgegeben wird. Diese Funktion spielt eine entscheidende Rolle bei der Vorbereitung der Eingabedaten, indem sie den Rohtext aus dem Dokument extrahiert und ihn so für nachfolgende Operationen wie Chunking, Einbetten und Abfragen vorbereitet. Sie bietet eine einfache und effiziente Möglichkeit, Textdaten aus jeder einfachen Textdatei zu verarbeiten.

Diese Funktion ermöglicht es uns, die Eingabedatei („Die Abenteuer des Sherlock Holmes“) zu verarbeiten und ihren Inhalt für weitere Operationen wie das Chunking und Einbetten von Text zu extrahieren. Sie stellt sicher, dass der Rohtext für die Analyse leicht verfügbar ist.

Schritt 8. Text in Abschnitte aufteilen

Um große Textblöcke effizient zu verarbeiten und zu indizieren, müssen wir den Text in kleinere, überschaubare Chunks unterteilen. Die folgende Funktion übernimmt diese Aufgabe:

def split_text_into_chunks(text, chunk_size=500, chunk_overlap=50):
           """Splits text into smaller chunks for indexing."""
           splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
return splitter.split_text(text)

Dersplit_text_into_chunks Die Funktion wurde entwickelt, um große Textblöcke in kleinere, überschaubare Chunks zu unterteilen, um eine effiziente Verarbeitung und Indizierung zu ermöglichen. Sie verwendet den Rohtext als Eingabe zusammen mit zwei optionalen Parametern:chunk_size , das die maximale Größe jedes Chunks festlegt (Standardwert ist 500 Zeichen), undchunk_overlap , das die Anzahl der überlappenden Zeichen zwischen aufeinanderfolgenden Chunks angibt (Standardwert ist 50).

Diese Funktion stellt die kontextuelle Kontinuität über die Chunks hinweg sicher. Die Funktion nutzt dieRecursiveCharacterTextSplitter vonLangChain , die den Text intelligent aufteilt und gleichzeitig seinen Kontext beibehält. Durch die Rückgabe einer Liste kleinerer Textabschnitte bereitet diese Funktion die Eingabe für weitere Vorgänge wie Einbetten und Indizierung vor.

Dies ist bei der Arbeit mit großen Dokumenten von entscheidender Bedeutung, da Sprachmodelle oft Token-Beschränkungen aufweisen und längeren Text nicht direkt verarbeiten können.

Schritt 9: Erstellen eines Vektorindex

Für eine effiziente semantische Suche müssen wir Textabschnitte in Einbettungen umwandeln und sie in einem durchsuchbaren Index speichern. In diesem Schritt werden FAISS- und HuggingFace-Einbettungen verwendet, um den Vektorindex zu erstellen, der die Grundlage für das Abrufen relevanter Informationen auf der Grundlage von Abfragen bildet.

def create_vector_index(chunks):
           """Creates a FAISS vector index from text chunks."""
               embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
               vector_store = FAISS.from_texts(chunks, embeddings)
return vector_store

Dercreate_vector_index Funktion erstellt einenFAISS-Vektor- Index aus den Textabschnitten, die im vorherigen Schritt generiert wurden. Diese Funktion ist entscheidend für die Ermöglichung der semantischen Suche durch Abbildung jedes Chunks in einem hochdimensionalen Vektorraum unter Verwendung von Einbettungen.

Sie initialisiert zunächst das HuggingFaceEmbeddings-Modell sentence-transformers/all-MiniLM-L6-v2 , das Vektoreinbettungen für die Textabschnitte erzeugt. Diese Einbettungen erfassen die semantische Bedeutung jedes Chunks.

Die Funktion verwendet dannFAISS , um durch Indizieren dieser Einbettungen einen Vektorspeicher zu erstellen, der später eine effiziente Ähnlichkeitssuche ermöglicht.

Der resultierende Vektorspeicher wird zurückgegeben und verwendet, um relevante Chunks auf der Grundlage von Benutzeranfragen zu finden, und bildet so das Rückgrat für den Such- und Abrufprozess des Agenten.

Schritt 10. Abfragen des Vektorindex mit Granite

Dieser Schritt beinhaltet die Abfrage des Vektorindex, um relevante Informationen abzurufen, und die Verwendung von IBM Granite LLM, um eine verfeinerte Antwort zu generieren. Durch die Integration von Ähnlichkeitssuche und LLM-Reasoning bietet die Funktion einen dynamischen und intelligenten Prozess zur Lösung von Anfragen.

def query_index_with_granite_dynamic(vector_store, query, llm):
         """Searches the vector index, uses Granite to refine the response, and returns all components."""
             # Perform similarity search
             print("\n> Entering new AgentExecutor chain...")
             thought = f"The query '{query}' requires context from the book to provide an accurate response."
             print(f" Thought: {thought}")
             action = "Search FAISS Vector Store"
             print(f" Action: {action}")
             action_input = query
             print(f" Action Input: \"{action_input}\"")
             # Retrieve context
             results = vector_store.similarity_search(query, k=3)
             observation = "\n".join([result.page_content for result in results])
             print(f" Observation:\n{observation}\n")
            # Generate response with Granite
            prompt = f"Context:\n{observation}\n\nQuestion: {query}\nAnswer:"
            print(f" Thought: Combining retrieved context with the query to generate a detailed answer.")
            final_answer = llm(prompt)
            print(f" Final Answer: {final_answer.strip()}")
            print("\n> Finished chain.")
            # Return all components as a dictionary
            return {
                    "Thought": thought,
                     "Action": action,
                     "Action Input": action_input,
                     "Observation": observation,
                     "Final Answer": final_answer.strip()
                     }

DerDie Funktion query_index_with_granite_dynamic nimmt drei Eingaben entgegen: erstens den Vektorspeicher (vector_store ), zweitens die Anfrage des Benutzers (query ) und drittens die Granite LLM-Instanz (LLM ).

Zunächst wird eine Ähnlichkeitssuche im Vektorindex durchgeführt, um die relevantesten Textabschnitte zu finden. Diese Chunks,Beobachtung genannt, werden zu einem einzigen Kontextblock zusammengefasst.

Die Funktion erstellt dann einen Prompt, indem sie die Abfrage und den abgerufenen Kontext kombiniert. Dieser Prompt wird an dasGranite LLM weitergegeben, wodurch eine detaillierte und kontextbezogene Antwort generiert wird (final_answer ).

Während des gesamten Prozesses werden die Zwischenschritte wie dieGedanken ,Maßnahme  undAktionseingaben  des Agenten aus Gründen der Transparenz ausgedruckt.

Schließlich gibt die Funktion ein Wörterbuch zurück, das alle Komponenten enthält, einschließlich des Denkprozesses, der ergriffenen Maßnahme, der abgerufenen Beobachtung und der endgültigen Antwort.

Dieser Schritt ist entscheidend, um die Abfrage von Rohdaten mithilfe der Argumentationsfunktionen des LLM in umsetzbare und aussagekräftige Erkenntnisse umzuwandeln.

Schritt 11: Generieren eines „DataFrame“ für Abfrageergebnisse

Dieser Schritt verarbeitet dynamisch mehrere Abfragen, ruft relevante Informationen ab und speichert die Ergebnisse in einem strukturierten Format zur Analyse. Die Funktion integriert Abfragen, Datenstrukturierung und Exportfunktionen.

def dynamic_output_to_dataframe(vector_store, queries, llm, csv_filename="output.csv"):
           """Generates a DataFrame dynamically for multiple queries and saves it as a CSV file."""
           # List to store all query outputs
           output_data = []
           # Process each query
           for query in queries:
           # Capture the output dynamically
           output = query_index_with_granite_dynamic(vector_store, query, llm)
           output_data.append(output)
           # Convert the list of dictionaries into a DataFrame
           df = pd.DataFrame(output_data)
           # Display the DataFrame
           print("\nFinal DataFrame:")
           print(df)
           # Save the DataFrame as a CSV file
           df.to_csv(csv_filename, index=False)
           print(f"\nOutput saved to {csv_filename}")

DerDie Funktion dynamic_output_to_dataframe  akzeptiert vier Eingaben: den Vektorspeicher (vector_store ), eine Liste von Abfragen (queries ), die Granite LLM-Instanz (LLM ) und einen optionalen CSV-Dateinamen (csv_filename , standardmäßigoutput.csv ).

Für jede Abfrage verwendet sie dieDie Funktion query_index_with_granite_dynamic  Funktion, um den relevanten Kontext abzurufen und eine Antwort unter Verwendung des LLM zu erzeugen. Die Ergebnisse, einschließlich Zwischenkomponenten wie z. B.Gedanken ,Beobachtung  undEndgültige Antwort  werden in einer Liste gespeichert.

Sobald alle Abfragen verarbeitet sind, wird die Ergebnisliste in einen pandas DataFrame umgewandelt. Dieses tabellarische Format ermöglicht eine einfache Analyse und Visualisierung der Abfrageergebnisse. Der DataFrame wird zur Überprüfung ausgedruckt und als CSV-Datei für die zukünftige Verwendung gespeichert.

Dieser Schritt ist unerlässlich, um die Ausgabe in einem benutzerfreundlichen Format zu organisieren, das nachgelagerte Aufgaben wie Genauigkeitsbewertung und Visualisierung ermöglicht.

Schritt 12: Ausführen des Haupt-Workflows

Dieser Schritt fasst alle vorherigen Schritte in einem einzigen Workflow zusammen, um eine Textdatei zu verarbeiten, Benutzeranfragen zu beantworten und die Ergebnisse in einem strukturierten Format zu speichern. Die Funktionmain_workflow fungiert als zentraler Orchestrator des Tutorials.

def main_workflow():
           # Replace with your text file
           file_path = "aosh.txt"
           # Extract text from the text file
           text = extract_text_from_txt(file_path)
           # Split the text into chunks
           chunks = split_text_into_chunks(text)
           # Create a vector index
           vector_store = create_vector_index(chunks)
           # Define queries
           queries = [
                     "What is the plot of 'A Scandal in Bohemia'?",
                     "Who is Dr. Watson, and what role does he play in the stories?",
                     "Describe the relationship between Sherlock Holmes and Irene Adler.",
                     "What methods does Sherlock Holmes use to solve cases?"
                     ]
           # Generate and save output dynamically
          dynamic_output_to_dataframe(vector_store, queries, llm)

Sehen wir uns an, wie dieser Workflow ausgeführt wird:

Eingabe einer Textdatei: Die Variablefile_path gibt die zu verarbeitende Textdatei an. In diesem Tutorial handelt es sich bei der Eingabedatei um„aosh.txt“ , die den Text von „Die Abenteuer des Sherlock Holmes“ enthält.

Textextraktion:extract_text_from_txt wird aufgerufen, um den Inhalt der Eingabetextdatei zu lesen und zu extrahieren.

Textzerlegung: Der extrahierte Text wird mit Hilfe dersplit_text_into_chunks Funktion in kleinere Teile unterteilt, um die Einbettung und Indizierung zu erleichtern.

Create a vector index: The text chunks are converted into embeddings and stored in aFAISS-Vektor- index by using thecreate_vector_index getätigt.

Abfragen definieren: Es wird eine Liste von Beispielabfragen bereitgestellt, die jeweils zum Abrufen bestimmter Informationen aus dem Text konzipiert sind. Diese Anfragen werden vom Agenten beantwortet.

Abfragen verarbeiten: DieDie Funktion dynamic_output_to_dataframe  Funktion verarbeitet die Abfragen unter Verwendung des Vektorindex und des Granite LLM von IBM. Sie ruft den relevanten Kontext ab, generiert Antworten und speichert die Ergebnisse als CSV-Datei zur weiteren Analyse.

Dieser Schritt integriert alle Komponenten des Tutorials in einen zusammenhängenden Workflow. Er automatisiert den Prozess von der Textextraktion bis zur Lösung der Anfrage, sodass Sie die Funktionen des Agenten testen und die Ergebnisse in einem strukturierten Format überprüfen können.

Um den Workflow auszuführen, rufen Sie einfach die Funktionmain_workflow()  auf, und die gesamte Pipeline wird nahtlos ausgeführt.

# Run the workflow
main_workflow()

Ausgabe


 

> Entering new AgentExecutor chain...
 Thought: The query 'What is the plot of 'A Scandal in Bohemia'?' requires context from the book to provide an accurate response.
 Action: Search FAISS Vector Store
 Action Input: "What is the plot of 'A Scandal in Bohemia'?"
 Observation:
I. A SCANDAL IN BOHEMIA


I.
“I was aware of it,” said Holmes dryly.

“The circumstances are of great delicacy, and every precaution has to
be taken to quench what might grow to be an immense scandal and
seriously compromise one of the reigning families of Europe. To speak
plainly, the matter implicates the great House of Ormstein, hereditary
kings of Bohemia.”

“I was also aware of that,” murmured Holmes, settling himself down in
his armchair and closing his eyes.
Contents

   I.     A Scandal in Bohemia
   II.    The Red-Headed League
   III.   A Case of Identity
   IV.    The Boscombe Valley Mystery
   V.     The Five Orange Pips
   VI.    The Man with the Twisted Lip
   VII.   The Adventure of the Blue Carbuncle
   VIII.  The Adventure of the Speckled Band
   IX.    The Adventure of the Engineer’s Thumb
   X.     The Adventure of the Noble Bachelor
   XI.    The Adventure of the Beryl Coronet
   XII.   The Adventure of the Copper Beeches

 Thought: Combining retrieved context with the query to generate a detailed answer.
/var/folders/4w/smh16qdx6l98q0534hr9v52r0000gn/T/ipykernel_2648/234523588.py:23: LangChainDeprecationWarning: The method `BaseLLM.__call__` was deprecated in langchain-core 0.1.7 and will be removed in 1.0. Use :meth:`~invoke` instead.
  final_answer = llm(prompt)
 Final Answer: Step 1: Identify the main characters and their roles.
- Sherlock Holmes: The detective who is approached by a client with a delicate matter.
- An unnamed client: A representative of the great House of Ormstein, hereditary kings of Bohemia, who seeks Holmes' help to prevent a potential scandal.

Step 2: Understand the main issue or conflict.
- The main issue is a delicate matter that, if exposed, could lead to a massive scandal and compromise one of the reigning families of Europe, specifically the House of Ormstein.

Step 3: Ident

> Finished chain.

> Entering new AgentExecutor chain...
 Thought: The query 'Who is Dr. Watson, and what role does he play in the stories?' requires context from the book to provide an accurate response.
 Action: Search FAISS Vector Store
 Action Input: "Who is Dr. Watson, and what role does he play in the stories?"
 Observation:
“Sarasate plays at the St. James’s Hall this afternoon,” he remarked.
“What do you think, Watson? Could your patients spare you for a few
hours?”

“I have nothing to do to-day. My practice is never very absorbing.”
“Try the settee,” said Holmes, relapsing into his armchair and putting
his fingertips together, as was his custom when in judicial moods. “I
know, my dear Watson, that you share my love of all that is bizarre and
outside the conventions and humdrum routine of everyday life. You have
shown your relish for it by the enthusiasm which has prompted you to
chronicle, and, if you will excuse my saying so, somewhat to embellish
so many of my own little adventures.”
“My God! It’s Watson,” said he. He was in a pitiable state of reaction,
with every nerve in a twitter. “I say, Watson, what o’clock is it?”

“Nearly eleven.”

“Of what day?”

“Of Friday, June 19th.”

“Good heavens! I thought it was Wednesday. It is Wednesday. What d’you
want to frighten a chap for?” He sank his face onto his arms and began
to sob in a high treble key.

“I tell you that it is Friday, man. Your wife has been waiting this two
days for you. You should be ashamed of yourself!”

 Thought: Combining retrieved context with the query to generate a detailed answer.
 Final Answer: Dr. Watson is a character in the Sherlock Holmes stories, written by Sir Arthur Conan Doyle. He is a former military surgeon who becomes the narrator and chronicler of Holmes' adventures. Watson is a close friend and confidant of Holmes, often accompanying him on cases and providing a more human perspective to the stories. He is known for his enthusiasm for the bizarre and unconventional, as well as his skill in recording the details of their investigations. Watson's role is crucial in presenting the narrative and offering insights into Holmes' character and methods.

> Finished chain.


Final DataFrame:
                                             Thought  \
0  The query 'What is the plot of 'A Scandal in B...   
1  The query 'Who is Dr. Watson, and what role do...   
2  The query 'Describe the relationship between S...   
3  The query 'What methods does Sherlock Holmes u...   

                      Action  \
0  Search FAISS Vector Store   
1  Search FAISS Vector Store   
2  Search FAISS Vector Store   
3  Search FAISS Vector Store   

                                        Action Input  \
0        What is the plot of 'A Scandal in Bohemia'?   
1  Who is Dr. Watson, and what role does he play ...   
2  Describe the relationship between Sherlock Hol...   
3  What methods does Sherlock Holmes use to solve...   

                                         Observation  \
0  I. A SCANDAL IN BOHEMIA\n\n\nI.\n“I was aware ...   
1  “Sarasate plays at the St. James’s Hall this a...   
2  “You have really got it!” he cried, grasping S...   
3  to learn of the case was told me by Sherlock H...   

                                        Final Answer  
0  Step 1: Identify the main characters and their...  
1  Dr. Watson is a character in the Sherlock Holm...  
2  Sherlock Holmes and Irene Adler have a profess...  
3  Sherlock Holmes uses a variety of methods to s...  

Output saved to output.csv

 

Nach dem Ausführen dermain_workflow() Funktion haben wir eine Textdatei (aosh.txt) verarbeitet und vier benutzerdefinierte Abfragen zu den „Abenteuern des Sherlock Holmes“ ausgeführt. Die Ausgabe enthält eine detaillierte Aufschlüsselung, wie jede Abfrage behandelt wurde:

  • Gedanke beschreibt die Argumentation hinter der Frage und den Kontext, der für eine genaue Beantwortung erforderlich ist.
  • Aktion zeigt den unternommenen Schritt an, in diesem Fall die Durchführung einer Ähnlichkeitssuche unter Verwendung des FAISS-Vektorindex.
  • Aktionseingabe ist die spezifische Abfrage, die in einer Iteration verarbeitet wird.
  • Unter Beobachtung versteht man die Textabschnitte, die aus dem Vektorindex abgerufen werden und für die Abfrage relevant sind.
  • Die endgültige Antwort ist die detaillierte Antwort, die von IBM Granite LLM unter Verwendung des abgerufenen Kontexts generiert wird.

Zusätzlich wurden die Ergebnisse aller Abfragen in einen DataFrame strukturiert und unter gespeichertoutput.csv . Diese Datei enthält alle oben genannten Komponenten zur weiteren Analyse oder gemeinsamen Nutzung.

In diesem Prozess haben wir die Textabfrage mit LLM-Schlussfolgerungen kombiniert, um komplexe Abfragen zum Buch zu beantworten. Der Agent rief dynamisch relevante Informationen ab, nutzte den Kontext, um präzise Antworten zu generieren, und organisierte die Ausgabe in einem strukturierten Format für eine einfache Analyse.

Visualisierung der Ergebnisse

Nachdem die Datei output.csv erstellt wurde, werden wir nun die Ergebnisse und die zugehörigen Genauigkeitsmetriken visualisieren, um tiefere Erkenntnisse in die Leistung des Agenten zu erhalten.

In der folgenden Codezelle laden wir die gespeicherten Abfrageergebnisse aus demoutput.csv Datei in einen Pandas DataFrame, um sie für die Visualisierung und Analyse vorzubereiten. Der DataFrame ermöglicht es uns, die Daten in einem strukturierten Format zu bearbeiten und zu erkunden.

# Load the output.csv file into a DataFrame
df = pd.read_csv("output.csv")
print(df.head()) # Display the first few rows

AUSGABE


Thought  \
0  The query 'What is the plot of 'A Scandal in B...   
1  The query 'Who is Dr. Watson, and what role do...   
2  The query 'Describe the relationship between S...   
3  The query 'What methods does Sherlock Holmes u...   

                      Action  \
0  Search FAISS Vector Store   
1  Search FAISS Vector Store   
2  Search FAISS Vector Store   
3  Search FAISS Vector Store   

                                        Action Input  \
0        What is the plot of 'A Scandal in Bohemia'?   
1  Who is Dr. Watson, and what role does he play ...   
2  Describe the relationship between Sherlock Hol...   
3  What methods does Sherlock Holmes use to solve...   

                                         Observation  \
0  I. A SCANDAL IN BOHEMIA\n\n\nI.\n“I was aware ...   
1  “Sarasate plays at the St. James’s Hall this a...   
2  “You have really got it!” he cried, grasping S...   
3  to learn of the case was told me by Sherlock H...   

                                        Final Answer  
0  Step 1: Identify the main characters and their...  
1  Dr. Watson is a character in the Sherlock Holm...  
2  Sherlock Holmes and Irene Adler have a profess...  
3  Sherlock Holmes uses a variety of methods to s...

In diesem Code enthält der DataFrame wichtige Komponenten wie z. BGedanken ,Maßnahme ,Beobachtung  undEndgültige Antwort  für jede Abfrage. Indem wir die ersten Zeilen mithilfe vondf.head () anzeigen, stellen wir sicher, dass die Daten richtig formatiert und für die nächste Phase bereit sind: das Erstellen aussagekräftiger Visualisierungen.

Importieren von Visualisierungsbibliotheken

Um Visualisierungen der Abfrageergebnisse zu erstellen, importieren wir die erforderlichen Bibliotheken:

import matplotlib.pyplot as plt
from wordcloud import WordCloud

 

matplotlib.pyplot  ist eine weit verbreitete Bibliothek zur Erstellung statischer, interaktiver und animierter Visualisierungen in Python. Sie wird zur Erstellung von Balkendiagrammen, Kreisdiagrammen und anderen Visualisierungen verwendet.

wordcloud  ist eine Bibliothek zur Erstellung von Wortwolken, die die häufigsten Wörter in den Daten visuell hervorheben. Dieser Schritt hilft dabei, den aus dem Text abgerufenen Kontext zusammenzufassen und zu erkunden.

Wichtiger Hinweis: Wenn der Fehler„WordCloud nicht gefunden“ – Sie können das Problem beheben, indem Sie die Bibliothek mit dem Befehlpip install wordcloud installieren .

Visualisieren von Beobachtungs- und Antwortlängen

Mit diesem Code wird ein horizontales Balkendiagramm erstellt, um die Länge der Beobachtungen (abgerufener Kontext) und der Antworten (generierte Antworten) für jede Abfrage zu vergleichen. Diese Visualisierung bietet Erkenntnisse darüber, wie viel Kontext der Agent im Vergleich zur Länge der generierten Antworten verwendet.

def visualize_lengths_with_queries(df):
"""Visualizes the lengths of observations and answers with queries on the y-axis."""
df["Observation Length"] = df["Observation"].apply(len)
df["Answer Length"] = df["Final Answer"].apply(len)
# Extract relevant data
queries = df["Action Input"]
observation_lengths = df["Observation Length"]
answer_lengths = df["Answer Length"]
# Create a horizontal bar chart
plt.figure(figsize=(10, 6))
bar_width = 0.4
y_pos = range(len(queries))
plt.barh(y_pos, observation_lengths, bar_width, label="Observation Length", color="skyblue", edgecolor="black")
plt.barh([y + bar_width for y in y_pos], answer_lengths, bar_width, label="Answer Length", color="lightgreen", edgecolor="black")
plt.yticks([y + bar_width / 2 for y in y_pos], queries, fontsize=10)
plt.xlabel("Length (characters)", fontsize=14)
plt.ylabel("Queries", fontsize=14)
plt.title("Observation and Answer Lengths by Query", fontsize=16)
plt.legend(fontsize=12)
plt.tight_layout()
plt.show()
# Call the visualization function
visualize_lengths_with_queries(df)
 
Beobachtungs- und Antwortlängen nach Abfrage

Diese Funktion,visualize_lengths_with_queries – erstellt ein horizontales Balkendiagramm, um die Länge der Beobachtungen (abgerufener Kontext) und der Antworten (generierte Antworten) für jede Abfrage zu vergleichen.

Sie berechnet die Zeichenlängen der Beobachtungen und Antworten und fügt sie als neue Spalten (Länge der Beobachtung  undLänge der Antwort ) zum DataFrame hinzu. Unter Verwendung vonMatplotlib werden diese Längen für jede Abfrage grafisch dargestellt, wobei die Abfragen zur besseren Lesbarkeit auf der y-Achse angezeigt werden.

Das Balkendiagramm ist farbcodiert, um zwischen Beobachtungs- und Antwortlängen zu unterscheiden, und enthält zur besseren Übersichtlichkeit Beschriftungen, eine Legende und einen Titel.

Diese Visualisierung hilft bei der Analyse des Gleichgewichts zwischen der Größe des abgerufenen Kontexts und den Details in der generierten Antwort und bietet Einblicke in die Art und Weise, wie der Agent Anfragen verarbeitet und beantwortet.

Visualisieren des Textanteils, der für die Beobachtungen verwendet wurde

Dieser Schritt visualisiert, wie viel des gesamten vom Agenten verarbeiteten Textes im Vergleich zum verbleibenden Text für Beobachtungen verwendet wird (abgerufener Kontext). Um eine intuitive Darstellung des Anteils zu ermöglichen, wird ein Kreisdiagramm erstellt.

def visualize_text_proportion(df):
     """Visualizes the proportion of text used in observations."""
     total_text_length = sum(df["Observation"].apply(len)) + sum(df["Final Answer"].apply(len))
     observation_text_length = sum(df["Observation"].apply(len))
     sizes = [observation_text_length, total_text_length - observation_text_length]
     labels = ["Observation Text", "Remaining Text"]
     colors = ["#66b3ff", "#99ff99"]
     plt.figure(figsize=(4, 4))
     plt.pie(sizes, labels=labels, colors=colors, autopct="%1.1f%%", startangle=140)
     plt.title("Proportion of Text Used in Observations", fontsize=16)
     plt.show()
# Call the visualization function
visualize_text_proportion(df)
Diagramm mit Anteil des Textes, der für Beobachtungen verwendet wird

DerDie Funktion visualize_text_proportion  erstellt ein Kreisdiagramm, das den Anteil des Gesamttextes, der für Beobachtungen verwendet wird (abgerufener Kontext), im Vergleich zum übrigen Text veranschaulicht. Das System berechnet die Gesamttextlänge, indem es die Zeichenlängen aller Beobachtungen und Antworten summiert und dann den Anteil bestimmt, der allein auf die Beobachtungen zurückzuführen ist.

Diese Daten werden in einem Tortendiagramm mit klaren Beschriftungen für„Beobachtungstext“ und„Restlicher Text“ und unterschiedlichen Farben zur besseren Lesbarkeit dargestellt. Das Diagramm enthält Prozentwerte, damit die Proportionen leicht zu interpretieren sind.

Diese Visualisierung bietet einen Überblick darüber, wie viel Text der Agent während der Abfrageverarbeitung als Kontext verwendet, sowie Aufschluss über die Effizienz und den Fokus des Abrufprozesses.

Generieren von Wortwolken für Beobachtungen und endgültige Antworten

Dieser Code erzeugt zwei Wortwolken, um die am häufigsten vorkommenden Wörter in den Beobachtung und Endgültige Antwort Texten visuell darzustellen.

def generate_wordclouds_side_by_side(df):
      """Generates and displays word clouds for Observations and Final Answers side by side."""
      # Combine text for Observations and Final Answers
      observation_text = " ".join(df["Observation"])
      final_answer_text = " ".join(df["Final Answer"])
      # Create word clouds
      observation_wordcloud = WordCloud(width=800, height=400, background_color="white").generate(observation_text)
      final_answer_wordcloud = WordCloud(width=800, height=400, background_color="white").generate(final_answer_text)
      # Create a side-by-side visualization
      plt.figure(figsize=(16, 8))
      # Plot the Observation word cloud
      plt.subplot(1, 2, 1)
      plt.imshow(observation_wordcloud, interpolation="bilinear")
      plt.axis("off")
      plt.title("Word Cloud of Observations", fontsize=16)
      # Plot the Final Answer word cloud
      plt.subplot(1, 2, 2)
      plt.imshow(final_answer_wordcloud, interpolation="bilinear")
      plt.axis("off")
      plt.title("Word Cloud of Final Answers", fontsize=16)
      plt.tight_layout()
      plt.show()
# Call the function to generate and display the word clouds
generate_wordclouds_side_by_side(df)
 
Wortwolke für Beobachtungen

Dieser Code erzeugt zwei Wortwolken, um die am häufigsten vorkommenden Wörter in denBeobachtung undEndgültige Antwort Texte und zeigt sie nebeneinander an, um sie leichter vergleichen zu können. DieBeobachtung  undEndgültige Antwort  Texte werden zunächst mit" ".join()  zu zwei separaten Zeichenfolgen verkettet, um alle Zeilen aus den jeweiligen Spalten zu kombinieren. DieWordCloud -Bibliothek wird dann verwendet, um für jeden Text mit bestimmten Konfigurationen Wortwolken zu erzeugen.

Um eine parallele Visualisierung zu erstellen, werden Unterdiagramme verwendet: Das erste Unterdiagramm zeigt die Wortwolke fürBeobachtung und das zweite die für dieEndgültige Antwort . Dietight_layout() -Funktion, die für einen sauberen Abstand zwischen den Diagrammen sorgt. Diese Wortwolken ermöglichen es uns, die Leistung des Agenten intuitiv zu analysieren, indem wir Schlüsselbegriffe hervorheben, die aus dem Kontext abgerufen werden (Beobachtung ) und diejenigen, die in den Antworten hervorgehoben werden (Endgültige Antwort ).

Genauigkeit des Agenten testen

In diesem Abschnitt bewerten wir die Leistung des Agenten anhand mehrerer Metriken:Schlüsselwortabgleich ,BLEU-Scores ,Präzision/Rückruf  undF1-Scores . Diese Metriken bieten einen umfassenden Überblick darüber, wie gut der Agent auf der Grundlage von Benutzeranfragen korrekte und relevante Antworten generiert.

Importieren erforderlicher Bibliotheken

Bevor wir mit den Tests beginnen, importieren wir die erforderlichen Bibliotheken zur Genauigkeitsbewertung.

from sklearn.feature_extraction.text import CountVectorizer
from nltk.translate.bleu_score import sentence_bleu
from sklearn.metrics import precision_score, recall_score

Diese Bibliotheken enthalten Tools für den Schlüsselwortabgleich, die Berechnung des BLEU-Scores, Präzision und Rückrufbewertung. Stellen Sie sicher, dass Sie diese Bibliotheken in Ihrer Umgebung installiert haben, um Importfehler zu vermeiden.

Genauigkeit des Schlüsselwortabgleichs

Mit diesem Test wird bewertet, wie gut die generierten Antworten die Schlüsselwörter aus den Abfragen einbeziehen. Er verwendetCountVectorizer , um Schlüsselwörter aus den Abfragen und Antworten zu tokenisieren und zu extrahieren. Die Funktion berechnet den Anteil der Schlüsselwörter, die in der generierten Antwort enthalten sind, und markiert die Antwort als korrekt, wenn dieser Anteil einen Schwellenwert überschreitet (standardmäßig 0,5). Die Ergebnisse werden dem DataFrame unter den SpaltenKeyword Match Score undIs Accurate hinzugefügt. .

def keyword_matching_accuracy(df):
      """Checks if key phrases from the query are present in the final answer."""
      vectorizer = CountVectorizer(stop_words='english')
      def check_keywords(query, answer):
      query_keywords = set(vectorizer.build_tokenizer()(query.lower()))
      answer_keywords = set(vectorizer.build_tokenizer()(answer.lower()))
      common_keywords = query_keywords & answer_keywords
      return len(common_keywords) / len(query_keywords) # Proportion of matched keywords
      df["Keyword Match Score"] = df.apply(lambda row: check_keywords(row["Action Input"], row["Final Answer"]), axis=1)
      df["Is Accurate"] = df["Keyword Match Score"] >= 0.5 # Set a threshold for accuracy
      return df
# Apply keyword matching
df = keyword_matching_accuracy(df)
df.to_csv("output_with_accuracy.csv", index=False)
df
Dies ist die Ausgabe einer Codezelle für das Tutorial auf einer Think-Seite.

Berechnung des BLEU-Scores

Dieser Test misst, wie gut die generierten Antworten mit den abgerufenen Beobachtungen übereinstimmen.BLEU (Bilingual Evaluation Understudy) ist eine beliebte Metrik zur Bewertung der Textähnlichkeit basierend aufn-gram -Überlappungen. Die Funktion berechnetBLEU-Scores  für jedes Abfrage-Antwort-Paar und hängt sie an den DataFrame unter der BLEU-Score-Spalte an.

def calculate_bleu_scores(df):
    """Calculates BLEU scores for answers against observations."""
    df["BLEU Score"] = df.apply(
       lambda row: sentence_bleu([row["Observation"].split()], row["Final Answer"].split()),
       axis=1
       )
    return df
# Apply BLEU score calculation
df = calculate_bleu_scores(df)
df.to_csv("output_with_bleu.csv", index=False)
Diagramm, das für ein Tutorial auf der Think-Seite erstellt wurde.

Präzision und Rückruf

Präzision und Rückruf werden berechnet, um die Relevanz und Vollständigkeit der Antworten zu bewerten. Die Präzision misst den Anteil der abgerufenen Wörter in der Antwort, die relevant sind, während der Rückruf den Anteil der relevanten Wörter in der Beobachtung misst, die in der Antwort vorkommen.

Diese Metriken werden an den DataFrame unter den Spalten Präzision und Rückruf angehängt.

def calculate_precision_recall(df):
     """Calculates precision and recall for extractive answers."""
         def precision_recall(observation, answer):
                observation_set = set(observation.lower().split())
                answer_set = set(answer.lower().split())
                precision = len(observation_set & answer_set) / len(answer_set) if answer_set else 0
                recall = len(observation_set & answer_set) / len(observation_set) if observation_set else 0
         return precision, recall
        df[["Precision", "Recall"]] = df.apply(
        lambda row: pd.Series(precision_recall(row["Observation"], row["Final Answer"])),
        axis=1
        )
return df
# Apply precision/recall
df = calculate_precision_recall(df)
df.to_csv("output_with_precision_recall.csv", index=False)
df
Ausgabe einer Codezelle für das Tutorial auf einer Think-Seite

Berechnung des F1-Scores

Der F1-Score kombiniert Präzision und Rückruf in einer einzigen Metrik und bietet so eine ausgewogene Bewertung von Relevanz und Vollständigkeit. Die Formel für den F1-Score lautet: F1 Score = 2 * (Precision * Recall) / (Precision + Recall)

Die berechnetenF1-Scores werden dem DataFrame unter der Spalte F1-Score hinzugefügt.

def calculate_f1(df):
      """Calculates F1 scores based on precision and recall."""
          df["F1 Score"] = 2 * (df["Precision"] * df["Recall"]) / (df["Precision"] + df["Recall"])
          df["F1 Score"].fillna(0, inplace=True) # Handle divide by zero
          return df
# Apply F1 calculation
df = calculate_f1(df)
df.to_csv("output_with_f1.csv", index=False)
df
Ausgabe einer Codezelle für das Tutorial auf einer Think-Seite

Zusammenfassen von Genauigkeitsmetriken

Schließlich konsolidiert eine Zusammenfassungsfunktion alle Metriken, um einen Überblick über die Leistung des Agenten zu erhalten. Sie berechnet die Gesamtzahl der Abfragen, die Anzahl und den Prozentsatz der korrekten Antworten sowie die durchschnittlichen BLEU- und F1-Scores.

def summarize_accuracy_metrics(df):
      """Summarizes overall accuracy metrics."""
          total_entries = len(df)
          accurate_entries = df["Is Accurate"].sum()
          average_bleu = df["BLEU Score"].mean()
          average_f1 = df["F1 Score"].mean()
          print(f"Total Entries: {total_entries}")
          print(f"Accurate Entries: {accurate_entries} ({accurate_entries / total_entries * 100:.2f}%)")
          print(f"Average BLEU Score: {average_bleu:.2f}")
          print(f"Average F1 Score: {average_f1:.2f}")
# Call summary function
summarize_accuracy_metrics(df)

AUSGABE


 

Total Entries: 4
Accurate Entries: 4 (100.00%)
Average BLEU Score: 0.04
Average F1 Score: 0.24

Diese Genauigkeitstests bieten eine detaillierte Bewertung der Fähigkeit des Agenten, relevante und korrekte Antworten zu generieren. Jeder Test konzentriert sich auf einen bestimmten Aspekt, von der Einbeziehung von Schlüsselwörtern über Textähnlichkeit bis hin zur Vollständigkeit der Antwort. In der Zusammenfassung werden diese Metriken konsolidiert, um eine Momentaufnahme der Gesamtleistung zu erhalten.

Zusammenfassung

Dieses Tutorial führte Sie durch die Erstellung eines autonomen Agenten, der auf Granite LLM von IBM und LangChain basiert. Beginnend mit der Textextraktion über die Vektorisierung bis hin zur Lösung von Abfragen haben wir den gesamten Prozess der Konzeption und Implementierung eines funktionalen LLM-basierten Agenten behandelt. Zu den wichtigsten Schritten gehörten die Speicherverwaltung mit Vektorspeicher, die Verarbeitung von Abfragen und die Generierung von Antworten mit Granite.

Wir haben die Leistung des Agenten anhand von Metriken wie Schlüsselwortübereinstimmung, BLEU-Scores, Präzision, Rückruf und F1-Scores bewertet. Visualisierungen wie Balkendiagramme, Kreisdiagramme und Wortwolken lieferten zusätzliche Erkenntnisse über das Verhalten und die Effektivität des Agenten.

Durch die Absolvierung dieses Tutorials haben Sie gelernt, wie Sie einen LLM-Agenten entwerfen und seine Leistung testen und visualisieren können. Diese Grundlage kann erweitert werden, um komplexere Datensätze zu bearbeiten, die Genauigkeit zu verbessern und erweiterte Funktionen wie Multiagentensysteme zu erkunden.

Weiterführende Lösungen
KI-Agenten für Unternehmen

Entwickeln, implementieren und verwalten Sie leistungsstarke KI-Assistenten und -Agenten, die Workflows und Prozesse mit generativer KI automatisieren.

    Entdecken Sie watsonx Orchestrate
    IBM KI-Agenten-Lösungen

    Gestalten Sie die Zukunft Ihres Unternehmens mit KI-Lösungen, denen Sie vertrauen können.

    KI-Agenten-Lösungen erkunden
    IBM Consulting KI-Dienstleistungen

    Die KI-Services von IBM Consulting unterstützen Sie dabei, die Art und Weise, wie Unternehmen mit KI arbeiten, neu zu denken.

    Erkunden Sie die Services im Bereich der künstlichen Intelligenz
    Machen Sie den nächsten Schritt

    Ganz gleich, ob Sie vorgefertigte Apps und Skills anpassen oder mithilfe eines KI-Studios eigene Agentenservices erstellen und bereitstellen möchten, die IBM watsonx-Plattform bietet Ihnen alles, was Sie brauchen.

    Entdecken Sie watsonx Orchestrate watsonx.ai erkunden