symfony/ai-weaviate-store
Weaviate vector store integration for Symfony AI Store. Connect to a Weaviate instance to index embeddings and run similarity search using Weaviate’s APIs (REST/GraphQL). Part of the Symfony AI ecosystem.
composer require symfony/ai-weaviate-store
config/services.php or a dedicated Weaviate config file:
'weaviate' => [
'host' => env('WEAVIATE_HOST', 'http://localhost:8080'),
'api_key' => env('WEAVIATE_API_KEY', null),
'collection' => env('WEAVIATE_COLLECTION', 'default'),
],
// app/Providers/WeaviateServiceProvider.php
use Symfony\Component\AI\Store\StoreInterface;
use Symfony\Component\AI\Store\WeaviateStore;
class WeaviateServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(StoreInterface::class, function ($app) {
$config = $app['config']['weaviate'];
return new WeaviateStore(
$config['host'],
$config['collection'],
$config['api_key'] ?? null
);
});
}
}
// In a controller or command
$store = app(StoreInterface::class);
// Upsert a vector (e.g., from an embedding)
$store->upsert([
'id' => 'doc_123',
'embedding' => [0.1, 0.5, ..., 0.9], // Your vector data
'metadata' => ['title' => 'Example Document', 'category' => 'tech'],
]);
// Find nearest vectors
$results = $store->findNearest(
[0.2, 0.6, ..., 0.8], // Query vector
limit: 5,
filter: ['category' => 'tech'] // Optional Weaviate filter
);
findNearest).upsert, findNearest, remove).$store->upsert([
'id' => 'unique_id',
'embedding' => $vectorArray,
'metadata' => ['author' => 'John', 'tags' => ['ai', 'php']],
]);
$store->remove(['id' => 'unique_id']);
foreach ($vectors as $vector) {
Queue::push(new UpsertWeaviateVector($store, $vector));
}
$results = $store->findNearest(
$queryVector,
limit: 3,
filter: ['tags' => ['ai']] // Filter by metadata
);
// Requires raw GraphQL query (not in StoreInterface)
$client = $store->getHttpClient();
$response = $client->request('POST', '/graphql', [
'json' => [
'query' => '
{
Get {
MyCollection(
where: { path: ["tags"], operator: ContainsAny, valueText: "ai" }
) {
vectors {
nearestVector {
id
distance
}
}
}
}
}
',
],
]);
// 1. Retrieve context
$context = $store->findNearest($queryEmbedding, limit: 2);
// 2. Pass to LLM (e.g., via symfony/ai)
$aiClient = new AiClient(new OpenAI());
$response = $aiClient->ask(
"Answer based on: " . implode("\n", $context),
"What is the user asking?"
);
$filteredResults = $store->findNearest(
$vector,
filter: [
'operator' => 'And',
'operands' => [
['path' => ['category'], 'operator' => 'Equal', 'valueString' => 'tech'],
['path' => ['rating'], 'operator' => 'GreaterThan', 'valueNumber' => 4],
],
]
);
Extend the Symfony store with Laravel-specific features:
// app/Services/WeaviateStoreDecorator.php
class WeaviateStoreDecorator implements StoreInterface
{
use StoreTrait;
public function __construct(private StoreInterface $store) {}
public function findNearest(array $vector, int $limit = 3, ?array $filter = null): array
{
$results = $this->store->findNearest($vector, $limit, $filter);
// Add Laravel-specific logic (e.g., caching, logging)
Cache::remember("weaviate_{$vector[0]}", now()->addHours(1), fn() => $results);
return $results;
}
}
Offload heavy operations to Laravel Queues:
// app/Jobs/UpsertWeaviateVectors.php
class UpsertWeaviateVectors implements ShouldQueue
{
public function handle(StoreInterface $store, array $vectors)
{
foreach ($vectors as $vector) {
$store->upsert($vector);
}
}
}
Trigger Weaviate updates via Laravel Events:
// In a model observer
ModelObserved::created(function ($model) {
UpsertWeaviateVector::dispatch(
$model->toVectorArray(), // Convert model to vector format
$model->weaviateCollection
);
});
Cache frequent queries with Laravel Cache:
public function findNearest(array $vector, int $limit = 3, ?array $filter = null): array
{
$cacheKey = md5(serialize([$vector, $limit, $filter]));
return Cache::remember($cacheKey, now()->addMinutes(5), function() use ($vector, $limit, $filter) {
return $this->store->findNearest($vector, $limit, $filter);
});
}
embedding property type, metadata fields).// Check if collection exists and has correct schema
$client = $store->getHttpClient();
$response = $client->request('GET', '/v1/schema');
if (!isset($response['data']['collections'][$config['collection']])) {
throw new \RuntimeException("Weaviate collection not found");
}
$expectedDim = 384; // Example: 'text-embedding-ada-002' outputs 1536 dims
if (count($vector) !== $expectedDim) {
throw new \InvalidArgumentException("Vector dimension mismatch");
}
How can I help you explore Laravel packages today?