Skip to main content
rag.open returns a RagSession: an open corpus you ingest into, search, and query. Each session owns its own native index, so two sessions over different documents can be live at once.

Opening a session

open loads both models, downloading them if needed. Passing nil for llmModel gives a retrieval-only session: search works, and query throws .modelNotLoaded. ModelRef is ExpressibleByStringLiteral, so embeddingModel: "all-minilm-l6-v2" also works.

RagSession

RagSession is an actor, so every call is await.

Ingesting documents

Or read from disk and let the backend do the parsing:
Batch ingest takes an array:
Chunking happens inside the session, controlled by RagConfig.

Retrieval without generation

Match carries text, score, and metadata. topK defaults to whatever the session was opened with.

Grounded answers

RagResult carries answer, sources, and the same metrics block generation results use: inputTokens, outputTokens, timeToFirstTokenMs, tokensPerSecond, requestId, model.

Streaming

.retrieved fires once, before the first token, so the UI can show sources while the answer is still being written.

RagConfig

Setting persistPath turns index persistence on, so the corpus survives a relaunch.

Stats and cleanup

Calling anything after close() throws .invalidState.

Managing session lifetime

Sessions are cheap to hold and expensive to rebuild, so keep one per corpus and close it when the corpus goes away.

Embeddings

When you want vectors rather than a session, embeddings.embed returns one per input, in input order.
Embedding carries index and vector. EmbedOptions controls post-processing:
embed auto-loads an embedding model the way generation does.

Reranking

A cross-encoder scores each document against the query directly, which is more accurate than cosine similarity over embeddings and slower. The usual shape is to retrieve widely with embeddings, then rerank the shortlist.
RankedResult carries index, pointing back into the documents you passed, and relevanceScore. Results are sorted best first. topN of nil returns all of them. Rerank has no model category, so the lifecycle cannot auto-load it. A rerank model must already be resident under the rerank component or the call throws .modelNotLoaded.

Error handling

LLM Generation

Generation options the query path shares

Configuration

Model registry and lifecycle