OrkaJS
Orka.JS

Knowledge & RAG

Index documents, perform semantic search, and build RAG pipelines with Orka AI.

Why orka.knowledge?

The orka.knowledge API follows Orka's intent-based design philosophy. Instead of dealing with low-level concepts like vectors, embeddings, or collections, you work with a high-level abstraction called "knowledge".

Abstraction

Hides complexity: chunking, embedding generation, vector storage, and similarity search are all handled automatically.

Fluent API

Natural method names: create(), add(), search(), delete(). Your code reads like plain English.

Configurable

Swap the underlying VectorDB (Memory, Pinecone, Qdrant, Chroma) without changing your application code.

Consistent

Same pattern as other Orka APIs: orka.ask(), orka.workflow(), orka.agent(), orka.knowledge.

What Happens Under the Hood

When you call orka.knowledge.create(), Orka performs a sophisticated pipeline of operations:

1
Source Normalization

Your source (string, array, file path, URL) is converted into a uniform Document[] format. Each document gets a unique ID and metadata.

2
Chunking

Documents are split into smaller chunks based on chunkSize (default: 1000 characters) with overlap (default: 200 characters) to preserve context at boundaries.

3
Embedding Generation

Each chunk is converted into a high-dimensional vector (embedding) using your configured LLM adapter. These vectors capture the semantic meaning of the text.

4
Vector Storage

A collection is created in your VectorDB with the appropriate dimension. Vectors are upserted in batches of 100 for efficiency.

API Reference

create(options)

Creates a new knowledge base from your source documents. This is the main entry point for indexing content.

const result = await orka.knowledge.create({
name: 'my-docs', // Required: unique name for this knowledge base
source: [...], // Required: content to index (see formats below)
chunkSize: 1000, // Optional: max characters per chunk (default: 1000)
chunkOverlap: 200, // Optional: overlap between chunks (default: 200)
metadata: { // Optional: metadata attached to all documents
category: 'support',
version: '1.0',
},
});
 
// Returns:
// {
// name: 'my-docs',
// documentCount: 5, // Number of source documents processed
// chunkCount: 23, // Total chunks created
// }
Understanding Chunk Size & Overlap

chunkSize determines how much text each vector represents. Smaller chunks = more precise retrieval but less context. Larger chunks = more context but may include irrelevant info. chunkOverlap ensures important information at chunk boundaries isn't lost.

Source Formats

Orka accepts multiple source formats, automatically detecting and processing each type:

* Single String

A long text that will be automatically chunked. Ideal for articles, documentation pages, or any single document.

await orka.knowledge.create({
name: 'article',
source: 'This is a very long article about AI... [thousands of characters]',
});
* String Array

Multiple documents as an array of strings. Each string is treated as a separate document, then chunked individually.

await orka.knowledge.create({
name: 'faq',
source: [
'How do I reset my password? Go to Settings > Security > Reset Password...',
'How do I contact support? Email us at support@example.com or...',
'What are the pricing plans? We offer Free, Pro, and Enterprise tiers...',
],
});
* Structured Objects with Metadata

Documents with per-document metadata. Metadata is preserved and returned in search results for filtering or display.

await orka.knowledge.create({
name: 'products',
source: [
{ text: 'iPhone 15 Pro features...', metadata: { category: 'phones', brand: 'Apple' } },
{ text: 'Galaxy S24 Ultra specs...', metadata: { category: 'phones', brand: 'Samsung' } },
{ text: 'MacBook Pro M3 review...', metadata: { category: 'laptops', brand: 'Apple' } },
],
});
* File or Directory Path

Load from filesystem. If a directory, all text files (.txt, .md, .json, .csv, .html, .xml, .yaml, .js, .ts, .py, etc.) are loaded recursively.

// Single file
await orka.knowledge.create({
name: 'readme',
source: { path: './README.md' },
});
 
// Entire directory
await orka.knowledge.create({
name: 'docs',
source: { path: './documentation/' },
});
* URL (HTTP/HTTPS)

Fetch content from a URL. Includes security protections: protocol validation, 30s timeout, 50MB size limit.

await orka.knowledge.create({
name: 'external-docs',
source: { url: 'https://example.com/api-documentation.html' },
});

API Reference

add(name, source, options?)

Adds more documents to an existing knowledge base. Uses the same source formats as create().

// Add new documents to existing knowledge base
const { addedChunks } = await orka.knowledge.add('my-docs', [
'New document content...',
'Another new document...',
], {
chunkSize: 1000,
chunkOverlap: 200,
metadata: { addedAt: '2024-01-15' },
});
 
console.log(`Added ${addedChunks} new chunks`);

search(name, query, options?)

Performs semantic search on a knowledge base. Returns the most relevant chunks based on vector similarity.

