Knowledge

RAG integration with document processing and vector search

Overview#

The Knowledge system provides retrieval-augmented generation (RAG) capabilities, allowing agents to access and utilize external documents in their responses. It automatically processes documents, creates vector embeddings, and enables semantic search for relevant information. Agents with knowledge can provide more accurate, contextual responses based on your documents.

Enabling Knowledge#

Enable knowledge for an agent by setting the knowledge option to true:

typescript
import { Agent } from '@astreus-ai/astreus';

const agent = await Agent.create({
  name: 'KnowledgeAgent',
  model: 'gpt-4o',
  knowledge: true,  // Enable knowledge base access (default: false)
  embeddingModel: 'text-embedding-3-small' // Optional: specify embedding model
});

Adding Documents#

Add Text Content#

Add content directly as a string:

typescript
await agent.addKnowledge(
  'Your important content here',
  'Document Title',
  { category: 'documentation' }
);

Add from File#

Add content from supported file types:

typescript
// Add PDF file
await agent.addKnowledgeFromFile(
  '/path/to/document.pdf',
  { source: 'manual', version: '1.0' }
);

// Add text file
await agent.addKnowledgeFromFile('/path/to/notes.txt');

Add from Directory#

Process all supported files in a directory:

typescript
await agent.addKnowledgeFromDirectory(
  '/path/to/docs',
  { project: 'documentation' }
);

Supported File Types#

  • Text files: .txt, .md, .json
  • PDF files: .pdf (with text extraction)

How It Works#

The knowledge system follows a sophisticated processing pipeline:

Document Processing#

Documents are stored and indexed in the knowledge database with metadata.

Text Chunking#

Content is split into chunks (1500 characters with 300 character overlap) for optimal retrieval.

The overlap ensures context continuity: overlap ratio=3001500=0.2=20%\text{overlap ratio} = \frac{300}{1500} = 0.2 = 20\%

This prevents important information from being split across chunk boundaries.

Vector Embeddings#

Each chunk is converted to vector embeddings using OpenAI, Gemini, or Ollama embedding models.

Common embedding dimensions:

  • text-embedding-3-small: 1536 dimensions (OpenAI)
  • text-embedding-3-large: 3072 dimensions (OpenAI)
  • text-embedding-ada-002: 1536 dimensions (OpenAI)
  • text-embedding-004: 768 dimensions (Gemini)

The Euclidean distance between vectors can also be used: d(p⃗,q⃗)=∑i=1n(pi−qi)2d(\vec{p}, \vec{q}) = \sqrt{\sum_{i=1}^{n}(p_i - q_i)^2}

When agents receive queries, relevant chunks are retrieved using cosine similarity search.

The similarity between query and document vectors is calculated using:

cosine similarity=cos⁡(θ)=A⃗⋅B⃗∣∣A⃗∣∣⋅∣∣B⃗∣∣=∑i=1nAiBi∑i=1nAi2⋅∑i=1nBi2\text{cosine similarity} = \cos(\theta) = \frac{\vec{A} \cdot \vec{B}}{||\vec{A}|| \cdot ||\vec{B}||} = \frac{\sum_{i=1}^{n} A_i B_i}{\sqrt{\sum_{i=1}^{n} A_i^2} \cdot \sqrt{\sum_{i=1}^{n} B_i^2}}

Where:

  • A⃗\vec{A} is the query embedding vector
  • B⃗\vec{B} is the document chunk embedding vector
  • Higher values (closer to 1) indicate greater similarity

Context Integration#

Retrieved information is automatically added to the agent's context for enhanced responses.

Example Usage#

Here's a complete example of using knowledge with an agent:

typescript
import { Agent } from '@astreus-ai/astreus';

// Create agent with knowledge enabled
const agent = await Agent.create({
  name: 'DocumentAssistant',
  model: 'gpt-4o',
  knowledge: true,
  embeddingModel: 'text-embedding-3-small', // Optional: specify embedding model
  systemPrompt: 'You are a helpful assistant with access to company documentation.'
});

// Add documentation
await agent.addKnowledgeFromFile('./company-handbook.pdf', {
  type: 'handbook',
  department: 'hr'
});

await agent.addKnowledge(`
Our API uses REST principles with JSON responses.
Authentication is done via Bearer tokens.
Rate limiting is 1000 requests per hour.
`, 'API Documentation', {
  type: 'api-docs',
  version: '2.0'
});

// Query with automatic knowledge retrieval
const response = await agent.ask('What is our API rate limit?');
console.log(response);
// The agent will automatically search the knowledge base and include relevant context

// Manual knowledge search
const results = await agent.searchKnowledge('API authentication', 5, 0.7);
results.forEach(result => {
  console.log(`Similarity: ${result.similarity}`);
  console.log(`Content: ${result.content}`);
});

Managing Knowledge#

Available Methods#

typescript
// List all documents with metadata
const documents = await agent.getKnowledgeDocuments();
// Returns: Array<{ id: string; title: string; created_at: string }>

// Delete specific document by ID (documentId is UUID string)
const success = await agent.deleteKnowledgeDocument(documentId);
// Returns: boolean indicating success

// Delete specific chunk by ID (chunkId is UUID string)
const success = await agent.deleteKnowledgeChunk(chunkId);
// Returns: boolean indicating success

