A unified, expressive API for interacting with AI providers — build agents with tools and structured output, generate images, synthesise and transcribe audio, create vector embeddings, and more, all with a consistent Laravel-friendly interface.
Laravel AI SDK provides a unified, expressive API for interacting with AI providers such as OpenAI, Anthropic, Gemini, and more. With the AI SDK you can build intelligent agents with tools and structured output, generate images, synthesize and transcribe audio, create vector embeddings, and much more — all using a consistent, Laravel-friendly interface.
Laravel AI SDK is an official package (laravel/ai) available in Laravel 13.
The default models for each capability (text, images, audio, transcription, embeddings) may also be configured in config/ai.php. For example, to default to GPT-4o for text generation and dall-e-3 for image generation:
Agents are the fundamental building block of the Laravel AI SDK. Each agent is a PHP class that encapsulates a system prompt, conversation context, tools, and an optional structured output schema.
$response = (new SalesCoach)->prompt('Analyze this sales transcript...');return (string) $response;
Use make to resolve the agent from the service container:
$agent = SalesCoach::make(user: $user);
Override the provider, model, or timeout per request:
use Laravel\Ai\Enums\Lab;$response = (new SalesCoach)->prompt( 'Analyze this sales transcript...', provider: Lab::Anthropic, model: 'claude-haiku-4-5-20251001', timeout: 120,);
The RemembersConversations trait stores and retrieves history automatically using the published migrations:
use Laravel\Ai\Concerns\RemembersConversations;class SalesCoach implements Agent, Conversational{ use Promptable, RemembersConversations; public function instructions(): string { return 'You are a sales coach...'; }}// Start a new conversation$response = (new SalesCoach)->forUser($user)->prompt('Hello!');$conversationId = $response->conversationId;// Continue an existing conversation$response = (new SalesCoach) ->continue($conversationId, as: $user) ->prompt('Tell me more about that.');
use Laravel\Ai\Files;$response = (new SalesCoach)->prompt( 'Analyze the attached sales transcript...', attachments: [ Files\Document::fromStorage('transcript.pdf'), Files\Document::fromPath('/home/laravel/transcript.md'), $request->file('transcript'), ]);
For image attachments use Files\Image:
$response = (new ImageAnalyzer)->prompt('What is in this image?', attachments: [ Files\Image::fromStorage('photo.jpg'), Files\Image::fromPath('/home/laravel/photo.jpg'), $request->file('photo'),]);
Broadcast each streamed event over a Laravel channel:
use Illuminate\Broadcasting\Channel;$stream = (new SalesCoach)->stream('Analyze this sales transcript...');foreach ($stream as $event) { $event->broadcast(new Channel('channel-name'));}
Or use broadcastOnQueue to broadcast asynchronously:
(new SalesCoach)->broadcastOnQueue( 'Analyze this sales transcript...', new Channel('channel-name'),);
Tools extend what an agent can do — query databases, call external APIs, perform calculations, etc.
php artisan make:tool RandomNumberGenerator
<?phpnamespace App\Ai\Tools;use Illuminate\Contracts\JsonSchema\JsonSchema;use Laravel\Ai\Contracts\Tool;use Laravel\Ai\Tools\Request;use Stringable;class RandomNumberGenerator implements Tool{ public function description(): Stringable|string { return 'This tool may be used to generate cryptographically secure random numbers.'; } public function handle(Request $request): Stringable|string { return (string) random_int($request['min'], $request['max']); } public function schema(JsonSchema $schema): array { return [ 'min' => $schema->integer()->min(0)->required(), 'max' => $schema->integer()->required(), ]; }}
Register tools in the agent’s tools method:
use Laravel\Ai\Contracts\HasTools;class SalesCoach implements Agent, HasTools{ use Promptable; public function tools(): iterable { return [new RandomNumberGenerator]; }}
Agent middleware lets you inspect or modify prompts and responses before and after they are sent.
php artisan make:agent-middleware LogPrompts
Implement the middleware on the agent:
use App\Ai\Middleware\LogPrompts;use Laravel\Ai\Contracts\HasMiddleware;class SalesCoach implements Agent, HasMiddleware{ use Promptable; public function middleware(): array { return [new LogPrompts]; }}
A middleware class:
<?phpnamespace App\Ai\Middleware;use Closure;use Laravel\Ai\Prompts\AgentPrompt;class LogPrompts{ public function handle(AgentPrompt $prompt, Closure $next) { Log::info('Prompting agent', ['prompt' => $prompt->prompt]); return $next($prompt); }}
Inspect the response after it is generated using then:
public function handle(AgentPrompt $prompt, Closure $next){ return $next($prompt)->then(function (AgentResponse $response) { Log::info('Agent responded', ['text' => $response->text]); });}
Create a one-off agent inline with the agent() helper:
use function Laravel\Ai\{agent};$response = agent( instructions: 'You are an expert at software development.', messages: [], tools: [],)->prompt('Tell me about Laravel');
With structured output:
use Illuminate\Contracts\JsonSchema\JsonSchema;$response = agent( schema: fn (JsonSchema $schema) => ['number' => $schema->integer()->required()],)->prompt('Generate a random number less than 100');
Generate images with the Image class. Supported providers: OpenAI, Gemini, xAI, Azure, Bedrock, OpenRouter.
use Laravel\Ai\Image;$image = Image::of('A donut sitting on the kitchen counter')->generate();$rawContent = (string) $image;
Specify quality and aspect ratio:
$image = Image::of('A donut sitting on the kitchen counter') ->quality('high') ->landscape() ->timeout(120) ->generate();
Generate from a reference image:
use Laravel\Ai\Files;$image = Image::of('Update this photo to be in the style of an impressionist painting.') ->attachments([Files\Image::fromStorage('photo.jpg')]) ->landscape() ->generate();
Generate speech from text with the Audio class. Supported providers: OpenAI, ElevenLabs, Gemini.
use Laravel\Ai\Audio;$audio = Audio::of('I love coding with Laravel.')->generate();$rawContent = (string) $audio;
Select a voice:
$audio = Audio::of('I love coding with Laravel.')->female()->generate();$audio = Audio::of('I love coding with Laravel.')->voice('voice-id-or-name')->generate();$audio = Audio::of('I love coding with Laravel.')->female()->instructions('Said like a pirate')->generate();
use Laravel\Ai\Responses\AudioResponse;Audio::of('I love coding with Laravel.') ->queue() ->then(function (AudioResponse $audio) { $path = $audio->store(); });
Generate embeddings using the Embeddings class or the Str macro.
use Illuminate\Support\Str;$embeddings = Str::of('Napa Valley has great wine.')->toEmbeddings();
use Laravel\Ai\Embeddings;$response = Embeddings::for([ 'Napa Valley has great wine.', 'Laravel is a PHP framework.',])->generate();$response->embeddings; // [[0.123, 0.456, ...], [0.789, 0.012, ...]]
Specify dimensions and model:
$response = Embeddings::for(['Napa Valley has great wine.']) ->dimensions(1536) ->generate(Lab::OpenAI, 'text-embedding-3-small');
$response = Embeddings::for(['Napa Valley has great wine.'])->cache()->generate();$response = Embeddings::for(['Napa Valley has great wine.'])->cache(seconds: 3600)->generate();// Via the Str macro$embeddings = Str::of('Napa Valley has great wine.')->toEmbeddings(cache: true);$embeddings = Str::of('Napa Valley has great wine.')->toEmbeddings(cache: 3600);
Rerank a list of documents by relevance to a query. Supported providers: Cohere, Jina, VoyageAI.
use Laravel\Ai\Reranking;$response = Reranking::of([ 'Django is a Python web framework.', 'Laravel is a PHP web application framework.', 'React is a JavaScript library for building user interfaces.',])->rerank('PHP frameworks');$response->first()->document; // "Laravel is a PHP web application framework."$response->first()->score; // 0.95$response->first()->index; // 1$response = Reranking::of($documents)->limit(5)->rerank('search query');
Pass an array of providers to automatically fall back when one is unavailable:
use App\Ai\Agents\SalesCoach;use Laravel\Ai\Image;$response = (new SalesCoach)->prompt( 'Analyze this sales transcript...', provider: [Lab::OpenAI, Lab::Anthropic],);$image = Image::of('A donut sitting on the kitchen counter') ->generate(provider: [Lab::Gemini, Lab::xAI]);