const results = await orka.knowledge.search('my-docs', 'how to reset password', {
topK: 10, // Number of results to return (default: 5)
minScore: 0.7, // Minimum similarity score 0-1 (optional)
});
 
// Each result contains:
for (const result of results) {
console.log(result.id); // Unique chunk ID
console.log(result.content); // The chunk text
console.log(result.score); // Similarity score (0-1, higher = more relevant)
console.log(result.metadata); // { documentId, chunkIndex, ...your metadata }
}
How Semantic Search Works

Your query is converted to an embedding vector, then compared against all stored vectors using cosine similarity. This finds semantically similar content even if the exact words don't match. "reset password" will match "change my credentials" because they have similar meaning.

delete(name)

Deletes an entire knowledge base and all its vectors from the VectorDB.

await orka.knowledge.delete('my-docs');

How RAG Works with orka.ask()

RAG (Retrieval-Augmented Generation) combines your knowledge base with LLM generation. When you call orka.ask() with a knowledge parameter, here's the complete flow:

User QuestionEmbed QueryVector SearchTop-K ChunksBuild PromptLLMAnswer
// Basic RAG query
const answer = await orka.ask('How do I reset my password?', {
knowledge: 'my-docs', // Name of your knowledge base
topK: 5, // Number of chunks to retrieve
});
 
// With context inspection (for debugging)
const { answer, context } = await orka.ask('How do I reset my password?', {
knowledge: 'my-docs',
topK: 5,
includeContext: true, // Returns the chunks used
});
 
console.log('Answer:', answer);
console.log('Sources used:');
for (const chunk of context) {
console.log(`- [${chunk.score.toFixed(2)}] ${chunk.content.slice(0, 100)}...`);
}

Complete Example

Here's a full example showing how to build a documentation Q&A system:

knowledge-qa-example.ts
import { Orka } from 'orkajs/core';
import { OpenAIAdapter } from 'orkajs/adapters/openai';
import { MemoryVectorDB } from 'orkajs/adapters/memory';
 
// 1. Initialize Orka with adapters
const orka = new Orka({
llm: new OpenAIAdapter({ apiKey: process.env.OPENAI_API_KEY }),
vectorDB: new MemoryVectorDB(),
defaults: {
chunkSize: 800, // Smaller chunks for precise retrieval
chunkOverlap: 100,
topK: 3,
},
});
 
// 2. Create knowledge base from your docs
const { chunkCount } = await orka.knowledge.create({
name: 'product-docs',
source: { path: './docs/' },
metadata: { source: 'official-docs' },
});
console.log(`Indexed ${chunkCount} chunks`);
 
// 3. Add more content later
await orka.knowledge.add('product-docs', [
{ text: 'New feature: Dark mode is now available...', metadata: { type: 'release-note' } },
]);
 
// 4. Query with RAG
const { answer, context } = await orka.ask(
'How do I enable dark mode?',
{ knowledge: 'product-docs', includeContext: true }
);
 
console.log('Answer:', answer);
console.log('Based on', context.length, 'sources');
 
// 5. Direct search (without LLM)
const results = await orka.knowledge.search('product-docs', 'dark mode', { topK: 5 });
for (const r of results) {
console.log(`[${r.score.toFixed(2)}] ${r.content.slice(0, 80)}...`);
}

Pro Tips

💡 Choose the right chunk size

For Q&A: 500-1000 chars. For summarization: 1500-2000 chars. For code: 300-500 chars. Experiment to find what works best for your content.

💡 Use metadata for filtering

Add category, date, author, or type metadata. This enables filtered searches and helps trace which documents contributed to answers.

💡 Debug with includeContext

Always use includeContext: true during development. It shows exactly which chunks the LLM used, invaluable for tuning your RAG pipeline.

💡 Consider minScore

Set minScore (e.g., 0.7) to filter out low-relevance results. This prevents the LLM from being confused by irrelevant context.

Supported VectorDB Adapters

orka.knowledge works with any VectorDB adapter. Swap adapters without changing your application code:

MemoryVectorDB

In-memory, perfect for development and testing

PineconeAdapter

Managed cloud vector database, scales to billions

QdrantAdapter

Open-source, self-hosted or cloud

ChromaAdapter

Open-source, embedded or client-server

// Development: in-memory
import { MemoryVectorDB } from 'orkajs/adapters/memory';
const vectorDB = new MemoryVectorDB();
 
// Production: Pinecone
import { PineconeAdapter } from 'orkajs/adapters/pinecone';
const vectorDB = new PineconeAdapter({
apiKey: process.env.PINECONE_API_KEY,
environment: 'us-east-1',
indexName: 'my-index',
});
 
// Same orka.knowledge API works with both!