De native RAG maakt deel uit van denative AI die is geïntegreerd in de Aurabasebackend, naast NL2SQL: geen service van derden die bovenop een algemene basis moet worden gemonteerd. Vereisten om deze tutorial te volgen: een bestaand Aurabase-project, een geconfigureerde LLM-provider (OpenAI of Google Gemini voor insluitingen, een van de drie native providers voor generatie) en een project-API-sleutel.
- Een Aurabase RAG-pijplijn bestaat uit twee aanroepen:
ragIngest()om een document te indexeren,rag()om een query uit te voeren en een antwoord te genereren. Chunking, insluitingen en zoeken naar vectoren worden aan de serverzijde beheerd. - Onder de motorkap bevinden zich standaard PostgreSQL en pgvector: een
embeddings-tabel met één vectorkolom per dimensieklasse (768, 1536, 3072) en een gedeeltelijke HNSW-index per klasse. - Chunking maakt gebruik van een echte tokenizer (
tiktokeno200k), met configureerbare overlap en een anti-explosiebeveiliging voor grote documenten. - De opgehaalde inhoud wordt geneutraliseerd voordat deze in de prompt wordt geïnjecteerd: een document dat probeert aan zijn tag te ontsnappen om systeeminstructies te vervalsen, wordt expliciet onschadelijk gemaakt.
- Alleen OpenAI en Gemini genereren inbedding aan de Aurabase-kant. Anthropic/Claude heeft geen openbare insluitings-API, deze blijft gereserveerd voor het genereren van het uiteindelijke antwoord.
Hoe deze RAG-pijplijn werkt
De pijpleiding vindt plaats in vijf fasen. Bij opname wordt de tekst opgedeeld, elk deel wordt in batch gevectoriseerd en vervolgens opgeslagen. Bij het bevragen wordt de vraag op zijn beurt gevectoriseerd, vergeleken met de brokken die zijn opgeslagen door middel van cosinus-gelijkenis, en de dichtstbijzijnde fragmenten worden geïnjecteerd in de prompt die naar het generatiemodel wordt gestuurd.
Chunking (tiktoken) → Inbedding (batch) → pgvectoropslag (HNSW) → Zoeken naar gelijkenis → Uitgebreide generatie
Een architectonisch detail dat er bij de productie toe doet: er wordt geen Postgres-verbinding tot stand gebracht tijdens netwerkoproepen naar de inbeddings- of generatieprovider. De DB-transactie wordt gesloten vóór de externe oproep en wordt daarna opnieuw geopend, zodat een gedeelde PgBouncer-backend nooit wordt geblokkeerd voor netwerklatentie van derden.
Maak het project
In tegenstelling tot een typische zelf-gehoste pgvector hoeft u CREATE EXTENSION vector niet uit te voeren of zelf een tabel te maken voor deze pijplijn. Het embeddings-schema van het project, met zijn vectorkolommen en HNSW-indexen, wordt automatisch ingericht wanneer het project wordt gemaakt.
De inbeddingsprovider wordt eenmalig geconfigureerd, aan de projectzijde (Studio → IA → Leveranciers). Het is deze provider die de effectieve dimensie van uw vectoren bepaalt, dus de kolom die wordt gebruikt in de tabel embeddings.
Indexeer uw documenten met ragIngest()
Eén aanroep is voldoende om een document te indexeren: de tekst wordt in stukken verdeeld, elk stuk wordt gevectoriseerd en vervolgens opgeslagen in de gevraagde naamruimte. De splitsing maakt gebruik van een echte tokenizer (tiktoken, codering o200k_base), niet een eenvoudige splitsing door spaties, wat correct blijft bij tekst zonder spaties, zoals in sommige Aziatische talen.
In onbewerkte HTTP is de equivalente route POST /v1/ai/{project_id}/rag/ingest, geverifieerd door de API-sleutel van het project.
De opname is standaard idempotent: er wordt automatisch een document-ID afgeleid (SHA-256-hash van de inhoud, of metadata.document_id als u deze opgeeft). Door dezelfde inhoud opnieuw op te nemen, worden de bestaande delen vervangen in plaats van deze te dupliceren, waardoor een periodieke synchronisatietaak veilig opnieuw kan worden afgespeeld.
Wat er daadwerkelijk in Postgres terechtkomt
Geen eigen magie hier: de tabel die uw vectoren ontvangt is een gewone Postgres-tabel, met één vector kolom per dimensieklasse en een gedeeltelijke HNSW-index per kolom (alleen actief op de rijen die deze bevolken). Hier is de echte definitie, vereenvoudigd:
Elke zoekopdracht vergelijkt de vectoren met de cosinusafstandsoperator (<=>), degene waarop de operatorklassen vector_cosine_ops en halfvec_cosine_ops van de index gericht zijn. Voor details over de afweging tussen terugroeping en latentie van HNSW versus IVFFlat, zie het artikel gewijd aan HNSW-indexering. Voor de keuze van de inbeddingsdimensie zelf, zie de vergelijking 768 vs 1536 vs 3072.
Query's uitvoeren en antwoorden genereren met rag()
Aan de kant van de zoekopdracht combineert rag() de vectorisering van de vraag, het zoeken op gelijkenis in de naamruimte, de constructie van de uitgebreide prompt en de aanroep naar het generatiemodel, in een enkele netwerkrondreis aan de clientzijde.
Het antwoord bevat het gegenereerde antwoord en de bronnen ervan, waarbij de provider daadwerkelijk gebruikt:
De opgehaalde inhoud wordt nooit onbewerkt in de systeemprompt geïnjecteerd. Dit zijn onbetrouwbare gegevens (door gebruiker geüpload, geïndexeerde pagina): een document dat bijvoorbeeld een tag voor het afsluitende gedeelte bevat, gevolgd door valse instructies, wordt vóór de montage geneutraliseerd, de punthaken worden vervangen door haakjes, de tekst blijft behouden maar de structuur wordt onschadelijk gemaakt.
Als rag() niets vindt, ook al is uw naamruimte niet leeg, bevat het antwoord een expliciete waarschuwing in plaats van een misleidende stilte: uw corpus is waarschijnlijk geïndexeerd onder een ander model of een andere inbeddingsdimensie. Indexeer het opnieuw via POST /v1/ai/{project_id}/rag/{namespace}/reindex.
Van LangChain en een handgemaakte pgvector: wat verandert
Als je al een RAG-chatbot op PostgreSQL met LangChain hebt gebouwd, heeft elke handmatige steen hier een beheerd equivalent aan de serverzijde, zonder de onderliggende database te wijzigen.
| Het opbreken van de tekst | RecursiveCharacterTextSplitter om zelf in te stellen | ragIngest(): geïntegreerde tiktoken chunking, standaard 512 tokens / 64 overlappend |
|---|---|---|
| Inbedding | Handmatige oproep naar OpenAIEmbeddings, beheer van batchlimieten | Automatisch batchgewijs, ingebouwde tijdelijke nieuwe poging |
| Vectoropslag | pgvector table + HNSW index om zelf te creëren en te migreren | Schema en indexen ingericht per project |
| Zoeken + prompt | PGVector.similarity_search() en vervolgens de prompt handmatig samenstellen | rag(): zoeken en verbeterde generatie in één aanroep |
| Herstelde inhoud | Geïnjecteerd zoals aangegeven in de prompt | Automatische neutralisatie van structuurtags vóór montage |
Migreert u een bestaand project gebouwd op Supabase met deze vorm van handmatige montage? De migratielogica voor de rest van de backend (schema, RLS-beleid, SDK) wordt behandeld in onze Supabase naar Aurabase migratiegids.
Instellingen en limieten waar u rekening mee moet houden voordat u in productie gaat
Drie instellingen zijn rechtstreeks van invloed op de kosten en latentie, allemaal geverifieerd in de aura-aiservicecode. Het aantal pogingen voor een tijdelijke inbeddingsoproep (netwerkfout, providerfout 429) is standaard 3, met een basisuitstel van 100 ms. Grote documenten worden standaard ingebed in subbatches die beperkt zijn tot 2048 delen, om de API-plafonds van de leveranciers te respecteren zonder dat er één groot document mislukt. Een vangrail (standaard 10.000 chunks, configureerbaar) verwerpt expliciet de opname van een document dat een afwijkend aantal chunks zou produceren.
Aan de zoekzijde wordt de grootte van de HNSW-kandidatenlijst automatisch aangepast naar max(64, top_k × 4): hoe meer resultaten u opvraagt, hoe meer kandidaten de index onderzoekt om de herinnering te behouden. Een vaste waarde blijft mogelijk via een omgevingsvariabele als uw corpus een bepaald profiel heeft.
De vectorruimten van verschillende modellen worden nooit met elkaar vergeleken: elke zoekopdracht blijft beperkt tot het huidige inbeddingsmodel, en het veranderen van modellen vereist een expliciete herindexering in plaats van een stille omschakeling die de consistentie van de resultaten zou verbreken.
Huidige limieten waar u rekening mee moet houden
De insluitingsdimensie moet in een van de drie ondersteunde klassen vallen: 768, 1536 of 3072. Een provider die een andere dimensie retourneert, wordt afgewezen met een expliciete fout en mag nooit worden afgekapt of stilzwijgend worden gecast.
Het genereren van inbedding is alleen beschikbaar via OpenAI of Google Gemini van de drie native providers: Anthropic/Claude stelt geen openbare inbeddings-API beschikbaar, dus deze wordt alleen gebruikt voor het genereren van het uiteindelijke antwoord in deze pijplijn, nooit voor vectorisatie.
De JavaScript SDK maakt de overschrijvingen top_k en threshold op de aanroep rag() nog niet zichtbaar: ze blijven toegankelijk in directe HTTP, respectievelijk beperkt tot [1, 50] en [0, 1], maar niet vanaf aura.ai.rag() zoals nu het geval is. De standaarddrempel voor gelijkenis (0,3) is opzettelijk tolerant; beperk het tot een compact corpus om irrelevante bronnen in de prompt te vermijden.
Om verder te gaan
De RAG behandelt vragen over ongestructureerde inhoud (documenten, notities, tickets). Voor vragen over uw relationele gegevens vertaalt Aurabase's native NL2SQL een vraag direct naar gevalideerde SQL. Voor details over de hierboven genoemde HNSW-parameters en dimensieklassen, zie het artikel over HNSW-indexering en de vergelijking van inbeddingsafmetingen. De volledige API-referentie blijft de RAG & pgvector-documentatie en de AI Gateway-documentatie.