Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Embedding Laravel Package

x-laravel/embedding

Laravel package that auto-generates and stores vector embeddings for Eloquent models via laravel/ai. Supports single or multi-slot embeddings with field-based triggers, queued generation per slot, driver-based similarity search across many databases, and optional reranking.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require x-laravel/embedding laravel/ai
    php artisan migrate
    
  2. Basic Setup: Add the Embeddable trait and define toEmbeddingText() in your Eloquent model:

    use XLaravel\Embedding\Concerns\Embeddable;
    use XLaravel\Embedding\Contracts\HasEmbeddings;
    
    class Post extends Model implements HasEmbeddings
    {
        use Embeddable;
    
        public function toEmbeddingText(): string
        {
            return $this->title . ' ' . $this->body;
        }
    }
    
  3. First Use Case: Trigger embedding generation on a new post:

    $post = Post::create(['title' => 'Laravel Embedding', 'body' => '...']);
    $post->embed(); // Dispatches a queued job to generate embeddings
    

Where to Look First

  • Model Integration: Focus on toEmbeddingText() and $embeddable configuration.
  • Similarity Search: Use similarTo() or similarToText() for basic retrieval.
  • Artisan Commands: Run php artisan embedding:status to verify setup.

Implementation Patterns

Usage Patterns

  1. Single-Slot Models:

    class Post extends Model implements HasEmbeddings
    {
        use Embeddable;
    
        protected array $embeddable = ['title', 'body'];
    
        public function toEmbeddingText(): string
        {
            return $this->title . ' ' . $this->body;
        }
    }
    
    • Trigger: Embeddings auto-generate when title or body changes.
    • Usage: $post->embed() or $post->embedSync().
  2. Multi-Slot Models:

    class Post extends Model implements HasEmbeddings
    {
        use Embeddable;
    
        protected array $embeddable = [
            'title' => ['title'],
            'body'  => ['body'],
            'full'  => ['title', 'body'],
        ];
    
        public function toEmbeddingText(): string|array
        {
            return [
                'title' => $this->title,
                'body'  => $this->body,
                'full'  => $this->title . ' ' . $this->body,
            ];
        }
    }
    
    • Trigger: Only re-embed slots tied to changed fields (e.g., updating title skips body slot).
    • Usage: $post->embed('title') or $post->embeddings() to fetch all slots.
  3. Attribute-Based Configuration:

    use XLaravel\Embedding\Attributes\EmbedOn;
    
    #[EmbedOn(['title', 'body'])]
    class Post extends Model implements HasEmbeddings { ... }
    
    • Use Case: Prefer attributes for dynamic or complex trigger logic.

Workflows

  1. RAG Pipeline:

    • Generate embeddings for documents.
    • Query with similarToText():
      $results = Post::similarToText('Laravel AI', limit: 5);
      
    • Rerank results:
      $reranked = $results->rerankWithScores('Laravel AI performance', take: 3);
      
  2. Bulk Embedding:

    • Use embedding:generate for backfilling:
      php artisan embedding:generate "App\Models\Post" --limit=1000
      
  3. Similarity Search with Filters:

    $results = Post::similarTo($vector, threshold: 0.8)
        ->where('published_at', '>', now()->subYear());
    

Integration Tips

  • Queue Workers: Ensure queue workers are running for async embedding generation.
  • Driver Selection: Install a database-specific driver (e.g., embedding-pgsql-driver) for native vector search.
  • Pulse Plugin: Add monitoring with:
    composer require x-laravel/embedding-pulse-plugin
    
    Then include Livewire cards in your Pulse dashboard.

Gotchas and Tips

Pitfalls

  1. Blocking Operations:

    • Avoid embedSync() in production; use queued jobs (embed()) for scalability.
    • Fix: Monitor queue backlogs with embedding:status.
  2. Slot Mismatches:

    • Deleting a slot from $embeddable won’t auto-cleanup old embeddings.
    • Fix: Run php artisan embedding:clean --invalid-slots-only to prune stale slots.
  3. Soft Deletes:

    • Default behavior deletes all embeddings on soft delete. Override with:
      protected bool $keepEmbeddingOnSoftDelete = true;
      
  4. Driver Conflicts:

    • Mixing drivers (e.g., php and pgsql) may cause unexpected behavior.
    • Fix: Explicitly set the driver in config/embedding.php:
      'similarity' => ['driver' => 'pgsql'],
      
  5. Reranking Limits:

    • Reranking APIs (Cohere/Voyage) have rate limits. Batch queries to avoid throttling.
    • Tip: Use take parameter to control batch size:
      ->rerankWithScores('query', take: 10)
      

Debugging

  • Failed Jobs: Check embedding.failures Pulse card or queue logs.
  • Embedding Status: Use embedding:status to verify slot coverage:
    php artisan embedding:status "App\Models\Post"
    
  • Slow Queries: Enable query logging in config/embedding.php:
    'debug' => [
        'log_queries' => true,
    ],
    

Config Quirks

  1. Embedding Disabled:

    • Global suppression with Post::disableEmbedding() may persist across requests.
    • Fix: Re-enable explicitly:
      Post::enableEmbedding();
      
  2. Vector Dimensions:

    • Ensure laravel/ai and embedding models use the same vector dimension (e.g., 1536 for OpenAI).
    • Tip: Validate in config/ai.php:
      'default' => [
          'model' => 'openai',
          'options' => [
              'embedding' => [
                  'model' => 'text-embedding-ada-002',
                  'dimensions' => 1536,
              ],
          ],
      ],
      
  3. Queue Stuck Jobs:

    • Retry failed jobs with:
      php artisan queue:retry all
      

Extension Points

  1. Custom Drivers:

    • Extend XLaravel\Embedding\Contracts\SimilarityDriver for unsupported databases.
    • Register via:
      app(SimilarityManager::class)->extend('custom', fn() => new MyDriver());
      
  2. Event Hooks:

    • Tap into ModelEmbedding/ModelEmbedded events for auditing or side effects:
      Post::onEmbedded(fn($post, $slot) => Log::info("Embedded slot {$slot} for post {$post->id}"));
      
  3. Dynamic Slots:

    • Use toEmbeddingText() to generate slots dynamically (e.g., per-user embeddings):
      public function toEmbeddingText(): array
      {
          return [
              'user_' . $this->user_id => $this->content,
          ];
      }
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky