Skip to main content

Introduzione

Laravel AI SDK fornisce un’API unificata ed espressiva per dialogare con provider AI come OpenAI, Anthropic, Gemini. Con l’AI SDK puoi realizzare, tramite un’interfaccia coerente e nello stile di Laravel, tante funzionalità AI: costruire agenti intelligenti dotati di tool e output strutturato, generare immagini, sintetizzare/trascrivere audio, creare embedding vettoriali e molto altro.
Laravel AI SDK è il pacchetto ufficiale aggiunto in Laravel 13. È distribuito come laravel/ai e permette di usare più provider AI attraverso la stessa API.

Provider supportati

Installazione

1

Installa il pacchetto

Installa Laravel AI SDK tramite Composer.
2

Pubblica file di configurazione e migrazioni

Pubblica i file di configurazione e le migrazioni con il comando Artisan vendor:publish.
3

Esegui le migrazioni

Esegui le migrazioni del database. Vengono create le tabelle agent_conversations e agent_conversation_messages, usate per salvare lo storico delle conversazioni.

Configurazione

Variabili d’ambiente

Imposta nel file .env le API key dei provider AI che utilizzi.
I modelli predefiniti per testo, immagini, audio, trascrizioni ed embedding possono essere configurati in config/ai.php.

Base URL personalizzate

Se vuoi passare per un servizio proxy, puoi impostare una URL personalizzata per ciascun provider.
La base URL personalizzata è supportata per OpenAI, Anthropic, Gemini, Groq, Cohere, DeepSeek, xAI e OpenRouter.

Provider OpenAI-Compatible

Se usi API compatibili con OpenAI (LM Studio, vLLM, Together, Fireworks, gateway locali ecc.), puoi configurare il provider con il driver openai-compatible. url è obbligatoria e, se specifichi key, viene inviata come Bearer token.
Dopo la configurazione, puoi indicarlo per nome come qualsiasi altro provider.
Impostando un modello di testo predefinito, puoi usarlo senza specificare il modello a ogni chiamata.
Il provider OpenAI-Compatible supporta generazione di testo, streaming, tool, output strutturato e allegati immagine. Se l’endpoint richiede campi aggiuntivi nel body della richiesta, usa le opzioni del provider.

Enum Lab

Per riferirti ai provider dal codice usa l’enum Lab.

Agenti

Gli agenti sono il mattone fondamentale di Laravel AI SDK. Puoi generare una classe agente con il comando make:agent.
L’agente generato viene collocato nella directory app/Ai/Agents/. Ecco un esempio di agente che implementa tutte le principali interfacce.

Prompt

Invia un messaggio all’agente con il metodo prompt().
Con il metodo statico make() puoi creare un’istanza risolvendo le dipendenze dal container.
Provider, modello e timeout possono essere sovrascritti dagli argomenti di prompt().

Contesto conversazionale

Implementando l’interfaccia Conversational e definendo il metodo messages(), puoi passare all’AI lo storico delle conversazioni precedenti. Usando il trait RemembersConversations puoi salvare e recuperare automaticamente lo storico delle conversazioni nel database.
Con forUser() inizi una conversazione; usando il conversationId restituito puoi continuare la conversazione con continue().

Output strutturato

Implementando l’interfaccia HasStructuredOutput e definendo lo schema JSON nel metodo schema(), puoi ricevere la risposta dell’AI come dato strutturato.

Oggetti annidati

Array di oggetti

anyOf (scelta tra più schemi)

Quando un valore deve corrispondere a uno tra diversi schemi, usa il metodo anyOf.

Allegati

Puoi passare documenti o immagini all’agente tramite l’argomento attachments.
Le immagini si allegano allo stesso modo.

Streaming

Con il metodo stream() puoi restituire la risposta in chunk. Utile per inviare in tempo reale al frontend risposte molto lunghe.
Con la callback then() puoi definire il post-processing dopo il completamento dello streaming.
Puoi anche iterare manualmente sullo stream.

Protocollo Vercel AI SDK

Se usi Vercel AI SDK sul frontend, chiama usingVercelDataProtocol().

Broadcasting

Puoi inviare gli eventi dello stream ai canali di broadcasting, ad esempio Laravel Echo.
Con broadcastOnQueue() puoi trasmettere passando per una coda.

Saltare eventi troppo grandi

Alcune piattaforme di broadcasting limitano il messaggio WebSocket a circa 10 KB. Alcuni eventi dello stream con molti dati (ad esempio grandi risultati di tool) possono superare questo limite e fallire la trasmissione. Usa l’attributo WithoutBroadcasting per escludere dal broadcasting specifici tipi di evento.
Gli eventi esclusi non vengono trasmessi, ma vengono comunque salvati nella tabella agent_conversation_messages. Il frontend può quindi recuperare tutti i dati del tool a fine stream. Funziona sia in modalità coda (broadcastOnQueue) sia sincrona (broadcast / broadcastNow).

