Passer au contenu principal

Introduction

Le Laravel AI SDK fournit une API unifiée et expressive pour dialoguer avec OpenAI, Anthropic, Gemini, etc. Construisez des agents intelligents avec tools et sorties structurées, générez images, audio, transcriptions, embeddings — le tout via une interface cohérente et laravelienne.
Laravel AI SDK est un package officiel ajouté avec Laravel 13 (laravel/ai).

Providers supportés

FonctionnalitéProviders
Génération de texteOpenAI, OpenAI Compatible, Anthropic, Gemini, Azure, Bedrock, Groq, xAI, DeepSeek, Mistral, Ollama, OpenRouter
Génération d’imagesOpenAI, Gemini, xAI, Azure, Bedrock, OpenRouter
Synthèse vocale (TTS)OpenAI, ElevenLabs, Gemini
Reconnaissance vocale (STT)OpenAI, ElevenLabs, Mistral, Gemini
EmbeddingsOpenAI, Gemini, Azure, Bedrock, Cohere, Mistral, Jina, VoyageAI, Ollama, OpenRouter
RerankingCohere, Jina, VoyageAI
FichiersOpenAI, Anthropic, Gemini, Azure

Installation

1

Installer le package

composer require laravel/ai
2

Publier config et migrations

php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"
3

Migrer

Crée agent_conversations et agent_conversation_messages pour l’historique.
php artisan migrate

Configuration

Variables d’environnement

ANTHROPIC_API_KEY=
AZURE_OPENAI_API_KEY=
COHERE_API_KEY=
DEEPSEEK_API_KEY=
ELEVENLABS_API_KEY=
GEMINI_API_KEY=
GROQ_API_KEY=
MISTRAL_API_KEY=
OLLAMA_API_KEY=
OPENAI_API_KEY=
OPENROUTER_API_KEY=
JINA_API_KEY=
VOYAGEAI_API_KEY=
XAI_API_KEY=
Modèles par défaut réglables dans config/ai.php.

URL de base personnalisée

Passez par un proxy en configurant l’URL par provider.
'providers' => [
    'openai' => [
        'driver' => 'openai',
        'key' => env('OPENAI_API_KEY'),
        'url' => env('OPENAI_URL'),
    ],
    'anthropic' => [
        'driver' => 'anthropic',
        'key' => env('ANTHROPIC_API_KEY'),
        'url' => env('ANTHROPIC_BASE_URL'),
    ],
],
Disponible pour OpenAI, Anthropic, Gemini, Groq, Cohere, DeepSeek, xAI, OpenRouter.

Provider OpenAI-Compatible

LM Studio, vLLM, Together, Fireworks, gateways locaux… Utilisez le driver openai-compatible. url obligatoire ; key envoyée en Bearer.
'providers' => [
    'local' => [
        'driver' => 'openai-compatible',
        'url' => env('LOCAL_AI_URL'),
        'key' => env('LOCAL_AI_API_KEY'),
    ],
],
Utilisation :
agent()->prompt('What is Laravel?', provider: 'local', model: 'local-model');
Modèle par défaut :
'local' => [
    'driver' => 'openai-compatible',
    'url' => env('LOCAL_AI_URL'),
    'key' => env('LOCAL_AI_API_KEY'),
    'models' => [
        'text' => [
            'default' => env('LOCAL_AI_MODEL'),
        ],
    ],
],
Supporte génération, streaming, tools, sorties structurées, pièces jointes image. Pour d’autres champs, voir les options de provider.

Enum Lab

Référence les providers en code.
use Laravel\Ai\Enums\Lab;

Lab::Anthropic;
Lab::OpenAI;
Lab::Gemini;

Agents

Composant de base. Générez une classe agent :
php artisan make:agent SalesCoach

# Avec sortie structurée
php artisan make:agent SalesCoach --structured
Créé dans app/Ai/Agents/. Exemple implémentant les interfaces principales :
<?php

namespace App\Ai\Agents;

