A community-driven registry for Claude, Cursor, Windsurf, Cline & more. Not affiliated with Anthropic.
Are you the author? Sign in to claim
A complete, driver based RAG pipeline for Laravel with pgvector & sqlite-vec, streaming, agentic retrieval, hybrid searc
A complete, driver-based RAG (Retrieval-Augmented Generation) pipeline for Laravel. Built on Prism PHP for provider-agnostic LLM and embedding support.
.env$table->vector(), $table->vectorIndex() feel native to LaravelHasVectorSearch and AutoEmbeds for zero-boilerplate integrationRag::from(Document::class)->ask('question')rag:index, rag:test, rag:estimate, rag:eval, rag:mcp-serve<livewire:rag-chat> with streaming and sourcesVector store (choose one):
Note: sqlite-vec requires PHP compiled with SQLite extension loading support. macOS PHP (Herd, Homebrew) does not support this. Use Docker, Laravel Sail, or switch to pgvector on macOS.
composer require moneo/laravel-rag
Publish the config:
php artisan vendor:publish --tag=rag-config
Run migrations:
php artisan vendor:publish --tag=rag-migrations
php artisan migrate
# Vector store: pgvector (production) or sqlite-vec (local dev)
RAG_VECTOR_STORE=pgvector
# Embedding provider (via Prism)
RAG_EMBEDDING_DRIVER=openai
RAG_EMBEDDING_MODEL=text-embedding-3-small
RAG_EMBEDDING_DIMENSIONS=1536
# LLM provider (via Prism)
RAG_LLM_PROVIDER=openai
RAG_LLM_MODEL=gpt-4o
# Embedding cache (reduces API costs)
RAG_EMBEDDING_CACHE=true
Works everywhere. Requires PostgreSQL with pgvector extension.
RAG_VECTOR_STORE=pgvector
CREATE EXTENSION IF NOT EXISTS vector;
Zero-infrastructure local dev. Does NOT work on macOS Herd/Homebrew PHP.
RAG_VECTOR_STORE=sqlite-vec
RAG_SQLITE_DATABASE=/path/to/your/vectors.sqlite
Linux (Ubuntu/Debian):
# 1. Download sqlite-vec
wget https://github.com/asg017/sqlite-vec/releases/download/v0.1.7/sqlite-vec-0.1.7-loadable-linux-x86_64.tar.gz
tar xzf sqlite-vec-*.tar.gz
sudo mkdir -p /usr/lib/sqlite-vec && sudo cp vec0.so /usr/lib/sqlite-vec/
# 2. Add to php.ini
echo "sqlite3.extension_dir=/usr/lib/sqlite-vec" | sudo tee /etc/php/8.3/cli/conf.d/99-sqlite-vec.ini
# 3. Verify
php -r '$db = new SQLite3(":memory:"); $db->loadExtension("vec0.so"); echo "OK\n";'
Docker / Laravel Sail:
# Add to your Dockerfile
RUN wget -q https://github.com/asg017/sqlite-vec/releases/download/v0.1.7/sqlite-vec-0.1.7-loadable-linux-x86_64.tar.gz \
&& tar xzf sqlite-vec-*.tar.gz && mkdir -p /usr/lib/sqlite-vec && cp vec0.so /usr/lib/sqlite-vec/ \
&& echo "sqlite3.extension_dir=/usr/lib/sqlite-vec" >> /usr/local/etc/php/conf.d/sqlite-vec.ini
macOS: sqlite-vec is not supported with Herd or Homebrew PHP. Use pgvector instead:
RAG_VECTOR_STORE=pgvector
use Moneo\LaravelRag\Concerns\HasVectorSearch;
use Moneo\LaravelRag\Concerns\AutoEmbeds;
class Document extends Model
{
use HasVectorSearch, AutoEmbeds;
protected string $embedSource = 'content';
protected string $vectorColumn = 'embedding';
}
Schema::create('documents', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->text('content');
$table->vector('embedding', 1536);
$table->json('metadata')->nullable();
$table->timestamps();
$table->vectorIndex('embedding', method: 'hnsw', distance: 'cosine');
$table->fulltextIndex('content');
});
use Moneo\LaravelRag\Facades\Ingest;
// From file
Ingest::file('docs/guide.pdf')
->chunk(strategy: 'markdown', size: 500)
->storeIn(Document::class)
->run();
// From text
Ingest::text($content)
->chunk(strategy: 'sentence')
->withMetadata(['category' => 'tech'])
->storeIn(Document::class)
->dispatch(); // async via queue
use Moneo\LaravelRag\Facades\Rag;
// Simple RAG
$result = Rag::from(Document::class)
->limit(5)
->threshold(0.8)
->ask('What is pgvector?');
echo $result->answer;
echo $result->totalTimeMs(); // timing
// With sources
$result = Rag::from(Document::class)
->askWithSources('How does indexing work?');
foreach ($result->sources() as $source) {
echo "{$source['source']} (score: {$source['score']})";
}
// Dry run — retrieve only
$chunks = Rag::from(Document::class)
->dryRun('What is pgvector?');
// In a controller
return Rag::from(Document::class)
->stream($request->question)
->toStreamedResponse();
$result = Rag::from(Document::class)
->hybrid(semanticWeight: 0.7, fulltextWeight: 0.3)
->limit(10)
->ask('pgvector performance');
$result = Rag::from(Document::class)
->limit(20) // retrieve 20 candidates
->rerank(topK: 5) // LLM scores and keeps top 5
->ask('question');
$result = Rag::from(Document::class)
->agentic(maxSteps: 3)
->ask('Complex multi-part question?');
echo $result->answer;
echo $result->stepCount(); // retrieval iterations
echo $result->totalChunksRetrieved; // total chunks gathered
use Moneo\LaravelRag\Memory\RagThread;
$thread = RagThread::create(['model' => Document::class]);
$result1 = $thread->ask('What is Laravel?');
$result2 = $thread->ask('Compare it with Symfony.'); // context-aware
Ingest::text($content)
->chunk(strategy: 'character', size: 500, overlap: 50)
->chunk(strategy: 'sentence')
->chunk(strategy: 'markdown')
->chunk(strategy: 'semantic', threshold: 0.85)
->storeIn(Document::class)
->run();
use Moneo\LaravelRag\Facades\RagEval;
$report = RagEval::suite()
->using(Rag::from(Document::class))
->add(question: 'What is pgvector?', expected: 'A PostgreSQL extension for vector similarity search')
->add(question: 'How to install?', expected: 'Run composer require...')
->run();
$report->passes(0.8); // bool
$report->toJson(); // export for CI
CLI:
php artisan rag:eval --suite=tests/rag/evals.json --fail-below=0.8
// In AppServiceProvider::boot()
use Moneo\LaravelRag\Mcp\RagMcpServer;
app(RagMcpServer::class)
->register(Document::class)
->as('company-docs')
->description('Search internal company documentation')
->expose();
php artisan rag:mcp-serve --port=3000
# Index all records
php artisan rag:index "App\Models\Document" --chunk=100
# Test a query
php artisan rag:test "What is pgvector?" --model="App\Models\Document" --rerank
# Estimate costs
php artisan rag:estimate --model="App\Models\Document"
# Run evals
php artisan rag:eval --suite=tests/rag/evals.json --fail-below=0.8
# Start MCP server
php artisan rag:mcp-serve --port=3000
<livewire:rag-chat
:model="App\Models\Document"
system-prompt="Answer only in Turkish."
:thread-id="$threadId"
placeholder="Ask anything..."
:limit="5"
/>
// In your PanelProvider
->plugins([
\Moneo\LaravelRag\Filament\RagPlugin::make(),
])
Auto-registers when barryvdh/laravel-debugbar is installed. Shows:
Auto-registers when laravel/telescope is installed. Records:
All Prism API calls are wrapped in PrismRetryHandler with exponential backoff:
EmbeddingRateLimitException after 3 attemptsEmbeddingServiceExceptionEmbeddingTimeoutExceptionEmbeddingResponseExceptionDimensionMismatchException before storageException hierarchy:
RagException (abstract)
├── EmbeddingException
│ ├── EmbeddingRateLimitException
│ ├── EmbeddingServiceException
│ ├── EmbeddingTimeoutException
│ ├── EmbeddingResponseException
│ └── DimensionMismatchException
├── VectorStoreException
│ ├── DeadlockException
│ └── VectorStoreLockException
├── GenerationException
└── CacheTableMissingException
All operations emit structured logs via RagLogger (channel: rag.*):
rag.embedding.* — API calls, cache hits/missesrag.retrieval.* — search operationsrag.generation.* — LLM generationrag.cache.* — cache operationsrag.error.* — all caught exceptions with contextText fields are SHA-256 hashed for privacy — raw user input never appears in logs.
Implement VectorStoreContract:
use Moneo\LaravelRag\VectorStores\Contracts\VectorStoreContract;
class QdrantStore implements VectorStoreContract
{
public function upsert(string $id, array $vector, array $metadata): void { /* ... */ }
public function similaritySearch(array $vector, int $limit, float $threshold = 0.0): Collection { /* ... */ }
public function hybridSearch(string $query, array $vector, float $semanticWeight, float $fulltextWeight, int $limit): Collection { /* ... */ }
public function delete(string $id): void { /* ... */ }
public function flush(string $collection): void { /* ... */ }
public function table(string $table): static { /* ... */ }
public function supportsFullTextSearch(): bool { return false; }
}
Register in a service provider:
$this->app->singleton(VectorStoreContract::class, QdrantStore::class);
| Operation | 1K docs | 10K docs | 100K docs |
|---|---|---|---|
| Character chunking (500 chars) | 0.3ms | 2.8ms | 28ms |
| Sentence chunking | 0.5ms | 4.5ms | 45ms |
| Markdown chunking | 0.4ms | 3.8ms | 38ms |
| RRF merge (100+100 results) | 0.1ms | 0.1ms | 0.1ms |
| Similarity search (pgvector HNSW) | 2ms | 5ms | 12ms |
| Hybrid search (pgvector) | 8ms | 15ms | 35ms |
| Embedding cache hit | 0.5ms | 0.5ms | 0.5ms |
Benchmarks run on Apple M2 Pro, PostgreSQL 16 with pgvector 0.7. Results may vary.
This package ships with built-in security hardening:
InputSanitiser::clean() strips 40+ known prompt injection patterns before text reaches the LLMVectorValidator::validate() checks dimensions, NaN, and infinity before every upsert# Unit tests
vendor/bin/pest --testsuite=Unit
# Feature tests
vendor/bin/pest --testsuite=Feature
# Property-based tests (10K random inputs per property)
RAG_ERIS_ITERATIONS=10000 vendor/bin/pest tests/Property
# Chaos tests (fault injection)
vendor/bin/pest tests/Chaos
# Fuzz tests (adversarial inputs)
vendor/bin/pest tests/Fuzz
# Memory leak tests
vendor/bin/pest tests/Memory
# Architecture tests
vendor/bin/pest --testsuite=Architecture
# Contract tests (both vector store drivers)
vendor/bin/pest --testsuite=Contract
# All tests with coverage
vendor/bin/pest --coverage --min=99
# Mutation testing
vendor/bin/infection --threads=4 --min-msi=85
# Static analysis
vendor/bin/phpstan analyse
vendor/bin/rector --dry-run
# Benchmarks
vendor/bin/phpbench run --report=default
All of these must pass before merge:
| Gate | Requirement |
|---|---|
| PHPStan | Level 9, zero errors |
| Test Coverage | >= 99% line, >= 95% branch |
| Mutation Score (MSI) | >= 85% |
| Rector | Zero suggestions |
| Architecture Tests | All Pest arch() rules green |
| Security Audit | composer audit — zero vulnerabilities |
| CI Matrix | PHP 8.2/8.3/8.4 x Laravel 11/12 |
vendor/bin/phpstan analyse
vendor/bin/pest --coverage --min=99
vendor/bin/infection --threads=4 --min-msi=85
vendor/bin/rector --dry-run
vendor/bin/pest --testsuite=ArchitectureCommunity drivers should:
moneo/laravel-rag-{driver} (e.g., moneo/laravel-rag-qdrant)VectorStoreContractVectorStoreContractTest from this package to prove complianceSee SECURITY.md for vulnerability disclosure policy and security measures.
MIT License. See LICENSE for details.
mcp-language-server gives MCP enabled clients access semantic tools like get definition, references, rename, and diagnos
Run Claude Code as an MCP server so any agent can delegate coding tasks to it
Browser automation using accessibility snapshots instead of screenshots
MCP server integration for DaVinci Resolve Studio