Skip to content

RAG for large schemas

Scale-up guide

Big databases need retrieval. @askdb/rag chunks the same schema artifact and indexes it in a vector store. Per question, AskDB retrieves the relevant slice instead of stuffing the whole thing into every prompt.

A rule of thumb: if your schema artifact has more than ~30 tables, or if rendered DDL routinely exceeds 8K tokens, you’ll save money and improve generation quality by retrieving instead of stuffing.

The retrieval trigger is configurable. By default ask() uses retrieval when a retriever is supplied and the schema’s chunk count exceeds 30.

Terminal window
npm install @askdb/rag
# pgvector store (recommended)
npm install pg

You’ll also need an embedder. The Vercel AI SDK providers from Bring your own model work as embedders too — most teams use OpenAI’s embeddings.

pgvector is the recommended store: it lives in Postgres alongside your other data, you already know how to back it up, and AskDB ships ready-made DDL.

There are three provisioning paths — pick the one that matches your deploy story.

Studio auto-provisions the pgvector schema on first use. Configure the store in askdb.config.ts:

export default {
rag: {
embedder: "openai",
store: "pgvector",
storeConfig: {
pgvector: {
databaseUrl: process.env.PGVECTOR_URL,
},
},
},
};

Launch Studio (npx askdb studio --schema ./my-app.schema) and the first RAG operation creates the table.

Path 2: askdb-rag setup-store (CI / staging)

Section titled “Path 2: askdb-rag setup-store (CI / staging)”

One idempotent command. All DDL uses IF NOT EXISTS so it’s safe to re-run on every deploy.

Terminal window
askdb-rag setup-store \
--pg-url "$PGVECTOR_URL" \
--dimensions 1536

Drop it into a deploy step:

- name: Provision pgvector schema
run: askdb-rag setup-store --pg-url "${{ secrets.PGVECTOR_URL }}" --dimensions 1536

For production teams that want all DDL in a versioned migration file:

import { createPgvectorStore } from "@askdb/rag/stores/pgvector";
const store = createPgvectorStore({
connectionString: process.env.DATABASE_URL!,
dimensions: 1536,
});
console.log(store.setupSql());

Paste the output (CREATE EXTENSION, CREATE TABLE, CREATE INDEX) into Flyway, Liquibase, Drizzle, or whatever migration runner your team uses.

After the store is provisioned, index your schema’s chunks:

import {
buildSchemaIndex,
createAiSdkEmbedder,
createPgvectorStore,
loadChunkerSourcesFromDir,
} from "@askdb/rag";
import { openai } from "@ai-sdk/openai";
const store = createPgvectorStore({
connectionString: process.env.PGVECTOR_URL!,
dimensions: 1536,
});
const embedder = createAiSdkEmbedder({
model: openai.textEmbeddingModel("text-embedding-3-small"),
});
const { retriever, stats } = await buildSchemaIndex({
schema: loadChunkerSourcesFromDir("./my-app.schema"),
store,
embedder,
embedderId: "openai:text-embedding-3-small", // changes force a full re-embed
lockFilePath: "./my-app.schema/schema.lock.json", // skip unchanged chunks
});

buildSchemaIndex chunks the artifact, embeds only what changed since the last run (tracked in schema.lock.json), and returns a ready-to-use retriever plus indexing stats.

Pass the retriever to ask(). AskDB calls it with the question and substitutes the retrieved chunks for the full DDL in the prompt.

If you just ran buildSchemaIndex in the same process, pass its returned retriever directly. To retrieve in a separate process (the common production shape), rebuild one from the store:

import { ask } from "@askdb/core";
import { createRetriever } from "@askdb/rag";
const retriever = createRetriever({ store, embedder });
const { sql } = await ask({
question,
schema,
dialect: "postgres",
model,
retriever,
retrievalThresholdChunks: 30, // default
});

Chunks marked as sensitive in the schema artifact carry that flag into the store. Configure your indexing policy to exclude sensitive content from embeddings if your trust model requires it — see the sensitive fields contract on GitHub for the full rules.

To isolate multiple AskDB deployments in the same Postgres database, pass a custom table name and a matching embedding dimension:

Terminal window
askdb-rag setup-store \
--pg-url "$DATABASE_URL" \
--pg-table myapp_rag_chunks \
--dimensions 1536

Match the same table value in askdb.config.ts under rag.storeConfig.pgvector.table.