Laravel AI SDK: feature AI provider-agnostic, e perché ora è risk-mitigation non comodità
Il 5 febbraio 2026 Taylor Otwell ha rilasciato il Laravel AI SDK, un pacchetto first-party per costruire funzionalità AI dentro un'applicazione Laravel, diventato poi production-stable con Laravel 13 a marzo 2026. Quando è uscito, l'ho integrato e l'ho raccontato a chi me lo chiedeva come una comodità: un'unica interfaccia per parlare con OpenAI, Anthropic o Gemini, lo switch del provider gestito da un file di configurazione, niente più codice cablato sull'SDK specifico di un fornitore. Era un buon argomento di produttività, e si fermava lì. Poi è arrivato il 12 giugno 2026: un modello di frontiera è stato sospeso per tutti i clienti del mondo per una direttiva governativa, come documentato nello statement ufficiale di Anthropic. E quella stessa funzionalità che vendevo come comodità ha cambiato natura davanti ai miei occhi.
Lo switch di provider via config non è più una comodità da developer pigro. È il meccanismo di fallback che, il giorno in cui un modello viene spento dall'alto, separa chi cambia una riga e prosegue da chi è cablato sul fornitore e si ferma a tempo indeterminato.
Questo articolo è un how-to concreto, ma con una tesi: il Laravel AI SDK, dopo l'affaire Fable, va adottato e ragionato come risk-mitigation, non come scorciatoia. Mostro cos'è davvero, come funziona lo switch, e soprattutto cosa serve perché quello switch sia indolore quando conta, perché la parte difficile non è la riga di configurazione, è tutto ciò che la rende affidabile.
Cos'è davvero il Laravel AI SDK, e cosa lo distingue da Prism?
Conviene partire dalla genealogia, perché chi lavora in Laravel ha già sentito nominare Prism e la confusione è comune. Il Laravel AI SDK non sostituisce Prism, ci si costruisce sopra: lo usa come dipendenza di basso livello. Otwell stesso ha descritto il rapporto con un'analogia che un laravelista capisce al volo: Prism sta al SDK come il query builder sta a Eloquent. Prism fornisce le chiamate API di basso livello verso i provider; il SDK ci aggiunge sopra il pattern Agent, l'output strutturato, la memoria di conversazione, lo streaming, gli helper di testing e l'integrazione più stretta con il framework. È inoltre ispirato, nella filosofia, al Vercel AI SDK del mondo JavaScript: definisci un'interfaccia unica, scrivi un driver per ciascun provider, e tieni il codice applicativo completamente agnostico rispetto al fornitore.
La parte che qui conta di più è proprio l'interfaccia provider-agnostica. Per la generazione di testo il SDK supporta OpenAI, Anthropic, Google Gemini, Groq e xAI; per gli embeddings OpenAI, Cohere, Mistral e Voyage. Gestisce inoltre dietro le quinte una serie di preoccupazioni operative che altrimenti dovresti scrivere a mano: la logica di retry, la normalizzazione degli errori tra provider e l'integrazione con le code. Tutto questo senza accoppiare l'applicazione al contratto SDK di un singolo fornitore, che è esattamente il punto debole che l'affaire Fable ha messo a nudo.
Va detta però una cosa con onestà, perché è il tipo di dettaglio che distingue un consiglio responsabile da un entusiasmo da changelog: il SDK è giovane. È nato a v0.1.2, è ancora pre-1.0 anche dopo essere diventato production-stable in Laravel 13, e l'API può cambiare. Su un progetto nuovo è una scelta solida; su un progetto esistente in produzione, l'approccio prudente, che è quello che adotto, è introdurlo gradualmente accanto al setup attuale e non fare una migrazione big-bang, perché la cronaca delle prime migrazioni da Prism ha già mostrato rotture silenziose in agenti che sembravano migrati bene. La maturità di un pacchetto è una variabile di rischio, e in un articolo che parla di mitigare il rischio sarebbe ipocrita ometterla.
Se stai valutando come portare le funzionalità AI dentro un'applicazione Laravel in modo che siano robuste e non cablate su un singolo fornitore, nel mio hub dedicato all'AI per lo sviluppo raccolgo gli articoli con la metodologia che applico sul campo.
Come funziona lo switch di provider, in concreto
Il cuore della tesi è banale da mostrare e profondo nelle conseguenze. Con un'interfaccia agnostica, la scelta del modello vive nella configurazione, non nel codice. Il codice applicativo chiede "genera questo testo" senza sapere chi risponde:
// Il codice applicativo è agnostico: non sa quale provider risponde.
$summary = AI::text()
->using(config('ai.primary.provider'), config('ai.primary.model'))
->withPrompt($document)
->generate();E la configurazione, in un file dedicato, definisce chi è il primario e chi il fallback:
return [
// Il giorno del kill-switch si riordina QUESTO, non il codice applicativo.
'primary' => ['provider' => 'anthropic', 'model' => 'claude-opus-4-8'],
'fallback' => ['provider' => 'openai', 'model' => 'gpt-5.5'],
'sovereign'=> ['provider' => 'ollama', 'model' => 'mistral-large-3'],
];Quando un modello diventa indisponibile, l'intervento è spostare il fallback al posto del primario: una riga, nessuna ricompilazione della logica di business, nessuna caccia alle chiamate cablate sparse in venti controller. È la materializzazione, in ecosistema Laravel, del principio architetturale generale che ho descritto in progettare la sostituibilità del modello AI: il modello è un driver, non una fondazione. E il 12 giugno questo ha smesso di essere teoria. Chi aveva l'applicazione cablata sull'SDK ufficiale del fornitore sospeso ha dovuto mettere mano al codice sotto pressione; chi aveva l'astrazione ha cambiato una voce di configurazione. Il contesto completo di quell'evento, e perché segna un punto di non ritorno, l'ho raccontato in hanno spento il modello AI più potente del mondo in tre giorni.
Un esempio concreto: classificare documenti con un fallback reale
Astrarre è bello, ma il valore si vede su un caso. Immagina un flusso aziendale ricorrente: arrivano documenti, vanno riconosciuti per tipo (fattura, contratto, ordine) e instradati. È un task a basso giudizio, perfetto per l'AI, e voglio che resti in piedi anche se il modello primario sparisce. Con l'interfaccia agnostica e l'output strutturato del SDK, la logica resta pulita e indipendente dal fornitore:
class DocumentClassifier
{
public function classify(string $content): string
{
foreach (['primary', 'fallback', 'sovereign'] as $tier) {
try {
$cfg = config("ai.$tier");
return AI::text()
->using($cfg['provider'], $cfg['model'])
->withPrompt($this->prompt($content))
->asStructured(DocumentType::class) // output validato
->generate()
->type;
} catch (ProviderUnavailable | RequestTimeout) {
continue; // degrada al tier successivo della catena
}
}
return 'needs_human_review'; // nessun tier disponibile: coda umana, non blocco
}
}Ci sono tre cose da notare, e sono tutte conseguenze della disciplina, non del pacchetto. La prima è che la classe non nomina mai un fornitore: cambiare l'assegnazione dei tier non la tocca. La seconda è l'output strutturato e validato, che protegge dal fatto che modelli diversi formattano le risposte in modo diverso: il SDK valida contro uno schema, e ciò che non rispetta lo schema non passa silenziosamente. La terza, la più importante, è il comportamento in assenza totale di modelli: il flusso non si blocca, mette il documento in coda per revisione umana. Questo è il punto che distingue un'architettura che assorbe il kill-switch da una che lo subisce: la degradazione è prevista e graziosa, non un'eccezione non gestita che ferma la pipeline.
In una demo questo codice gira identico su qualunque provider. In produzione, la differenza la fa il fatto che ciascuno di quei tier sia stato davvero provato sul tuo workload, ed è il tema della sezione che segue.
Cosa serve perché lo switch sia davvero indolore?
Qui sta la parte che gli annunci di prodotto omettono, ed è quella che fa la differenza tra un fallback che funziona e uno che ti illude. La riga di configurazione è il dieci per cento del lavoro; il novanta per cento è ciò che la rende affidabile. Perché cambiare provider non è come cambiare driver di database: un database risponde alle stesse query con gli stessi dati, un modello no. Cambiare modello cambia il comportamento, e il comportamento è dove si nascondono le sorprese.
Il primo prerequisito è una eval di portabilità: un set di casi reali del tuo dominio su cui misuri quanto si degrada la qualità passando dal primario al fallback. Senza quel numero, lo switch è un salto al buio, e scopri solo in produzione che il fallback estrae i campi in un formato leggermente diverso, o che il suo tono non passa il tuo controllo qualità. Il secondo prerequisito è il warm standby: tenere già in produzione una quota di traffico reale sul fallback, così che le differenze emergano mentre il primario regge ancora, non nel momento dell'emergenza. Il terzo è la consapevolezza del lock-in comportamentale: i prompt che hai calibrato sono tarati sulle idiosincrasie di un modello specifico, e su un altro modello vanno riverificati. Il SDK ti dà l'interfaccia unica e la normalizzazione degli errori, ma non può sapere se il tuo prompt, ottimizzato per un modello, regge sull'altro: quello lo verifichi tu, con la eval.
C'è poi il livello operativo, dove il SDK aiuta davvero e va sfruttato: gestisce retry, normalizzazione degli errori e integrazione con le code, il che significa che la logica di fallback in caso di errore o timeout puoi appoggiarla all'infrastruttura invece di scriverla a mano. Quando una chiamata al primario fallisce, una pipeline ben costruita riprova e, se serve, degrada al fallback in modo asincrono senza bloccare la richiesta utente. Su come gestire le chiamate LLM in modo asincrono con retry e tracciamento dei costi dentro Laravel ho scritto in dettaglio in Laravel Horizon per le chiamate LLM asincrone: è l'altra metà di un'integrazione AI seria, quella che non si vede nelle demo ma che decide se reggi in produzione.
Testare l'integrazione senza dipendere dai provider
C'è un aspetto del Laravel AI SDK che merita attenzione proprio in chiave di risk-mitigation, ed è uno dei motivi per cui preferisco un pacchetto first-party integrato al framework: gli helper di testing. Un'integrazione AI non testata è una bomba a orologeria, perché i suoi punti di rottura, formati di output inattesi, errori del provider, timeout, sono esattamente quelli che non emergono finché non sei in produzione con traffico vero. Il SDK permette di simulare le risposte dei provider nei test, così che la suite verifichi la logica applicativa, la catena di fallback e la gestione degli errori senza chiamare un'API reale, senza spendere token e senza dipendere dalla disponibilità di un modello durante la build.
Questo abilita un pattern che considero non negoziabile per un'integrazione seria. Primo, i test della logica di business simulano il provider e verificano che il classificatore instradi correttamente, che il fallback scatti quando il primario lancia un'eccezione, e che il caso "nessun modello disponibile" finisca davvero in coda umana e non in un errore. Sono test deterministici, veloci, che girano a ogni commit. Secondo, separata da questi, vive la eval di portabilità, che invece chiama i modelli veri su un golden set e misura il degrado di qualità tra i tier: non gira a ogni commit, perché costa token e tempo, ma gira a cadenza fissa e ogni volta che cambi un prompt o aggiorni un provider. La distinzione tra i due livelli è cruciale: i test di logica garantiscono che il meccanismo di fallback funzioni, la eval garantisce che il fallback produca un risultato di qualità accettabile. Servono entrambi, e fanno cose diverse.
Il valore di tutto questo, in chiave di continuità, è che il giorno del kill-switch non scopri sorprese. Hai già verificato in CI che la catena di fallback regge meccanicamente, e hai già misurato che il modello alternativo produce risultati accettabili sul tuo dominio. Lo switch diventa allora ciò che deve essere: un'operazione noiosa e prevista, non un'emergenza. Ed è esattamente in quella noia, in quell'assenza di sorprese sotto pressione, che si misura la qualità di un'integrazione AI di produzione.
La sintesi: un pacchetto giovane, una disciplina vecchia
Il Laravel AI SDK è un ottimo pezzo di ingegneria che porta dentro il framework, in modo idiomatico e testabile, l'astrazione provider-agnostica che prima dovevi costruirti a mano o appoggiare a un pacchetto community. Per un'applicazione Laravel nuova è oggi la via naturale per integrare l'AI senza cablarsi a un fornitore. Ma il valore vero, dopo il 12 giugno, non è la comodità che vendeva all'uscita: è che incarna una disciplina antica, il disaccoppiamento del codice di business dal componente volatile, applicata al layer che il 2026 ha scoperto essere il più fragile, il modello. Adottarlo come comodità ti dà un'API pulita; adottarlo come risk-mitigation, con la eval di portabilità, il warm standby e la consapevolezza del lock-in comportamentale, ti dà la continuità il giorno in cui un modello viene spento dall'alto. La differenza tra le due adozioni non sta nel codice, che è identico, sta nella disciplina che ci metti attorno. Se vuoi impostare l'integrazione AI della tua applicazione Laravel perché sia robusta e sostituibile per davvero, e non solo pulita sulla carta, puoi usare il modulo di preventivo gratuito: sette domande, due minuti, e ti dico se il tuo caso rientra nel mio perimetro o se ti conviene un'altra figura.