Code

Con il metodo queue() puoi accodare il prompt per l’elaborazione asincrona.

Tool

I tool permettono all’AI di chiamare funzioni del tuo codice. Puoi generare una classe tool con il comando make:tool.
Registra i tool dal metodo tools() dell’agente.

Tool di ricerca per similarità

Puoi aggiungere facilmente un tool di ricerca per similarità basato su embedding vettoriali.
Puoi passare anche opzioni.
Puoi anche definire una logica di ricerca personalizzata con una closure.
Con withDescription() puoi personalizzare la descrizione del tool.

Tool di storage file

Con la factory di tool FileStorage puoi dare all’agente l’accesso a un disco filesystem di Laravel. Il metodo all restituisce l’intero set di tool per elencare, leggere, generare URL, scrivere, cancellare e copiare file sul disco indicato.
Per concedere solo l’accesso in sola lettura usa il metodo readOnly.
Questi metodi restituiscono una Illuminate\Support\Collection, quindi puoi restringere ulteriormente i tool forniti.

Tool MCP

Se nella tua applicazione usi Laravel MCP, puoi mettere a disposizione dell’agente i tool esposti da un server Model Context Protocol. Usando il client MCP di Laravel puoi connetterti a un server MCP remoto o locale e passarne i tool direttamente all’agente.
Per usare i tool MCP nella tua applicazione deve essere installato il pacchetto Laravel MCP.
Il metodo tools del client MCP restituisce una collection, quindi usa l’operatore di spread ... per espanderla nell’array tools dell’agente.
L’AI SDK avvolge automaticamente ogni tool MCP in modo che l’agente possa richiamarlo come qualsiasi altro tool. Puoi anche usare client MCP con nome.
Oppure connetterti a un server MCP locale.
Per la creazione del client MCP e l’autenticazione (Bearer token, OAuth ecc.) consulta la documentazione del client MCP.

Tool del provider

Tool speciali implementati nativamente dai provider AI.

Ricerca web

Aggiunge una ricerca web all’agente. Supportata da Anthropic, OpenAI, Gemini e OpenRouter.
Puoi specificare opzionalmente il numero di risultati, la restrizione di dominio e le informazioni di località.

Recupero web

Un tool per recuperare il contenuto di un URL indicato. Supportato da Anthropic e Gemini.

Ricerca file

Un tool per cercare documenti in un vector store. Supportato da OpenAI e Gemini.
Puoi anche specificare filtri complessi con FileSearchQuery.

Sub-agenti

Un agente può essere restituito anche dal metodo tools() di un altro agente. Registrando un agente come tool, un agente principale può delegare a un sub-agente compiti specifici e integrarne il risultato nella risposta originale. È utile quando un agente generico deve accedere a un agente specializzato con istruzioni, tool, configurazioni di modello e provider dedicati. Ad esempio, un agente di customer support delega le domande sulla politica di rimborso a un agente specializzato in rimborsi.
Per personalizzare come il sub-agente viene presentato all’agente principale, implementa nel sub-agente l’interfaccia CanActAsTool e definisci nome e descrizione da usare come tool.
Per i sub-agenti che non implementano CanActAsTool, Laravel usa il nome della classe come nome del tool e genera automaticamente una descrizione generica. Ogni chiamata di sub-agente avviene in modo indipendente e non eredita lo storico della conversazione dell’agente principale.

Middleware

Puoi aggiungere middleware all’agente per intercettare prompt e risposte.
Implementa nell’agente l’interfaccia HasMiddleware e registra i middleware nel metodo middleware().
Esempio di implementazione di un middleware.
Con then() puoi aggiungere anche logica successiva alla risposta.

Agenti anonimi

Con l’helper agent() puoi usare un agente anonimo senza definire una classe.
Puoi anche creare agenti anonimi con output strutturato.

Configurazione dell’agente (attributi PHP)

Con gli attributi PHP puoi descrivere in modo dichiarativo le impostazioni predefinite dell’agente.
Sono disponibili anche attributi scorciatoia per la scelta del modello.

Opzioni del provider

Implementando l’interfaccia HasProviderOptions puoi passare opzioni specifiche del provider.

Approvazione umana (Human Tool Approval)

