Durch den steigenden Einsatz von „Generative AI“ oder intelligenten Chatbots sind Large Language Models (LLMs) zunehmend im Trend. DeepSet setzt sich mit Haystack zum Ziel, LLMs schnell und unkompliziert in eigene Applikationen zu integrieren. Dabei können Natural Language Processing (NLP) Tasks wie Question-Answering (QA), Information Retrieval und Document Search abgebildet werden. Als Open Source (OS) Framework erleichtert Haystack die Entwicklung von NLP-Applikationen erheblich, indem es Komponenten für die effiziente Speicherung, Organisation und Abfrage von Informationen in großen textbasierten Datenmengen anbietet.
Dieser Blogpost bietet einen groben Überblick über die Funktionalität von Haystack und veranschaulicht anhand eines Beispiels aus der Praxis, wie die Technologie eingesetzt werden kann. Dadurch wird klar, für welche Anwendungsfälle sich Haystack eignet und welche Möglichkeiten diese Technologie bietet.
Haystack auf einen Blick
Haystack besteht aus verschiedenen Komponenten, welche in den folgenden Abschnitten kurz erklärt werden:
Nodes: Die Kernkomponenten von Haystack
Haystack’s Funktionalitäten sind modular gestaltet und werden durch sogenannte Nodes bereitgestellt. Einzelne Nodes sind miteinander kombinierbar. Das Framework bietet eine Vielzahl an Funktionalitäten, wie bspw. Data Handling, Semantic Search, Routing und viele weitere. Jeder Node kann über eine entsprechende Konfiguration individualisiert werden. So ergibt sich eine Vielfalt an Optionen, unterschiedliche Daten(-typen) zu integrieren und LLMs einzubinden. Zusätzlich zu den bereits existierenden Nodes können Custom Nodes mit selbst geschriebener Funktionalität implementiert werden. Eine wichtige Node ist der vielseitig einsetzbare Prompt Node, welcher die Einbindung von LLMs ermöglicht.
Pipelines: Die Schalttafel von Haystack
Pipelines beschreiben die Verbindung verschiedener Nodes miteinander. Der Output einer Node wird dabei als Input für die nächste Node verwendet. Viele Nodes sind beliebig austauschbar, damit die Pipeline flexibel erstellt und erweitert werden kann. Eine Pipeline könnte wie folgt aussehen:
Die Nodes enthalten die einzelnen Funktionalitäten und werden miteinander zu einer Pipeline verknüpft. Zusätzlich gibt es die Möglichkeit, Decision Components zu nutzen, die lediglich die Ausführung eines bestimmten Zweigs auslösen. Der letzte Output der Pipeline dient als Rückgabewert, welcher in eine Datenbank geschrieben oder dem anfragenden User wiedergegeben wird. Ein konkretes Beispiel für eine Haystack Pipeline ist im Praxisteil des Blog Artikels zu finden.
Agenten in Haystack: Intelligente Entscheidungsträger
Mit Haystack ist es nicht nur möglich, eine einzelne Pipeline auszuführen, sondern diese flexibel anzupassen. Durch sogenannte Agenten, welche implizit LLMs verwenden, können dynamische Verarbeitungsketten erzeugt werden. Wenn eine Anfrage an den Agenten gestellt wird, entscheidet dieser, welche Node oder Pipeline für die Bearbeitung dieser spezifischen Anfrage verwendet wird. Der Node oder die Pipeline, für die sich der Agent entscheidet, wird Expert genannt. Diese Entscheidung wird durch sogenannte Labels getroffen, die den jeweiligen Experten (Node oder Pipeline) bei ihrer Erstellung zugewiesen werden.
Durch diese intelligente Label-basierte Steuerung bildet sich eine dynamische Pipeline, die sich bei jeder Anfrage neu zusammensetzt und so in der Lage ist, effizient und zielgerichtet auf verschiedene Anfragen zu reagieren. Neue Experten können erstellt und dem Agent hinzugefügt werden, was eine kontinuierliche Erweiterung und Anpassung ermöglicht.
Jeder Agent in Haystack benötigt eine Prompt Node. Diese Prompt Node ist eine entscheidende Komponente, welche die Anfragen entgegennimmt und den Inhalt der Anfragen interpretiert und klassifiziert. Dementsprechend wird mit der Klassifizierung auf die Labels gemappt und entschieden, welcher spezifische Expert für die weitere Bearbeitung der Anfrage verwendet werden soll.
Document Store: Die Speicherlösung in Haystack
Typischerweise wird der Input von Sprachmodellen mit weiteren Inhalten angereichert, bspw. den Dokumenten, welche zusammengefasst werden sollen. Daher ist es erforderlich, diese Dokumente in einem Document Store vorzuhalten. Neben dem Inhalt der Dokumente enthält dieser Document Store Metadaten, die ebenfalls zur Laufzeit zur Verfügung gestellt werden können. Es gibt bereits eine Vielzahl an möglichen Document Stores, darunter Elasticsearch (ES), In-Memory-Datenbanken, Object Storage (OS) und Vektor-Datenbanken wie Milvus und Pinecone.
Bevor die Daten in den Document Store gespeichert werden können, müssen sie als Document Objects formatiert werden. Anschließend können sie im Document Store hinterlegt werden und sind für spätere Abfragen verfügbar. Liegen die Dokumente bereits in einer existierenden OpenSearch-Datenbank, ermöglicht Haystack die nahtlose Integration in den Workflow.
Deployment von Haystack: Praktische Aspekte und REST API-Anwendung
Haystack bietet die Möglichkeit, in verschiedenen Anwendungsfällen eingesetzt zu werden. Um diese Flexibilität zu gewährleisten, stellt Haystack zwei Ansätze bereit. Zum einen die Integration in eine Python-Anwendung und zum anderen die Verwendung eines Docker-Images.
Python-Anwendung: Verwendung der Haystack-Library in einer Python-Anwendung und Bereitstellung der Schnittstellen durch ein Web Framework. Diese Schnittstellen aktivieren Pipelines, welche mit Python Code definiert wurden. Mit dieser Methode können individuelle Anwendungen entwickelt werden, die auf die spezifischen Anforderungen des Projekts zugeschnitten sind.
Docker-Image: Eines der vorhandenen Haystack Docker-Images kann verwendet werden. Es gibt vier Varianten dieser Docker-Images, abhängig davon, ob eine GPU genutzt werden soll oder ob Dependencies für eine potenzielle UI vorab installiert werden sollen. Bei dieser Option wird dem Container eine YAML-File übergeben, welche die gewünschten Pipelines beinhaltet.
Beispiel-YAML:
Haystack in der Praxis
Haystack im Einsatz: Das COSMIC-X-Forschungsprojekt
Das Haystack Framework wird im Forschungsprojekt COSMIC-X eingesetzt, um einen Chatbot mit Dokumenten-Suchfunktion zu implementieren. In der Abbildung ist der Kontext dargestellt:
Ein Chatbot eröffnet Servicetechnikern die Möglichkeit, auf sämtliche interne Dokumentationen deutscher Sprache mittels semantischer Suche zuzugreifen.
Dieser kann innerhalb von Channels sowie in privaten Chats verwendet werden und soll damit den Wissenstransfer und Austausch unter den Servicetechnikern fördern. Die Ergebnisse werden in einer benutzerfreundlichen Sprache präsentiert.
Haystacks Rolle im Projekt: Ein Blick auf die Integration
Um Anfragen und Problemstellungen von Servicetechnikern auf die passenden Einträge in der großen Menge an Dokumenten semantisch abbilden zu können, wird eine geeignete Vektor-Repräsentation (Embedding) benötigt. Zudem können die Dokumente in unterschiedlichen Formaten vorliegen, was eine Automatisierung des Vorgangs erschwert. Durch die Haystack Pipelines lässt sich dieser Prozess in all seinen Teilschritten zentralisiert konfigurieren. Im Folgenden sind zwei solcher Pipelines mit unterschiedlichen Aufgaben dargestellt:
Die Indexing Pipeline wird genutzt, um unstrukturierte Daten, wie beispielsweise PDFs, in einem strukturierten Format abzuspeichern. Die Search-Pipeline verarbeitet User-Anfragen, sucht nach passenden Dokumentenabschnitten und generiert eine Antwort.
Indexing Pipeline
- Filetype-Classifier: Klassifiziert Datei-Typ für Weiterverarbeitung
- PDF Converter: Formatiert PDF zu Text
- Pre-Processor: Textverarbeitung
- Entfernt Kopf- und Fußzeilen, Leerzeichen, leere Zeilen
- Teilt Dokument in kleinere Abschnitte
- Embedding Retriever: Erstellt Embedding für jede Einheit
- Document Store: Speichert Dokumente und Embeddings
Search Pipeline
- Retriever: Extrahiert zur Nutzeranfrage passende Dokumente
- PromptNode: Anbindung von Large Language Models (z.B. GPT3.5)
Eine nähere Erläuterung der einzelnen Komponenten befindet sich auf der offiziellen Dokumentation von Haystack.
Praktische Leitfäden und Empfehlungen für eine effiziente Haystack-Nutzung
- Um Entwicklungszeit zu sparen und keine eigene API zu implementieren, eignet sich die bereits implementierte Haystack REST-API, welche durch YAML-Files konfiguriert wird.
- Eine breite Palette von Vorlagen und Anleitungen steht zur Verfügung, um die Entwicklungsprozesse zu beschleunigen. Dazu zählen unter anderem vorgefertigte Abläufe sowie ein Prompt Hub mit vordefinierten Prompts, die eine optimale Nutzung großer Sprachmodelle ermöglichen.
- Die Haystack REST-API stellt bereits eine Vielzahl von Endpunkten bereit und kann durch vordefinierte Docker Container direkt in die eigene Architektur integriert werden.
- Dennoch ist es ratsam, Pipelines zu Beginn in Python Code abzubilden, da der Großteil der Haystack-Dokumentation auf Python-Code-Beispielen basiert. Eine eingebaute Hilfsfunktion ermöglicht zudem den Export von Python-Pipelines in das YAML-Pipeline-Format.
- Falls die vorgegebenen Haystack-Nodes nicht ausreichen, müssen eigene Custom-Nodes implementiert werden, die bisher nicht mit der No-Code YAML-Variante kompatibel sind. In diesem Fall muss eine eigene API aufgesetzt werden. Hierfür eignet sich beispielsweise FastAPI.
- Die Integration von Object Stores, welche nicht direkt von Haystack unterstützt werden, ist ebenfalls durch YAML-Pipelines erschwert. Auch in diesem Fall eignet sich ein Wechsel zur eigenen API-Implementierung.
Brauche ich dann noch Chatbot-Frameworks wie Rasa?
Dank der REST-API von Haystack kann die Kommunikation zwischen Chatbot-Frameworks und einem individuellen Haystack-Service nahtlos erfolgen. Die Umsetzung von Rasa ist in dieser offiziellen Dokumentation ausführlich erklärt. Es ist erwähnenswert, dass Haystack sowohl eigenständig als Chatbot mit Hilfe seiner Komponenten fungiert, als auch in bestehende Chatbots integriert werden kann.
Haystack und Rasa sind beide Open-Source-Plattformen, die zur Entwicklung von Conversational AI-Systemen verwendet werden können. Allerdings unterscheiden sie sich in ihrer Funktionalität und im Schwerpunkt:
Haystack:
- Konzentriert sich auf die Umsetzung von Frage-Antwort-Systemen und Information Retrieval.
- Bietet leistungsstarke Funktionen für die Suche und Extraktion von Informationen aus großen Textdateien und Verarbeitung natürlicher Sprache (NLP).
- Ziel: Speicherung, Organisation und semantische Abfrage von Informationen aus textbasierten Datenquellen.
Rasa:
- Conversational AI-Framework zur Entwicklung interaktiver Chatbots und Sprachassistenten.
- NLP-Verarbeitung & Dialogmarketing.
- Ziel: Entwicklung komplexer Dialoge und Zustandsmaschinen für unterschiedliche Kontexte, um natürliche Gespräche zu ermöglichen.
Eine Kombination beider Frameworks ist ebenfalls denkbar. Mit den generisch definierbaren Pipelines erleichtert Haystack die Handhabung großer Wissensdatenbanken und ermöglicht ein semantisches QA.
Wenn komplexere, domänenspezifische Konversationsverläufe abgebildet werden sollen, lässt sich Rasa einbinden. Durch Rasas Ansatz lassen sich Intentionen von Nutzern in verzweigten Dialogen identifizieren und auf konkrete Aktionen abbilden. Eine Aktion könnte beispielsweise eine Haystack Query-Pipeline sein.
Fazit: Haystack – Eine Schlüsselkomponente für effiziente NLP-Anwendungen
Insgesamt bietet Haystack eine vielseitige Lösung, die eine effiziente Strukturierung, Speicherung und Durchsuchung von textbasierten Informationen ermöglicht. Die individuelle Konfigurierbarkeit von Pipelines ermöglicht den Einsatz in vielen Anwendungsfeldern für unterschiedliche Projekte. Zusätzlich kann Haystack in bestehende Chatbot-Frameworks integriert werden, in denen nur die benötigten Komponenten verwendet werden. Im Umfang des Blogpost wurde Version 1.19 von Haystack verwendet, derzeit (August 2023) befindet sich Version 2.0 in Entwicklung.
Danksagung
Die Inhalte dieser Arbeit stammen aus dem Projekt „Kollaborative Smart Services für industrielle Wertschöpfungsnetze in GAIA-X (COSMIC-X)“. Dieses Forschungs- und Entwicklungsprojekt wird mit Mitteln des Bundesministeriums für Bildung und Forschung (BMBF) (Förderkennzeichen 02J21D146) gefördert und vom Projektträger Karlsruhe (PTKA) betreut. Die Verantwortung für den Inhalt dieser Veröffentlichung liegt bei den Autor:innen.