Katalog in Echtzeit gelesen, ohne Schlüssel und ohne Plugin
Für WooCommerce verwenden wir Store API, die öffentliche Shop-Schnittstelle: `/wp-json/wc/store/v1/products`, 100 Produkte pro Seite, maximale Wartezeit 20 Sekunden, eine eigene Client-ID im Header und ausschließlich die Annahme des Codes 200. Die Anzahl der Seiten lesen wir aus dem Header `x-wp-totalpages`, und die Gesamtzahl der Produkte aus `x-wp-total` — wir paginieren nicht, bis es auffällt. Die erste Seite wird allein geholt, der Rest parallel, mit einer Obergrenze von 30 Seiten. Im Shop wird nichts installiert und uns werden keine Händler-Keys gegeben.
Der Preis korrekt übersetzt, und null als nicht veröffentlicht behandelt
Die Store API gibt den Preis als Zeichenkette in Mindesteinheiten zurück, plus die Anzahl der Dezimalstellen der Währung. Wir teilen durch zehn hoch diese Zahl, nicht fest durch 100 — sonst ist jede Währung mit einer anderen Anzahl von Dezimalstellen falsch, und niemand merkt es. Null wird zu `null`, und in der Antwort erscheint „Preis auf Anfrage — wird von Kolleg:innen bestätigt“, zusammen mit der expliziten Anweisung an den Agenten, nichts zu erfinden und die Bestätigung einer Kollegin oder eines Kollegen anzufordern. Der Preis geht gleichzeitig in zwei Formen hinaus: als fertig anzeigbarer Text für die Oberfläche und als Zahl für die Logik im Hintergrund.
Drei Werkzeuge, die der Agent aufrufen kann
In der Assistentenplattform ist der Katalog als drei eingebaute Werkzeuge exponiert — Suche nach Wörtern, Treffer auf ein Gerät oder einen Anwendungsfall, und Abruf eines Produkts nach Kennung. Der Agent sieht sie unter den Namen `catalog_cauta`, `catalog_potrivire` und `catalog_produs`, jeweils mit seinen deklarierten Parametern. Wenn die Plattform des Shops nicht die erwartete ist oder die Adresse fehlt, verweigert das Werkzeug ausdrücklich, statt eine leere Liste zurückzugeben, die als „wir haben das Produkt nicht“ interpretiert würde.
Bindewörter verderben das Ergebnis nicht
Die wörtliche Suche nach „Wasserfilter“ passt auf alles, was „de“ enthält. Im gelieferten Katalog-Endpunkt und in der Suche des Sprach-Widgets entfernen wir die Stoppwörter — `si`, `sau`, `de`, `din`, `la`, `cu`, `pe`, `in`, `pentru` — und wenn nach dem Entfernen nichts Nützliches übrig bleibt, greifen wir auf Wörter mit mehr als zwei Buchstaben zurück. Die Teilübereinstimmung hat einen Schwellenwert: Ein Produkt gelangt nur dann in die Ergebnisse, wenn es mindestens die Hälfte der verbleibenden Wörter erreicht.
Wenn der Shop keine Oberfläche hat, lesen wir die Seite
Nicht jeder Shop hat eine Store API. Für den Rest haben wir einen Extraktor, der die Listen-Seiten öffnet und ihre Produktkarten liest, mit im Code festgeschriebenem Budget: maximal 20 Listen-Seiten, 200 Produkte, 24 Detailseiten, 50.000 Zeichen HTML pro Seite, 5 Sekunden pro Anfrage und eine Frist von 45 Sekunden für den gesamten Vorgang. Er liest zuerst die strukturierten Produktdaten von der Seite, dann die Karten, dann die Sharing-Metadaten — in dieser Reihenfolge, weil die erste Quelle die ist, die der Shop absichtlich geschrieben hat.
Frische mit geschriebenen Grenzen, nicht mit Hoffnung
Der Katalog wird 10 Minuten pro Shop im Speicher gehalten, und gleichzeitige Anfragen für denselben Shop werden zu einer einzigen zusammengeführt, damit zehn Kund:innen, die im selben Moment fragen, nicht zehn Downloads erzeugen. Auf dem öffentlichen Katalogpunkt trägt die Antwort auch Cache-Anweisung für das Verteilungsnetz: 5 Minuten frisch, weitere 10 Minuten alt serviert, während im Hintergrund aktualisiert wird. Die Anzahl der zurückgegebenen Ergebnisse ist auf 20 begrenzt, mit dem Standardwert 6.
Bestellung, Warenkorb und Anbindung an das Verwaltungssystem
Der Warenkorb, das Absenden der Bestellung und die Übergabe an das Verwaltungssystem des Kunden sind getrennte Funktionen, kein Formular. Es gibt auch die Wiederherstellung verlassener Warenkörbe, die Bestellung per Gespräch und die Verfolgung des Bestellstatus, mit zwei geplanten Aufgaben, die alle 15 Minuten laufen — eine synchronisiert das Ergebnis der Bestellungen, die andere ergänzt die Status aus dem Verwaltungssystem über ein Fenster von zwei Tagen zurück und einen Tag voraus.
Zahlungen: was funktioniert und was nicht
Funktional und im Code: die MAIB-Oberfläche für Händler — Token, dann Zahlungsanfrage, mit den aus der Datenbank gelesenen Zugangsdaten jedes Shops und der explizit aktivierten Funktion — und Stripe, mit in Mindesteinheiten umgerechneter Summe und verbuchter Zahlung im Register. Was NICHT funktional ist, damit es keine Überraschungen gibt: Paynet, Netopia und mobilPay haben keine Implementierung, und der Code verweigert ausdrücklich, wenn sie angefordert werden. Der Moldindconbank-Pfad ist ein Gerüst, das ohne Zugangsdaten einen Fehler zurückgibt. Wir nehmen sie im Projekt als Arbeit, nicht als vorhandene Integration.
Der Agent erfindet nicht, wenn das Netzwerk ausfällt
Wenn die Abfrage des Shops fehlschlägt, gibt das Werkzeug keine leere Liste zurück — es gibt eine Nachricht zurück, die dem Agenten sagt, keine Antwort über den Katalog zu formulieren. Der Unterschied ist wichtig: Eine leere Liste wird zu „wir haben nichts“, und falsch gesagt „wir haben nichts“ kostet einen Auftrag ebenso sicher wie ein falscher Preis.