Vor drei Tagen hat Proton den AI-Assistenten Lumo vorgestellt. Und heute hatte ich mein Handy mit dem 2-Step-Authentication-Knickknack und das iPad mit der Lumo-App zur gleichen Zeit zur Hand und ich konnte mich in der App endlich mal mit meinem Proton-Account anmelden. Ohne Login geht’s allerdings auch.
Ein Merkmal des Assistenten ist der sensible Umgang mit der Privatsphäre, mit dem Proton doch so gern kokettiert. Der Service ist frei nutzbar, aber um unbegrenzt chatten zu können, kostet der Spaß 12,99 €/Monat oder 119,99 €/Jahr. Nun ja, da ich jetzt schon nicht wusste, mit welchem Anliegen ich den Assistenten behelligen sollte, muss ich mir um Unlimited wohl kaum Gedanken machen.
Und? Funktioniert's? – Ja, so weit, so knöchern. Kann sogar ein bisschen programmieren. Ich habe mal eine recht einfache Frage gestellt und dazu Code geliefert bekommen, auf den man aufbauen kann.
Zeige mir einen Shopware-CartProcessor, mit dessen Hilfe der Wert eines jeden promotion line items auf product line items umgesetzt wird und anschließend die promotion line items entfernt.
Ein banaler Algorithmus (Umlage von Werten), gepaart mit ein wenig Fachkenntnis über Shopware (CartProcessort).
Ich habe mit Absicht eine Frage zu einem extrem stark verbreiteten, öffentlichen Projekt gestellt, um die Adaptionsfähigkeit des Assistenten bewerten zu können.
Und das war das Ergebnis:
class PromotionToProductCartProcessor implements CartProcessorInterface
{
private EntityRepositoryInterface $productRepository;
public function __construct(EntityRepositoryInterface $productRepository)
{
$this->productRepository = $productRepository;
}
public function process(Cart $cart, SalesChannelContext $context): void
{
// Find all promotion line items
$promotionItems = array_filter($cart->getLineItems()->getElements(), function (LineItem $item) {
return $item->getType() === LineItem::TYPE_PROMOTION;
});
foreach ($promotionItems as $promotionItem) {
// Get the promotion amount
$promotionAmount = $promotionItem->getPrice()->getTotalPrice();
// Find all product line items
$productItems = array_filter($cart->getLineItems()->getElements(), function (LineItem $item) {
return $item->getType() === LineItem::TYPE_PRODUCT;
});
// Calculate total product price
$totalProductPrice = 0;
foreach ($productItems as $productItem) {
$totalProductPrice += $productItem->getPrice()->getTotalPrice();
}
// Distribute promotion amount proportionally to product line items
foreach ($productItems as $productItem) {
$productPrice = $productItem->getPrice()->getTotalPrice();
$promotionShare = ($productPrice / $totalProductPrice) * $promotionAmount;
// Update product price
$newPrice = new CalculatedPrice(
$productItem->getPrice()->getUnitPrice() + $promotionShare,
$productItem->getPrice()->getUnitPrice() + $promotionShare,
$productItem->getPrice()->getRules(),
$productItem->getPrice()->getTaxRules()
);
$productItem->setPrice($newPrice);
}
// Remove promotion line item
$cart->remove($promotionItem->getId());
}
}
}
Ich werde keine Worte über den Code-Style (property promotion etc.) verlieren.
Der CartProcessor versucht folgendes Interface zu implementieren:
interface CartProcessorInterface
{
public function process(CartDataCollection $data, Cart $original, Cart $toCalculate, SalesChannelContext $context, CartBehavior $behavior): void;
}
Auf der positiven Seite:
- Der Assistent hat lobenswerterweise das richtige Interface implementiert, wenn auch falsch.
- Die Algorithmik ist grundsätzlich nicht falsch.
Auf der fatalen Seite:
- Die Implementierung des Interfaces ist falsch. Das kann man schnell von Hand lösen. Allerdings hätte ich von dem Assistenten einen Hinweis erwartet, der klarstellt, welcher der übergebenen Carts bearbeitet werden muss (
$toClaculte). Das sind die kleinen Dinge, an die ich von einem Assistenten erinnert werden möchte. $promotion = LineItemCollection::filterType(LineItem::PROMOTION_LINE_ITEM_TYPE);wäre die geschickte Alternative zu dem Quatsch unter „Find all promotion line items“ bzw. „Find all product line items“. Und auch noch falsche Konstantennamen.- Vielleicht fiel da ein wenig die PriceDefinition unter den Tisch!
- Quantity wurde auch nicht berücksichtigt.
- Kein Wort der Warnung, dass nicht jeder Discount mit jedem Produkt verrechenbar ist. Ich kann verstehen, dass die Implementierung nicht vorhanden ist, da nicht danach gefragt wurde. Aber ein Hinweis wäre angebracht gewesen.
Die Adaption eines einfachen Algorithmus an eine spezielle Umgebung – in diesem Fall Shopware – würde ich als ungenügend bezeichnen.
Ich habe den Chat noch etwas weitergeführt und auf die Probleme hingewiesen. Dem Ding Promotion Rules und das Matchen von Produkten zu entlocken, wurde dann etwas mühevoll und ich habe kapituliert.
Im Vergleich zu anderen AI-Assistenten?
Tatsächlich handelt es sich hierbei um ein praktisches Problem, das ich auch mal Chat GPT vor die Füße geworfen habe. Damals bin ich zu einer Lösung gekommen, die für den praktischen Einsatz noch markant nachgebessert werden muss. Aber mit zahlreichen Hinweisen hat ChatGPT es geschafft, lauffähigen Code zu erzeugen. Hätte ich auf das Matchen der Discount-Rules verzichtet, wäre auch Lumo nach einer Weile mit lauffähigem Code am Start gewesen. Wobei lauffähig natürlich nicht bedeutet, dass es auf einem Produktivsystem eingesetzt werden kann.
Fazit
Ja, nett, wenn man nach dem Wochentag fragt.
Spaß beiseite: Der Assistent ist gerade erst vorgestellt worden und die Produkte von Proton werden kontinuierlich weiterentwickelt. Erst die Tage habe ich mich gefreut, dass die CalendarApp endlich an das iPad angepasst wurde.
Hätte ich fairerweise nach einem reinen Algorithmus für PHP gefragt, der evtl. mit Symfony Collection hantiert, wäre die Lösung sicherlich ein bisschen „praxisnäher“ gewesen. Es ist sicherlich etwas gemein, so einen armen, jungen Assistenten aufs Glatteis zu führen und Spitzfindigkeiten wie den passenden Cart zur Bearbeitung auszuwählen oder die Regeln in einer Promotion zu berücksichtigen.
Je mehr AI-Chats ich ausprobiere, desto sicherer bin ich mir, dass ich mir in den letzten Jahren meiner Laufbahn im Bereich Softwareentwicklung keine Gedanken machen muss, dass ich meinen Job an ein AI-Entwicklungs-Dings verlieren könnte. Irgendwann wird sich das Blatt wenden. Da bin ich mir recht sicher. Aber ich bin 51 Jahre und dann bin ich in Rente. Allerdings würde ich mich freuen, wenn in der Zeit bis dahin AI-Assistenten so weit reifen würden, dass ich den generierten Code nicht mehr so häufig in die Tonne hauen muss, sondern nur noch ein bisschen refinieren muss, bis etwas Brauchbares herauskommt.