Zum Inhalt springen
im Trend

Anleitungen

Ticket-Routing mit Strands Decider 2B: Python-Anleitung

Ticket-Routing mit KI: So klassifizieren Sie Kundenanfragen mit dem lokalen Modell Strands Decider 2B in Python zuverlässig nach Abteilung und Dringlichkeit.

Text: 8 Min. Lesezeit
Ticket-Routing mit Strands Decider 2B: Python-Anleitung

👁 113 Aufrufe

Ein Entscheidungsmodell eignet sich für das Routing von Support-Tickets oft besser als ein Chat-LLM: Es wählt eine Abteilung aus Ihrer festen Liste, liefert einen mathematischen Konfidenzwert und ermöglicht es, unsichere Fälle automatisch an menschliche Mitarbeiter zu eskalieren. Nachfolgend zeigen wir ein funktionierendes Python-Skript auf Basis des offenen Modells Strands Decider 2B, das wir auf unserem Rechner getestet haben - inklusive Testergebnissen und zwei typischen Fallstricken. Was Entscheidungsmodelle genau sind und wie sie in unserem Benchmark mit 30 Support-Tickets abgeschnitten haben, lesen Sie in unserem Leitfaden Entscheidungsmodelle im KI-Einsatz.

Die EUR-Beträge sind unverbindliche Umrechnungen der veröffentlichten USD-Preise zum EZB-Referenzkurs vom 2026-10-12: 1 EUR = 1.1181 USD. Es handelt sich nicht um bestätigte örtliche Endpreise einschließlich Steuern. Anbieter und Bank können andere Kurse oder Gebühren berechnen. ECB.

Was wir bauen

Ein Skript, das für jedes eingehende Ticket folgende Werte ermittelt:

  • Abteilung - eine von sechs Kategorien (Zahlung, Versand, Retoure, Konto, Störung, Vertrieb) oder „Sonstiges“,
  • Konfidenz - die Sicherheit der Auswahl als Wert zwischen 0 und 1,
  • Queue - die zuständige Fachabteilung bei ausreichender Konfidenz oder an_mitarbeiter,
  • Dringlichkeit - ob das Anliegen noch am selben Tag bearbeitet werden muss.

Das Ergebnis ist eine saubere JSON-Zeile pro Ticket, die sich direkt in ein Helpdesk-System, Tabellenkalkulationen oder bestehende KI-Automatisierungen einspeisen lässt.

Voraussetzungen

  • Python 3.10 oder neuer.
  • PyTorch - idealerweise mit CUDA-Unterstützung, falls Sie eine NVIDIA-Grafikkarte nutzen (das Modell belegt knapp 4 GB VRAM). Ohne dedizierte GPU läuft es auch auf der CPU, allerdings spürbar langsamer.
  • Das Paket strands-decider (Apache-2.0). Beim ersten Start lädt es ca. 4,4 GB herunter: das Basismodell Qwen3.5-2B-Base sowie den Adapter von AWS.
pip install strands-decider

Unter Windows neigt der Paketmanager pip mitunter dazu, eine bestehende PyTorch-Installation durch eine reine CPU-Version zu ersetzen. Prüfen Sie dies mit dem Befehl python -c "import torch; print(torch.cuda.is_available())". Gibt dieser False zurück, installieren Sie PyTorch direkt über die Befehle von pytorch.org passend zu Ihrer CUDA-Version nach. Genau dieser Fall trat bei unserem Testsystem auf.

Das Skript routing.py

# Ticket-Routing mit dem Entscheidungsmodell Strands Decider 2B (lokal, Apache-2.0).
# pip install strands-decider (plus PyTorch mit CUDA bei NVIDIA-Grafikkarte)
import json, sys
from strands_decider.infer import load_engine
from strands_decider.schema import SystemOneRequest

MODEL = "StrandsAgents/strands-decider-2B-hobson-v19"
DZIALY = {
    "platnosci": "Płatności, faktury, obciążenia karty, abonament",
    "dostawa": "Wysyłka, kurier, śledzenie paczki, adres dostawy",
    "zwrot": "Zwroty towaru, reklamacje, wymiana, uszkodzony produkt",
    "konto": "Logowanie, hasło, dane konta, bezpieczeństwo konta, RODO",
    "awaria": "Błędy aplikacji lub strony, awarie, integracje, wydajność",
    "sprzedaz": "Pytania o ofertę, plany, rabaty, wdrożenia dla firm",
    "inne": "Z treści nie da się ustalić, czego dotyczy zgłoszenie",
}
SCHWELLE_ABTEILUNG = 0.60   # Unter diesem Wert geht das Ticket an einen Mitarbeiter
SCHWELLE_DRINGEND = 0.40    # Empirischer Schwellenwert aus unserem Testset