// Clear all knowledge for this agent
await agent.clearKnowledge();
// Returns: void

// Search with custom parameters
const results = await agent.searchKnowledge(
  'search query',
  10,    // limit: max results (default: 5)
  0.8    // threshold: similarity threshold (0-1, default: 0.7)
);
// Returns: Array<{ content: string; metadata: MetadataObject; similarity: number }>

// Get relevant context for a query
const context = await agent.getKnowledgeContext(
  'query text',
  5      // limit: max chunks to include (default: 5)
);
// Returns: string with concatenated relevant content

// Expand context around a specific chunk
const expandedChunks = await agent.expandKnowledgeContext(
  documentId,   // Document ID (UUID string)
  chunkIndex,   // Chunk index within document
  2,            // expandBefore: chunks to include before (default: 1)
  2             // expandAfter: chunks to include after (default: 1)
);
// Returns: Array<string> with expanded chunk content

Configuration#

Environment Variables#

bash
# Database (required)
KNOWLEDGE_DB_URL=postgresql://user:password@host:port/database

# API key for embeddings
OPENAI_API_KEY=your_openai_key
# Or use dedicated embedding keys:
OPENAI_EMBEDDING_API_KEY=your_embedding_key
OPENAI_EMBEDDING_BASE_URL=https://api.openai.com/v1  # Optional: custom endpoint for embeddings
GEMINI_API_KEY=your_gemini_key
GEMINI_EMBEDDING_API_KEY=your_gemini_embedding_key

# For Ollama embeddings (local)
OLLAMA_BASE_URL=http://localhost:11434

Embedding Model Configuration#

Specify the embedding model directly in the agent configuration:

typescript
const agent = await Agent.create({
  name: 'KnowledgeAgent',
  model: 'gpt-4o',
  embeddingModel: 'text-embedding-3-small',  // Specify embedding model here
  knowledge: true
});

Response Types#

Understanding knowledge method responses helps you work with the data effectively.

Add Knowledge Response#

Adding knowledge returns the UUID of the created document:

typescript
const documentId = await agent.addKnowledge(
  "TypeScript is a typed superset of JavaScript...",
  "TypeScript Overview",
  { source: "documentation", version: "5.0" }
);

// Response: "550e8400-e29b-41d4-a716-446655440000" (UUID string)

Search Knowledge Response#

Search returns an array of chunks with content, metadata, and similarity scores:

typescript
const results = await agent.searchKnowledge("TypeScript types", 5, 0.7);

// Response structure:
[
  {
    content: "TypeScript provides static typing which helps catch errors at compile time...",
    metadata: {
      title: "TypeScript Overview",
      source: "documentation",
      version: "5.0"
    },
    similarity: 0.95
  },
  {
    content: "Types in TypeScript include primitives like string, number, boolean...",
    metadata: {
      title: "Type System",
      source: "tutorial"
    },
    similarity: 0.87
  },
  {
    content: "Advanced types like generics and conditional types provide powerful abstractions...",
    metadata: {
      title: "Advanced Types",
      source: "documentation"
    },
    similarity: 0.79
  }
]

Get Knowledge Context Response#

Context retrieval returns a concatenated string of relevant chunks:

typescript
const context = await agent.getKnowledgeContext("TypeScript", 3);

// Response: concatenated string with separator
"TypeScript is a typed superset of JavaScript...\n\n---\n\nTypes help catch errors at compile time...\n\n---\n\nAdvanced types provide powerful abstractions..."

Get Knowledge Documents Response#

Listing documents returns metadata for all stored documents:

typescript
const documents = await agent.getKnowledgeDocuments();

// Response structure:
[
  {
    id: "doc-uuid-1",                      // UUID string
    title: "TypeScript Overview",
    created_at: "2024-01-15T10:30:00Z"    // ISO 8601 timestamp
  },
  {
    id: "doc-uuid-2",
    title: "Advanced Types",
    created_at: "2024-01-16T14:20:00Z"
  },
  {
    id: "doc-uuid-3",
    title: "Best Practices",
    created_at: "2024-01-17T09:15:00Z"
  }
]

Expand Knowledge Context Response#

Context expansion returns an array of chunk strings:

typescript
const chunks = await agent.expandKnowledgeContext("doc-uuid", 5, 2, 2);

// Response structure (plain chunk content):
[
  "Earlier context before the target chunk...",
  "More context leading to the target...",
  "This is the target chunk with the main content...",
  "Following context after the target...",
  "Additional context for full understanding..."
]

Delete Responses#

Delete operations return booleans indicating success:

typescript
// Delete specific document
const docDeleted = await agent.deleteKnowledgeDocument("doc-uuid");
// Returns: true or false

// Delete specific chunk
const chunkDeleted = await agent.deleteKnowledgeChunk("chunk-uuid");
// Returns: true or false

Clear Knowledge Response#

Clearing all knowledge returns void (no return value):

typescript
await agent.clearKnowledge();
// Returns: void (undefined)

File Operations Response#

File-based knowledge operations return void on success or throw on error:

typescript
// Add from file
await agent.addKnowledgeFromFile('./document.pdf', { source: 'manual' });
// Returns: void

// Add from directory
await agent.addKnowledgeFromDirectory('./docs', { project: 'main' });
// Returns: void