Installation
composer require laraigent/larai-kit
php artisan vendor:publish --provider="LarAIgent\LarAIKit\LarAIKitServiceProvider" --tag="config"
Publish migrations and run:
php artisan migrate
Configure AI Provider
Add your API keys to .env (e.g., OPENAI_API_KEY) and set the default provider in config/larai-kit.php:
'providers' => [
'default' => 'openai',
],
First Use Case: Document Ingestion Upload a PDF/DOCX via a controller:
use LarAIgent\LarAIKit\Facades\Document;
public function ingestDocument(Request $request) {
$file = $request->file('document');
$document = Document::ingest($file)->save();
return response()->json(['id' => $document->id]);
}
Query the Vector Store
use LarAIgent\LarAIKit\Facades\VectorSearch;
$results = VectorSearch::search('What is RAG?', 3);
README.md and docs/ folder in the repo).config/larai-kit.php for provider settings, chunking logic, and multi-tenancy.database/migrations/ for vector store tables (e.g., vector_documents, vector_chunks).config/larai-kit.php:
'chunking' => [
'size' => 512,
'overlap' => 50,
],
Document::ingestBatch() for bulk uploads:
$documents = collect([$file1, $file2])->each->ingest()->toArray();
Document::ingestBatch($documents)->process();
$response = VectorSearch::rag('Explain Laravel RAG', 3, 'gpt-3.5-turbo');
app/Providers/LarAIKitServiceProvider.php:
public function boot() {
LarAIKit::setRagTemplate(function ($query, $context) {
return "Answer using ONLY this context: {$context}";
});
}
$stream = Chat::stream('What is Laravel?', [
'model' => 'gpt-4',
'temperature' => 0.3,
]);
return response()->stream(fn () => $stream);
$conversation = Chat::start('User', 'Hello');
$conversation->reply('Bot', 'Hi there!');
$response = $conversation->ask('How are you?');
LarAIKit::setTenant('tenant_id_123');
$results = VectorSearch::search('Query'); // Only searches tenant_id_123
VectorSearch::forTenant('tenant_id_456')->search('Query');
Laravel\AI\ classes (e.g., Laravel\AI\Services\OpenAI) alongside LarAIKit for hybrid workflows.Document::ingested(function ($document) {
// Post-process chunks (e.g., log, index elsewhere)
});
Document::ingest($file)->dispatchSyncOn('chunking-queue');
Vector Store Mismatches
pgvector without the correct extension installed.CREATE EXTENSION vector; in PostgreSQL before migrating.config/larai-kit.php for vector_store setting and ensure it matches your DB setup.Chunking Overhead
max_execution_time or process in chunks:
Document::ingest($file)->chunkSize(1024)->overlap(100)->save();
Multi-Tenancy Leaks
public function handle(Request $request, Closure $next) {
LarAIKit::setTenant(auth()->user()->tenant_id);
return $next($request);
}
Rate Limiting
config/larai-kit.php:
'retry' => [
'max_attempts' => 3,
'delay' => 1000, // ms
],
Log Chunks: Enable chunk logging in config:
'debug' => [
'log_chunks' => true,
],
Check storage/logs/larai-kit.log for chunk boundaries.
Vector Search Queries: Inspect raw queries with:
VectorSearch::enableQueryLogging();
Custom Vector Stores
LarAIgent\LarAIKit\Contracts\VectorStore for unsupported databases (e.g., Milvus):
class MilvusStore implements VectorStore {
public function search($query, $limit) { ... }
}
config/larai-kit.php:
'vector_stores' => [
'milvus' => \App\Services\MilvusStore::class,
],
Embedding Providers
LarAIgent\LarAIKit\Contracts\EmbeddingProvider for custom models:
class CustomEmbeddingProvider implements EmbeddingProvider {
public function embed($text) { ... }
}
AppServiceProvider:
LarAIKit::extend('custom', function () {
return new CustomEmbeddingProvider();
});
Post-Processing Hooks
Document::ingested(function ($document) {
$document->chunks()->each(function ($chunk) {
// Sanitize, translate, or enrich chunks
});
});
config/larai-kit.php doesn’t specify a default model, it uses gpt-3.5-turbo.overlap to 0 for non-overlapping chunks (faster but less context).config/larai-kit.php streaming_timeout (default: 60 seconds) for long responses.$results = VectorSearch::hybridSearch('Laravel OR "AI agent"', 5);
$results = Cache::remember("rag_{$query}", now()->addHours(1), function () use ($query) {
return VectorSearch::search($query, 3);
});
public function handle($request, Closure $next) {
$startTokens = LarAIKit::getTokenCount();
$response = $next($request);
$usedTokens = LarAIKit::getTokenCount() - $startTokens;
// Log or alert on high usage
return $response;
}
How can I help you explore Laravel packages today?