symfony/ai-chroma-db-store
ChromaDB Store integration for Symfony AI Store. Use ChromaDB as a vector store to manage collections and run query/get operations for embeddings and similarity search. Includes links to Chroma docs plus Symfony AI contributing and issue/PR resources.
Install the Package:
composer require symfony/ai-chroma-db-store
Ensure symfony/ai (≥v0.8.0) is also installed.
Configure ChromaDB:
Add to .env:
CHROMA_HOST=http://localhost:8000
CHROMA_API_KEY=your_api_key_here
CHROMA_COLLECTION=laravel_vectors
Bind the Store:
In AppServiceProvider@register():
$this->app->bind(\Symfony\AI\Store\StoreInterface::class, function ($app) {
return new \Symfony\AI\ChromaDbStore(
host: env('CHROMA_HOST'),
apiKey: env('CHROMA_API_KEY'),
collection: env('CHROMA_COLLECTION')
);
});
First Use Case: Store and query a vector in a Laravel controller:
use Symfony\AI\Store\StoreInterface;
public function storeVector(StoreInterface $store)
{
$vector = [0.1, 0.2, 0.3, 0.4]; // Example embedding
$metadata = ['document_id' => 123, 'source' => 'user_guide'];
// Store
$store->add($vector, $metadata);
// Query
$results = $store->find($vector, limit: 3);
return $results;
}
Test Locally: Spin up ChromaDB via Docker:
docker run -p 8000:8000 chromadb/chroma
Insert:
$store->add($vector, $metadata);
Use for storing embeddings (e.g., from symfony/ai's EmbeddingGenerator).
Update:
$store->update($id, $newVector, $newMetadata);
Update existing vectors (e.g., retraining embeddings).
Delete:
$store->remove($id);
Remove vectors by ID (e.g., user deletion).
Bulk Operations:
$store->addMany([[$vector1, $metadata1], [$vector2, $metadata2]]);
Combine vector similarity with metadata filters:
$results = $store->find(
$queryVector,
limit: 5,
where: ['category' => 'tech', 'published' => true]
);
whereMetadata()).Abstract ChromaDB calls in a Laravel repository:
namespace App\Repositories;
class VectorRepository {
public function __construct(private StoreInterface $store) {}
public function findSimilarDocuments($queryVector, int $limit = 3) {
return $this->store->find($queryVector, limit: $limit);
}
public function storeDocumentEmbedding($vector, array $metadata) {
$this->store->add($vector, $metadata);
}
}
Register the repository in Laravel’s container:
$this->app->bind(VectorRepository::class, function ($app) {
return new VectorRepository($app->make(StoreInterface::class));
});
Dispatch Laravel events for ChromaDB operations:
use Illuminate\Support\Facades\Event;
$store->add($vector, $metadata);
Event::dispatch(new VectorStored($metadata));
Listen for events in EventServiceProvider:
protected $listen = [
VectorStored::class => [
\App\Listeners\LogVectorStorage::class,
\App\Listeners\UpdateSearchIndex::class,
],
];
Offload bulk operations to Laravel queues:
// Job: ProcessEmbeddingsJob
public function handle() {
$vectors = $this->getVectorsFromDatabase();
$this->store->addMany($vectors);
}
Dispatch the job:
ProcessEmbeddingsJob::dispatch();
StoreInterface to ChromaDbStore for loose coupling.config('chroma') for host/API key settings:
'chroma' => [
'host' => env('CHROMA_HOST'),
'api_key' => env('CHROMA_API_KEY'),
'collection' => env('CHROMA_COLLECTION'),
],
use Illuminate\Support\Facades\Validator;
$validator = Validator::make($metadata, [
'document_id' => 'required|integer',
'source' => 'required|string',
]);
Artisan command to initialize:
public function boot() {
if (! $this->chromaCollectionExists()) {
$this->createChromaCollection();
}
}
sentence-transformers).$cacheKey = 'vector_query_' . md5(serialize($queryVector));
$results = Cache::remember($cacheKey, now()->addMinutes(5), function () use ($store, $queryVector) {
return $store->find($queryVector);
});
addMany() for bulk inserts (e.g., during data migration).API Key Exposure:
CHROMA_API_KEY in .env may not be secure enough for production.Vault or a secrets manager (e.g., AWS Secrets Manager).Vector Dimension Mismatch:
if (count($vector) !== config('chroma.vector_dimension')) {
throw new \InvalidArgumentException('Vector dimension mismatch');
}
Filter Syntax Errors:
// ❌ Wrong (Laravel-style)
$store->find($vector, where: ['category' => 'tech']);
// ✅ Correct (ChromaDB-style)
$store->find($vector, where: ['category' => 'tech', 'operator' => 'Equal']);
Connection Timeouts:
$client = new \Symfony\Contracts\HttpClient\HttpClient([
'timeout' => 60,
]);
Collection Not Found:
if (! $this->chromaCollectionExists()) {
$this->createChromaCollection();
}
Metadata Size Limits:
Symfony AI Version Mismatch:
symfony/ai version breaks the store.composer.json:
"symfony/ai": "^0.8.0",
"symfony/ai-chroma-db-store": "^0.8.0"
$client = new \Symfony\Contracts\HttpClient\HttpClient([
'headers' => ['Authorization
How can I help you explore Laravel packages today?