laravel-vector-search

SkillSearch

Use when implementing semantic/vector search in Laravel 13 with PostgreSQL + pgvector.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the laravel-vector-search skill

What this skill tells your AI

The instructions your AI receives, as published by fusengine/agents in plugins/laravel-expert/skills/laravel-vector-search/SKILL.md and read by ahel’s review.

Laravel 13 Vector Search (pgvector)

Agent Workflow (MANDATORY)

Before ANY implementation, spawn 3 agents in parallel, one Agent call each with a name:

  1. fuse-ai-pilot:explore-codebase - Check current DB driver (must be PostgreSQL) and existing embedding columns
  2. fuse-ai-pilot:research-expert - Verify pgvector extension version and HNSW vs IVFFlat tradeoffs
  3. mcp__context7__query-docs - Pull laravel.com/docs/13.x/search + queries examples

After implementation, run fuse-ai-pilot:sniper for validation.


Overview

FeatureDescription
PostgreSQL onlyRequires pgvector extension; not available on MySQL/SQLite
Schema helperSchema::ensureVectorExtensionExists() enables the extension
Query builderwhereVectorSimilarTo(), selectVectorDistance(), whereVectorDistanceLessThan(), orderByVectorDistance()
Auto-embeddingPass a raw string and Laravel generates the embedding via AI SDK
Cosine similarityDefault distance; threshold via minSimilarity (0.0 - 1.0)

Critical Rules

  1. Use PostgreSQL - Vector clauses ONLY work on pgsql connections - no fallback to MySQL/SQLite
  2. Create an HNSW index - Without an index, queries do full table scans; > 10k rows means seconds-to-minutes latency
  3. Match dimensions exactly - Insert-time and query-time embedding models MUST share the same dimensions
  4. Cache embeddings - Regenerating embeddings on every request is the #1 cost driver; persist them
  5. Lock the embedding model - Changing the model invalidates ALL stored embeddings; treat the model as a schema field

Architecture

database/migrations/
└── XXXX_create_documents_table.php   # Schema::ensureVectorExtensionExists(), vector(1536) col, HNSW index

app/Models/
└── Document.php                       # casts embedding to array, uses whereVectorSimilarTo

app/Ai/Services/
└── VectorSearchService.php            # encapsulates query + threshold logic

→ See Document-model.php.md for full example


Reference Guide

TopicReferenceWhen to Consult
pgvector setuppgvector-setup.mdMigrations + index creation
Embedding workflowembeddings-workflow.mdGenerating + persisting vectors
Query patternsqueries.mdwhereVectorSimilarTo and friends

Templates

TemplateWhen to Use
Document-model.php.mdEloquent model with vector column
VectorSearchService.php.mdReusable service

Quick Reference

Migration

Schema::ensureVectorExtensionExists();

Schema::create('documents', function (Blueprint $table) {
    $table->id();
    $table->text('content');
    $table->vector('embedding', 1536);
    $table->timestamps();
    $table->vectorIndex('embedding', algorithm: 'hnsw');
});

Query

$documents = Document::query()
    ->whereVectorSimilarTo('embedding', 'best wineries in Napa Valley', minSimilarity: 0.4)
    ->limit(10)
    ->get();

→ See VectorSearchService.php.md for complete example


Best Practices

DO

  • Create an HNSW index BEFORE inserting bulk data - faster total ingest
  • Store the embedding model name alongside the vector to detect drift
  • Use minSimilarity 0.3-0.5 as a starting threshold; tune empirically
  • Combine vector search with classic where() for hybrid filtering (date ranges, tenancy)

DON'T

  • Don't run vector queries without an index past a few thousand rows - it becomes a full table scan
  • Don't mix embedding models in the same column - distances become meaningless
  • Don't generate query embeddings inside loops - batch them via Embeddings::for([...])
  • Don't store embeddings as JSON strings - use the native vector column type for index support

Signals

GitHub stars
27
Forks
4
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
laravel-vector-search
Source
github.com/fusengine/agents