use App\Ai\Tools\RetrievePreviousTranscripts;
use App\Models\History;
use App\Models\User;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\Conversational;
use Laravel\Ai\Contracts\HasStructuredOutput;
use Laravel\Ai\Contracts\HasTools;
use Laravel\Ai\Messages\Message;
use Laravel\Ai\Promptable;
use Stringable;

class SalesCoach implements Agent, Conversational, HasTools, HasStructuredOutput
{
    use Promptable;

    public function __construct(public User $user) {}

    public function instructions(): Stringable|string
    {
        return 'You are a sales coach, analyzing transcripts and providing feedback and an overall sales strength score.';
    }

    public function messages(): iterable
    {
        return History::where('user_id', $this->user->id)
            ->latest()
            ->limit(50)
            ->get()
            ->reverse()
            ->map(function ($message) {
                return new Message($message->role, $message->content);
            })->all();
    }

    public function tools(): iterable
    {
        return [new RetrievePreviousTranscripts];
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'feedback' => $schema->string()->required(),
            'score' => $schema->integer()->min(1)->max(10)->required(),
        ];
    }
}

Prompt

$response = (new SalesCoach)->prompt('Analyze this sales transcript...');
return (string) $response;
make() résout les dépendances via le conteneur.
$agent = SalesCoach::make(user: $user);
Override par appel :
$response = (new SalesCoach)->prompt(
    'Analyze this sales transcript...',
    provider: Lab::Anthropic,
    model: 'claude-haiku-4-5-20251001',
    timeout: 120,
);

Contexte conversationnel

Implémentez Conversational et messages(). Trait RemembersConversations pour la persistance auto.
use Laravel\Ai\Concerns\RemembersConversations;

class SalesCoach implements Agent, Conversational
{
    use Promptable, RemembersConversations;

    public function instructions(): string
    {
        return 'You are a sales coach...';
    }
}
forUser() puis continue() avec l’ID :
$response = (new SalesCoach)->forUser($user)->prompt('Hello!');
$conversationId = $response->conversationId;

$response = (new SalesCoach)->continue($conversationId, as: $user)->prompt('Tell me more about that.');

Sortie structurée

Implémentez HasStructuredOutput + schema().
public function schema(JsonSchema $schema): array
{
    return ['score' => $schema->integer()->required()];
}

$response = (new SalesCoach)->prompt('Analyze this...');
return $response['score'];

Objets imbriqués

public function schema(JsonSchema $schema): array
{
    return [
        'score' => $schema->integer()->required(),
        'metadata' => $schema->object(fn ($schema) => [
            'confidence' => $schema->string()->enum(['low', 'medium', 'high'])->required(),
            'language' => $schema->string()->required(),
        ])->required(),
    ];
}

Tableaux d’objets

public function schema(JsonSchema $schema): array
{
    return [
        'feedback' => $schema->array()->items(
            $schema->object(fn ($schema) => [
                'comment' => $schema->string()->required(),
                'score' => $schema->integer()->required(),
            ])
        )->required(),
    ];
}

anyOf

public function schema(JsonSchema $schema): array
{
    return [
        'content' => $schema->anyOf([
            $schema->object(fn ($schema) => [
                'type' => $schema->string()->enum(['article'])->required(),
                'title' => $schema->string()->required(),
            ]),
            $schema->object(fn ($schema) => [
                'type' => $schema->string()->enum(['image'])->required(),
                'url' => $schema->string()->required(),
            ]),
        ])->required(),
    ];
}

Pièces jointes

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'),
    ]
);
Images :
$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'),
]);

Streaming

stream() retourne la réponse en chunks.
Route::get('/coach', function () {
    return (new SalesCoach)->stream('Analyze this sales transcript...');
});
Callback de fin :
use Laravel\Ai\Responses\StreamedAgentResponse;

