@molecule/api-ai-rag-qa

Utility · ai-rag-qa · API (Node) · v1.0.2 · Apache-2.0

Chunk + embed + retrieve + ground answer pipeline

npm install @molecule/api-ai-rag-qa

npm · Source on GitHub

How it works

@molecule/api-ai-rag-qa is a utility package for the API (Node) side (ai-rag-qa).

import { indexDocument, answerQuestion } from '@molecule/api-ai-rag-qa'

await indexDocument({
  collection: 'docs',
  documentId: 'getting-started',
  text: longMarkdown,
  metadata: { source: 'README.md' },
})

const { answer, sources } = await answerQuestion({
  collection: 'docs',
  question: 'How do I configure auth?',
})

Works with: @molecule/api-ai, @molecule/api-ai-embeddings, @molecule/api-ai-vector-store, @molecule/api-bonds-default-express, @molecule/api-database, @molecule/api-i18n, @molecule/api-middleware-validation

Reference

@molecule/api-ai-rag-qa — RAG (retrieval-augmented generation) Q&A pipeline. Chunk source documents, embed them, store in the vector bond, then answer questions grounded in retrieved sources.

Composes the existing @molecule/api-ai, @molecule/api-ai-embeddings, and @molecule/api-ai-vector-store bonds — works with any provider mix (Anthropic + OpenAI embeddings + pgvector, etc.).

Extracted from the rag-knowledge-base flagship.

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Quick Start

import { indexDocument, answerQuestion } from '@molecule/api-ai-rag-qa'

await indexDocument({
  collection: 'docs',
  documentId: 'getting-started',
  text: longMarkdown,
  metadata: { source: 'README.md' },
})

const { answer, sources } = await answerQuestion({
  collection: 'docs',
  question: 'How do I configure auth?',
})

Type

utility

Installation

npm install @molecule/api-ai-rag-qa @molecule/api-ai @molecule/api-ai-embeddings @molecule/api-ai-vector-store @molecule/api-bonds-default-express @molecule/api-database @molecule/api-i18n @molecule/api-middleware-validation

API

Interfaces

Chunk

A chunk of source material to be embedded + indexed.

interface Chunk {
  id: string
  text: string
  metadata?: Record<string, unknown>
}

RetrievalHit

A retrieval hit from the vector store.

interface RetrievalHit {
  id: string
  text: string
  score: number
  metadata?: Record<string, unknown>
}

GroundedAnswer

Final grounded answer + the sources it cited.

interface GroundedAnswer {
  answer: string
  sources: RetrievalHit[]
  /** Token / chunk count used for the prompt (for cost telemetry). */
  contextTokens?: number
}

ChunkOptions

Chunking options for chunkText.

interface ChunkOptions {
  /** Max characters per chunk. Default 1000. */
  maxChars?: number
  /** Overlap characters between adjacent chunks. Default 200. */
  overlap?: number
  /** Prefer chunking at paragraph boundaries when possible. Default true. */
  preferParagraphs?: boolean
}

Functions

chunkText(text, opts?)

Split a long text into overlapping chunks suitable for embedding.

Tries paragraph boundaries first, then sentence boundaries, then character boundaries. Each chunk includes overlap characters from the prior chunk to preserve context across boundaries.

function chunkText(text: string, opts?: ChunkOptions): string[]

indexDocument(opts)

Index a long document by chunking, embedding, and upserting to the vector store.

function indexDocument(opts: {
  collection: string
  documentId: string
  text: string
  metadata?: Record<string, unknown>
  chunking?: ChunkOptions
}): Promise<string[]>

deleteDocument(opts)

Delete all chunks for a previously-indexed document.

function deleteDocument(opts: {
  collection: string
  documentId: string
  maxChunks?: number
}): Promise<void>

retrieve(opts)

Retrieve top-K most similar chunks for a query.

function retrieve(opts: {
  collection: string
  query: string
  topK?: number
  filter?: MetadataFilter[]
}): Promise<RetrievalHit[]>

answerQuestion(opts)

Full RAG round-trip: retrieve top-K chunks, format them as numbered sources, and ground a generated answer in them.

function answerQuestion(opts: {
  collection: string
  question: string
  topK?: number
  filter?: MetadataFilter[]
  promptTemplate?: string
  model?: string
  temperature?: number
}): Promise<GroundedAnswer>

Injection Notes

Requirements

Peer dependencies:

  • @molecule/api-bonds-default-express ^1.0.1
  • @molecule/api-database ^1.0.1
  • @molecule/api-i18n ^1.0.1
  • @molecule/api-middleware-validation ^1.0.1
  • @molecule/api-ai ^1.0.1
  • @molecule/api-ai-embeddings ^1.0.1
  • @molecule/api-ai-vector-store ^1.0.1

Runtime Dependencies

  • @molecule/api-ai
  • @molecule/api-ai-embeddings
  • @molecule/api-ai-vector-store
  • @molecule/api-bonds-default-express
  • @molecule/api-database
  • @molecule/api-i18n
  • @molecule/api-middleware-validation

Wiring — the three composed cores use TWO different mechanisms:

  • @molecule/api-ai-embeddings and @molecule/api-ai-vector-store each keep their OWN singleton: wire each with THAT core's setProvider(...) (e.g. setProvider(provider) from @molecule/api-ai-embeddings-local). A generic bond('ai-embeddings', …) / bond('ai-vector-store', …) call is never seen by those cores — indexDocument() / retrieve() then throw "provider not configured" even though the bond call appeared to succeed.
  • @molecule/api-ai (used by answerQuestion) IS registry-based: bond('ai', provider) or named providers work.

Vectors are only comparable within ONE embeddings model + dimension: after switching embeddings providers/models, re-index the collection — retrieve() against vectors from a different model returns meaningless similarity scores, not an error.

deleteDocument() deletes constructed chunk ids (<documentId>::0..N-1, default maxChunks: 1000) — pass a larger maxChunks if a document chunked into more. answerQuestion() with zero retrieval hits resolves with the literal "I don't know based on the provided sources." and sources: [] — no model call is made.