Je commence par une confession : l'an dernier, j'ai pointé un modèle de classe frontière sur la question « ce commentaire est-il du spam ? » et j'ai payé plein tarif pour chaque réponse, en argent et dans les 800 millisecondes que mes utilisateurs passaient à fixer un spinner. C'était absurde à l'époque et ça paraît pire aujourd'hui, parce que le Laravel AI SDK vient de sortir en v1.0.0 et que le morceau vers lequel je reviens sans cesse est le plus petit de tous. La classification est désormais une capacité de première classe, qui tourne sur Jev, un modèle de TypeSafe conçu pour exactement une tâche : répondre vite et pour trois fois rien à des questions oui/non ou à choix unique. Voici ma thèse, et je vais la défendre : la majorité de ce que les product managers appellent des « fonctionnalités IA » dans une app web classique sont des problèmes de classification, et un framework qui le dit enfin à voix haute compte plus que n'importe quel widget de chat.
<?php
use Laravel\Ai\Classification;
use Laravel\Ai\Classification\Boolean;
use Laravel\Ai\Classification\Choice;
$response = Classification::of($ticket->body)->questions([
'is_urgent' => new Boolean('Does this message convey urgency?'),
'department' => new Choice('Which team should handle this?', [
'billing' => 'Payments, invoicing, refunds',
'technical' => 'Bugs, outages, integrations',
'sales' => 'Pricing, plans, upgrades',
]),
])->classify();L'API reflète cette honnêteté. Tu passes le corps d'un ticket à Classification::of(), tu attaches une question Boolean sur l'urgence et une question Choice sur l'équipe responsable, tu appelles classify(), et tu récupères des réponses structurées sur lesquelles tu peux brancher ta logique. Pour le cas d'une seule ligne, il y a même une macro Str::decide(), ce qui veut dire que la vérification de spam que j'ai payée trop cher est maintenant une méthode de chaîne. Triage de tickets de support, modération de commentaires, routage, signalement : rien de tout ça n'a besoin d'un modèle capable d'écrire des sonnets. Ça a besoin d'un verdict rapide, inspectable, et qui coûte si peu que tu ne penses jamais à la facture.
Pourquoi est-ce important que le framework nomme ce besoin ? Parce que les défauts façonnent les équipes. Quand le seul outil dans laravel/ai était « envoyer un prompt à un gros modèle », chaque décision triviale passait par le chemin le plus cher disponible, comme chaque problème de données récoltait jadis une instance Redis, qu'il en ait besoin ou non. Dès que le framework offre une voie dédiée aux petites décisions, la conversation en revue de code change. Quelqu'un dégaine un appel de génération complet pour vérifier si un message exprime de l'urgence, et un collègue peut maintenant pointer Classification du doigt et demander pourquoi. Cet effet social vaut plus que le gain de latence, et le gain de latence est bien réel.
Le contre-argument honnête mérite son temps d'antenne. La classification ne parle pour l'instant qu'à deux fournisseurs, TypeSafe et OpenRouter, et ça me gratte un peu qu'un SDK first-party sorte avec le modèle maison d'un seul vendeur en tête d'affiche. Les petits modèles ratent aussi les nuances, et un « pas urgent » mal étiqueté, c'est un vrai client qui attend toute la nuit. J'atterris quand même là où j'atterris, pour deux raisons. D'abord, l'équipe Laravel annonce que d'autres fournisseurs se brancheront sur la même API, et l'abstraction est clairement construite pour ça. Ensuite, les gros modèles se trompent aussi en triage, à trente fois le coût, et une sortie booléenne est ridiculement facile à logger, échantillonner et auditer. Si tu peux mesurer le taux d'erreur, tu peux le gérer. Tu n'as jamais pu dire ça d'un paragraphe de raisonnement en texte libre.
Le reste de la release 1.0 confirme le récit de maturité. Le contrat Approvable permet à un agent de s'arrêter et d'attendre un humain avant d'exécuter un outil risqué, et tu peux rejeter l'appel avec une raison que le modèle voit vraiment, ou éditer les arguments avant l'exécution. C'est la différence entre une démo d'agent et un agent que tu accepterais de connecter à quoi que ce soit qui supprime des données. Le streaming parle désormais nativement les protocoles Vercel Chat et AG-UI, ToolSearch charge paresseusement les outils rarement utilisés chez OpenAI et Anthropic, et les middlewares tournent à chaque étape de génération au lieu d'une fois par prompt. Le breaking change à connaître : l'historique de conversation a déménagé dans une seule colonne steps, donc si tu interrogeais directement les anciennes colonnes, prévois du temps de migration. L'équipe suggère de laisser la commande /upgrade-ai-sdk-v1 de Laravel Boost guider l'assistant de ton éditeur à travers le chantier, un usage plaisamment circulaire de la technologie.
Pendant ce temps, Laravel 13.33 a atterri avec le genre de correctifs que tu n'apprécies que si tu t'es déjà fait mordre. L'attribut #[Refreshes] résout enfin le problème du modèle périmé avec les colonnes calculées en base : crée une ligne dont le net_salary vient d'une expression storedAs et, jusqu'à la 13.32, ton objet Eloquent n'avait tout simplement pas cette valeur, sauf à appeler refresh() et tout recharger. Maintenant le framework récupère juste les colonnes nommées avec une minuscule requête ciblée après chaque save. Une réserve à respecter : cette requête part à chaque save pour ce modèle, donc si tu n'as besoin de la valeur qu'à un seul endroit, un refresh() manuel reste le meilleur compromis. Cache::memo() qui gagne le support des tags est l'autre bonne pioche, elle t'épargne des allers-retours Redis répétés pour la même vérification de permissions au sein d'une seule requête. Ajoute AsCollection::nullable() qui stocke enfin un vrai NULL au lieu de la chaîne "null", et tu obtiens une release mineure qui paie son loyer.
Prends du recul et les deux releases riment. Utilise le plus petit outil qui répond à la question, que ce soit un modèle de décision spécialisé ou une requête de suivi sur une colonne au lieu d'un rechargement complet de la ligne. La communauté Go prêche le dimensionnement juste depuis des années pendant qu'on empilait joyeusement une couche de plus, alors c'est satisfaisant de voir Laravel faire de la frugalité une fonctionnalité first-party. Maintenant dis-moi où tu traces la ligne : quelle décision dans ta codebase confierais-tu à un classificateur dès demain, et laquelle ne laisserais-tu jamais à un modèle sans humain dans la boucle, peu importe à quel point l'appel devient bon marché ?




Commentaires
Pas encore de commentaire — écris le premier.
Lance la discussion
Pas de compte ni de mot de passe — saisis simplement ton adresse e-mail et nous t’envoyons un lien de connexion à usage unique. Première visite ? Tout se met en place automatiquement.
Ton évaluation sera appliquée automatiquement après ta connexion.
Vérifie ta boîte mail
Nous avons envoyé un lien de connexion à …. Ouvre-le sur cet appareil — cet onglet te connectera automatiquement.
Rien reçu ? Vérifiez le dossier spam — et marquez le message « Non spam » pour qu'il arrive directement la prochaine fois.