Kan Postgres håndtere din RAG-pipeline?

Vi testede pgai's databasebaserede tilgang for at se, hvor den forenkler RAG-driften – og hvor komplekse arbejdsgange stadig kræver mere fleksibilitet.

Resumé

  • 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-metoden

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:

  1. Tag en samling dokumenter.

  2. Opdel dem i tekststykker. Det kan gøres på mange forskellige måder (f.eks. efter afsnit eller semantiske grupperinger).

  3. Omdan hvert tekststykke til en embedding.

  4. Gem embeddings i en vektordatabase (Pinecone, Milvus osv.) eller i Postgres ved hjælp af pgvector.

  5. 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

Formålet med pgai

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.

De første indtryk af pgai

Det kunne vi lide

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.

Det oplevede vi som begrænsende

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.

Tekst-til-SQL-lag

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

OPENAI_API_KEY="your-OpenAPI-key-goes-here"TARGET_DB="postgres://user:password@host:port/database"CATALOG_DB="postgres://user:password@host:port/database"

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

---schema: postgres_airname: aircrafttype: tabledescription: Lists aircraft models with performance characteristics and unique codes.columns:- name: model  description: Commercial name of the aircraft model.- name: range  description: Maximum flight range in kilometers.- name: class  description: Airframe class category or configuration indicator.- name: velocity  description: Cruising speed of the aircraft.- name: code  description: Three-character aircraft code serving as the primary key....

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

pgai semantic-catalog search -p "Your natural language question goes here!"

Hent rå kontekst:

Dette viser den rå YAML-kontekst, der er relateret til din forespørgsel i naturligt sprog:

Bash

pgai semantic-catalog search -p "Your natural language question goes here!" --render

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

pgai semantic-catalog generate-sql -p "Your natural language question goes here!"

Sådan kan du bruge pgai allerede nu

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.

Her ville vi være forsigtige

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.

GitHub-graf over antallet af stjerner, som viser udbredelsen af Timescales pgai over tid.

Opsummering

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.

Forfatter

Andrew Liubinas