Ich gestehe zuerst etwas: Letztes Jahr habe ich ein Modell der Frontier-Klasse auf die Frage "Ist dieser Kommentar Spam?" angesetzt und für jede Antwort den vollen Preis bezahlt, in Geld und in den 800 Millisekunden, die meine Nutzer auf einen Spinner gestarrt haben. Es fühlte sich schon damals absurd an und sieht heute noch schlechter aus, denn das Laravel AI SDK hat gerade v1.0.0 veröffentlicht, und der Teil davon, zu dem ich immer wieder zurückkomme, ist der kleinste. Klassifikation ist jetzt eine erstklassige Fähigkeit, laufend auf Jev, einem Modell von TypeSafe, das für genau einen Job gebaut wurde: billige Ja/Nein- und Auswahlfragen schnell zu beantworten. Hier ist meine These, und ich werde sie verteidigen: Die Mehrheit dessen, was Produktmanager in einer typischen Web-App "KI-Features" nennen, sind Klassifikationsprobleme, und dass ein Framework das endlich laut ausspricht, ist wichtiger als jedes Chat-Widget.

TicketTriage.php
<?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();

Die API spiegelt diese Ehrlichkeit wider. Du übergibst Classification::of() den Text eines Tickets, hängst eine Boolean-Frage zur Dringlichkeit und eine Choice-Frage dazu an, welches Team zuständig ist, rufst classify() auf und bekommst strukturierte Antworten, auf denen du verzweigen kannst. Für den Einzeiler-Fall gibt es sogar ein Str::decide()-Makro, was bedeutet, dass der Spam-Check, für den ich zu viel bezahlt habe, jetzt eine String-Methode ist. Ticket-Triage im Support, Kommentar-Moderation, Routing, Flagging: Nichts davon braucht ein Modell, das Sonette schreiben kann. Es braucht ein schnelles, nachvollziehbares Urteil, und es muss so wenig kosten, dass du nie über die Rechnung nachdenkst.

Warum ist es wichtig, dass das Framework dieses Muster beim Namen nennt? Weil Defaults Teams formen. Als das einzige Werkzeug in laravel/ai noch "schick einen Prompt an ein großes Modell" war, wurde jede triviale Entscheidung über den teuersten verfügbaren Pfad geleitet, so wie früher jedes Datenproblem eine Redis-Instanz bekam, ob es sie brauchte oder nicht. Sobald das Framework eine eigene Spur für kleine Entscheidungen anbietet, verändert sich das Gespräch im Code Review. Jemand greift zu einem vollen Generation-Call, um zu prüfen, ob eine Nachricht Dringlichkeit ausdrückt, und ein Kollege kann jetzt auf Classification zeigen und fragen, warum. Dieser soziale Effekt ist mehr wert als der Latenzgewinn, und der Latenzgewinn ist real.

Das ehrliche Gegenargument verdient seinen Platz. Klassifikation spricht aktuell mit zwei Providern, TypeSafe und OpenRouter, und es juckt mich ein bisschen, dass ein First-Party-SDK mit dem maßgeschneiderten Modell eines einzelnen Anbieters als Star ausgeliefert wird. Kleine Modelle übersehen außerdem Nuancen, und ein falsch als "nicht dringend" einsortiertes Ticket ist ein echter Kunde, der über Nacht wartet. Ich lande trotzdem da, wo ich lande, aus zwei Gründen. Erstens sagt das Laravel-Team, dass weitere Provider an dieselbe API andocken werden, und die Abstraktion ist erkennbar dafür gebaut. Zweitens liegen große Modelle bei der Triage auch daneben, zum dreißigfachen Preis, und ein boolescher Output lässt sich trivial loggen, stichprobenartig prüfen und auditieren. Wenn du die Fehlerrate messen kannst, kannst du sie managen. Über einen Absatz freien Denkens konntest du das nie sagen.

Der Rest des 1.0-Releases untermauert die Reife-Geschichte. Der Approvable-Contract lässt einen Agenten anhalten und auf einen Menschen warten, bevor er ein riskantes Tool ausführt, und du kannst den Aufruf mit einer Begründung ablehnen, die das Modell tatsächlich sieht, oder die Argumente vor der Ausführung bearbeiten. Das ist der Unterschied zwischen einer Agenten-Demo und einem Agenten, den du an irgendetwas anschließen würdest, das Daten löscht. Streaming spricht jetzt nativ die Protokolle Vercel Chat und AG-UI, ToolSearch lädt selten genutzte Tools bei OpenAI und Anthropic lazy nach, und Middleware läuft pro Generationsschritt statt einmal pro Prompt. Der Breaking Change, den du kennen solltest: Die Konversationshistorie ist in eine einzelne steps-Spalte umgezogen, wenn du also direkt auf die alten Spalten zugegriffen hast, plane Zeit für die Migration ein. Das Team schlägt vor, den /upgrade-ai-sdk-v1-Befehl von Laravel Boost den Assistenten deines Editors durch die Umstellung führen zu lassen, was eine erfreulich zirkuläre Nutzung der Technologie ist.

Nebenbei ist Laravel 13.33 gelandet, mit der Sorte Fixes, die du nur zu schätzen weißt, wenn du schon einmal gebissen wurdest. Das #[Refreshes]-Attribut löst endlich das Problem veralteter Models bei datenbankberechneten Spalten: Lege eine Zeile an, deren net_salary aus einem storedAs-Ausdruck kommt, und bis 13.32 hatte dein Eloquent-Objekt diesen Wert schlicht nicht, außer du hast refresh() aufgerufen und alles neu geladen. Jetzt holt das Framework nach jedem Save nur die benannten Spalten mit einer winzigen, gezielten Query. Ein Vorbehalt, den du respektieren solltest: Diese Query feuert bei jedem Save dieses Models, wenn du den Wert also nur an einer einzigen Stelle brauchst, bleibt manuelles refresh() der bessere Deal. Dass Cache::memo() Tag-Support bekommt, ist der andere Keeper, denn er erspart dir wiederholte Redis-Roundtrips für denselben Berechtigungscheck innerhalb eines einzelnen Requests. Rechne noch dazu, dass AsCollection::nullable() endlich ein echtes NULL statt des Strings "null" speichert, und das ist ein Minor-Release, das seine Miete zahlt.

Tritt einen Schritt zurück, und beide Releases reimen sich. Nutze das kleinste Werkzeug, das die Frage beantwortet, egal ob das ein zweckgebautes Entscheidungsmodell ist oder eine Ein-Spalten-Nachfrage statt eines kompletten Zeilen-Reloads. Die Go-Gemeinde predigt Right-Sizing seit Jahren, während wir fröhlich noch eine Schicht draufgeschraubt haben, also ist es befriedigend zuzusehen, wie Laravel Sparsamkeit zum First-Party-Feature macht. Jetzt sag mir, wo du die Grenze ziehst: Welche Entscheidung in deiner Codebasis würdest du morgen einem Klassifikator übergeben, und welche würdest du niemals ein Modell ohne einen Menschen in der Schleife treffen lassen, egal wie billig der Aufruf wird?