En vektordatabase løser retrieval-delen af en RAG-pipeline. Men et rigtigt produkt skal også ingeste indhold, style spørgsmål mod databasen, rerank'e resultaterne og til sidst generere et svar, og det skal kaldes fra jeres egen kode. Det er det, vi netop har udgivet to officielle klient-biblioteker til: liviate-rag-py til Python og liviate-rag-dotnet til .NET.
Begge wrapper den samme underliggende pipeline, ingest, embed, retrieve, rerank og (valgfrit) generér, i en håndfuld linjer kode, i stedet for at man selv skal bygge HTTP-kald, autentificering og fejlhåndtering op omkring vores API.
Python: liviate-rag
pip install liviate-rag
from liviate_rag import RAGClient
client = RAGClient(api_key="...") # eller sæt LIVIATE_API_KEY
client.ingest("handbook.pdf", collection="hotel-kirstine")
result = client.query("Har I parkering?", collection="hotel-kirstine", model="anthropic/claude-sonnet-5")
print(result.answer)
print(result.sources)
Vil I selv styre, hvilken model der genererer svaret, kan I nøjes med retrieval-delen og hente ranked kontekst alene:
context = client.retrieve("Har I parkering?", collection="hotel-kirstine", top_k=5)
For asynkron kode findes AsyncRAGClient med samme metodenavne, klar til at bruges med async/await.
ingest() genkender selv, om input er en fil, en URL, en ren tekststreng eller en stream, og understøtter PDF, DOCX, Markdown, TXT, CSV, JSON og HTML. Skal en hel hjemmeside crawles i stedet for en enkelt fil, er der en separat, explicit metode til det: client.ingest_site("https://example.com", collection="x", max_pages=200).
.NET: Liviate.Rag
dotnet add package Liviate.Rag
using Liviate.Rag;
await using var client = new RagClient(); // eller new RagClient(apiKey: "sk-...")
await client.IngestAsync("handbook.pdf", "hotel-kirstine");
var result = await client.QueryAsync("Har I parkering?", "hotel-kirstine", "anthropic/claude-sonnet-5");
Console.WriteLine(result.Answer);
.NET-versionen er en port af Python-biblioteket, men med én strukturel forskel: der er ikke en separat sync- og async-klient. .NET's indbyggede async/Task gør den opdeling overflødig, så alle I/O-kald på RagClient er async Task (eller IAsyncEnumerable for streamet generation).
Samme retrieval-only mønster findes her:
var context = await client.RetrieveAsync("Har I parkering?", "hotel-kirstine", topK: 5);
For en ingest, der ikke skal blokere, mens den kører, er der StartIngest, som returnerer et IngestJob med det samme i stedet for at afvente, at den er færdig.
Ærligt om status
De to biblioteker er ikke lige langt. Python-versionen er en v1-scaffold, bygget efter rimelige antagelser om nogle af request- og response-formaterne, hvor et par kontrakter mod selve backend'en endnu ikke er endeligt bekræftet, det er markeret direkte i koden med kommentarer, hvor det er relevant.
.NET-porten kom bagefter og er bygget direkte mod kontrakter, der allerede var bekræftet live i produktion: Ingest → Retrieve → Query er alle verificeret end-to-end mod den rigtige pipeline, ikke kun mod en mock. Til gengæld er IngestSiteAsync i .NET endnu ikke implementeret, den kaster en NotImplementedException, så skal en hel hjemmeside crawles fra .NET i dag, gøres det ved at kalde IngestAsync med en liste af enkelte side-URL'er i stedet.
Begge biblioteker er open source, og begge tager imod issues og PR'er.
Hvor det passer ind
Bibliotekerne dækker selve kald-laget. Det, de kalder ind i, er den samme managed vektordatabase og RAG-pipeline, vi har skrevet om tidligere, skalering, indeksering og isolation mellem kunder håndteret for jer, uden at I selv skal drifte databasen bagved.
Er I i gang med at bygge noget, der skal ingeste jeres eget indhold og svare på baggrund af det? Skriv til os, og lad os tage en snak om, hvor I kunne starte.