Drivers & Extension Points
Swap the embedder, choose a vector store, and scale to pgvector
Drivers & Extension Points
Both the embedding provider and the storage engine are resolved through contracts, so you can replace either without touching your models. Everything is wired through the OiLaravelRaggable static resolver, which reads config.
Custom embedder
Implement the Embedder contract and point config at your class:
use OiLab\OiLaravelRaggable\Contracts\Embedder;
use OiLab\OiLaravelRaggable\Data\EmbeddingResult;
class MyEmbedder implements Embedder
{
public function embed(array $texts): EmbeddingResult
{
// Return one vector per input, in the same order.
return new EmbeddingResult(
vectors: $vectors, // list<list<float>>
provider: 'mine',
model: 'my-model',
);
}
}// config/oi-laravel-raggable.php
'embedder' => \App\Ai\MyEmbedder::class,The default LaravelAiEmbedder wraps laravel/ai; provider and model come from config/ai.php. In tests, bind a fake embedder to the Embedder contract so no real API calls happen.
Vector stores
The active store is chosen by driver:
database(DatabaseVectorStore) — stores vectors as JSON and computes cosine distance in PHP. Works on any database (including SQLite), needs no extension, and keeps the package testable everywhere. Ideal for small to medium corpora.pgvector(PgvectorStore) — stores nativevectorcolumns and runs nearest-neighbor search in PostgreSQL through the<=>cosine operator against an HNSW index. Fast at scale.
Both implement the VectorStore contract, so you can register your own under stores.<driver> and select it with driver.
Scaling to pgvector
- Use a PostgreSQL connection with the
vectorextension available (e.g. thepgvector/pgvectorDocker image). - Set
RAGGABLE_DRIVER=pgvectorand the correctRAGGABLE_DIMENSIONS. - Run
php artisan migrate— the migration enables the extension, creates nativevectorcolumns, and builds HNSW cosine indexes. - Backfill with
php artisan raggable:embed --fresh.
Dimensions are load-bearing. They must match the embedding model exactly. Changing the model or dimensions later means recreating the vector columns and indexes, then re-running
raggable:embed --fresh.
How storage stays driver-agnostic
Vectors are cast (via VectorCast) to a bracketed list such as [0.1,0.2,0.3] — which is simultaneously valid JSON for the database driver and a valid pgvector text input for the pgvector driver. The same Embedding and Chunk models therefore work unchanged across both.