pgvector store
The production RAG store — cosine/L2/inner similarity over a vector(N) column on Postgres + pgvector, through @adonisjs/lucid, with a published migration and safe identifier handling.
retrievers.pgvector is the production retriever: it stores chunk embeddings in a vector(N) column and ranks them with pgvector's distance operators over @adonisjs/lucid. Postgres + the pgvector extension only. The Lucid peer is imported lazily inside the factory thunk, so it stays optional.
Run the migration
node ace configure @adonis-agora/agent publishes a create_agent_rag_chunks migration alongside the core tables. Apply it (Postgres):
node ace migration:runIt provisions the vector extension, the chunk table (default agent_rag_chunks), and the metric's index opclass.
Wire the retriever
import { defineConfig, retrievers } from '@adonis-agora/agent'
export default defineConfig({
model: () => aiSdkModel(openai('gpt-4o-mini')),
retriever: retrievers.pgvector({
embedder: myEmbedder,
dimension: 1536,
}),
retrievalTopK: 5,
})Configuration
| Field | Default | Meaning |
|---|---|---|
embedder | — | The EmbeddingProvider (query + ingestion), or a lazy factory. Required. |
db | resolved lazily | A structural Lucid DB handle (bring-your-own). Omit to resolve @adonisjs/lucid's default db service inside the thunk. |
connection | default connection | Lucid connection name (used only when db is omitted). |
table | agent_rag_chunks | Chunk table name. Validated against a strict identifier regex. |
dimension | 1536 | Embedding width — must match the model (e.g. 1536 for text-embedding-3-small). |
metric | cosine | Similarity metric / distance operator (cosine, l2, inner). |
columns | mirror defaults | Override the physical column names (each validated). |
ensureSchema | false | Provision the extension/table/index at boot (idempotent DDL). Handy for tests; production should run the migration. |
documents | — | Documents to chunk → embed → upsert at boot. |
chunkSize / overlap | 800 / 100 | Chunking parameters. |
Identifiers are validated, embeddings are bound
The store composes raw SQL for pgvector's operators (Lucid has no native vector type), but every table/column name is validated against a strict identifier regex before it is ever spliced in, and the query embedding is passed as a ?::vector binding — never string-concatenated. Scores are normalized so a higher score always means more relevant, across all three metrics.
Scores and ranking
Each metric maps to a pgvector operator (<=>, <->, <#>) and an index opclass. The store rewrites the raw distance into a monotonically-increasing relevance score on each returned Passage, so downstream code (inject-mode context, a reranker, your UI) can treat score uniformly regardless of the configured metric.
For the in-memory alternative and the retrieval SPIs, see RAG & retrieval.
RAG & retrieval
Ground the agent in your own corpus — the Retriever, EmbeddingProvider, and Reranker SPIs, the memory and pgvector retrievers, and always-on "inject" retrieval that folds cited passages into the system prompt.
Qdrant store
A managed vector database as the RAG backend — collection provisioning, payload-filter ACLs, batched upserts, and the metric handling that keeps scores comparable with pgvector.