
Teilen Sie:
Benjamin Aronov ist ein Entwickler-Befürworter bei Vonage. Er ist ein bewährter Community Builder mit einem Hintergrund in Ruby on Rails. Benjamin genießt die Strände von Tel Aviv, das er sein Zuhause nennt. Von Tel Aviv aus kann er einige der besten Startup-Gründer der Welt treffen und von ihnen lernen. Außerhalb der Tech-Branche reist Benjamin gerne um die Welt auf der Suche nach dem perfekten Pain au Chocolat.
Verstärkt: Erstellen einer Laravel-App ohne Laravel-Kenntnisse
In diesem Tutorial lernen Sie, wie Sie mit Laravel, OpenAI und der Vonage Messages API einen WhatsApp-Reise-Concierge über einen KI-Agenten erstellen.
WhatsApp chat interface showing the Vonage-powered travel concierge ready to receive and respond to user messages.
Einführung
TL;DR: Überspringen Sie den Vorgang und finden Sie den funktionierenden Code auf GitHub.
Vor ein paar Monaten, Jim Seconde mich gefragt, ob ich ein paar PHP-Inhalte schreiben wolle. Jim ist schon seit Jahren eine PHP-Berühmtheit und hat sich mit so ziemlich allem beschäftigt, was mit PHP zu tun hat. Aber ich? Ich habe PHP seit wahrscheinlich 12 Jahren nicht mehr angerührt.
Jim sagte: "Mach dir keine Sorgen. Es gibt diese coole neue Sache namens Laravel Boost. Es ist ein Laravel-spezifischer MCP-Server, der Ihnen bei der Erstellung von Laravel-Anwendungen hilft. Keine Elefanten erforderlich. Daraus wurde ein kleines Experiment mit einer sehr klaren Vorgabe: Kann ich eine nicht-triviale Laravel-Anwendung mit einem Stack erstellen, den ich kaum kenne, und dabei einen KI-Codierungsagenten als primäres Implementierungswerkzeug verwenden?
Ich habe mir absichtlich eine schwierige Aufgabe gestellt: einen WhatsApp-Reise-Concierge in Laravel und PHP zu entwickeln. Die App konnte nicht nur Text zurückgeben. Sie musste WhatsApp-Nachrichten über die Vonage Messages APIempfangen, OpenAI verwenden, um Antworten zu generieren, den richtigen WhatsApp-Nachrichtentyp für die Antwort auswählen, interaktive Elemente wie Schaltflächen und Listen unterstützen und genügend Konversationsspeicher behalten, um sich wie ein Assistent und nicht wie ein zustandsloser Bot zu fühlen.
Das machte es zu einem nützlichen Testfall. Es handelte sich nicht um eine Spielzeug-CRUD-Anwendung und auch nicht um ein Framework-Tutorial, durch das ich mich durchmogeln konnte. Es ging um Webhooks, Hintergrundaufträge, API-Authentifizierung, externe Plattformbeschränkungen und strukturierte Nachrichtenformate.
Dieser Artikel ist kein Schritt-für-Schritt-Laravel-Tutorial. Er ist ein Bericht darüber, wie es tatsächlich war, eine echte Anwendung auf diese Weise zu erstellen: welche Aufforderungen halfen, welche Phasen die Arbeit unter Kontrolle hielten, wo der Agent nützlich war, wo er umkippte und wie die MCP-gestützte Dokumentation das Ergebnis veränderte, wenn es schwierig wurde.
Das ganze Projekt dauerte etwa acht Stunden an zwei Tagen. Am Ende hatte ich eine funktionierende Laravel-WhatsApp-Demo. Und was noch wichtiger ist: Ich hatte eine viel klarere Vorstellung davon, wozu agenturische Entwicklung eigentlich gut ist.
Voraussetzungen
PHP
PHP-Komponist
Laravel Boost-fähiger Agent (z. B. GitHub CoPilot)
OpenAI API Account oder andere LLM
ngrok
Ein verifizierter WhatsApp Business Account (WABA)
Vonage API-Konto
Eine virtuelle Nummer von Vonage
Vonage API-Konto
Um dieses Tutorial durchzuführen, benötigen Sie ein Vonage API-Konto. Wenn Sie noch keines haben, können Sie sich noch heute anmelden und mit einem kostenlosen Guthaben beginnen. Sobald Sie ein Konto haben, finden Sie Ihren API-Schlüssel und Ihr API-Geheimnis oben auf dem Vonage-API-Dashboard.
Konfigurieren der Vonage-Anwendung
Um eine Anwendung zu erstellen, gehen Sie auf die Seite Erstellen einer Anwendung auf dem Vonage Dashboard und legen Sie einen Namen für Ihre Anwendung fest.
Wenn Sie eine API verwenden möchten, die Webhooks nutzt, benötigen Sie einen privaten Schlüssel. Klicken Sie auf "Generate public and private key", der Download sollte automatisch starten. Bewahren Sie ihn sicher auf; dieser Schlüssel kann bei Verlust nicht erneut heruntergeladen werden. Er folgt der Namenskonvention privat_<Ihre App-ID>.key. Dieser Schlüssel kann nun zur Authentifizierung von API-Aufrufen verwendet werden. Hinweis: Ihr Schlüssel funktioniert erst, wenn Ihre Anwendung gespeichert ist.
Wählen Sie die benötigten Funktionen (z. B. Voice, Nachrichten, RTC usw.) und stellen Sie die erforderlichen Webhooks bereit (z. B. Ereignis-URLs, Antwort-URLs oder URLs für eingehende Nachrichten). Diese werden im Lernprogramm beschrieben.
Zum Speichern und Bereitstellen klicken Sie auf "Neue Anwendung generieren", um die Einrichtung abzuschließen. Ihre Anwendung ist nun bereit für die Verwendung mit Vonage-APIs.
Sie müssen die Funktionen für Nachrichten aktivieren. Für Nachrichten müssen Sie Webhooks aktivieren. Fügen Sie vorerst nur Platzhalter hinzu. Später, wenn die lokale Anwendung über ngrok läuft, aktualisieren Sie den eingehenden Webhook, damit er auf den Laravel-Endpunkt zeigt.
Setzen Sie die eingehende URL auf https://placeholder.com/inbound.
Setzen Sie die Status-URL auf https://placeholder.com/status.
Dann verknüpfen Sie Ihr WhatsApp Business (WABA) indem Sie auf die Registerkarte "Externe Konten verknüpfen" klicken:
Vonage dashboard showing a WhatsApp Business Account linked to an application in the “Link external accounts” section.Achten Sie darauf, dass Sie die:
ID der Anwendung
Privater Schlüssel (heruntergeladen als .key Datei)
API-Schlüssel/Geheimnis
Diese werden wir später für unsere Laravel-App benötigen.
Konfigurieren des Agenten
In einem normalen Lehrgang müssen wir nur unsere Anwendung einrichten. Aber in einem agentenbasierten Tutorial wie diesem müssen wir auch unseren Agenten einrichten.
Ich habe eine einfache Plan-First-Anweisungsdatei verwendet (kopiert von Alex Finn):
Lesen Sie den Codebase und denken Sie über das Problem nach.
Schreiben Sie einen Plan in todo.md.
Warten Sie die Genehmigung ab, bevor Sie mit der Umsetzung beginnen.
Erledigen Sie eine Aufgabe nach der anderen.
Erläutern Sie Änderungen auf hohem Niveau.
Halten Sie Änderungen einfach und minimal.
Außerdem habe ich den Agenten ausdrücklich aufgefordert, zwei MCP-gestützte Tools zu verwenden:
Die Laravel Boost MCP Server, für Framework-bewusste Gerüste und Konventionen
Die Vonage Dokumentation MCP-Serverfür die Korrektheit der API und Details zum Nachrichtenformat
Dies ist eine der ersten klaren Lehren aus dem Projekt: Sofortengineering ist eigentlich Workflow-Engineering, und MCP-Tools machen diesen Workflow zu etwas Zuverlässigem.
Erstellen Sie zunächst das Verzeichnis, in dem Ihre Regeln gespeichert werden sollen:
touch ./github/instructions/workflow.instructions.md
Und fügen Sie dann die Anweisungen gemäß der Syntax der Copilot-Anweisungen:
4 Schritte zur Erstellung der App
Als ich anfing, hatte ich keine Ahnung, wie lange es dauern und was alles dazugehören würde. Aber jedes Mal, wenn der Agent eine ToDo-Liste abschloss, benannte ich die Datei um und speicherte sie. Dann konnte ich die erledigten Aufgaben zusammen mit dem ursprünglichen Projektumfang an den Agenten senden, der dann die nächste Gruppe von Zielen erstellte.
Anstatt den Agenten mit umfangreichen Anweisungen zu konfrontieren, konzentrierte ich mich auf kleine Phasen mit klaren Ergebnissen.
Erstellung der grundlegenden Laravel-App und WhatsApp-Integration
Hinzufügen von WhatsApp-Antworten aus der App an den Benutzer
Hinzufügen von Konversationsspeicher für bessere Antworten von OpenAI
Hinzufügen intelligenter Nachrichtentypen (Schaltflächen, Listen)
Ich fasse zusammen, was in jeder Phase geschah, und hebe die interessantesten Vorschläge hervor.
Phase 1: Lassen Sie den Agenten die App planen
Siehe: initial_todo.md für Agentenaufgaben.
Die erste Aufforderung war absichtlich sehr allgemein gehalten. Ich beschrieb die Demo-App, die WhatsApp-Integration und die Anforderung, OpenAI sowohl für Entscheidungen über den Inhalt als auch über den Nachrichtentyp zu verwenden.
Initial prompt used to define the travel concierge app and guide the agent to generate a structured development plan using Laravel Boost and Vonage docs.
Hier hat Laravel Boost MCP einen deutlichen Unterschied gemacht.
Anstatt eine generische PHP-Struktur zu erzeugen, lehnte sich der Agent sofort an Laravel-Konventionen an. Er schlug Routen, Controller, Jobs in Warteschlangen und Serviceklassen vor, die sich an der typischen Organisation von Laravel-Anwendungen orientierten. Er schlug auch eine schrittweise todo.md Plan vor, ohne dass dies explizit gefordert wurde.
Der Agent nutzte das durch MCP bereitgestellte Framework-Wissen, um die Architektur zu gestalten. Er erstellte eine Webhook-Route, einen Controller für die Validierung, Jobs in Warteschlangen für die Verarbeitung und den Versand von Nachrichten sowie Serviceklassen für OpenAI und Vonage.
Hätte ich ohne Laravel-Erfahrung gearbeitet, hätte es deutlich länger gedauert, dies manuell zusammenzusetzen. Die erste Erkenntnis ist also klar: Wenn der Agent Zugriff auf Framework-fähige MCP-Tools hat, ist er sehr stark bei der Erstellung von Gerüsten auf der grünen Wiese.
AI-generated development plan outlining the Laravel WhatsApp app architecture, including webhooks, queue jobs, services, and OpenAI integration.
Der erste Fehlschlag: Code, der richtig aussah, aber nichts bewirkte
Die Gerüstphase war überraschend gut verlaufen. Der Agent hatte eine vollständige Laravel-Anwendung erstellt: Routen, Controller, Jobs, Dienste, sogar eine Testdatei. Mit Laravel Boost MCP, das die Struktur steuert, sah es viel früher wie eine echte Anwendung aus, als ich erwartet hatte.
Die ersten Probleme traten auf, als ich die Tests durchführte, die ich den Agenten hatte schreiben lassen.
Einer von ihnen fiel sofort aus:
The expected [App\Jobs\ProcessIncomingMessage] job was not dispatched.
Das sah einfacher aus, als es tatsächlich war.
Der Agent hat den Fehler nicht zum Controller zurückverfolgt. Er blieb an der Oberfläche und spekulierte über die Konfiguration und die Testeinrichtung, obwohl der Fehler konsistent war: Der Webhook lieferte eine Antwort, aber der Auftrag wurde nie versandt.
Nachdem der Test und das Steuergerät nebeneinander geprüft worden waren, wurde das Problem schließlich gefunden. Der Controller validierte die Anfrage und gab eine Antwort zurück, löste aber nie den Rest des Systems aus. Die Lösung bestand aus einer einzigen Zeile:
ProcessIncomingMessage::dispatch($data['to'], $data['from'], $data['message']);
Danach war der Test bestanden. Bis zu diesem Punkt war der Agent sehr effektiv bei der Erstellung von Gerüsten gewesen. Er produzierte Code, der korrekt aussah und den Rahmenkonventionen folgte. Aber er stellte nicht zuverlässig sicher, dass sich das System durchgängig verhält.
Indem ich Tests in den Arbeitsablauf einfügte, erhielt ich eine leichtgewichtige Version von TDD. Der Test definierte das Verhalten, und der Agent musste iterieren, bis die Implementierung damit übereinstimmte. Es war keine reibungslose Schleife, aber es gab mir ein stabiles Signal, gegen das ich steuern konnte.
Der Agent erledigte die sich wiederholenden Aufgaben, während ich mich darauf konzentrierte, sie mit dem erwarteten Verhalten in Einklang zu bringen. Dies ist ein idealer Weg, um die Arbeit zwischen Agenten und Menschen aufzuteilen.
Nicht, weil der Agent perfekt war, sondern weil er etwas wie TDD leichter durchzuhalten machte, als es normalerweise von Hand möglich ist.
Jetzt konnte ich eine Nachricht an die App senden und sehen, dass sie auf dem Terminal protokolliert wurde:
[2026-03-09 17:15:00] local.INFO: WhatsApp webhook received {
"from":"1***2364506",
"to":"1***3508504",
"message_type":"text",
"text_body":"Let’s test the Vonage WhatsAppp Service"
}
Phase 2: Die App beginnt zu sprechen
Siehe: second_todo.md für Agentenaufgaben.
Die Grundstruktur war vorhanden, aber es gab ein Problem. Ich habe keine Nachrichten von der App zurückbekommen. Der Fluss sollte folgendermaßen sein: Der Benutzer sendet eine WhatsApp-Nachricht, diese trifft auf den Webhook, fließt durch Laravel, erhält eine Antwort von OpenAI und geht dann zurück durch Vonage.
Es sah so aus, als ob das alles existierte. Der Agent hatte die Aufträge, Dienste und Integrationen eingerüstet. Die Nachrichten erreichten die App, und nichts war offensichtlich defekt. Aber es funktionierte immer noch nicht durchgängig.
Fehler in der Echtzeit beim letzten Schritt
Als das System das erste Mal ganz durchlief, schlug es tief in der Pipeline mit einem Laufzeitfehler fehl:
Sending message via Vonage {"to":"unknown","type":"text"}
Undefined array key "to"Dies ist eine spezielle Art von Fehler, der erst auftritt, wenn ein System größtenteils verkabelt ist. Da der Agent alle Teile isoliert aufgebaut hatte, sah alles korrekt aus. Und stromaufwärts funktionierte alles: Der Webhook empfing die Nachricht, der Auftrag wurde versandt, OpenAI generierte eine Antwort.
Der Fehler trat erst auf, als ich versuchte, die Antwort zu senden. Ein Blick in die Protokolle zeigt, dass das Problem nur subtil war:
{
"to": unknown,
"type": "text"
}
Das System versuchte, eine Nachricht ohne einen echten Empfänger zu versenden. Irgendwann war dieser Wert verloren gegangen und wurde ersetzt durch "unbekannt". Das lag daran, dass der Agent isoliert betrachtet alles gut aussehen ließ, aber den Überblick über das große Ganze und die Zusammenhänge verlor.
Copilot repariert immer wieder die falsche Schicht
Dies war der erste Punkt, an dem der Agent zu kämpfen begann. Er hat den Fehler nicht ignoriert. Er schlug immer wieder Korrekturen vor. Aber auch hier blieben die Vorschläge nahe an der Oberfläche: Anpassung der Prompts, Optimierung der Art und Weise, wie die OpenAI-Antwort analysiert wurde, Änderung der Antwortformate
Alles vernünftige Ideen, aber keine davon befasste sich mit dem eigentlichen Fehler. Das Problem war nicht, wie die Antwort erzeugt wurde. Es ging darum, wie die Daten das System durchliefen.
Drei Dinge geschahen auf einmal: Das Modell durfte Felder definieren wie anzu definieren, ungültige Werte durchliefen mehrere Ebenen, und nichts erzwang vor dem Senden erforderliche Felder. Diese Kombination bedeutete, dass das System erst ganz am Ende versagte, als Vonage versuchte, die Daten zu verwenden.
Selbst nach einigen Iterationen konvergierte der Agent nicht zu diesem Ergebnis. Er produzierte immer wieder plausible Korrekturen, die das Ergebnis nicht veränderten.
Der Wechsel des Agenten veränderte den Ansatz
An diesem Punkt wechselte ich von CoPilot mit GPT-5 Mini zu meiner Lieblings-IDE, Windsurf mit Claude Sonnetum und gab ihr die vollständigen Protokolle statt nur der Fehler. Der Unterschied war nicht, dass es besseren Code schrieb. Es ging das Problem anders an. Anstatt sich auf die fehlerhafte Zeile zu konzentrieren, verfolgte es den gesamten Pfad der Nachricht:
Webhook → OpenAI → Auftrag → Vonage
Dann fügte es an jeder Grenze Prüfungen hinzu: frühzeitige Validierung von Eingaben, Erzwingen von Pflichtfeldern vor dem Senden und Protokollierung von Zwischenständen.
Die wichtigste Änderung war, wo die Validierung stattfand. Bis zu diesem Punkt ging das System davon aus, dass alles gültig war, und versagte spät. Nach diesem Durchlauf begann es, an vorhersehbaren Stellen frühzeitig zu versagen. Sobald diese Prüfungen durchgeführt wurden, verschwand das "bis"-"unbekannt"-Problem.
Claude analyzing the error across the full message pipeline and applying validation at multiple layers instead of patching a single failure point.
Der Agent versuchte, das Rad neu zu erfinden
Nachdem der Datenfluss behoben war, machte das System Fortschritte und stieß sofort auf das nächste Problem. Ausgehende Nachrichten schlugen immer noch fehl, dieses Mal mit 401 Nicht autorisiert. Die Reaktion des Agenten war hier interessant. Anstatt das vorhandene Tooling zu verwenden, begann er, die Authentifizierungsschicht von Grund auf neu zu erstellen:
manuelle Erzeugung von JWTs
mit openssl_sign()
Spielsteine von Hand konstruieren
Senden von rohen HTTP-Anfragen
Oberflächlich betrachtet, sah der Code für die KI vernünftig aus. Aber er hat nie zuverlässig funktioniert. Dies ist ein anderer Fehlermodus. In diesem Fall hat die KI erraten, wie die Authentifizierung bei Vonage funktioniert, anstatt die SDK-Konventionen zu verwenden.
Der Wendepunkt: Dokumentation über MCP erzwingen
Die Lösung kam durch eine sehr direkte Aufforderung:
Warum haben Sie nicht das Vonage Docs Tool verwendet, um ein JWT über das SDK zu generieren? Wir scheitern immer wieder bei dem Versuch, diese manuell zu erstellen.
Anstatt weiter zu improvisieren, griff der Agent auf das MCP-Tool der Vonage-Dokumentation zurück und wechselte den Ansatz. Er verwendete das offizielle PHP-SDK von Vonageund ließ das SDK die JWT-Generierung direkt durchführen.
Damit war das Problem vollständig gelöst.
Prompt that forced the agent to stop generating JWTs manually and use the Vonage documentation MCP tool and official SDK.
Phase 3: Hinzufügen eines Gesprächsspeichers
Siehe: third_todo.md für Agentenaufgaben.
Zu diesem Zeitpunkt hatte ich einen einfachen WhatsApp-Chatbot, der funktionierte. Aber es fühlte sich sehr dumm an. Jede Nachricht wurde isoliert behandelt. Der Assistent antwortete zwar korrekt, aber er hatte keine Erinnerung an das, was vorher kam.
Das Ziel war einfach: den Gesprächsverlauf zu speichern, die letzten Nachrichten in die OpenAI-Eingabeaufforderung einzubeziehen und dies auf eine einfache Art und Weise zu tun, die keine neue Komplexität mit sich bringt.
Im Vergleich zu Phase 2 fühlte sich dies wie eine unkomplizierte Erweiterung an.
Ein reibungsloser erster Durchgang
Der Agent implementierte den Konversationsspeicher mit einer SQLite-Datenbank ohne große Probleme.
Der Agent hat eine Konversation Modell und eine Tabelle, begann mit der Speicherung eingehender Nachrichten im bestehenden Job und übergab die letzten Nachrichten an die OpenAI-Eingabeaufforderung. Da der Rest der App bereits auf eine ziemlich standardmäßige Laravel-Art strukturiert war, fügte sich dies ganz natürlich ein. Es gab nicht viel Hin und Her oder Debugging.
Dies ist eine der Stellen, an denen sich die frühere Struktur auszahlt. Wenn die Form der App erst einmal feststeht, sind Agenten in der Regel ziemlich gut darin, sie auf vorhersehbare Weise zu erweitern.
"Arbeiten" war nicht wirklich arbeiten
Nach der ersten Implementierung schien die Funktion zu funktionieren. Die App reagierte auf Nachrichten. Sie verwies auf früheren Kontext. Es fühlte sich an, als sei der Speicher vorhanden.
Ein kurzer Praxistest zeigte jedoch das Problem: Der Assistent konnte sich das Gespräch nicht richtig merken. Das System hat nicht völlig versagt. Es verhielt sich nur uneinheitlich. Das war eine andere Art von Fehler als in früheren Phasen.
Example of inconsistent conversation memory: the assistant initially references prior context (user name), but fails to connect follow-up messages about Tel Aviv and May.
Der subtile Fehler: Unvollständiger Speicher
Als der Agent sich ansah, was tatsächlich gespeichert wurde, war das Problem klar. Es wurden nur Benutzernachrichten gespeichert. Die Antworten der Assistenten wurden nicht gespeichert.
Der Gesprächsverlauf bei der Gründung von OpenAI sah also folgendermaßen aus:
User: I want to plan a trip to Tel Aviv
User: Can you help me plan this trip in May?Aus der Sicht des Modells fand kein Gespräch statt. Es gibt keine Aufzeichnungen darüber, wie der Assistent reagiert hat, so dass er nichts hat, worauf er aufbauen kann. Stellen Sie sich vor, Sie versuchen, ein Gespräch zu führen, hören aber nur die Hälfte von dem, was gesagt wird!
Anstatt alles als einen einzigen Strom von Nachrichten zu behandeln, musste das System beide Seiten explizit verfolgen. Der Agent aktualisierte die Struktur, um sowohl die Eingaben des Benutzers als auch die Antworten des Assistenten zu speichern, die Konversation in Form von abwechselnden Runden zu rekonstruieren und dann die letzten paar Runden an OpenAI zu übergeben.
Sobald dies der Fall war, entsprach das Verhalten den Erwartungen. Folgefragen ergaben nun einen Sinn, weil das Modell den vorherigen Austausch sehen konnte.
Ein weiterer Fehlerpunkt: Tests und Migrationen
Dies war auch das erste Mal, dass die Persistenz Auswirkungen auf die Testsuite hatte. Alles funktionierte lokal, aber die Tests fingen sofort an, mit fehlzuschlagen:
SQLSTATE[HY000]: no such table: conversationsDies war kein Problem mit der Anwendung. Die Testdatenbank verfügte einfach nicht über die neue Tabelle. Die Migrationen wurden nicht als Teil der Testeinrichtung ausgeführt. Ein Laravel-Entwickler würde die Lösung kennen: Verwenden Sie RefreshDatabase damit Migrationen in Tests ausgeführt werden und die Test-Payloads so aktualisiert werden, dass sie alle erforderlichen Felder enthalten, wie von.
Sobald dies erledigt war, wurden die Tests erneut bestanden.
Phase 4: Strukturierte Nachrichten (MCP wird obligatorisch)
Siehe: fourth_todo.md für Agentenaufgaben.
Zu diesem Zeitpunkt konnte die App bereits zuverlässig Nachrichten senden und empfangen. Aber nur Textnachrichten. Der letzte Schritt bestand darin, das volle Potenzial von WhatsApp auszuschöpfen und durch Hinzufügen etwas Cooles zu schaffen:
Antworttasten
interaktive Listen
Was sich wie eine kleine Erweiterung anfühlte, erwies sich als der integrationsintensivste Teil des Projekts.
Plausible Nutzlast von WhatsApp abgelehnt
Beim ersten Versuch schien es zu funktionieren. OpenAI lieferte strukturierte Antworten wie:
{
"type": "list",
"content": {
"items": [...]
}
}
Auf der Laravel-Seite sah alles korrekt aus: 1) die OpenAI-Antwort kam im erwarteten Format zurück, 2) der Auftrag wurde ausgeführt und 3) der Vonage-Dienst wurde aufgerufen.
Doch der letzte Schritt ist damit gescheitert:
Invalid params: The value of one or more parameters is invalid.Oder manchmal, was noch verwirrender war, wurde überhaupt nichts in WhatsApp angezeigt. Aus der Sicht von Laravel funktionierte alles. Die API war da anderer Meinung.
Laravel logs showing a WhatsApp list message flowing through OpenAI and Vonage correctly, but failing at the final step with an “Invalid params” error due to a malformed interactive payload.Der Agent reagierte so, wie er es in früheren Phasen getan hatte. Er versuchte, die Nutzdaten umzuformen, die Formate anzupassen und sogar auf reinen Text zurückzugreifen, nur um etwas durchzubekommen. Das funktionierte zwar technisch, aber es ging am eigentlichen Problem vorbei.
Interaktive WhatsApp-Nachrichten sind nicht einfach nur strukturierter Text. Sie müssen strengen Schemata folgen, und kleine Abweichungen machen sie ungültig. Der Agent verfügte nicht über ein zuverlässiges Modell dieser Beschränkungen, so dass er immer wieder Nutzdaten erzeugte, die zwar vernünftig aussahen, aber nicht akzeptiert wurden.
Fehlende Übereinstimmung der Nachrichten: SDK vs. Realität
Nach ein paar Wiederholungen trat ein anderer Fehler auf:
Argument #1 ($message) must be of type BaseMessage, array given
Das Vonage SDK erwartet typisierte Nachrichtenobjekte, während interaktive Nachrichten tief verschachteltes JSON erfordern. Der Agent übergab Arrays, die der Form der Nutzlast entsprachen, aber das SDK wies sie zurück.
Zu diesem Zeitpunkt lag das Problem nicht nur in der Nutzlast, sondern auch in der Schicht, über die wir sie zu senden versuchten.
Runde zwei: Dokumentation über MCP erzwingen
An dieser Stelle wurde das Vonage MCP-Dokumentationstool erneut entscheidend.
Anstatt weiterhin Nutzdaten umzugestalten, habe ich den Agenten dazu gebracht, die tatsächlichen WhatsApp-Nachrichtenschemata zu untersuchen und von dort aus zu arbeiten.
Der Ansatz änderte sich ziemlich schnell:
das SDK dort einsetzen, wo es hilfreich ist (Authentifizierung, Basis-Client)
interaktive Nachrichten über rohes HTTP senden
Nutzdaten zu erstellen, die genau der dokumentierten Struktur entsprechen
Sobald der Agent das Schema vor sich hatte, war er erfolgreich.
Using the Vonage documentation MCP tool to confirm the correct SDK-based approach before refactoring the integration.
Schlussfolgerung
Zwei Tage zuvor hätte ich Laravel nicht für etwas anderes als ein Tutorial gewählt. Am Ende hatte ich einen funktionierenden WhatsApp-Reise-Concierge mit OpenAI, Konversationsspeicher und strukturierter Nachrichtenübermittlung. Aber wichtiger als die App war das Verständnis, wie diese Art des Aufbaus tatsächlich funktioniert.
Der Agent war hilfsbereit, aber nicht selbstständig. Er kam gut mit Gerüsten und Erweiterungen zurecht, vor allem, wenn die Struktur einmal vorhanden war. Probleme gab es an den Grenzen (Datenfluss, Authentifizierung, strenge APIs), wo "fast korrekt" nicht gut genug ist.
Was den Unterschied ausmachte, war der Arbeitsablauf. Durch die Unterteilung der Arbeit in Phasen, die frühzeitige Durchführung von Tests und die Verwendung von MCP-Tools zur Verankerung des Agenten in der eigentlichen Dokumentation konnte ich komplizierte Funktionen schnell zum Laufen bringen. Ohne diese Maßnahmen neigte der Agent dazu, zu raten. Mit dem richtigen Arbeitsablauf konnte ich eine Anwendung erstellen, deren Syntax ich nicht erklären kann.
Nächste Schritte
Von hier aus gibt es jede Menge Möglichkeiten, die App zu erweitern. Sie könnten neue WhatsApp-Nachrichtentypen hinzufügen, z. B. Standortnachrichten, um den Nutzern genau zu zeigen, wo sich die Orte auf ihrer Reiseroute befinden, oder Dateinachrichten verwenden, um eine PDF-Version eines Reiseplans zu erstellen und zu versenden. Diese Arten von Erweiterungen treiben die Integration weiter voran und zeigen, wo strukturierte APIs und ein klarer Datenfluss wirklich wichtig sind.
Die Schlussfolgerung ist ziemlich einfach: Mit einem Agenten kann man sich viel schneller in unbekannte Stapel einarbeiten, aber nur, wenn man die Kontrolle über die Struktur und die Grenzen behält. Wenn Sie das gesamte Projekt, einschließlich des phasenweisen Arbeitsablaufs, erkunden möchten, finden Sie den vollständigen Code im GitHub-Repository.
Haben Sie eine Frage oder möchten Sie etwas mitteilen? Beteiligen Sie sich am Gespräch auf dem Vonage Community Slackund bleiben Sie auf dem Laufenden mit dem Entwickler-Newsletter, folgen Sie uns auf X (früher Twitter), abonnieren Sie unseren YouTube-Kanal für Video-Tutorials, und folgen Sie der Vonage Entwickler-Seite auf LinkedInein Raum für Entwickler, um zu lernen und sich mit der Community zu vernetzen. Bleiben Sie in Verbindung, teilen Sie Ihre Fortschritte und halten Sie sich über die neuesten Nachrichten, Tipps und Veranstaltungen für Entwickler auf dem Laufenden!
Teilen Sie:
Benjamin Aronov ist ein Entwickler-Befürworter bei Vonage. Er ist ein bewährter Community Builder mit einem Hintergrund in Ruby on Rails. Benjamin genießt die Strände von Tel Aviv, das er sein Zuhause nennt. Von Tel Aviv aus kann er einige der besten Startup-Gründer der Welt treffen und von ihnen lernen. Außerhalb der Tech-Branche reist Benjamin gerne um die Welt auf der Suche nach dem perfekten Pain au Chocolat.