engine = load_engine(MODEL, device="cuda")  # "cpu" funktioniert ebenfalls, nur langsamer

def klassifizieren(text: str) -> dict:
    anfrage = SystemOneRequest(state=text, questions={
        "dzial": {"type": "choice", "instructions": "Do którego działu trafia to zgłoszenie?", "criteria": DZIALY},
        "pilne": {"type": "noul", "instructions": "Czy zgłoszenie wymaga reakcji jeszcze dziś (awaria, utrata pieniędzy, włamanie, nieprzekraczalny termin)?"},
    })
    antwort = engine.evaluate(anfrage).answers
    abteilung, konfidenz, p_dringend = antwort["dzial"].choice, antwort["dzial"].confidence, antwort["pilne"].noul
    queue = abteilung if konfidenz >= SCHWELLE_ABTEILUNG and abteilung != "inne" else "an_mitarbeiter"
    return {"queue": queue, "abteilung": abteilung, "konfidenz": round(konfidenz, 2),
            "dringend": p_dringend >= SCHWELLE_DRINGEND, "p_dringend": round(p_dringend, 2)}

if __name__ == "__main__":
    for zeile in sys.stdin:
        if zeile.strip():
            print(json.dumps({"text": zeile.strip()[:60], **klassifizieren(zeile)}, ensure_ascii=False))

Wir haben diesen Test mit polnischsprachigen Tickets und Kriterien durchgeführt. Die im Code definierten Anweisungen und Kategorien bedeuten auf Deutsch:

  • Do którego działu trafia to zgłoszenie? = „Welcher Abteilung ist dieses Ticket zuzuordnen?“
  • Czy zgłoszenie wymaga reakcji jeszcze dziś (awaria, utrata pieniędzy, włamanie, nieprzekraczalny termin)? = „Erfordert das Ticket eine Reaktion noch heute (Systemausfall, Geldverlust, Einbruch/Sicherheitsvorfall, unaufschiebbare Frist)?“
  • Die Kriterienkataloge der Abteilungen: platnosci (Zahlungen, Rechnungen, Kartengebühren, Abos), dostawa (Versand, Kurier, Tracking, Lieferadresse), zwrot (Retouren, Reklamationen, Umtausch, defekte Ware), konto (Login, Passwort, Kontodaten, Sicherheit, DSGVO), awaria (Softwarefehler, Systemausfälle, Schnittstellen, Performance), sprzedaz (Angebote, Tarife, Rabatte, B2B-Projekte), inne (Aus dem Inhalt lässt sich kein Thema eindeutig feststellen).

Einige architektonische Entscheidungen dahinter:

  • Zwei Fragen in einer Anfrage: Das Modell verarbeitet den Ticket-Text nur ein einziges Mal. Nachfolgende Fragen erzeugen kaum Zusatzaufwand - eine dritte Klassifizierung (wie etwa „Droht der Kunde mit Kündigung?“) verlängert die Berechnungszeit kaum.
  • Entscheidungslogik im Code, nicht im Modell: Das neuronale Netz liefert ausschliesslich Wahrscheinlichkeitswerte. Die Schwellen und Routingregeln steuern Sie im Python-Code, wodurch Anpassungen ohne Re-Training oder Prompt-Bastelei möglich sind.

Ausführung und Testergebnisse

Die Tickets werden zeilenweise über die Standardeingabe übergeben:

python routing.py < tickets.txt

Hier sind die Ergebnisse auf einer RTX 4090 für sechs reale Tickets, die das Modell zuvor nicht im Trainingsset hatte:

Ticket (Originaltext und Übersetzung) Ohne Option „Sonstiges“ Mit Option „Sonstiges“
Od rana nie działa logowanie przez Google, cały zespół stoi. (Seit heute Morgen funktioniert der Google-Login nicht, das ganze Team steht still.) konto 0,54 - an Mitarbeiter, dringend konto 0,46 - an Mitarbeiter, dringend
Proszę o fakturę VAT na firmę do zamówienia 77120. (Bitte um eine Firmen-Umsatzsteuerrechnung für Bestellung 77120.) platnosci 0,46 - an Mitarbeiter inne 0,63 - an Mitarbeiter
Paczka wróciła do nadawcy, bo kurier nie mógł znaleźć adresu. (Das Paket ging an den Absender zurück, weil der Bote die Adresse nicht finden konnte.) dostawa 0,96 dostawa 0,90
Czy macie zniżki dla szkół i uczelni? (Gibt es Rabatte für Schulen und Universitäten?) sprzedaz 0,58 - an Mitarbeiter sprzedaz 0,31 - an Mitarbeiter
Hej, mam pytanie. Coś mi nie gra. (Hey, ich habe eine Frage. Irgendwas stimmt bei mir nicht.) awaria 0,80 awaria 0,41 - an Mitarbeiter
Zwracam kurtkę, ale nie wiem, czy zwrot pójdzie na kartę czy na konto. (Ich schicke die Jacke zurück, weiß aber nicht, ob die Erstattung auf die Karte oder aufs Konto geht.) zwrot 0,94 zwrot 0,84

Eine einzelne Inferenz dauerte auf der Grafikkarte rund 135 ms, das initiale Laden des Modells benötigte 16 Sekunden. Alle Tickets, die das System automatisiert weiterleitete, landeten in der korrekten Zielabteilung. Als dringend wurde ausschliesslich der vollständige Ausfall des Google-Logins eingestuft - exakt das gewünschte Verhalten.

Fallstrick 1: Hohe Scheinsicherheit bei inhaltsleeren Tickets

In unserer ersten Testversion existierte keine Auffang-Kategorie wie „Sonstiges“. Die vage Nachricht Hej, mam pytanie. Coś mi nie gra. ordnete das Modell prompterweise der Störungsabteilung (awaria) mit einer Konfidenz von 0,80 zu. Da dieser Wert über der Schwelle lag, wäre das Ticket ungeprüft beim Support-Team für Softwarefehler gelandet. Das ist kein Defekt des Modells: Wenn wir es zwingen, aus sechs Abteilungen zu wählen, müssen sich die Wahrscheinlichkeiten mathematisch zu 1 aufsummieren. Ein Entscheidungsmodell kann nicht von sich aus „Ich weiss es nicht“ sagen, solange ihm keine entsprechende Option bereitgestellt wird.

Die Lösung: Die zusätzliche Option inne („Sonstiges“) mit der Definition „Aus dem Inhalt lässt sich kein Thema eindeutig feststellen“ in Verbindung mit einer Programmregel, dass dieser Wert grundsätzlich an einen Menschen übergeben wird. Mit dieser Anpassung fiel der Score der leeren Anfrage auf 0,41 und wurde korrekt zur manuellen Triage weitergeleitet.

Fallstrick 2: Die „Sonstiges“-Option mindert die Konfidenz

Diese Absicherung hat jedoch eine Nebenwirkung: Die Wahrscheinlichkeitsmasse verteilt sich neu, wodurch die Konfidenzwerte auch bei eindeutigen Tickets leicht absinken (beim Paketproblem von 0,96 auf 0,90, bei der Retoure von 0,94 auf 0,84). Die Anfrage nach der Rechnung wurde sogar fälschlicherweise als „Sonstiges“ eingestuft statt bei der Rechnungsabteilung zu landen. So steuern Sie dagegen:

  • Vokabular Ihrer Kunden abbilden: Wenn Begriffe wie „Umsatzsteuerrechnung“ bei „Sonstiges“ landen, ergänzen Sie die Kriterienbeschreibung der Zahlungsabteilung explizit um Schlagworte wie „Rechnung, USt-Rechnung, Rechnungskorrektur“.
  • Schwellenwerte an eigenen Daten eichen: Nutzen Sie 50 bis 100 manuell geprüfte historische Anfragen aus Ihrem System, lassen Sie das Skript darüberlaufen und ermitteln Sie den optimalen Trennwert. Unsere Konfidenzschwelle von 0,60 ist ein praktischer Ausgangspunkt, aber kein Gesetz.
  • Eskalationsquote überwachen: Steigt der Anteil der an Mitarbeiter weitergeleiteten Tickets über 30 bis 40 %, sind die Kriterienbeschreibungen entweder zu unspezifisch formuliert oder die Abteilungszuständigkeiten überschneiden sich zu stark.

Dringlichkeit: Auch hier Schwellen kalibrieren

