Docs menu
RAG pipeline — chunking, pgvector, GraphRAG
Deterministic chunking, a durable pgvector store, and similarity-graph (GraphRAG) retrieval; run inside createRagTool it's journaled → exactly-once / replayable RAG.
What it's for / when to use it#
@gnldev/ragturns a knowledge base into a tool the agent can call. The critical difference: when the RAG tool is used inside runDurable its result is journaled → on resume/replay the same documents come back, no new embed/query call is made (exactly-once RAG) — a retrieval that already ran is replayed from the journal rather than re-issued.
The pipeline has three parts: (1) chunking — splits raw text/documents into chunks; (2) vector store — in-memory, durable Postgres/pgvector, or a similarity graph (GraphRAG); (3) createRagTool — packages embed + query + optional rerank into a single tool.
Chunking — chunkText / chunkDocuments#
chunkText splits raw text into chunks; three strategies: recursive (default — splits by preferring paragraph → line → sentence → word boundaries), markdown (sections by heading hierarchy; adds a heading breadcrumb metadata field to every chunk), and character (fixed window). Consecutive chunks overlap via overlap (context continuity).
chunkDocuments splits VectorDocs and produces a list ready for indexDocuments. The chunk id is <docId>#<i> — deterministic, so re-indexing upserts into the same ids instead of producing duplicates. A document that fits in a single chunk passes through unsplit (no pointless #0 derivation).
import { chunkDocuments, indexDocuments, InMemoryVectorStore } from '@gnldev/rag';
const chunks = chunkDocuments(docs, {
size: 1200, overlap: 120, strategy: 'markdown',
});
// chunks[i].id === 'guide#3', metadata: { source: 'guide', chunk: 3, heading: 'Kurulum > Docker' }
const store = new InMemoryVectorStore();
await indexDocuments(store, chunks, embed);Durable store — PostgresVectorStore (pgvector)#
PostgresVectorStoreand InMemoryVectorStore expose the same interface — Postgres backs it durably with pgvector: it takes an injectable pool, lazy-loads the pg driver, and supports HNSW or ivfflat indexes. This means the knowledge base persists across restarts in real customer projects.
import { PostgresVectorStore, createRagTool } from '@gnldev/rag';
import { Pool } from 'pg';
const store = new PostgresVectorStore({
pool: new Pool({ connectionString: process.env.DATABASE_URL }),
dimension: 1536,
index: 'hnsw',
});
await store.upsert(items); // the same signature as InMemoryGraphRAG — indirect-relevance retrieval#
GraphRagdoes retrieval over a similarity graph between chunks (the graph-retrieval pattern, over the same journal as everything else GraphRAG ). It catches what plain vector search misses: chunks that aren't directly similar to the query but are strongly connected to chunks that are (indirect relevance) also join the results. Since it implements the VectorStore interface, it's a drop-in for createRagTool.
Parameters: threshold (edge threshold, default 0.75), hops (neighbor-expansion depth, default 1; 0 = plain vector search), decay (per-hop score decay, default 0.7), and seeds (number of direct results seeding the expansion, default 4). If a node is reached by more than one path, the highest score is kept; ties break deterministically by id.
import { GraphRag, createRagTool } from '@gnldev/rag';
const graph = new GraphRag({ threshold: 0.75, hops: 1, decay: 0.7, seeds: 4 });
await graph.upsert(items); // edges are built incrementally
const ragTool = createRagTool({ store: graph, embed, topK: 6 });createRagTool — deterministic / exactly-once#
createRagTool packages embed + store.query + optional rerankinto a single tool. It works with any VectorStore (InMemory / Postgres / GraphRag). Because runDurable journals the durableTool result, resume returns the same documents; no new embed/query/rerank call runs.
API reference#
chunkText(text, opts?) → Chunk[]; recursive/markdown/character strategy, size/overlap, markdown heading breadcrumb.
chunkDocuments(docs, opts?) → VectorDoc[]; deterministic <docId>#<i> chunk id → re-indexing upserts.
PostgresVectorStoreDurable pgvector store; injectable pool, lazy pg, HNSW/ivfflat — same interface as InMemory.
GraphRagSimilarity-graph VectorStore; indirect-relevance retrieval via threshold/hops/decay/seeds, drop-in for createRagTool.
createRagTool({ store, embed, topK?, rerank?, ... }) → tool; journaled inside durable = exactly-once/replayable RAG.
InMemoryVectorStore / indexDocumentsIn-memory store + bulk index helper (test/prototype).