Ein RAG-System mit PostgreSQL aufbauen
(pgdash.io)- Mit einem Retrieval-Augmented-Generation-(RAG)-System lässt sich ein KI-Assistent erstellen, der Fragen auf Basis einer bestehenden internen Wissensbasis beantworten kann, etwa Wikis, Handbücher sowie Schulungs- und Referenzmaterialien
- Ein RAG-System lässt sich allein mit PostgreSQL, pgvector, ollama und weniger als 200 Zeilen Go-Code aufbauen
Überblick
- Einige Absätze einer Geschichte werden als „Dokumentkorpus“ verwendet, und für jedes Dokument werden mit Metas Llama3 Dokument-Embeddings erzeugt, lokal gehostet über ollama
- Dokumente und Embeddings werden in einer PostgreSQL-Tabelle gespeichert; die Erweiterung pgvector übernimmt das Speichern und den Zugriff auf die Embeddings
- Für eine Nutzerabfrage wird das relevanteste Dokument aus der Tabelle abgerufen und anschließend mit Llama3 eine Antwort erzeugt
- ollama stellt eine OpenAI-ähnliche HTTP-API bereit, um Embeddings und Chat-Antworten zu erzeugen
- Der Go-Code kommuniziert mit Postgres über jackc/pgx und pgvector-go und nutzt das ollama-Client-API-Paket für die Aufrufe der HTTP-API
Modelle mit Ollama ausführen
- Ollama ist ein Tool, mit dem sich Open-Source-Modelle lokal ausführen lassen, und es bietet eine REST-API im OpenAI-Stil
- Mit dem Befehl
ollama pull llama3lässt sich das llama3-Modell ausführen - Der HTTP-Server von ollama ist standardmäßig unter
127.0.0.1:11434erreichbar
pgvector installieren
- pgvector ist eine Erweiterung für PostgreSQL 12 bis 16 und kann bei Nutzung des pgdg-APT-Repositories mit
sudo apt install postgresql-16-pgvectorinstalliert werden - Nach der Installation wird die Erweiterung mit
create extension vector;in der Datenbank eingerichtet - Mit
create table items (id serial primary key, doc text, embedding vector(4096));wird eine Tabelle zum Speichern von Dokumenten und Embeddings erstellt
Dokumentdaten
- Verwendet werden vier Absätze aus der Sherlock-Holmes-Geschichte „The Boscombe Valley Mystery“ (Public Domain, Projekt Gutenberg)
Code
- Es steht Demo-Code unter MIT-Lizenz auf GitHub zur Verfügung
- Dokumente werden mit
INSERT INTO items (doc, embedding) VALUES ($1, $2)eingefügt - Das relevanteste Dokument wird mit
SELECT doc FROM items ORDER BY embedding <-> $1 LIMIT 1gesucht (der Operator<->wird von pgvector bereitgestellt) - Für Aufrufe der Ollama-API wird das Go-Paket von ollama verwendet
- Zur Erzeugung von Embeddings wird
api.EmbeddingRequestverwendet - Zur Erzeugung von Chat-Antworten wird
api.ChatRequestverwendet, wobei das abgerufene Dokument in den Prompt aufgenommen wird
- Zur Erzeugung von Embeddings wird
Kommandozeilenoberfläche
- Mit
ragdemo -insert {path-to-doc-file}werden Dokumente in der Datenbank gespeichert - Mit
ragdemo -query {query-text}wird ein Prompt eingegeben und eine Antwort erzeugt
Gesamtablauf
- Beim Speichern eines Dokuments mit der Option
-insertwird der Dateiinhalt gelesen, mit Llama3 ein Embedding erzeugt und in PostgreSQL gespeichert - Bei Verwendung der Option
-querywird ein Prompt-Embedding erzeugt und mit den übrigen Embeddings in der Tabelleitemsverglichen, um das „nächste“ Dokument zu finden (L2-Distanzberechnung über den Operator<->) - Das gefundene Dokument wird in den Prompt aufgenommen, an Llama3 übergeben, und die erzeugte Chat-Antwort wird ausgegeben
Zusätzliche Tipps
- Es kann sinnvoll sein, ein speziell für Embeddings ausgelegtes Modell zu verwenden, statt llama3
- Für andere Sprachen als Englisch sollte nach besser geeigneten Modellen gesucht werden
- Neben der L2-Distanz lassen sich auch andere Distanzmethoden ausprobieren, da pgvector weitere Verfahren unterstützt
- Ein vollständiger Tabellenscan ist nicht gut skalierbar; daher sollten etwa pgvector-Indizes genutzt werden
- In der Generierungsphase kann es helfen, mehr Dokumente einzubeziehen oder zusätzliche Dokumente per Keyword-Matching nachzuladen
- Durch Anpassung des Generierungs-Prompts und Tests mit verschiedenen LLMs lässt sich die Ausgabequalität verbessern
Noch keine Kommentare.