In unserem Test mit 30 Tickets wies Strands Decider dringenden Fällen Wahrscheinlichkeitswerte zwischen 0,22 und 0,47 zu. Bei einem theoretischen Standard-Grenzwert von 0,50 wäre kein einziger Fall als dringend erkannt worden - daher haben wir im Code den Grenzwert 0,40 gewählt. Das grössere Modell Clef-flash von Cloudflare zeigte genau das gegenteilige Verhalten und funktionierte erst ab einem Grenzwert von 0,95 verlässlich. Die Grundregel lautet: Behandeln Sie die Rohwerte des Modells als Ranking und legen Sie die Entscheidungsgrenze anhand eigener Testdaten fest.

Wechsel auf alternative Entscheidungsmodelle

Strands Decider, Cloudflare Clef sowie Kev und Jev von TypeSafe setzen auf dieselbe standardisierte Abfragestruktur (System One: state + questions). Das Skript lässt sich daher mit minimalen Anpassungen am Aufruf auf andere Engines umstellen:

  • Clef-flash lokal (GPU mit 24 GB VRAM erforderlich): Aufrufbar über die Funktion systemone() aus der Datei joint_schema_model.py im Repository Cloudflare/clef-flash. In unserem Test arbeitete das Modell mit 112 ms minimal schneller und traf Entscheidungen noch präziser, belegt aber knapp 18 GB Grafikspeicher. Details zu den Hintergründen erläutern wir im Bericht zu Cloudflare Clef.
  • Workers AI: Per POST an den Endpunkt /ai/run/@cf/cloudflare/clef-flash mit identischem JSON-Payload. Die Kosten liegen bei 0,0805 EUR (0,09 USD) pro Million Input-Token, flankiert von einem kostenlosen täglichen Kontingent (Cloudflare-Konto vorausgesetzt).
  • Strands HTTP-Server: Starten Sie den Service via strands-decider serve ... --port 8000 und senden Sie Anfragen an /v1/systemone. Das Skript muss das Modell in diesem Fall nicht selbst im Arbeitsspeicher vorhalten.

Ausführlichere Informationen zur Architektur, Lizenzierung und Performance finden Sie in unserem Testbericht zu Strands Decider 2B.

Wann sich ein Entscheidungsmodell nicht empfiehlt

  • Wenn das System direkt eine formulierte Kundenantwort ausgeben soll - dafür ist zwingend ein generatives Sprachmodell erforderlich. Das Entscheidungsmodell kann jedoch vorab determinieren, welche Textvorlage verwendet wird.
  • Bei einem sehr geringen Volumen von wenigen Tickets pro Tag - hier ist eine JSON-Generierung über grosse Chat-Modelle oft unkomplizierter einzurichten (siehe dazu unsere Hinweise zu Structured Output).
  • Wenn sich Abteilungsstrukturen wöchentlich ändern und keine historischen Ticketdaten für die Eichung vorliegen - in diesem Fall lassen sich kaum verlässliche Konfidenzgrenzen bestimmen.
Google · Deine QuellenWissnox höher in Ihrem Google - mit einem KlickZu bevorzugten Quellen hinzufügen →

Quellen

Kinetyra

// read next

More on this from WISSNOX

Wissnox

Wissnox

ADMINISTRATOR
weiterlesenKI-Filmmusik: Eleven Music, Stable Audio oder Suno?ki-werkzeugeKI-Filmmusik: Eleven Music, Stable Audio oder Suno?Welche KI eignet sich am besten für Filmmusik und Video-Hintergründe? Eleven Music, Stable Audio 3 und Suno im Vergleich: Lizenzen, Kosten und Prompts.

Meistgelesen

  1. 1100.000 Qubits statt einer Million: Wie nah ist der Quanten-Codeknacker wirklich?
  2. 2Die partielle Mondfinsternis im August 2026: Warum 96 % kein „Blutmond“ sind - und gerade deshalb faszinieren
  3. 3Seedance 2.5 im Test: 8 Video-Beispiele mit Prompts
// Sitemap

Diese Seite in anderen Sprachen6

wissnox in Zahlen 0Texte im Archiv0News der letzten 7 Tage0Videomodelle im Observatorium
🎬 KI-Video Empfehlung: Higgsfield AI DoP Kamera-Presets & Rechner • Higgsfield AI 50% Gutschein • Higgsfield vs Kling AI
× ‹ Vergrößerung ›