Tous les articles
Mer. 3 juin 2026 · 8 min de lecture

🧠 Laravel AI SDK : construire des applications intelligentes avec Laravel

Laravel AI SDK

📚 Introduction

Jusqu’ici, intégrer une fonctionnalité IA dans une application Laravel passait par un patchwork de SDK officiels (OpenAI, Anthropic, Google), de wrappers communautaires plus ou moins maintenus, et beaucoup de glue code pour gérer le retry, le streaming, les tool calls et les structured outputs.

Avec la sortie du Laravel AI SDK officiel (en même temps que Laravel 13), tout cela rentre dans le rang. C’est un package maintenu par Laravel, installable via Composer, qui offre une API unifiée pour les providers majeurs : OpenAI, Anthropic, Gemini, Groq, xAI, DeepSeek, Mistral, Cohere, Azure, Bedrock, Ollama, OpenRouter, ElevenLabs… Texte, images, audio, transcription, embeddings, reranking, vector stores : tout y passe, avec des helpers de test natifs.

🚀 Installation

composer require laravel/ai
php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"
php artisan migrate

On déclare ensuite les clés API dans le .env :

ANTHROPIC_API_KEY=...
OPENAI_API_KEY=...
GEMINI_API_KEY=...

🤖 Premier agent

Le SDK est résolument orienté objet : un agent = une classe. La commande Artisan make:agent scaffolde le squelette :

php artisan make:agent SalesCoach
namespace App\Ai\Agents;
 
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Promptable;
use Stringable;
 
class SalesCoach implements Agent
{
	use Promptable;
 
	public function instructions(): Stringable|string
	{
		return 'You are a sales coach, analyzing transcripts and providing feedback.';
	}
}

Côté contrôleur, on l’invoque comme n’importe quel service :

use App\Ai\Agents\SalesCoach;
 
$response = (new SalesCoach)
	->prompt('Analyze this sales transcript...');
 
return (string) $response;

On peut surcharger le provider et le modèle pour un prompt précis :

use Laravel\Ai\Enums\Lab;
 
$response = (new SalesCoach)->prompt(
	'Analyze this sales transcript...',
	provider: Lab::Anthropic,
	model: 'claude-haiku-4-5-20251001',
	timeout: 120,
);

🧱 Structured Output

C’est probablement la fonctionnalité qui transforme le plus la façon de construire des features IA. Au lieu de parser du texte ou du JSON à la main, on déclare un schéma typé et on récupère un tableau validé :

use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasStructuredOutput;
use Laravel\Ai\Promptable;
 
class SalesCoach implements Agent, HasStructuredOutput
{
	use Promptable;
 
	public function instructions(): string
	{
		return 'You are a sales coach...';
	}
 
	public function schema(JsonSchema $schema): array
	{
		return [
			'feedback' => $schema->string()->required(),
			'score' => $schema->integer()->min(1)->max(10)->required(),
		];
	}
}
$response = (new SalesCoach)->prompt('Analyze this...');
return $response['score']; // accès direct au champ typé

Les schémas supportent les objets imbriqués, les tableaux d’objets, les enums, les contraintes (min/max/required), ce qui couvre la grande majorité des besoins métier.

🛠️ Tools : laisser l’agent appeler du code Laravel

Un tool est une classe Laravel\Ai\Contracts\Tool avec une description, un schéma de paramètres et une méthode handle() :

php artisan make:tool RandomNumberGenerator
namespace App\Ai\Tools;
 
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Tool;
use Laravel\Ai\Tools\Request;
 
class RandomNumberGenerator implements Tool
{
	public function description(): string
	{
		return 'Generate cryptographically secure random numbers.';
	}
 
	public function handle(Request $request): 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(),
		];
	}
}

Côté agent, on déclare les tools via HasTools :

use Laravel\Ai\Contracts\HasTools;
 
class SalesCoach implements Agent, HasTools
{
	use Promptable;
 
	public function tools(): iterable
	{
		return [
			new RandomNumberGenerator,
		];
	}
}

Le SDK orchestre automatiquement la boucle prompt → tool call → résultat → relance. Pas de parsing manuel, pas de gestion des tool_calls à la main.

🌐 Provider Tools : WebSearch, WebFetch, FileSearch

Trois tools fournis nativement et exécutés côté provider :

use Laravel\Ai\Providers\Tools\FileSearch;
use Laravel\Ai\Providers\Tools\WebFetch;
use Laravel\Ai\Providers\Tools\WebSearch;
 