Route::get('/coach', function () {
    return (new SalesCoach)
        ->stream('Analyze this sales transcript...')
        ->then(function (StreamedAgentResponse $response) {
            // $response->text, $response->events, $response->usage...
        });
});
Itération manuelle :
$stream = (new SalesCoach)->stream('Analyze this sales transcript...');

foreach ($stream as $event) {
    // ...
}

Protocole Vercel AI SDK

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

Broadcast

use Illuminate\Broadcasting\Channel;

$stream = (new SalesCoach)->stream('Analyze this sales transcript...');

foreach ($stream as $event) {
    $event->broadcast(new Channel('channel-name'));
}
Version en queue :
(new SalesCoach)->broadcastOnQueue(
    'Analyze this sales transcript...',
    new Channel('channel-name'),
);

Ignorer les gros events

Certaines plateformes limitent les WebSocket à ~10 KB. Excluez les events volumineux avec WithoutBroadcasting.
<?php

namespace App\Ai\Agents;

use Laravel\Ai\Attributes\WithoutBroadcasting;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasTools;
use Laravel\Ai\Promptable;
use Laravel\Ai\Streaming\Events\ToolCall;
use Laravel\Ai\Streaming\Events\ToolResult;

#[WithoutBroadcasting(ToolCall::class, ToolResult::class)]
class SearchAgent implements Agent, HasTools
{
    use Promptable;

    // ...
}
Les events exclus ne sont pas diffusés mais restent enregistrés dans agent_conversation_messages — le frontend peut récupérer les infos après le stream.

Queue

use Laravel\Ai\Responses\AgentResponse;

Route::post('/coach', function (Request $request) {
    (new SalesCoach)
        ->queue($request->input('transcript'))
        ->then(function (AgentResponse $response) { /* ... */ })
        ->catch(function (Throwable $e) { /* ... */ });

    return back();
});

Tools

Fonctions callables par l’IA.
php artisan make:tool RandomNumberGenerator
<?php

namespace 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(),
        ];
    }
}
Enregistrez sur l’agent :
public function tools(): iterable
{
    return [new RandomNumberGenerator];
}
use App\Models\Document;
use Laravel\Ai\Tools\SimilaritySearch;

public function tools(): iterable
{
    return [
        SimilaritySearch::usingModel(Document::class, 'embedding'),
    ];
}
Options :
SimilaritySearch::usingModel(
    model: Document::class,
    column: 'embedding',
    minSimilarity: 0.7,
    limit: 10,
    query: fn ($query) => $query->where('published', true),
),
Closure personnalisée :
new SimilaritySearch(using: function (string $query) {
    return Document::query()
        ->where('user_id', $this->user->id)
        ->whereVectorSimilarTo('embedding', $query)
        ->limit(10)
        ->get();
}),
Personnaliser la description :
SimilaritySearch::usingModel(Document::class, 'embedding')
    ->withDescription('Search the knowledge base for relevant articles.'),

Outils FileStorage

Accès à un disque filesystem.
use Laravel\Ai\Tools\FileStorage;

public function tools(): iterable
{
    return FileStorage::all('local');
}
Lecture seule :
return FileStorage::readOnly('local');
Filtrez la collection :
use Laravel\Ai\Tools\Filesystem\DeleteFile;

return FileStorage::all('s3')
    ->reject(fn ($tool) => $tool instanceof DeleteFile);

Tools MCP

Si vous utilisez Laravel MCP, donnez à l’agent les tools exposés par vos serveurs MCP.
Nécessite le package Laravel MCP.
Spread des tools du client MCP :
use App\Ai\Tools\RandomNumberGenerator;
use Laravel\Mcp\Client;

/**
 * @return Tool[]
 */
public function tools(): iterable
{
    return [
        ...Client::web('https://mcp.example.com')
            ->withToken($token)
            ->tools(),

        new RandomNumberGenerator,
    ];
}
Client nommé :
use Laravel\Mcp\Facades\Mcp;

public function tools(): iterable
{
    return [
        ...Mcp::client('github')->tools(),
    ];
}
Ou serveur MCP local :
use Laravel\Mcp\Client;

