Indexing Engine
SymbolicAI supports multiple indexing engines for vector search and RAG (Retrieval-Augmented Generation) operations. This document covers both the default naive vector engine and the production-ready Qdrant engine.
Naive Vector Engine (Default)
By default, text indexing and retrieval is performed with the local naive vector engine using the Interface abstraction:
from symai.interfaces import Interface
db = Interface('naive_vectordb', index_name="my_index")
db("Hello world", operation="add")
result = db("Hello", operation="search", top_k=1)
print(result.value) # most relevant matchYou can also add or search multiple documents at once, and perform save/load/purge operations:
docs = ["Alpha document", "Beta entry", "Gamma text"]
db = Interface('naive_vectordb', index_name="my_index")
db(docs, operation="add")
db("save", operation="config")
# Load or purge as neededQdrant RAG Engine
The Qdrant engine provides a production-ready vector database for scalable RAG applications. It supports both local and cloud deployments, advanced document chunking, and comprehensive collection management.
Setup
Option 1: Local Qdrant Server
Start a local Qdrant server using the built-in wrapper:
# Using Docker (default)
python -m symai.server.qdrant_server
# Using Qdrant binary
python -m symai.server.qdrant_server --mode binary --binary-path /path/to/qdrant
# Custom configuration
python -m symai.server.qdrant_server --host 0.0.0.0 --port 6333 --storage-path ./qdrant_storageOption 2: Cloud Qdrant
Configure your cloud Qdrant instance:
import os
os.environ["INDEXING_ENGINE_URL"] = "https://your-cluster.qdrant.io"
os.environ["INDEXING_ENGINE_API_KEY"] = "your-api-key"Basic Usage
The Qdrant engine automatically registers when a Qdrant server is available. Use it through the Interface abstraction:
from symai.interfaces import Interface
# Qdrant engine is used automatically when server is running
db = Interface('naive_vectordb', index_name="my_collection")
db("Hello world", operation="add")
result = db("Hello", operation="search", top_k=5)
print(result.value) # list of relevant matchesAdvanced Usage: Direct Engine Access
For more control, use the Qdrant engine directly:
from symai.backend.engines.index.engine_qdrant import QdrantIndexEngine
# Initialize engine
engine = QdrantIndexEngine(
url="http://localhost:6333", # or your cloud URL
api_key=None, # optional, for cloud instances
index_name="my_collection",
index_dims=1536, # embedding dimension
index_top_k=5, # default top-k for searches
index_metric="Cosine" # Cosine, Dot, or Euclidean
)Collection Management
Create and manage collections programmatically:
import asyncio
async def manage_collections():
# Create a new collection
await engine.create_collection(
collection_name="documents",
vector_size=1536,
distance="Cosine"
)
# Check if collection exists
exists = await engine.collection_exists("documents")
# List all collections
collections = await engine.list_collections()
# Get collection info
info = await engine.get_collection_info("documents")
print(f"Points: {info['points_count']}")
# Delete collection
await engine.delete_collection("documents")
asyncio.run(manage_collections())Document Chunking and RAG
The Qdrant engine includes built-in document chunking for RAG workflows:
import asyncio
async def add_documents():
# Chunk and index text directly
num_chunks = await engine.chunk_and_upsert(
collection_name="documents",
text="Your long document text here...",
metadata={"source": "manual_input", "author": "John Doe"}
)
print(f"Indexed {num_chunks} chunks")
# Chunk and index from a file (PDF, DOCX, etc.)
num_chunks = await engine.chunk_and_upsert(
collection_name="documents",
document_path="/path/to/document.pdf",
metadata={"source": "document.pdf"}
)
# Chunk and index from a URL
num_chunks = await engine.chunk_and_upsert(
collection_name="documents",
document_url="https://example.com/document.pdf",
metadata={"source": "url"}
)
# Custom chunker configuration
num_chunks = await engine.chunk_and_upsert(
collection_name="documents",
text="Your text...",
chunker_name="RecursiveChunker",
chunker_kwargs={"chunk_size": 512, "chunk_overlap": 50}
)
asyncio.run(add_documents())Point Operations
For fine-grained control over individual vectors:
import asyncio
import numpy as np
async def point_operations():
# Upsert points with embeddings
points = [
{
"id": 1,
"vector": [0.1] * 1536, # your embedding vector
"payload": {"text": "Document 1", "category": "tech"}
},
{
"id": 2,
"vector": [0.2] * 1536,
"payload": {"text": "Document 2", "category": "science"}
}
]
await engine.upsert(collection_name="documents", points=points)
# Retrieve points by ID
retrieved = await engine.retrieve(
collection_name="documents",
ids=[1, 2],
with_payload=True,
with_vectors=False
)
# Search for similar vectors
query_vector = [0.15] * 1536
results = await engine.search(
collection_name="documents",
query_vector=query_vector,
limit=10,
score_threshold=0.7 # optional minimum similarity
)
# Delete points
await engine.delete(collection_name="documents", points_selector=[1, 2])
asyncio.run(point_operations())Configuration Options
The Qdrant engine supports extensive configuration:
engine = QdrantIndexEngine(
# Connection settings
url="http://localhost:6333",
api_key="your-api-key", # for cloud instances
# Collection settings
index_name="default_collection",
index_dims=1536, # must match your embedding model
index_top_k=5,
index_metric="Cosine", # Cosine, Dot, or Euclidean
# Chunking settings
chunker_name="RecursiveChunker",
tokenizer_name="gpt2",
embedding_model_name="minishlab/potion-base-8M",
# Retry settings
tries=20,
delay=0.5,
max_delay=-1,
backoff=1,
jitter=0
)Environment Variables
Configure Qdrant via environment variables:
# Qdrant connection
export INDEXING_ENGINE_URL="http://localhost:6333"
export INDEXING_ENGINE_API_KEY="your-api-key" # optional
# Embedding model (shared with other engines)
export EMBEDDING_ENGINE_API_KEY="" # empty for local, or API key for cloud
export EMBEDDING_ENGINE_MODEL="all-mpnet-base-v2" # or your preferred modelEmbedding Model & API Key Behavior
If
EMBEDDING_ENGINE_API_KEYis empty ("", the default), SymbolicAI will use a local, lightweight embedding engine based on SentenceTransformers. You can specify any supported model name viaEMBEDDING_ENGINE_MODEL(e.g."all-mpnet-base-v2").If you DO provide an
EMBEDDING_ENGINE_API_KEY, then the respective remote embedding engine will be used (e.g. OpenAI). The model is selected according to theEMBEDDING_ENGINE_MODELkey where applicable.
This allows you to easily experiment locally for free, and switch to more powerful cloud backends when ready.
Installation
Install Qdrant support using the package extra (recommended):
pip install symai[qdrant]This installs all required dependencies:
qdrant-client- Qdrant Python clientchonkie[all]- Document chunking librarytokenizers- Tokenization support
Alternatively, install dependencies individually:
pip install qdrant-client chonkie tokenizersSee Also
See
tests/engines/index/test_qdrant_engine.pyfor comprehensive usage examplesQdrant documentation: https://qdrant.tech/documentation/
Last updated