Navigare principală

Poate Postgres să gestioneze fluxul tău RAG?

Am testat abordarea pgai axată pe baza de date pentru a vedea unde simplifică operațiunile RAG și unde sarcinile complexe necesită încă mai multă flexibilitate.

Rezumat executiv

  • LLM-urile pot „vedea” simultan doar o cantitate limitată de text (fereastra contextuală). Acest lucru funcționează pentru sarcini mici, dar nu și atunci când o bază de cunoștințe cuprinde mii de pagini. Chiar și atunci când fereastra contextuală este suficientă, performanța poate scădea din cauza problemei „acului în carul cu fân”.

  • RAG („generare augmentată prin regăsire”) a devenit un tipar foarte răspândit: întreții o bază de cunoștințe (documente, wikiuri, politici, transcrieri etc.), efectuezi o căutare semantică pe baza interogării utilizatorului pentru a regăsi cele mai relevante fragmente folosind reprezentări vectoriale, apoi trimiți acele fragmente către LLM împreună cu întrebarea. Astfel se restrânge contextul modelului și, dacă procesul este implementat corect, se poate îmbunătăți calitatea răspunsurilor și reduce numărul halucinațiilor.

  • pgai este o extensie Postgres open-source (însoțită de instrumente auxiliare) care te ajută să creezi fluxuri de lucru pentru „regăsire cu IA” pe baza PostgreSQL, o bază de date open-source de încredere.

  • Ideea principală este transferarea unei părți mai mari din fluxul RAG standard în stratul bazei de date (preluare → segmentare → vectorizare → sincronizarea reprezentărilor vectoriale), în loc ca baza de date să fie tratată drept „simplu spațiu de stocare” pentru acestea.

  • Primele impresii sunt promițătoare, dar soluția nu mai este potrivită de îndată ce fluxul RAG devine cât de cât complicat, în special în privința metodelor de segmentare. Vom urmări însă îndeaproape acest proiect.

Tiparul RAG