public function tools(): iterable
{
    return [
        ...Client::local('php', ['artisan', 'mcp:start'])->tools(),
    ];
}

Tools de provider

Anthropic, OpenAI, Gemini, OpenRouter.
use Laravel\Ai\Providers\Tools\WebSearch;

public function tools(): iterable
{
    return [new WebSearch];
}
Options :
(new WebSearch)->max(5)->allow(['laravel.com', 'php.net']),
(new WebSearch)->location(city: 'New York', region: 'NY', country: 'US');

Web fetch

Anthropic, Gemini.
use Laravel\Ai\Providers\Tools\WebFetch;

public function tools(): iterable
{
    return [new WebFetch];
}

(new WebFetch)->max(3)->allow(['docs.laravel.com']),
OpenAI, Gemini.
use Laravel\Ai\Providers\Tools\FileSearch;

public function tools(): iterable
{
    return [new FileSearch(stores: ['store_id'])];
}

new FileSearch(stores: ['store_1', 'store_2']);

new FileSearch(stores: ['store_id'], where: ['author' => 'Taylor Otwell', 'year' => 2026]);
Requêtes complexes :
use Laravel\Ai\Providers\Tools\FileSearchQuery;

new FileSearch(stores: ['store_id'], where: fn (FileSearchQuery $query) =>
    $query->where('author', 'Taylor Otwell')
          ->whereNot('status', 'draft')
          ->whereIn('category', ['news', 'updates'])
);

Sous-agents

Un agent peut être exposé comme un tool d’un autre agent, pour déléguer.
<?php

namespace App\Ai\Agents;

use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasTools;
use Laravel\Ai\Promptable;

class CustomerSupportAgent implements Agent, HasTools
{
    use Promptable;

    public function instructions(): string
    {
        return 'You help customers with account, order, and billing questions. Delegate refund policy questions to the refunds specialist.';
    }

    public function tools(): iterable
    {
        return [
            new RefundsAgent,
        ];
    }
}
Personnalisez son exposition via CanActAsTool.
<?php

namespace App\Ai\Agents;

use App\Ai\Tools\LookupOrder;
use Laravel\Ai\Attributes\Provider;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\CanActAsTool;
use Laravel\Ai\Contracts\HasTools;
use Laravel\Ai\Enums\Lab;
use Laravel\Ai\Promptable;

#[Provider(Lab::Anthropic)]
class RefundsAgent implements Agent, CanActAsTool, HasTools
{
    use Promptable;

    public function instructions(): string
    {
        return 'You are a refunds specialist. Use order details and the refund policy to give concise eligibility guidance.';
    }

    public function name(): string
    {
        return 'refunds_specialist';
    }

    public function description(): string
    {
        return 'Determine whether an order is eligible for a refund and explain the next step.';
    }

    public function tools(): iterable
    {
        return [
            new LookupOrder,
        ];
    }
}
Sans CanActAsTool, Laravel utilise le nom de classe et une description générique. Chaque appel de sous-agent est indépendant — pas d’héritage d’historique.

Middleware

Interceptez les prompts / réponses.
php artisan make:agent-middleware LogPrompts
Implémentez HasMiddleware :
<?php

namespace App\Ai\Agents;

use App\Ai\Middleware\LogPrompts;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasMiddleware;
use Laravel\Ai\Promptable;

class SalesCoach implements Agent, HasMiddleware
{
    use Promptable;

    public function middleware(): array
    {
        return [new LogPrompts];
    }
}
Classe middleware :
<?php

namespace 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);
    }
}
Traitement post-réponse :
public function handle(AgentPrompt $prompt, Closure $next)
{
    return $next($prompt)->then(function (AgentResponse $response) {
        Log::info('Agent responded', ['text' => $response->text]);
    });
}

Agents anonymes

Sans définir de classe :
use function Laravel\Ai\{agent};

