symfony/ai-vektor-store
Symfony AI Store integration for the Vektor vector database. Use Vektor as a vector store backend in Symfony AI apps to store, index, and query embeddings for retrieval and semantic search. Links to Vektor docs and Symfony AI contribution resources.
Install Dependencies
composer require symfony/ai centamiv/vektor
Ensure your Laravel app uses Symfony 6.4+ (or Laravel 10+ with Symfony components).
Configure Vektor Backend Choose either Redis or PostgreSQL for Vektor. Example for Redis:
docker run -p 6379:6379 redis/redis-stack-server:latest
Or for PostgreSQL with pgvector:
docker run --name pgvector -e POSTGRES_PASSWORD=password -p 5432:5432 -d centos/pgvector
Set Up Symfony AI in Laravel
Register the Vektor store in config/ai.php:
'stores' => [
'vektor' => [
'type' => 'vektor',
'options' => [
'connection' => 'redis', // or 'postgresql'
'index_name' => 'laravel_ai',
'dimensions' => 384, // Adjust based on your embedding model
],
],
],
First Query: Embed and Retrieve Use the store in a Laravel service:
use Symfony\Component\AI\Store\VectorStoreInterface;
class AiSearchService {
public function __construct(
private VectorStoreInterface $vectorStore
) {}
public function findSimilarDocuments(string $query, int $limit = 3) {
$embedding = $this->vectorStore->embed($query);
$results = $this->vectorStore->findNearest($embedding, $limit);
return $results;
}
}
Bind the store in AppServiceProvider:
public function register() {
$this->app->bind(VectorStoreInterface::class, function ($app) {
return new \Symfony\Component\AI\Store\VektorStore(
$app['config']['ai.stores.vektor.options']
);
});
}
Test with a Simple Example Add a test document and query it:
$this->vectorStore->add(
'doc1',
[0.1, 0.2, ..., 0.384] // Replace with a real embedding
);
$results = $this->findSimilarDocuments("What is Laravel?");
Embedding and Storage
EmbeddingGenerator (e.g., all-MiniLM-L6-v2):
$embedding = $embeddingGenerator->generate($text);
$this->vectorStore->add('doc_id', $embedding);
$this->vectorStore->addMany([
'doc1' => $embedding1,
'doc2' => $embedding2,
]);
Semantic Search
$queryEmbedding = $embeddingGenerator->generate($query);
$results = $this->vectorStore->findNearest($queryEmbedding, 5);
$results = $this->vectorStore->findNearest(
$queryEmbedding,
5,
['tags' => ['laravel', 'ai']]
);
Hybrid Search (Keyword + Vector) Combine with Laravel Scout or Algolia:
// Pseudocode: Merge keyword and vector results
$keywordResults = Scout::search($query);
$vectorResults = $this->findSimilarDocuments($query);
$merged = $this->mergeResults($keywordResults, $vectorResults);
Background Processing Use Laravel Queues for heavy operations (e.g., batch embeddings):
Queue::push(new ProcessEmbeddings($documents));
Job example:
class ProcessEmbeddings implements ShouldQueue {
public function handle() {
$embeddings = $this->generateEmbeddings($this->documents);
$this->vectorStore->addMany($embeddings);
}
}
'options' => [
'connection' => env('REDIS_VECTOR_CONNECTION', 'default'),
],
class DocumentObserver {
public function saved(Document $document) {
$embedding = $embeddingGenerator->generate($document->content);
$this->vectorStore->add($document->id, $embedding);
}
}
Route::get('/search', function (AiSearchService $service) {
return $service->findSimilarDocuments(request('q'));
});
Embedding Dimensions Mismatch
dimensions: 768, queries will fail.if (count($embedding) !== $this->vectorStore->getDimensions()) {
throw new \InvalidArgumentException('Embedding dimension mismatch');
}
Redis Memory Limits
redis-cli info memory
PostgreSQL pgvector Setup
pgvector is installed and the index is created:
CREATE EXTENSION vector;
CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops);
Symfony AI Version Conflicts
composer require symfony/ai:^0.8.0 --dev
composer.json:
"symfony/ai": "^0.8.0",
"symfony/ai-vektor-store": "^0.7.0"
No Native Laravel Support
symfony/flex).Enable Vektor Logging
Configure in config/ai.php:
'options' => [
'debug' => true,
],
Check logs for connection/query issues.
Validate Embeddings Sanity-check embeddings before storage:
$embedding = $embeddingGenerator->generate($text);
if (is_null($embedding) || !is_array($embedding)) {
throw new \RuntimeException('Invalid embedding generated');
}
Query Performance Profile slow queries with:
$start = microtime(true);
$results = $this->vectorStore->findNearest($embedding, 10);
$time = microtime(true) - $start;
logger()->info("Query took {$time}s");
Optimize: Adjust Vektor’s ef (search efficiency) and M (max neighbors) parameters.
Custom Vektor Client Extend the bridge to support custom Vektor configurations:
class CustomVektorStore extends \Symfony\Component\AI\Store\VektorStore {
public function __construct(array $options) {
$options['custom_param'] = 'value';
parent::__construct($options);
}
}
Metadata Filtering Add metadata support if Vektor’s backend allows it:
$this->vectorStore->findNearest($embedding, 5, ['author' => 'Taylor Otwell']);
Hybrid Search Logic Combine keyword and vector results in a custom service:
class HybridSearchService {
public function search(string $query) {
$vectorResults = $this->vectorStore->findNearest(...);
$keywordResults = Scout::search($query);
return $this->merge($vectorResults, $keywordResults);
}
}
Fallback Store Implement a fallback for when Vektor is unavailable:
class ResilientVectorStore {
public function __construct(
private VectorStoreInterface $primary,
private VectorStoreInterface $fallback
) {}
public function findNearest
How can I help you explore Laravel packages today?