Wie Sie die Leistung Ihrer RAG-Pipeline verbessern können
Mit der zunehmenden Beliebtheit von Retrieval Augmented Generation(RAG)-Anwendungen wächst auch das Interesse an der Verbesserung ihrer Leistung. Dieser Artikel stellt alle Möglichkeiten zur Optimierung von RAG-Pipelines vor und bietet entsprechende Illustrationen, damit Sie die wichtigsten RAG-Optimierungsstrategien schnell verstehen.
Es ist wichtig zu beachten, dass wir diese Strategien und Techniken nur auf einer hohen Ebene erforschen und uns darauf konzentrieren, wie sie in ein RAG-System integriert werden. Wir werden uns jedoch nicht in komplizierte Details vertiefen oder Sie Schritt für Schritt durch die Implementierung führen.
Eine Standard-RAG-Pipeline
Das folgende Diagramm zeigt die einfachste Vanilla-RAG-Pipeline. Zunächst werden Dokumentenstücke in einen Vektorspeicher (wie Milvus oder Zilliz Cloud) geladen. Dann ruft der Vektorspeicher die Top-K der relevantesten Chunks in Bezug auf die Anfrage ab. Diese relevanten Chunks werden dann in die Kontextabfrage des LLM eingefügt, und schließlich liefert der LLM die endgültige Antwort.
Verschiedene Arten von RAG-Anreicherungstechniken
Wir können verschiedene Ansätze zur RAG-Anreicherung auf der Grundlage ihrer Rolle in den Phasen der RAG-Pipeline klassifizieren.
- Abfrageanreicherung: Modifizierung und Manipulation des Abfrageprozesses der RAG-Eingabe, um die Abfrageabsicht besser auszudrücken oder zu verarbeiten.
- Indizierungsverbesserung: Optimierung der Erstellung von Chunking-Indizes durch Techniken wie Multi-Chunking, schrittweise Indizierung oder Mehrweg-Indizierung.
- Retriever-Verbesserung: Anwendung von Optimierungstechniken und -strategien während des Abrufprozesses.
- Generator-Verbesserung: Anpassung und Optimierung von Prompts bei der Zusammenstellung von Prompts für den LLM, um bessere Antworten zu erhalten.
- RAG-Pipeline-Erweiterung: Dynamisches Umschalten von Prozessen innerhalb der gesamten RAG-Pipeline, einschließlich der Verwendung von Agenten oder Tools zur Optimierung von Schlüsselschritten in der RAG-Pipeline.
Im Folgenden werden wir spezifische Methoden in jeder dieser Kategorien vorstellen.
Abfrageverbesserung
Im Folgenden werden vier effektive Methoden zur Verbesserung Ihrer Abfrageerfahrung vorgestellt: Hypothetische Fragen, hypothetische Dokumenteinbettungen, Unterabfragen und Stepback-Prompts.
Hypothetische Fragen erstellen
Bei der Erstellung von hypothetischen Fragen wird ein LLM verwendet, um mehrere Fragen zu generieren, die Benutzer zum Inhalt der einzelnen Dokumentabschnitte stellen könnten. Bevor die eigentliche Anfrage des Benutzers den LLM erreicht, ruft der Vektorspeicher die relevantesten hypothetischen Fragen, die sich auf die eigentliche Anfrage beziehen, zusammen mit den dazugehörigen Dokumentabschnitten ab und leitet sie an den LLM weiter.
Diese Methode umgeht das bereichsübergreifende Asymmetrieproblem bei der Vektorsuche, indem sie direkt eine Abfrage-zu-Abfrage-Suche durchführt und so die Belastung der Vektorsuche verringert. Allerdings führt dies zu zusätzlichem Overhead und Unsicherheit bei der Erstellung hypothetischer Fragen.
HyDE (Hypothetische Dokumenteneinbettungen)
HyDE steht für Hypothetical Document Embeddings (hypothetische Dokumenteneinbettungen). Es nutzt ein LLM, um ein "hypothetisches Dokument" oder eine gefälschte Antwort als Antwort auf eine Benutzeranfrage ohne Kontextinformationen zu erstellen. Diese gefälschte Antwort wird dann in Vektoreinbettungen umgewandelt und zur Abfrage der relevantesten Dokumentenabschnitte in einer Vektordatenbank verwendet. Anschließend ruft die Vektordatenbank die Top-K der relevantesten Dokumentabschnitte ab und überträgt sie an das LLM und die ursprüngliche Benutzeranfrage, um die endgültige Antwort zu generieren.
Diese Methode ähnelt der Technik der hypothetischen Frage, da sie die domänenübergreifende Asymmetrie bei der Vektorsuche berücksichtigt. Sie hat jedoch auch Nachteile, wie z. B. die zusätzlichen Rechenkosten und die Unsicherheiten bei der Generierung gefälschter Antworten.
Weitere Informationen finden Sie in dem HyDE-Papier.
Erstellen von Unterabfragen
Wenn eine Benutzerabfrage zu kompliziert ist, können wir sie mithilfe eines LLM in einfachere Unterabfragen zerlegen, bevor wir sie an die Vektordatenbank und den LLM weiterleiten. Schauen wir uns ein Beispiel an.
Stellen Sie sich vor, ein Nutzer fragt: "Welche Unterschiede gibt es zwischen Milvus und Zilliz Cloud?" Diese Frage ist ziemlich komplex und hat möglicherweise keine einfache Antwort in unserer Wissensdatenbank. Um dieses Problem anzugehen, können wir sie in zwei einfachere Unterabfragen aufteilen:
- Unterfrage 1: "Was sind die Merkmale von Milvus?"
- Unterabfrage 2: "Was sind die Merkmale von Zilliz Cloud?"
Sobald wir diese Unterabfragen haben, senden wir sie alle an die Vektordatenbank, nachdem wir sie in Vektoreinbettungen konvertiert haben. Die Vektordatenbank findet dann die Top-K-Dokumentenstücke, die für jede Unterabfrage am relevantesten sind. Schließlich verwendet der LLM diese Informationen, um eine bessere Antwort zu generieren.
Durch die Aufteilung der Benutzeranfrage in Unterabfragen wird es für unser System einfacher, relevante Informationen zu finden und präzise Antworten zu geben, selbst auf komplexe Fragen.
Stepback-Prompts erstellen
Eine weitere Möglichkeit zur Vereinfachung komplexer Benutzeranfragen besteht in der Erstellung von Stepback-Prompts. Bei dieser Technik werden komplizierte Benutzeranfragen mithilfe eines LLM in "Stepback-Fragen"** abstrahiert. Anschließend verwendet eine Vektordatenbank diese Stepback-Fragen, um die relevantesten Dokumententeile abzurufen. Schließlich generiert das LLM eine genauere Antwort auf der Grundlage dieser abgerufenen Dokumentenabschnitte.
Lassen Sie uns diese Technik anhand eines Beispiels veranschaulichen. Betrachten wir die folgende Anfrage, die recht komplex und nicht direkt zu beantworten ist:
Ursprüngliche Benutzerabfrage: "Ich habe einen Datensatz mit 10 Milliarden Datensätzen und möchte ihn in Milvus für Abfragen speichern. Ist das möglich?"
Um diese Benutzeranfrage zu vereinfachen, können wir ein LLM verwenden, um eine einfachere Stepback-Frage zu generieren:
Stepback-Frage: "Wie groß darf der Datensatz sein, den Milvus verarbeiten kann?"
Diese Methode kann uns helfen, bessere und genauere Antworten auf komplexe Abfragen zu erhalten. Sie zerlegt die ursprüngliche Frage in eine einfachere Form, so dass unser System leichter relevante Informationen finden und genaue Antworten geben kann.
Indizierungsverbesserung
Die Verbesserung der Indizierung ist eine weitere Strategie, um die Leistung Ihrer RAG-Anwendungen zu steigern. Sehen wir uns drei Techniken zur Verbesserung der Indizierung an.
Automatisches Zusammenführen von Dokumentenstücken (Chunks)
Beim Aufbau eines Indexes können wir zwei Granularitätsebenen verwenden: Child Chunks und ihre entsprechenden Parent Chunks. Zunächst suchen wir nach Child Chunks auf einer feineren Detailebene. Dann wenden wir eine Merging-Strategie an: Wenn eine bestimmte Anzahl n von Child Chunks aus den ersten k Child Chunks zu demselben Parent Chunk gehört, stellen wir dem LLM diesen Parent Chunk als Kontextinformation zur Verfügung.
Diese Methodik wurde in LlamaIndex implementiert.
Hierarchische Indizes konstruieren
Bei der Erstellung von Indizes für Dokumente können wir einen zweistufigen Index erstellen: einen für Dokumentenzusammenfassungen und einen für Dokumentenkomplexe. Die Vektorsuche erfolgt in zwei Schritten: Zunächst werden die relevanten Dokumente auf der Grundlage der Zusammenfassung gefiltert, und anschließend werden die entsprechenden Dokumentabschnitte ausschließlich in diesen relevanten Dokumenten gefunden.
Dieser Ansatz erweist sich als vorteilhaft in Situationen, in denen große Datenmengen anfallen oder die Daten hierarchisch aufgebaut sind, wie z. B. bei der Suche nach Inhalten in einer Bibliothek.
Hybrides Retrieval und Reranking
Bei der hybriden Retrieval- und Reranking-Technik werden eine oder mehrere zusätzliche Retrieval-Methoden mit dem Vektorähnlichkeitsretrieval integriert. Anschließend ordnet ein Reranker die abgerufenen Ergebnisse auf der Grundlage ihrer Relevanz für die Benutzeranfrage neu ein.
Zu den üblichen ergänzenden Retrieval-Algorithmen gehören lexikalische frequenzbasierte Methoden wie BM25 oder große Modelle, die spärliche Einbettungen wie Splade verwenden. Zu den Re-Ranking-Algorithmen gehören RRF oder komplexere Modelle wie Cross-Encoder, die BERT-ähnlichen Architekturen ähneln.
Bei diesem Ansatz werden verschiedene Retrieval-Methoden eingesetzt, um die Retrieval-Qualität zu verbessern und potenzielle Lücken im Recall von Vektoren zu schließen.
Retriever-Verbesserung
Die Verfeinerung der Retriever-Komponente innerhalb des RAG-Systems kann die RAG-Anwendungen ebenfalls verbessern. Lassen Sie uns einige effektive Methoden zur Verbesserung des Retrievers untersuchen.
Satzfenster-Retrieval
In einem grundlegenden RAG-System ist das dem LLM übergebene Dokumentstück ein größeres Fenster, das das abgerufenen Einbettungsstück umfasst. Dadurch wird sichergestellt, dass die dem LLM zur Verfügung gestellten Informationen ein breiteres Spektrum an kontextuellen Details umfassen und der Informationsverlust minimiert wird. Die Technik des Sentence Window Retrieval entkoppelt den für das Embedding Retrieval verwendeten Dokumentenchunk von dem dem LLM bereitgestellten Chunk.
Die Erweiterung der Fenstergröße kann jedoch zusätzliche störende Informationen einbringen. Wir können die Größe der Fenstererweiterung je nach den spezifischen Geschäftsanforderungen anpassen.
Metadaten-Filterung
Um präzisere Antworten zu gewährleisten, können wir die abgerufenen Dokumente verfeinern, indem wir Metadaten wie Zeit und Kategorie filtern, bevor wir sie an den LLM weitergeben. Wenn beispielsweise Finanzberichte aus mehreren Jahren abgerufen werden, können die Informationen durch Filtern nach dem gewünschten Jahr so verfeinert werden, dass sie den spezifischen Anforderungen entsprechen. Diese Methode erweist sich als effektiv in Situationen mit umfangreichen Daten und detaillierten Metadaten, wie z. B. bei der Abfrage von Inhalten in Bibliothekssammlungen.
Generator-Erweiterung
Lassen Sie uns weitere RAG-Optimierungstechniken erkunden, indem wir den Generator innerhalb eines RAG-Systems verbessern.
Komprimierung der LLM-Eingabeaufforderung
Die Rauschinformationen in den abgerufenen Dokumentenstücken können die Genauigkeit der endgültigen Antwort von RAG erheblich beeinflussen. Das begrenzte Eingabefenster in LLMs stellt ebenfalls eine Hürde für genauere Antworten dar. Um diese Herausforderung zu bewältigen, können wir irrelevante Details komprimieren, wichtige Absätze hervorheben und die Gesamtlänge des Kontexts der abgerufenen Dokumentenabschnitte reduzieren.
Dieser Ansatz ähnelt der zuvor diskutierten hybriden Such- und Reranking-Methode, bei der ein Reranker eingesetzt wird, um irrelevante Dokumentenstücke auszusieben.
Anpassen der Chunk-Reihenfolge in der Eingabeaufforderung
In der Arbeit "Lost in the middle" haben Forscher festgestellt, dass LLMs während des Schlussfolgerungsprozesses häufig Informationen in der Mitte der gegebenen Dokumente übersehen. Stattdessen neigen sie dazu, sich mehr auf die Informationen am Anfang und am Ende des Dokuments zu verlassen.
Auf der Grundlage dieser Beobachtung können wir die Reihenfolge der abgerufenen Chunks anpassen, um die Qualität der Antworten zu verbessern: Beim Abrufen mehrerer Wissens-Chunks werden Chunks mit relativ geringem Vertrauen in der Mitte platziert, während Chunks mit relativ hohem Vertrauen an den beiden Enden angeordnet werden.
RAG-Pipeline-Erweiterung
Wir können auch die Leistung Ihrer RAG-Anwendungen verbessern, indem wir die gesamte RAG-Pipeline verbessern.
Selbstreflexion
Bei diesem Ansatz wird das Konzept der Selbstreflexion von KI-Agenten genutzt. Wie funktioniert diese Technik dann?
Einige der anfänglich abgerufenen Top-K-Dokumente sind mehrdeutig und beantworten die Frage des Benutzers möglicherweise nicht direkt. In solchen Fällen können wir eine zweite Reflexionsrunde durchführen, um zu überprüfen, ob diese Teile die Anfrage wirklich beantworten können.
Diese Reflexion kann mit effizienten Reflexionsmethoden wie Natural Language Inference (NLI)-Modellen oder zusätzlichen Tools wie Internetsuchen zur Überprüfung durchgeführt werden.
Dieses Konzept der Selbstreflexion wurde in mehreren Arbeiten und Projekten untersucht, darunter Self-RAG, Corrective RAG, LangGraph, etc.
Abfrage-Routing mit einem Agenten
Manchmal ist es nicht notwendig, ein RAG-System zur Beantwortung einfacher Fragen zu verwenden, da dies zu mehr Missverständnissen und Rückschlüssen aus irreführenden Informationen führen könnte. In solchen Fällen können wir einen Agenten als Router in der Abfragephase einsetzen. Dieser Agent beurteilt, ob die Anfrage die RAG-Pipeline durchlaufen muss. Ist dies der Fall, wird die nachfolgende RAG-Pipeline eingeleitet; andernfalls wird die Anfrage direkt vom LLM bearbeitet.
Der Agent kann verschiedene Formen annehmen, z. B. ein LLM, ein kleines Klassifizierungsmodell oder sogar einen Satz von Regeln.
Durch das Routing von Abfragen auf der Grundlage der Benutzerabsicht können Sie einen Teil der Abfragen umleiten, was zu einer erheblichen Verbesserung der Antwortzeit und einer spürbaren Verringerung des unnötigen Rauschens führt.
Wir können die Technik des Query Routing auf andere Prozesse innerhalb des RAG-Systems ausdehnen, z. B. auf die Bestimmung, wann Tools wie die Websuche eingesetzt werden sollen, auf die Durchführung von Unterabfragen oder die Suche nach Bildern. Dieser Ansatz stellt sicher, dass jeder Schritt im RAG-System auf der Grundlage der spezifischen Anforderungen der Anfrage optimiert wird, was zu einer effizienteren und genaueren Informationsbeschaffung führt.
Zusammenfassung
Während eine einfache RAG-Pipeline einfach erscheinen mag, erfordert das Erreichen einer optimalen Unternehmensleistung oft ausgefeiltere Optimierungstechniken.
Dieser Artikel fasst verschiedene gängige Ansätze zur Verbesserung der Leistung Ihrer RAG-Anwendungen zusammen. Wir haben auch klare Illustrationen zur Verfügung gestellt, damit Sie diese Konzepte und Techniken schnell verstehen und ihre Implementierung und Optimierung beschleunigen können.
Sie können die einfachen Implementierungen der wichtigsten in diesem Artikel aufgeführten Ansätze über diesen GitHub-Link erhalten.