$response = agent(
    instructions: 'You are an expert at software development.',
    messages: [],
    tools: [],
)->prompt('Tell me about Laravel');
Sortie structurée :
use Illuminate\Contracts\JsonSchema\JsonSchema;

$response = agent(
    schema: fn (JsonSchema $schema) => ['number' => $schema->integer()->required()],
)->prompt('Generate a random number less than 100');

Configuration via attributs PHP

AttributDescription
#[Provider]Provider
#[Model]Modèle
#[MaxSteps]Nombre max d’appels de tools
#[MaxTokens]Max tokens
#[Temperature]Temperature (0.0-1.0)
#[TopP]Nucleus sampling (0.0-1.0)
#[Timeout]Timeout (s)
#[UseCheapestModel]Modèle le moins cher
#[UseSmartestModel]Modèle le plus performant
<?php

namespace App\Ai\Agents;

use Laravel\Ai\Attributes\MaxSteps;
use Laravel\Ai\Attributes\MaxTokens;
use Laravel\Ai\Attributes\Model;
use Laravel\Ai\Attributes\Provider;
use Laravel\Ai\Attributes\Temperature;
use Laravel\Ai\Attributes\Timeout;
use Laravel\Ai\Attributes\TopP;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Enums\Lab;
use Laravel\Ai\Promptable;

#[Provider(Lab::Anthropic)]
#[Model('claude-haiku-4-5-20251001')]
#[MaxSteps(10)]
#[MaxTokens(4096)]
#[Temperature(0.7)]
#[Timeout(120)]
#[TopP(0.9)]
class SalesCoach implements Agent
{
    use Promptable;
}
Raccourcis :
#[UseCheapestModel]
class SimpleSummarizer implements Agent
{
    use Promptable;
}

#[UseSmartestModel]
class ComplexReasoner implements Agent
{
    use Promptable;
}

Options provider

Interface HasProviderOptions pour des options spécifiques.
<?php

namespace App\Ai\Agents;

use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasProviderOptions;
use Laravel\Ai\Enums\Lab;
use Laravel\Ai\Promptable;

class SalesCoach implements Agent, HasProviderOptions
{
    use Promptable;

    public function providerOptions(Lab|string $provider): array
    {
        return match ($provider) {
            Lab::OpenAI => [
                'reasoning' => ['effort' => 'low'],
                'frequency_penalty' => 0.5,
                'presence_penalty' => 0.3,
            ],
            Lab::Anthropic => [
                'thinking' => ['budget_tokens' => 1024],
            ],
            default => [],
        };
    }
}

Génération d’images

Classe Image. Providers : OpenAI, Gemini, xAI.
use Laravel\Ai\Image;

$image = Image::of('A donut sitting on the kitchen counter')->generate();
$rawContent = (string) $image;
Qualité, ratio, timeout :
$image = Image::of('A donut sitting on the kitchen counter')
    ->quality('high')
    ->landscape()
    ->timeout(120)
    ->generate();
Avec pièces jointes de référence :
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();

Sauvegarde

$path = $image->store();
$path = $image->storeAs('image.jpg');
$path = $image->storePublicly();
$path = $image->storePubliclyAs('image.jpg');

En queue

use Laravel\Ai\Responses\ImageResponse;

Image::of('A donut sitting on the kitchen counter')
    ->portrait()
    ->queue()
    ->then(function (ImageResponse $image) {
        $path = $image->store();
    });

Synthèse vocale (TTS)

Classe Audio. Providers : OpenAI, ElevenLabs.
use Laravel\Ai\Audio;

$audio = Audio::of('I love coding with Laravel.')->generate();
$rawContent = (string) $audio;
Voix, instructions :
$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();

Sauvegarde

$path = $audio->store();
$path = $audio->storeAs('audio.mp3');
$path = $audio->storePublicly();
$path = $audio->storePubliclyAs('audio.mp3');

En queue

use Laravel\Ai\Responses\AudioResponse;