public function tools(): iterable
{
	return [
		(new WebSearch)->max(5)->allow(['laravel.com', 'php.net']),
		(new WebFetch)->max(3)->allow(['docs.laravel.com']),
		new FileSearch(stores: ['store_id'], where: [
			'author' => 'Taylor Otwell',
			'year' => 2026,
		]),
	];
}

L’agent peut chercher sur le web, fetcher une page précise, ou interroger un vector store géré par le provider. Filtrage par métadonnée inclus.

🔁 Streaming et broadcasting

Le streaming est intégré au framework :

Route::get('/coach', function () {
	return (new SalesCoach)->stream('Analyze this sales transcript...');
});

On peut chainer un callback après la fin du stream, itérer manuellement, ou même streamer au format Vercel AI SDK Protocol pour brancher un front Next.js / React :

return (new SalesCoach)
	->stream('Analyze this...')
	->usingVercelDataProtocol();

Le SDK supporte aussi le broadcast direct sur un canal :

use Illuminate\Broadcasting\Channel;
 
(new SalesCoach)->broadcastOnQueue(
	'Analyze this sales transcript...',
	new Channel('coach.{user-id}'),
);

Idéal pour un dashboard temps réel sans monter d’infrastructure additionnelle.

🧠 Conversations persistantes

Les agents peuvent gérer leur historique de conversation automatiquement via les traits Conversational et RemembersConversations :

use Laravel\Ai\Concerns\RemembersConversations;
use Laravel\Ai\Contracts\Conversational;
 
class SalesCoach implements Agent, Conversational
{
	use Promptable, RemembersConversations;
}
$response = (new SalesCoach)->forUser($user)->prompt('Hello!');
$conversationId = $response->conversationId;
 
// Plus tard…
$response = (new SalesCoach)
	->continue($conversationId, as: $user)
	->prompt('Tell me more about that.');

On ajoute aussi HasConversations sur le modèle User pour exposer $user->conversations(). Plus besoin de gérer le stockage et la reprise de contexte à la main.

📎 Attachments : PDF, images, fichiers uploadés

Tous les agents acceptent des attachments :

use Laravel\Ai\Files;
 
$response = (new SalesCoach)->prompt(
	'Analyze the attached sales transcript.',
	attachments: [
		Files\Document::fromStorage('transcript.pdf'),
		Files\Image::fromUrl('https://example.com/photo.jpg'),
		$request->file('transcript'),
	],
);

Compatible avec Storage (disques Laravel), URLs distantes, paths locaux et UploadedFile Symfony.

🖼️ Image, Audio, Transcription

Trois modalités complémentaires utilisent une API fluide cohérente :

use Laravel\Ai\Audio;
use Laravel\Ai\Image;
use Laravel\Ai\Transcription;
 
$image = Image::of('A donut sitting on the kitchen counter')
	->quality('high')
	->landscape()
	->generate();
 
$path = $image->store(); // Storage::disk('local')
 
$audio = Audio::of('I love coding with Laravel.')
	->female()
	->instructions('Said like a pirate')
	->generate();
 
$transcript = Transcription::fromStorage('audio.mp3')
	->diarize()
	->generate();

Et toutes ces opérations sont queueable :

Image::of('A donut...')
	->portrait()
	->queue()
	->then(fn ($image) => $image->store());

🔍 Embeddings et RAG

Pour la recherche sémantique, le SDK couvre l’ensemble du pipeline :

use Illuminate\Support\Str;
use Laravel\Ai\Embeddings;
 
// Un seul texte
$embeddings = Str::of('Napa Valley has great wine.')->toEmbeddings();
 
// Plusieurs textes
$response = Embeddings::for([
	'Napa Valley has great wine.',
	'Laravel is a PHP framework.',
])->generate();

Côté base de données, des helpers Schema et des macros Eloquent gèrent les colonnes vectorielles (PostgreSQL pgvector ou équivalent) :

Schema::ensureVectorExtensionExists();
 
Schema::create('documents', function (Blueprint $table) {
	$table->id();
	$table->string('title');
	$table->text('content');
	$table->vector('embedding', dimensions: 1536)->index();
	$table->timestamps();
});

Et la recherche par similarité devient triviale :

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

Le SDK gère automatiquement la génération de l’embedding à partir de la chaîne de recherche. Pour les cas avancés : selectVectorDistance, whereVectorDistanceLessThan, orderByVectorDistance, et caching natif des embeddings.

🏷️ Reranking

Pour affiner un classement de résultats par pertinence (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.',
])->rerank('PHP frameworks');
 
$response->first()->document; // 'Laravel is a PHP web application framework.'
$response->first()->score;    // 0.95

