> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Laravel AI SDK

> Guide complet du Laravel AI SDK : interface unifiée pour OpenAI, Anthropic, Gemini et plus. Agents, génération d'images, audio, embeddings et tests.

## Introduction

Le [Laravel AI SDK](https://github.com/laravel/ai) 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.

<Info>
  Laravel AI SDK est un package officiel ajouté avec Laravel 13 (`laravel/ai`).
</Info>

## Providers supportés

| Fonctionnalité              | Providers                                                                                                      |
| --------------------------- | -------------------------------------------------------------------------------------------------------------- |
| Génération de texte         | OpenAI, OpenAI Compatible, Anthropic, Gemini, Azure, Bedrock, Groq, xAI, DeepSeek, Mistral, Ollama, OpenRouter |
| Génération d'images         | OpenAI, Gemini, xAI, Azure, Bedrock, OpenRouter                                                                |
| Synthèse vocale (TTS)       | OpenAI, ElevenLabs, Gemini                                                                                     |
| Reconnaissance vocale (STT) | OpenAI, ElevenLabs, Mistral, Gemini                                                                            |
| Embeddings                  | OpenAI, Gemini, Azure, Bedrock, Cohere, Mistral, Jina, VoyageAI, Ollama, OpenRouter                            |
| Reranking                   | Cohere, Jina, VoyageAI                                                                                         |
| Fichiers                    | OpenAI, Anthropic, Gemini, Azure                                                                               |

## Installation

<Steps>
  <Step title="Installer le package">
    ```shell theme={null}
    composer require laravel/ai
    ```
  </Step>

  <Step title="Publier config et migrations">
    ```shell theme={null}
    php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"
    ```
  </Step>

  <Step title="Migrer">
    Crée `agent_conversations` et `agent_conversation_messages` pour l'historique.

    ```shell theme={null}
    php artisan migrate
    ```
  </Step>
</Steps>

## Configuration

### Variables d'environnement

```ini theme={null}
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.

```php theme={null}
'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.

```php theme={null}
'providers' => [
    'local' => [
        'driver' => 'openai-compatible',
        'url' => env('LOCAL_AI_URL'),
        'key' => env('LOCAL_AI_API_KEY'),
    ],
],
```

Utilisation :

```php theme={null}
agent()->prompt('What is Laravel?', provider: 'local', model: 'local-model');
```

Modèle par défaut :

```php theme={null}
'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.

```php theme={null}
use Laravel\Ai\Enums\Lab;

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

***

## Agents

Composant de base. Générez une classe agent :

```shell theme={null}
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 theme={null}
<?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(),
        ];
    }
}
```

```mermaid theme={null}
flowchart TD
    A["Prompt utilisateur"] --> B["Agent::prompt()"]
    B --> C["Application des options"]
    C -->|"Conversational"| D["Ajout de l'historique"]
    C -->|"HasTools"| E["Ajout des tools"]
    C -->|"HasStructuredOutput"| F["Ajout du schéma JSON"]
    D --> G["Envoi au provider IA"]
    E --> G
    F --> G
    B --> G
    G --> H["Réponse"]
    H -->|"Appel de tool"| I["Exécution du tool"]
    I --> G
    H -->|"Fin"| J["AgentResponse"]
```

### Prompt

```php theme={null}
$response = (new SalesCoach)->prompt('Analyze this sales transcript...');
return (string) $response;
```

`make()` résout les dépendances via le conteneur.

```php theme={null}
$agent = SalesCoach::make(user: $user);
```

Override par appel :

```php theme={null}
$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.

```php theme={null}
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 :

```php theme={null}
$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()`.

```php theme={null}
public function schema(JsonSchema $schema): array
{
    return ['score' => $schema->integer()->required()];
}

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

#### Objets imbriqués

```php theme={null}
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

```php theme={null}
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

```php theme={null}
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

```php theme={null}
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 :

```php theme={null}
$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.

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

Callback de fin :

```php theme={null}
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 :

```php theme={null}
$stream = (new SalesCoach)->stream('Analyze this sales transcript...');

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

#### Protocole Vercel AI SDK

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

### Broadcast

```php theme={null}
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 :

```php theme={null}
(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 theme={null}
<?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

```php theme={null}
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.

```shell theme={null}
php artisan make:tool RandomNumberGenerator
```

```php theme={null}
<?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 :

```php theme={null}
public function tools(): iterable
{
    return [new RandomNumberGenerator];
}
```

#### Similarity search

```php theme={null}
use App\Models\Document;
use Laravel\Ai\Tools\SimilaritySearch;

public function tools(): iterable
{
    return [
        SimilaritySearch::usingModel(Document::class, 'embedding'),
    ];
}
```

Options :

```php theme={null}
SimilaritySearch::usingModel(
    model: Document::class,
    column: 'embedding',
    minSimilarity: 0.7,
    limit: 10,
    query: fn ($query) => $query->where('published', true),
),
```

Closure personnalisée :

```php theme={null}
new SimilaritySearch(using: function (string $query) {
    return Document::query()
        ->where('user_id', $this->user->id)
        ->whereVectorSimilarTo('embedding', $query)
        ->limit(10)
        ->get();
}),
```

Personnaliser la description :

```php theme={null}
SimilaritySearch::usingModel(Document::class, 'embedding')
    ->withDescription('Search the knowledge base for relevant articles.'),
```

### Outils FileStorage

Accès à un [disque filesystem](/fr/filesystem).

```php theme={null}
use Laravel\Ai\Tools\FileStorage;

public function tools(): iterable
{
    return FileStorage::all('local');
}
```

Lecture seule :

```php theme={null}
return FileStorage::readOnly('local');
```

Filtrez la collection :

```php theme={null}
use Laravel\Ai\Tools\Filesystem\DeleteFile;

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

### Tools MCP

Si vous utilisez [Laravel MCP](/fr/mcp), donnez à l'agent les tools exposés par vos serveurs MCP.

<Info>
  Nécessite le package [Laravel MCP](/fr/mcp).
</Info>

Spread des tools du client MCP :

```php theme={null}
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é :

```php theme={null}
use Laravel\Mcp\Facades\Mcp;

public function tools(): iterable
{
    return [
        ...Mcp::client('github')->tools(),
    ];
}
```

Ou serveur MCP local :

```php theme={null}
use Laravel\Mcp\Client;

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

### Tools de provider

#### Web search

Anthropic, OpenAI, Gemini, OpenRouter.

```php theme={null}
use Laravel\Ai\Providers\Tools\WebSearch;

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

Options :

```php theme={null}
(new WebSearch)->max(5)->allow(['laravel.com', 'php.net']),
(new WebSearch)->location(city: 'New York', region: 'NY', country: 'US');
```

#### Web fetch

Anthropic, Gemini.

```php theme={null}
use Laravel\Ai\Providers\Tools\WebFetch;

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

(new WebFetch)->max(3)->allow(['docs.laravel.com']),
```

#### File search

OpenAI, Gemini.

```php theme={null}
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 :

```php theme={null}
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 theme={null}
<?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 theme={null}
<?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.

```shell theme={null}
php artisan make:agent-middleware LogPrompts
```

Implémentez `HasMiddleware` :

```php theme={null}
<?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 theme={null}
<?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 :

```php theme={null}
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 :

```php theme={null}
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 :

```php theme={null}
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

| Attribut              | Description                  |
| --------------------- | ---------------------------- |
| `#[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 theme={null}
<?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 :

```php theme={null}
#[UseCheapestModel]
class SimpleSummarizer implements Agent
{
    use Promptable;
}

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

### Options provider

Interface `HasProviderOptions` pour des options spécifiques.

```php theme={null}
<?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.

```php theme={null}
use Laravel\Ai\Image;

$image = Image::of('A donut sitting on the kitchen counter')->generate();
$rawContent = (string) $image;
```

Qualité, ratio, timeout :

```php theme={null}
$image = Image::of('A donut sitting on the kitchen counter')
    ->quality('high')
    ->landscape()
    ->timeout(120)
    ->generate();
```

Avec pièces jointes de référence :

```php theme={null}
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

```php theme={null}
$path = $image->store();
$path = $image->storeAs('image.jpg');
$path = $image->storePublicly();
$path = $image->storePubliclyAs('image.jpg');
```

### En queue

```php theme={null}
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.

```php theme={null}
use Laravel\Ai\Audio;

$audio = Audio::of('I love coding with Laravel.')->generate();
$rawContent = (string) $audio;
```

Voix, instructions :

```php theme={null}
$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

```php theme={null}
$path = $audio->store();
$path = $audio->storeAs('audio.mp3');
$path = $audio->storePublicly();
$path = $audio->storePubliclyAs('audio.mp3');
```

### En queue

```php theme={null}
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.

```php theme={null}
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

```php theme={null}
$text = Transcription::of($file)
    ->language('en')
    ->prompt('Meeting about Laravel')
    ->transcribe();
```

### En queue

```php theme={null}
use Laravel\Ai\Responses\TranscriptionResponse;

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

***

## Embeddings

Vecteurs pour la recherche sémantique.

```php theme={null}
use Laravel\Ai\Embeddings;

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

$response->embeddings; // [[0.1, 0.2, ...], [...]]
```

Via `Stringable` :

```php theme={null}
use Illuminate\Support\Str;

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

### Options

```php theme={null}
$response = Embeddings::for([...])
    ->provider('openai')
    ->model('text-embedding-3-small')
    ->dimensions(1536)
    ->generate();
```

Voir aussi [Recherche vectorielle](/fr/search#recherche-semantique-vectorielle).

***

## Reranking

Réordonner un ensemble de résultats. Providers : Cohere, Jina, VoyageAI.

```php theme={null}
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 :

```php theme={null}
$articles = Article::all()
    ->rerank('body', 'Laravel tutorials');
```

Voir [Recherche](/fr/search#reranking).

***

## Fichiers

Upload / gestion de fichiers vers les providers. OpenAI, Anthropic, Gemini, Azure.

```php theme={null}
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

```php theme={null}
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

```php theme={null}
Ai::fake([
    'First response',
    'Second response',
]);
```

### Assertions

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

### Fake tool

```php theme={null}
use Laravel\Ai\Tools\Fake;

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

### Fake JSON

Sortie structurée :

```php theme={null}
Ai::fake([
    ['score' => 8, 'feedback' => 'Great job!'],
]);

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

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

## Récapitulatif

<AccordionGroup>
  <Accordion title="Composants principaux">
    | Composant                     | Rôle                                                     |
    | ----------------------------- | -------------------------------------------------------- |
    | Agent                         | Interface principale (prompts, tools, sortie structurée) |
    | Tool                          | Fonction appelable par l'IA                              |
    | Image / Audio / Transcription | Génération et transcription média                        |
    | Embeddings                    | Génération de vecteurs                                   |
    | Reranking                     | Réordonnancement de résultats                            |
  </Accordion>

  <Accordion title="Fonctionnalités clés">
    * 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
  </Accordion>

  <Accordion title="Bonnes pratiques">
    * 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
  </Accordion>
</AccordionGroup>


## Related topics

- [Les nouveautés de Laravel 13](/fr/blog/laravel-13-new-features.md)
- [Mises à jour Laravel — mars 2026](/fr/blog/changelog/202603.md)
- [Intégration Laravel AI SDK](/fr/packages/laravel-copilot-sdk/ai-sdk.md)
- [Intégration Laravel AI SDK - VOICEVOX for Laravel](/fr/packages/laravel-voicevox/ai-sdk.md)
- [Pilote Amazon Bedrock pour Laravel AI SDK](/fr/packages/laravel-amazon-bedrock.md)