Audio::of('I love coding with Laravel.')
    ->queue()
    ->then(function (AudioResponse $audio) {
        $path = $audio->store();
    });

Transcription (STT)

Classe Transcription. Providers : OpenAI, ElevenLabs, Mistral, Gemini.
use Laravel\Ai\Transcription;
use Laravel\Ai\Files;

$text = Transcription::of(Files\Audio::fromStorage('recording.mp3'))->transcribe();

$text = Transcription::of($request->file('audio'))->transcribe();

Options

$text = Transcription::of($file)
    ->language('en')
    ->prompt('Meeting about Laravel')
    ->transcribe();

En queue

use Laravel\Ai\Responses\TranscriptionResponse;

Transcription::of($file)
    ->queue()
    ->then(function (TranscriptionResponse $response) {
        // $response->text
    });

Embeddings

Vecteurs pour la recherche sémantique.
use Laravel\Ai\Embeddings;

$response = Embeddings::for([
    'Laravel is awesome.',
    'PHP is great.',
])->generate();

$response->embeddings; // [[0.1, 0.2, ...], [...]]
Via Stringable :
use Illuminate\Support\Str;

$embedding = Str::of('Laravel is awesome.')->toEmbeddings();

Options

$response = Embeddings::for([...])
    ->provider('openai')
    ->model('text-embedding-3-small')
    ->dimensions(1536)
    ->generate();
Voir aussi Recherche vectorielle.

Reranking

Réordonner un ensemble de résultats. 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;
Macro rerank sur Collection :
$articles = Article::all()
    ->rerank('body', 'Laravel tutorials');
Voir Recherche.

Fichiers

Upload / gestion de fichiers vers les providers. OpenAI, Anthropic, Gemini, Azure.
use Laravel\Ai\Files;

// Depuis un chemin
$file = Files\Document::fromPath('/home/laravel/document.pdf');

// Depuis storage
$file = Files\Document::fromStorage('document.pdf');

// Depuis un upload
$file = Files\Document::fromUpload($request->file('document'));
Types : Document, Image, Audio, Video.

Tests

Fake response

use Laravel\Ai\Facades\Ai;

Ai::fake([
    'This is a fake response.',
]);

$response = agent()->prompt('Hello');

expect((string) $response)->toBe('This is a fake response.');

Séquence

Ai::fake([
    'First response',
    'Second response',
]);

Assertions

Ai::assertPrompted();
Ai::assertPromptedTimes(3);
Ai::assertPrompted(function ($prompt) {
    return str_contains($prompt->prompt, 'Laravel');
});
Ai::assertNothingPrompted();

Fake tool

use Laravel\Ai\Tools\Fake;

$agent->prompt('Test', tools: [
    Fake::tool('random_number')->returns('42'),
]);

Fake JSON

Sortie structurée :
Ai::fake([
    ['score' => 8, 'feedback' => 'Great job!'],
]);

$response = (new SalesCoach)->prompt('Analyze this');

expect($response['score'])->toBe(8);

Récapitulatif

ComposantRôle
AgentInterface principale (prompts, tools, sortie structurée)
ToolFonction appelable par l’IA
Image / Audio / TranscriptionGénération et transcription média
EmbeddingsGénération de vecteurs
RerankingRéordonnancement de résultats
  • Provider unifié (OpenAI, Anthropic, Gemini…)
  • Persistance conversationnelle (RemembersConversations)
  • Sortie structurée (JSON Schema)
  • Streaming avec broadcast
  • Middleware sur les agents
  • Sous-agents (délégation)
  • Attributs PHP pour la config
  • Compatible OpenAI-compatible (LM Studio, etc.)
  • Tools MCP intégrés
  • Utilisez des attributs pour fixer provider/model/temperature
  • Séparez logique métier via des tools
  • Loggez via un middleware
  • Testez avec Ai::fake() — ne jamais toucher aux vraies API en test
  • Utilisez queue() pour les traitements longs
  • Streamez pour l’UX temps réel
Dernière modification le 13 juillet 2026