Există numeroase modalități de a crea un sistem RAG. Pentru o prezentare mai amplă a diferitelor abordări, citește Exemple practice de soluții RAG personalizate. Odată ce calitatea devine importantă, opțiunile de proiectare se dovedesc surprinzător de complexe, iar abordarea „implicită” obișnuită arată, în general, astfel:

  1. Adună un set de documente.

  2. Împarte-le în fragmente. Există numeroase metode pentru aceasta (de exemplu, după paragrafe sau grupări semantice).

  3. Transformă fiecare fragment într-o reprezentare vectorială.

  4. Stochează reprezentările vectoriale într-o bază de date vectorială (Pinecone, Milvus etc.) sau în Postgres, folosind pgvector.

  5. În momentul interogării, caută fragmentele cele mai apropiate `și transmite-le către LLM (din nou... și aici există multe modalități de a proceda).

În multe stive tehnologice, pașii (1)–(3) au loc în afara bazei de date, în codul aplicației sau într-un flux de date, iar baza de date este folosită în principal pentru:

  • stocarea reprezentărilor vectoriale

  • căutarea în reprezentările vectoriale

Scopul pgai

pgai este o extensie Postgres (open-source, dezvoltată de Timescale) care încearcă să estompeze această delimitare.

În loc să trateze reprezentările vectoriale ca pe ceva ce aplicația trebuie să gestioneze manual, pgai le transformă într-o funcție a bazei de date:

  • Definești tabelul sau documentele pe care vrei să le vectorizezi.

  • Specifici modelul de vectorizare și strategia de segmentare.

  • pgai gestionează restul, inclusiv actualizarea reprezentărilor vectoriale pe măsură ce se modifică datele-sursă.

Promisiunea este atrăgătoare:

  • Mai puțin cod de integrare personalizat care trebuie întreținut.

  • Ar trebui să fie mai ușor ca reprezentările vectoriale să rămână „actuale” atunci când se modifică documentele-sursă.

  • Postgres/pgai gestionează reîncercările, limitele de rată, sarcinile eșuate etc.

Notă pentru cititori: pgai include pgvector (o altă extensie Postgres foarte populară pentru RAG). pgvector adaugă în Postgres stocarea vectorilor și căutarea după similitudine, iar pgai se bazează pe aceste funcții pentru a automatiza pașii fluxului RAG, precum segmentarea, vectorizarea și menținerea la zi a reprezentărilor vectoriale.

Primele impresii despre pgai

Ce ne-a plăcut

1) Este ușor de pus în funcțiune.

Scenariul ideal este destul de simplu:

  • Descarcă imaginile Docker de la Timescale (baza de date + procesul worker).

  • Furnizează cheia API a furnizorului de vectorizare.

  • Rulează câteva instrucțiuni SQL pentru a declara vectorizatorul (în esență: ce trebuie vectorizat, cum se segmentează și ce model se folosește).

Apoi, pgai configurează un proces worker separat pentru vectorizare, care generează asincron reprezentările vectoriale (de exemplu, la fiecare 5 minute sau la orice interval dorești).

2) Este util ca întregul flux să ruleze „aproape” de baza de date.

pgai poate prelua conținut din tabele, dar poate și încărca documente din servicii precum S3, apoi le poate analiza, segmenta și vectoriza. Poate gestiona și diverse formate de documente text, precum PDF, Markdown etc.

Ce ni s-a părut restrictiv

1) Pierzi mult control (iar RAG necesită uneori control).

Sistemele RAG de înaltă performanță (măsurată prin calitatea răspunsurilor) necesită adesea fluxuri personalizate, cum ar fi:

  • reguli personalizate de segmentare (după titluri, pagini, intervențiile vorbitorilor etc.)

  • segmentare care ține cont de metadate (păstrează titlurile secțiunilor, marcajele temporale, autorii și tipul documentului)

  • strategii de vectorizare diferite pentru fiecare tip de document

pgai oferă mai puțină flexibilitate în privința aspectelor de mai sus.

În prezent, există două strategii principale de segmentare: un separator de text după caractere și unul recursiv, plus opțiunea de a nu segmenta. Acestea pot fi suficiente în unele cazuri de utilizare, însă multe sisteme RAG de producție necesită mai multă personalizare.

Ar fi excelent dacă Timescale ar putea integra unele dintre strategiile mai sofisticate de segmentare întâlnite în biblioteci precum Chonkie și ar oferi și compatibilitate cu arhitecturi avansate precum regăsirea contextuală de la Anthropic.

2) Axat pe text, nu multimodal.

Multe probleme RAG interesante nu mai implică exclusiv text:

  • fișiere PDF cu diagrame

  • capturi de ecran/imagini

  • înregistrări audio

  • secvențe video

Chiar dacă poți „extrage text” din aceste surse, procesul nu echivalează cu un flux de vectorizare cu adevărat multimodal.

Dacă pgai va accepta în cele din urmă modele multimodale de la un capăt la altul (încărcare → segmentare → vectorizare pentru imagini mari, fișiere audio și video stocate în S3, cu sincronizare fiabilă), va deveni o soluție convingătoare. În prezent însă, este un flux de vectorizare a textului.

3) Dacă ai nevoie doar de reprezentări vectoriale, s-ar putea să nu ai nevoie de pgai.

Dacă fluxul tău de preluare este deja personalizat (sau trebuie să fie), atunci „vectorizarea fragmentelor de text” nu este cea mai dificilă parte a unui sistem RAG. În acest caz, pgai rezolvă cea mai ușoară parte a problemei.

În plus, dacă baza ta de cunoștințe este actualizată rar, sincronizarea automată a reprezentărilor vectoriale nu aduce la fel de multă valoare.

Stratul text-to-SQL

O modalitate deosebit de bună de a folosi pgai ar fi implementarea unei interfețe text-to-SQL peste bazele tale de date. Acest lucru se poate realiza destul de ușor cu modulul semantic_catalog oferit de pgai. Configurează-l pur și simplu astfel:

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"

apoi determină catalogul semantic să parcurgă dicționarele de date cu pgai semantic-catalog create. Astfel se generează din depozitul de date un context care arată aproximativ astfel:

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

Acest context este acum disponibil pentru pgai în mai multe moduri:

Prin căutare semantică:

Această interogare va returna tabelele, funcțiile și celelalte obiecte care ar putea fi relevante pentru interogarea ta în limbaj natural:

Bash

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

Obținerea contextului brut:

Această comandă va reda contextul YAML brut asociat interogării tale în limbaj natural:

Bash

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

Generarea codului SQL:

Sau poți genera direct codul SQL brut necesar pentru a răspunde interogării. Contextul de la pasul anterior este trimis unui LLM, care generează răspunsul:

Bash

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

Cum poți folosi pgai chiar acum

Dacă dezvolți un sistem RAG relativ simplu, merită să încerci pgai dacă îți dorești:

  • Postgres ca sursă oficială de date,

  • cât mai puțin cod de integrare,

  • reprezentări vectoriale sincronizate automat,

  • o modalitate rapidă de a aplica o soluție text-to-SQL bazelor tale de date,

  • să experimentezi cu noi instrumente RAG și extensii Postgres.

Când am recomanda prudență

Probabil că merită să mai aștepți înainte de a adopta pgai dacă fluxul tău RAG necesită oricare dintre următoarele:

  • logică foarte personalizată pentru preluare sau segmentare

  • numeroase tipuri de documente cu cerințe diferite de analiză

  • reprezentări vectoriale multimodale

În cele din urmă, deși este clar că pgvector a fost adoptat pe scară largă, nu se știe dacă pgai va suscita același interes și, implicit, va beneficia de același nivel de asistență (ținând cont și de faptul că există doar de aproximativ 18 luni).

Grafic GitHub cu evoluția numărului de stele, care arată adoptarea pgai de la Timescale în timp.

Rezumat

pgai propune o abordare interesantă pentru RAG, prin care bazele de date preiau mai multe dintre operațiunile de rutină, simplificând astfel codul aplicației.

În prezent, este:

  • utilizabil și cu adevărat plăcut pentru configurații RAG simple

  • insuficient de flexibil pentru fluxuri mai personalizate (în special multimodale)

Este promițător și merită cu siguranță urmărit pentru a vedea cum evoluează.

Autor

Andrew Liubinas