Le reranking s’applique aussi directement sur une Collection Eloquent :

$posts = Post::all()->rerank(['title', 'body'], 'Laravel tutorials');

C’est la deuxième brique d’une stack RAG sérieuse : embeddings pour le rappel, reranking pour la précision.

📚 Vector Stores

Pour les usages où l’on souhaite déléguer le stockage et l’indexation au provider (OpenAI, Anthropic, Gemini) :

use Laravel\Ai\Files\Document;
use Laravel\Ai\Stores;
 
$store = Stores::create(
	name: 'Knowledge Base',
	description: 'Documentation and reference materials.',
	expiresWhenIdleFor: days(30),
);
 
$store->add(Document::fromPath('/path/to/document.pdf'), metadata: [
	'author' => 'Taylor Otwell',
	'department' => 'Engineering',
]);

Le tool FileSearch peut ensuite cibler ce store depuis n’importe quel agent.

⚙️ Configuration via attributs PHP

Comme le reste de Laravel 13, le SDK profite des attributs PHP pour la configuration par défaut d’un agent :

use Laravel\Ai\Attributes\{MaxSteps, MaxTokens, Model, Provider, Temperature, Timeout};
use Laravel\Ai\Enums\Lab;
 
#[Provider(Lab::Anthropic)]
#[Model('claude-haiku-4-5-20251001')]
#[MaxSteps(10)]
#[MaxTokens(4096)]
#[Temperature(0.7)]
#[Timeout(120)]
class SalesCoach implements Agent
{
	use Promptable;
}

Deux raccourcis particulièrement utiles : #[UseCheapestModel] et #[UseSmartestModel], qui basculent automatiquement vers le bon modèle selon l’usage. Voir aussi mon post sur les attributs Laravel 13.

🔁 Failover automatique entre providers

Une des fonctionnalités les plus pragmatiques du SDK :

$response = (new SalesCoach)->prompt(
	'Analyze this sales transcript...',
	provider: [Lab::OpenAI, Lab::Anthropic],
);

Si OpenAI est down ou que la quota est dépassée, le SDK retombe automatiquement sur Anthropic. Idem côté image et audio.

🧪 Testing intégré

Le SDK livre des helpers fake() pour chaque capacité : agents, images, audio, transcriptions, embeddings, reranking, files, stores.

use App\Ai\Agents\SalesCoach;
use Laravel\Ai\Prompts\AgentPrompt;
 
SalesCoach::fake([
	'First response',
	'Second response',
]);
 
// ou dynamique
SalesCoach::fake(function (AgentPrompt $prompt) {
	return 'Response for: '.$prompt->prompt;
});

Et les assertions habituelles :

SalesCoach::assertPrompted('Analyze this...');
SalesCoach::assertNeverPrompted();
SalesCoach::fake()->preventStrayPrompts();

Le même pattern existe pour Image::fake(), Audio::fake(), Embeddings::fake(), Reranking::fake(), Files::fake(), Stores::fake(). Pour la première fois côté PHP, on peut tester des features IA sans hacker autour d’un mock HTTP.

🧩 Cohérence avec l’écosystème Laravel 13

Le SDK s’intègre naturellement avec les autres briques modernes de Laravel :

L’ensemble forme une stack cohérente : votre application Laravel devient à la fois un consommateur d’IA (via le SDK) et un environnement exploitable par des agents externes (via Boost et PAO).

⚠️ Quelques précautions

  • Coûts et quotas : chaque appel a un coût. Logger les usages et fixer des budgets par provider est indispensable dès le premier déploiement.
  • PII et RGPD : ne jamais envoyer de données personnelles non anonymisées à un provider distant sans validation juridique. Pour les sujets sensibles, basculer sur un provider local (Ollama via base URL custom).
  • Versionner les prompts et les schémas : ils sont du code applicatif. Mettez-les dans des classes dédiées, testez avec fake().
  • Évaluer la qualité : profitez du structured output pour bâtir un harness d’évaluation simple avec des fixtures.

🎉 Conclusion

Le Laravel AI SDK officiel transforme l’expérience de construction d’applications IA côté PHP. Avec une API unifiée orientée objet, des structured outputs natifs, un système d’agents + tools convaincant, le support du RAG (embeddings + reranking + vector stores) et un toolkit de tests complet, c’est exactement ce qui manquait pour que Laravel soit un choix sérieux dans la nouvelle génération d’applications.

Si vous avez un cas d’usage IA dans le pipeline (extraction documentaire, classification, agent métier, recherche sémantique, génération assistée), c’est le package à installer cette semaine.

🔗 Liens utiles