LLM'er kan kun »se« en begrænset mængde tekst ad gangen (kontekstvinduet). Det fungerer til små opgaver, men bryder sammen, når en vidensbase omfatter tusindvis af sider. Selv når kontekstvinduet er stort nok, kan ydeevnen stadig falde på grund af problemet med at »finde en nål i en høstak«.
RAG (»retrieval augmented generation«) er blevet en meget udbredt metode, hvor man vedligeholder en vidensbase (dokumenter, wikier, politikker, transskriptioner osv.), foretager en semantisk søgning på en brugers forespørgsel for at hente de mest relevante tekststykker ved hjælp af embeddings og derefter sender disse tekststykker til LLM'en sammen med spørgsmålet. Det afgrænser modellens kontekst og kan, når det gøres korrekt, forbedre svarkvaliteten og reducere hallucinationer.
pgai er en open source-udvidelse til Postgres (med tilhørende værktøjer), der hjælper dig med at bygge arbejdsgange til »AI-baseret hentning« oven på den velafprøvede open source-database PostgreSQL.
Hovedidéen er at flytte mere af den almindelige RAG-pipeline ned i databaselaget (indlæs → opdel → opret embeddings → hold embeddings synkroniseret) frem for blot at betragte databasen som »lagerplads« til embeddings.
Vores første indtryk er, at løsningen er lovende, men at den ikke er egnet, så snart din RAG-pipeline bliver bare en smule kompliceret – især hvad angår opdeling i tekststykker. Vi vil dog følge projektet tæt.
RAG kan bygges på mange måder. Hvis du vil have en mere udførlig gennemgang af forskellige RAG-tilgange, kan du læse Praktiske eksempler på skræddersyede RAG-løsninger. Mulighederne bliver overraskende omfattende, når kvaliteten er vigtig, men den almindelige standardtilgang ser typisk sådan ud:
Tag en samling dokumenter.
Opdel dem i tekststykker. Det kan gøres på mange forskellige måder (f.eks. efter afsnit eller semantiske grupperinger).
Omdan hvert tekststykke til en embedding.
Gem embeddings i en vektordatabase (Pinecone, Milvus osv.) eller i Postgres ved hjælp af pgvector.
Søg ved forespørgslen efter de nærmeste tekststykker `og send dem til LLM'en (også her er der mange måder at gøre det på).
I mange teknologistakke udføres trin (1)–(3) uden for databasen i applikationskode eller en datapipeline, mens databasen primært bruges til:
at gemme embeddings
at søge i embeddings
pgai er en Postgres-udvidelse (open source, udviklet af Timescale), der forsøger at udviske denne grænse.
I stedet for at behandle embeddings som noget, din app skal administrere manuelt, gør pgai dem til en databasefunktion:
Du angiver, hvilken tabel eller hvilke dokumenter der skal oprettes embeddings for.
Du angiver embedding-modellen og en strategi for opdeling i tekststykker.
pgai klarer resten, herunder at holde embeddings opdateret, når kildedataene ændres.
Det er et tiltalende løfte:
Mindre specialudviklet integrationskode, der skal vedligeholdes.
Det bør være lettere at holde embeddings »friske«, når de underliggende kildedokumenter ændres.
Postgres/pgai håndterer nye forsøg, hastighedsbegrænsninger, mislykkede jobs osv.
Bemærkning til læseren: pgai inkluderer pgvector (en anden meget populær RAG-udvidelse til Postgres). pgvector føjer vektorlagring og lighedssøgning til Postgres, mens pgai bygger videre på dette for at automatisere trin i RAG-pipelinen som opdeling, oprettelse af embeddings og løbende opdatering af dem.
1) Det er nemt at komme i gang.
Standardforløbet er forholdsvis enkelt:
Hent Timescales Docker-images (database + worker).
Angiv API-nøglen til din embedding-udbyder.
Kør en smule SQL for at definere vektoriseringen (grundlæggende: hvad der skal oprettes embeddings for, hvordan det skal opdeles, og hvilken model der skal bruges).
Derefter sørger pgai for, at en vektoriserings-worker kører som en separat proces og genererer embeddings asynkront (f.eks. hvert femte minut eller med det interval, du ønsker).
2) Det er praktisk at køre hele pipelinen »tæt på« databasen.
pgai kan indlæse indhold fra tabeller og hente dokumenter fra steder som S3 for derefter at fortolke, opdele og oprette embeddings for dem. Den kan også håndtere forskellige tekstdokumentformater som PDF, Markdown osv.
1) Du mister meget kontrol (og RAG kræver undertiden kontrol).
RAG-systemer med høj ydeevne (målt på svarkvalitet) kræver ofte skræddersyede pipelines såsom:
tilpassede regler for opdeling (efter overskrifter, sider, talerskift osv.)
metadataorienteret opdeling (bevar afsnitstitler, tidsstempler, forfattere og dokumenttype)
forskellige embedding-strategier for hver dokumenttype
pgai giver mindre fleksibilitet på ovenstående områder.
I øjeblikket findes der to primære strategier for opdeling: en tegnbaseret tekstopdeler og en rekursiv tegnbaseret tekstopdeler samt muligheden for slet ikke at opdele. Det kan være tilstrækkeligt til nogle anvendelser, men mange RAG-systemer i produktion kræver mere tilpasning.
Det ville være fantastisk, hvis Timescale kunne indarbejde nogle af de mere avancerede opdelingsstrategier, vi ser i biblioteker som Chonkie, og ligeledes understøtte avancerede løsninger som Anthropics kontekstuelle hentning.
2) Tekst først, ikke multimodalt.
Mange interessante RAG-problemer handler ikke længere kun om tekst:
PDF'er med diagrammer
skærmbilleder/billeder
lydoptagelser
videoklip
Selv hvis man kan »udtrække tekst« fra disse kilder, er det ikke det samme som en ægte multimodal embedding-pipeline.
Hvis pgai på et tidspunkt understøtter multimodale modeller hele vejen igennem (indlæs → opdel → opret embeddings for store billeder samt lyd og video lagret i S3 med robust synkronisering), vil det være attraktivt. I dag er det dog en arbejdsgang til tekst-embeddings.
3) Hvis du kun har brug for embeddings, har du måske ikke brug for pgai.
Hvis din indlæsningspipeline allerede er specialtilpasset (eller skal være det), er det ikke den sværeste del af RAG at »oprette embeddings for tekststykker«. I det scenarie løser pgai den letteste del af problemet.
Hvis din vidensbase sjældent opdateres, er værdien af automatisk synkronisering af embeddings desuden mindre.
En særligt god anvendelse af pgai er at implementere en tekst-til-SQL-grænseflade til dine databaser. Det kan forholdsvis nemt gøres med modulet semantic_catalog, som pgai tilbyder. Sæt det blot op sådan:
Bash
og få det semantiske katalog til at gennemgå dine dataordbøger med pgai semantic-catalog create. Det genererer kontekst fra dit datalager, som ser omtrent sådan ud:
Plain Text
Denne kontekst er nu tilgængelig for pgai på flere måder:
Via semantisk søgning:
Denne forespørgsel returnerer de tabeller, funktioner og andre objekter, der kan være relevante for din forespørgsel i naturligt sprog:
Bash
Hent rå kontekst:
Dette viser den rå YAML-kontekst, der er relateret til din forespørgsel i naturligt sprog:
Bash
Generér SQL:
Du kan også generere den rå SQL, der kræves for at besvare din forespørgsel, direkte. Konteksten fra det foregående trin sendes til en LLM, som genererer et svar:
Bash
Hvis du bygger et forholdsvis enkelt RAG-system, er pgai værd at afprøve, hvis du ønsker:
Postgres som dit primære datasystem,
et minimum af integrationskode,
embeddings, der automatisk holdes synkroniseret,
en hurtig måde at anvende tekst-til-SQL på dine databaser,
at eksperimentere med nye RAG-værktøjer og Postgres-udvidelser.
Det er sandsynligvis værd at vente med pgai, hvis din RAG-pipeline kræver noget af følgende:
meget specialtilpasset logik til indlæsning eller opdeling
mange dokumenttyper med forskellige krav til fortolkning
multimodale embeddings
Endelig er det tydeligt, at pgvector har opnået stor udbredelse, men det er uvist, om pgai vil tiltrække samme interesse og dermed få samme opbakning – selv om løsningen kun har eksisteret i omkring 18 måneder.


pgai er en interessant RAG-tilgang, hvor databaser udfører en større del af det rutinemæssige driftsarbejde, så applikationskoden kan blive enklere.
Lige nu er den:
anvendelig og virkelig behagelig at arbejde med til enkle RAG-opsætninger
ikke fleksibel nok til mere skræddersyede pipelines (især multimodale)
Den er lovende og bestemt værd at følge for at se, hvordan den udvikler sig.