Per usare l’approvazione dei tool è necessario un agente Conversational con storico della conversazione persistente. Per riprendere una chiamata sospesa, il trait RemembersConversations fornisce la persistenza necessaria.
Per i tool che eseguono operazioni sensibili o irreversibili — come cancellare file o effettuare bonifici — puoi richiedere l’approvazione umana prima dell’esecuzione. Per rendere un tool soggetto ad approvazione, implementa il contract Approvable e usa il trait InteractsWithApprovals. Per default, i tool soggetti ad approvazione la richiedono sempre.
Se vuoi decidere se richiedere o meno l’approvazione in base agli argomenti della chiamata del tool, definisci il metodo needsApproval sul tool. Questo metodo può restituire un booleano oppure un’istanza Approval che include il motivo dell’approvazione.
Puoi anche sovrascrivere il requisito di approvazione quando restituisci il tool dal metodo tools dell’agente.
Quando viene invocato un tool soggetto ad approvazione, l’agente si mette in pausa prima dell’esecuzione. Ispezionando pendingApprovals nella risposta puoi controllare ID, nome del tool, argomenti e motivo dell’approvazione per ciascuna chiamata.
Per riprendere l’agente, continua la conversazione passando un’istanza Decisions che contiene la decisione per ogni chiamata di tool in sospeso. Ogni decisione può approvare, rifiutare o modificare gli argomenti prima dell’esecuzione.
I booleani true e false sono scorciatoie per rispettivamente approvare e rifiutare. Per tutte le chiamate di tool in sospeso è necessaria una decisione. Passare ID di chiamate di tool sconosciuti, mancanti o già risolti solleva una ApprovalMismatchException. Per le chiamate senza una decisione esplicita puoi indicare una decisione di default con i metodi approveRemaining o rejectRemaining.
Rifiutando con un risultato come Decision::reject('Non approvata.'), il risultato viene restituito al modello e la risposta continua. Rifiutando senza risultato, il ciclo di generazione si arresta al momento in cui il rifiuto viene registrato. L’approvazione dei tool è supportata dai metodi prompt, stream, queue, broadcast, broadcastNow e broadcastOnQueue. Durante streaming e broadcasting, la sospensione è rappresentata come evento tool_approval_request. Se stai usando il protocollo stream di Vercel AI SDK, le richieste e i risultati di approvazione vengono emessi come part nativa di approvazione dei tool del protocollo. Per gli agenti in coda, la risposta risultante viene passata alla callback then e Laravel dispatcha anche l’evento ToolApprovalRequested. Laravel salva il risultato dell’esecuzione dei tool approvati prima di chiedere al modello di proseguire. Se la generazione successiva fallisce, le approvazioni sono già risolte. Non rinviare le stesse decisioni di approvazione: continua invece la conversazione con un normale prompt testuale.

Flusso completo di approvazione

Le route seguenti mostrano il flusso di approvazione completo. La route GET restituisce la schermata di chat, mentre la route POST riceve dal frontend un nuovo prompt testuale oppure una decisione di approvazione. Questo esempio presuppone che il modello User dell’applicazione usi il trait HasConversations.
Se lo status della risposta è awaiting_approval, la schermata di chat deve mostrare le approvazioni in sospeso e inviare allo stesso endpoint la scelta dell’utente, usando come chiave l’ID della chiamata di tool.
Per un normale messaggio di chat, invia invece il valore di message.
Il flusso di approvazione è un meccanismo che dà agli agenti AI poteri operativi molto forti, ma consente di inserire una verifica umana prima dell’esecuzione. Sfruttalo per i tool che comportano operazioni irreversibili come cancellazione di file, elaborazione di pagamenti o scritture verso API esterne.

Generazione di immagini

Puoi generare immagini con la classe Image. Supportata da OpenAI, Gemini e xAI.
Puoi specificare qualità, aspect ratio e timeout.
Puoi anche allegare un’immagine di riferimento da elaborare.

Salvataggio dell’immagine

Generazione di immagini in coda


Sintesi vocale (TTS)

Puoi convertire testo in audio con la classe Audio. Supportata da OpenAI ed ElevenLabs.
Puoi specificare il genere della voce, un voice ID specifico e istruzioni di stile.

Salvataggio dell’audio

Generazione dell’audio in coda


Trascrizione (STT)

Puoi convertire file audio in testo con la classe Transcription. Supportata da OpenAI, ElevenLabs e Mistral.

Diarizzazione (separazione degli speaker)

Con diarize() ottieni una trascrizione separata per parlante.

Trascrizione in coda


Riassunto di testi (Text Summarization)

Con il metodo summarize fornito dalla classe Stringable di Laravel puoi riassumere un testo. Per default il riassunto è entro tre frasi e viene usato il modello di testo più economico del provider configurato.
Puoi specificare anche il numero massimo di frasi, il provider, il modello e il timeout. La classe Str fornisce anche una versione statica del metodo.

Embedding

Puoi trasformare il testo in rappresentazioni vettoriali per la ricerca per similarità e altri scenari.
Puoi specificare provider, modello e numero di dimensioni.

Embedding multimodali

