Theo Docs
TheoKitTheoCloudTheo KnowledgeTheo PromptsTheo MemoryTheo GuardrailsTheo TracesTheoDB

Overview

RAG with citations, on your own Postgres.

Theo Knowledge is the open-source RAG engine of the Theo ecosystem — drop documents in, get cited answers out. It runs the whole pipeline (ingest → parse → chunk → embed → store → retrieve → answer) on your Postgres (with pgvector) and your LLM key: no proprietary vector database, no vendor lock-in, Apache-2.0. Use it as a composable TypeScript library (@usetheo/rag), a typed SDK, or a REST/MCP service — all validated by one Zod contract.

Pre-release (rc.60). The core ingest → retrieve → answer flow is feature-complete, but the package is not yet on npm — run it from source for now. We don't claim it production-ready until backed by sustained usage evidence.

Install

git clone https://github.com/usetheodev/theo-rag.git
cd theo-rag
pnpm install

Requires Node ≥ 20 and any Postgres with the pgvector extension. The core library publishes as @usetheo/rag (with @usetheo/rag-sdk for the typed HTTP client and @usetheo/rag-mcp for the MCP server).

Quick start

Compose a pipeline from swappable stages and ask a question — the answer comes back with the exact chunks it used:

answer.ts
import { Pool } from 'pg';
import { createUnpdfLoader } from '@usetheo/rag/loaders';
import { createTiktokenTokenizer, createRecursiveCharacterChunker } from '@usetheo/rag/chunkers';
import { createOpenAIEmbedder } from '@usetheo/rag/embedders';
import { createVectorRetriever } from '@usetheo/rag/retrievers';
import { createOpenAILlmProvider } from '@usetheo/rag/llm-providers';
import { createAnswerPipeline } from '@usetheo/rag/pipeline';

const pool = new Pool({ connectionString: process.env.THEORAG_PG_URI });
const embedder = createOpenAIEmbedder({ model: 'text-embedding-3-small' });

const pipeline = createAnswerPipeline({
  pool,
  loader: createUnpdfLoader(),
  chunker: createRecursiveCharacterChunker({
    tokenizer: createTiktokenTokenizer(),
    chunkSize: 512,
    chunkOverlap: 64,
  }),
  embedder,
  retriever: createVectorRetriever({ pool, embedder }),
  llmProvider: createOpenAILlmProvider({ apiKey: process.env.OPENAI_API_KEY, model: 'gpt-4o-mini' }),
});

const answer = await pipeline.answer('What is our refund window?');
// answer.citations → [{ document_id, chunk_id }]

Prefer HTTP? The @usetheo/rag-sdk RagClient mirrors the same surface (theo.answers.create(...), theo.answers.stream(...)), and the REST API exposes POST /v1/answers returning { answer, citations, retrieved_chunks }.

What you get

Swappable pipeline

Each stage (load, chunk, embed, retrieve, answer) sits behind an interface — bring your own loader, embedder, or LLM. `createAnswerPipeline` exposes `ingest`, `query`, `answer`, `answerStream`.

Three retrieval strategies

Dense `vector` (pgvector HNSW cosine), lexical `keyword` (Postgres FTS), and `hybrid` (Reciprocal Rank Fusion), plus Mongo-style metadata filters.

Citations by default

Every answer maps back to the exact chunks used — `citations: [{ document_id, chunk_id }]`. No ungrounded prose.

Self-reflective answers (Self-RAG)

Opt-in `self_check` grades groundedness and populates `confidence` (high / medium / low), regenerating once if ungrounded.

Corrective retrieval (CRAG)

Opt-in `corrective` relevance-gates chunks, rewrites the query and re-retrieves once when results are thin — bounded and fail-soft.

Streaming + evaluation

Token-by-token SSE via `answerStream` / `answers.stream()`, plus a `runEvaluation` harness for recall@k / MRR / faithfulness.

Where to go next

On this page