Mye har blitt sagt om språkmodellers tendens til å hallisunere.
Det er ingen tvil om modellene er en utrolig teknologi, noe som gjør det ekstra leit at de tar seg kunstneriske friheter når det kommer til sannheten.
En velkjent teknikk i det grynede feltet AI Engineering er bruken av RAG – Retrievel Augmented Generation – til å senke muligheten for slike kunstneriske friheter.
RAG – Retrievel Augmented Generation
Konseptet er ganske enkelt: For hvert spørsmål legger du til relevante tekstsnutter som kontekst til modellen, som da baserer svarene sine på tekstsnuttene, fremfor egen fantasi.
For å gjøre dette genererer du en vektor-embedding for hver av teksnuttene og spørsmålet ditt, og bruker vektorenes likhet i embedding-spacet som et mål på hvor relevant en gitt teksnutt er.
Den tradisjonelle måten å gjøre dette på er gjennom en vektordatabase som Pinecone, chroma eller Postgres med pgvector.
Til forskjell fra tradisjonelle databaser trenger du ikke å beskrive hvordan dataen din ser ut i form av kolonner, tabeller og fremmednøkler. Dette gjør metoden veldig fleksibel.
NAV hiver seg over AI: – Skal ikke ta jobbene fra noen
Ingen gratis lunsj
Men, som de pleier å si, there is no free lunch. Det du vinner på mer fleksibel datalagring taper du på mindre fleksibel spørring.
Der du før hadde hele friheten til SQL-spørringer, har du nå kun én operasjon: "Finn ting tekst som ligner på dette".
Metadata du vil bruke i spørringer må trekkes ut av teksten og legges til som kolonner eller relasjoner. Men, da tekst ofte beskriver komplekse sammenhenger, fører dette til mye jobb med eksplisitt datamodellering.
Det man altså vil ha er en mellomting: En database som kan beskrive arbitrære, fleksible sammenhenger mellom objekter samtidig som man kan bruke vektor-søk.
Neo4j
Det er her Neo4j med node-embeddinger kommer inn.
Grafstrukturen i databasen gir deg muligheten til å representere helt arbitrære datastrukturer, mens node-embeddingene lar deg bruke vektor-søk for å filtrere ned søket ditt.
Resultatet er at du kan gjøre fantastiske spørringer som dette:
MATCH (bike:Bicycle {name: 'X'})
CALL db.index.vector.queryNodes('wheel-embedding', 5, 'passer på landevei')
YIELD node AS wheel
WITH bike, wheel
MATCH (wheel)-[:FITS]->(bike)
RETURN wheel.name AS name
Her finner vi først sykler med navnet 'X', så finner vi hjul hvor embeddingen ligner 'passer til landevei', før vi igjen returnerer alle hjulene som passer til sykkelen.
Her har du alle fordelene: Du er ikke begrenset av en relasjonell database, men du kan fortsett gjøre komplekse spørringer.
Så ja, for å svare på tittelen: Neo4J som RAG-database er en perfect fit.