Il metodo Embeddings::for non accetta solo stringhe: accetta anche input di immagini, audio, documenti e video, così puoi generare embedding anche per contenuti non testuali. Gemini supporta embedding di immagini, audio, documenti e video, mentre VoyageAI supporta embedding di immagini e video.
Per gli input multimodali si usano le stesse classi di file degli allegati. Queste possono essere create da path locali, dischi filesystem, URL remote o contenuti Base64. Immagini, documenti e video possono essere creati anche da file caricati, e i documenti anche da contenuti stringa raw.
VoyageAI non consente di mescolare in una stessa richiesta media da URL remoto e media Base64. File locali, dallo storage e caricati vengono inviati come contenuto Base64; l’input testuale può essere combinato con entrambe le sorgenti media. Consulta la documentazione dei singoli provider per i modelli multimodali disponibili e i tipi di input supportati.

Ricerca vettoriale (pgvector)

Esempio di configurazione per la ricerca vettoriale con PostgreSQL e l’estensione pgvector.
1

Creazione della migrazione

2

Configurazione del modello

3

Query per similarità

Sono disponibili anche metodi di più basso livello.

Cache degli embedding

Puoi mettere in cache gli embedding per evitare di rigenerare quello dello stesso testo. Imposta la cache di default in config/ai.php.
Puoi anche controllare la cache per singola richiesta.

Reranking

Puoi ri-ordinare (rerank) i risultati di una ricerca in base alla rilevanza rispetto alla query. Supportato da Cohere e Jina.
Con limit() puoi restringere il numero di risultati.

Reranking di collection

Puoi rerankare direttamente collection Eloquent.

Gestione dei file

Puoi caricare file sul provider AI e riferirti a essi in seguito.
Puoi gestire anche stringhe e upload da form.

Riferimento a file salvati

Puoi allegare all’agente file già caricati usando il loro ID.

Recupero e cancellazione file

Specificare il provider

Specificare opzioni proprie del provider

Con il metodo withProviderOptions puoi passare opzioni di upload specifiche del provider. Ad esempio puoi impostare il purpose del file di OpenAI.
Per differenziare le opzioni per provider, passa una closure.

Vector store

I vector store ti permettono di far gestire i documenti dal provider.

Aggiungere file allo store

Puoi anche allegare metadata.

Rimuovere file dallo store


Failover

Specificando un array di provider, se il primo fallisce si passa automaticamente al successivo.

Test

Laravel AI SDK offre funzionalità di fake per i test, permettendoti di testare senza chiamare realmente le API.

Test degli agenti

Sono disponibili anche asserzioni per l’accodamento.
Con preventStrayPrompts() viene lanciata un’eccezione se viene chiamato un prompt non definito nella fake.
Per fingere agenti con output strutturato puoi specificare la risposta come array. L’agente restituirà una risposta strutturata contenente i dati indicati.
Se fake() viene chiamato su un agente con output strutturato senza passare esplicitamente i dati fake, Laravel genera automaticamente dati fake conformi allo schema definito dall’agente.
Per testare gli agenti anonimi usa AnonymousAgent::fake().

Test della generazione di immagini

Test della sintesi vocale

Test delle trascrizioni

Test degli embedding

Test del reranking

Test dei file

Test dei vector store

Puoi anche fare asserzioni sulle operazioni file su uno store.

Eventi

Laravel AI SDK dispatcha i seguenti eventi. Ascoltandoli puoi implementare log, monitoring e altro.
  • PromptingAgent — prima dell’invio del prompt
  • AgentPrompted — dopo l’invio del prompt
  • StreamingAgent — all’inizio dello streaming
  • AgentStreamed — al termine dello streaming
  • InvokingTool — prima della chiamata di un tool
  • ToolInvoked — dopo la chiamata di un tool
  • ToolApprovalRequested — quando è richiesta l’approvazione di un tool
  • ToolApprovalResolved — dopo la risoluzione dell’approvazione del tool
  • GeneratingImage — prima della generazione dell’immagine
  • ImageGenerated — dopo la generazione dell’immagine
  • GeneratingAudio — prima della generazione dell’audio
  • AudioGenerated — dopo la generazione dell’audio
  • GeneratingTranscription — prima della trascrizione
  • TranscriptionGenerated — dopo la trascrizione
  • GeneratingEmbeddings — prima della generazione degli embedding
  • EmbeddingsGenerated — dopo la generazione degli embedding
  • Reranking — prima del reranking
  • Reranked — dopo il reranking
  • StoringFile — prima del salvataggio del file
  • FileStored — dopo il salvataggio del file
  • FileDeleted — dopo la cancellazione del file
  • CreatingStore — prima della creazione dello store
  • StoreCreated — dopo la creazione dello store
  • AddingFileToStore — prima dell’aggiunta di un file allo store
  • FileAddedToStore — dopo l’aggiunta di un file allo store
  • RemovingFileFromStore — prima della rimozione di un file dallo store
  • FileRemovedFromStore — dopo la rimozione di un file dallo store
Ultima modifica il 2 agosto 2026