# Wie ein Tech Lead ein Beschaffungssystem in Telegram ohne Code zu schreiben aufbaute: Eine Fallstudie zu agentischer Entwicklung
Als die interne Beschaffung im Team im Chaos versank mit verlorenen Anfragen und unkoordinierten Abfragen, entschied sich der Tech Lead, ein System auf Basis von Telegram zu erstellen. Ohne eine einzige Zeile Code zu schreiben, unter Verwendung agentischer Systeme und einer klaren Architektur, baute er eine Lösung mit OCR, Moderation und sicherer Bereitstellung. So geht das, ohne die Kontrolle über die Qualität zu verlieren.
Problem: Chaos statt Beschaffungsprozess
In kleinen Teams beginnt die Beschaffung oft mit informellen Absprachen. Zuerst kommen Zettelwischereien, dann Notizen, dann ein dedizierter Telegram-Thread. Ein Prozess entsteht: Link, Preis, Menge und Begründung einwerfen. Aber in der Praxis gehen manche Anfragen unter, andere rutschen durch, manche fehlen Preis oder Begründung, und die Leute vergessen ihre eigenen Anfragen. Am Ende verbringt der Tech Lead Zeit damit, gegen das Chaos anzukämpfen, statt die Beschaffung zu managen. Wichtige Erkenntnis: Wenn ein Prozess Geld beinhaltet, sollte er nicht als freies Geplänkel existieren.
Infrastrukturanforderungen: Vom "Kleinen Bot" zum Vollwertigen System
Die anfängliche Idee – ein simpler Telegram-Bot – lief schnell in Infrastrukturprobleme. Aufgrund der Instabilität von Telegram ohne VPN brauchte es:
- Ausländischen VPS
- Eigenen VPN-Aufbau
- Zuverlässigen Auto-Restart
- Bequeme Bereitstellung
- Rollback-Mechanismus für fehlgeschlagene Releases
Das ist kein "schnelles Abend-Skript" mehr, sondern eine vollständige Engineering-Pipeline. Erfahrung zeigt: "Einfache Automatisierung" verbirgt oft komplexe Infrastruktur darunter.
Agentische Entwicklung: Beschleuniger, kein Ersatz für Denken
Das Projekt wurde mit ChatGPT und einem agentischen System umgesetzt, aber die aktive Beteiligung des Tech Leads war essenziell. Der Prozess umfasste:
- Formulierung der Aufgabe und Zuweisung von Rollen
- Klärung der Geschäftslogik
- Manuelles Testen von Szenarien
- Identifizierung von Widersprüchen und Bugs
- Iteration gezielter Korrekturen
- Retesten
Der Agent beschleunigte den Zyklus: Er verkürzte die Zeit zwischen Problemerkennung und Verifikation einer neuen Implementierung. Wichtige Erkenntnis: Syntax kannst du delegieren, aber Systemdenken und Architektur bleiben entscheidend. Ohne klares Prozessmodell beschleunigt der Agent nur die Umsetzung fehlerhafter Logik.
Abschied vom "Zauber": Wechsel zu einem Wizard-Flow
Die erste Hypothese – automatische Datenextraktion aus Links – erwies sich als undurchführbar wegen:
- Vielfalt der Seiten
- Instabilen Seitenstrukturen
- Mehrdeutigen Preisen
- Komplexer Datenrendering
- Feindlicher Marktplatz-Logik
Stattdessen wurde ein Wizard-Flow implementiert:
- Screenshot anhängen
- Link angeben
- Begründung schreiben
- Menge angeben
- Preis manuell eingeben, falls nötig (bei OCR-Fehlschlag)
- Finale Karte vor Bestätigung prüfen
Dieser Ansatz ist weniger "wow", sorgt aber für Steuerbarkeit – der Schlüsselfaktor für operative Prozesse.
Warum LLM nicht das Herz des Systems war
Obwohl verlockend, LLM für die Anfragenverarbeitung zu nutzen, wurde ein simpler Stack gewählt:
- Python
- Telegram-Bot-Framework
- SQLite
- Lokales OCR
- HTML-Berichte auf Vorlagen
- systemd für Services und Timer
Begründung:
- Läuft auf Low-Spec-VPS
- Keine Laufzeitabhängigkeit von externen APIs
- Keine kostenpflichtige Inferenz pro Anfrage
- Einfaches Debugging
- Vorhersehbares Verhalten
Diese Wahl unterstreicht ein Schlüsselprinzip: Nicht jede Aufgabe profitiert von KI. Manchmal liefern strenge FSM und Validierung mehr Wert als komplexe Modelle.
State Machine: Grundlage der Zuverlässigkeit
Eine Anfrage ist eine Entität mit Lebenszyklus inklusive Status:
- Entwurf
- Bild abwarten
- Link abwarten
- Begründung abwarten
- Bestätigung abwarten
- Moderation ausstehend
- Zur Überarbeitung zurück
- Auf nächsten Zeitraum verschoben
- Dringend
- Gesendet
FSM wurde genutzt, um diesen Zyklus zu managen. Code-Beispiel:
class PurchaseWizard(StatesGroup):
waiting_for_image = State()
waiting_for_link = State()
waiting_for_reason = State()
waiting_for_qty_lots = State()
waiting_for_lot_size = State()
waiting_for_manual_price = State()
waiting_for_confirmation = State()
und Domain-Status:
class PurchaseStatus(str, Enum):
DRAFT = "draft"
AWAITING_IMAGE = "awaiting_image"
AWAITING_LINK = "awaiting_link"
AWAITING_REASON = "awaiting_reason"
AWAITING_QTY = "awaiting_qty_lots"
AWAITING_CONFIRMATION = "awaiting_confirmation"
COMPLETE = "complete"
PENDING_MODERATION = "pending_moderation"
RETURNED_FOR_REVISION = "returned_for_revision"
APPROVED = "approved"
CANCELLED = "cancelled"
SENT = "sent"
Wenn Rollen, Geld und Fristen im Spiel sind, wechsle von Nachrichtenbehandlung zu Statusverwaltung.
Architektur: Einfachheit als Zeichen von Reife
Systemdiagramm:
Telegram user
↓
Bot handlers / FSM
↓
Purchase service
├── SQLite
├── OCR service
├── Moderation logic
├── HTML report builder
└── Reminder / maintenance jobs
↓
systemd service + timers
Projektstruktur:
purchase_bot/
├── app/
│ ├── bot/
│ ├── db/
│ ├── services/
│ ├── templates/
│ └── main.py
├── data/
│ ├── uploads/
│ ├── reports/
│ └── bot.db
├── scripts/
├── deploy/
└── README.md
Das Überspringen von Docker und schweren DBs in der ersten Version erlaubte Fokus auf Funktionalität. Für interne Tools ist einfache Architektur ein Zeichen von Reife, nicht Schwäche.
Telegram-UX: Oberfläche statt Nachrichtenstrom
Die Arbeit mit Telegram deckte Herausforderungen auf:
- Beharrliche alte Buttons
- Überlappende Karten
- Parallele alte und neue Anfragenversionen
- Verzögerte Benachrichtigungen
- Inkonsistentes "Zurück"-Button-Verhalten
- Bildschirm-Schleifen
- Chat-Wirrwarr
Lösung: Den Bot als bildschirmbasiertes Statussystem designen. Kernprinzipien:
- Einziger aktiver Bildschirm
- Löschen veralteter Nachrichten
- Sichere Handhabung alter Callback-Buttons
- Getrennte Regeln für Menüs, Benachrichtigungen und Arbeitskarten
Dieser Ansatz ist zwar nicht aufregend, gewährleistet aber tägliche Benutzbarkeit.
Reale Prozesse brechen Symmetrie
Die Umsetzung von Moderation, Dringend-Anfragen und Zeiträume-Verschiebungen zeigte: Reale Prozesse passen nicht zu sauberen Diagrammen. Zum Beispiel kann eine zweite Moderationsstufe unnötigen Reibung erzeugen, wenn die erste die Anfrage vollständig abdeckt. Die Logik musste für reale Bedürfnisse umgebaut werden, nicht für Diagramme. Tech Leads kennen dieses Muster: Wenn das Schema den Fluss behindert, breche das Schema.
Heimtückischste Bugs an Schichtgrenzen
Kritische Fehler entstanden nicht in Kernfunktionen, sondern an Schnittstellen. Zum Beispiel:
- "Bestätigen"-Button hängte wegen Zeitzonen-bewusstem vs. -naivem Objektvergleich
- Datenformat-Ungleichheiten zwischen Modulen
- Status-Sync-Probleme bei Updates
Diese Bugs unterstreichen die Wichtigkeit sorgfältigen Interface-Designs von Komponenten.
Wichtige Erkenntnisse
- Architektur vor Agents: Auch mit agentischen Systemen sind klare Architektur und Systemdenken obligatorisch. Agents beschleunigen die Umsetzung, ersetzen aber kein Design.
- Steuerbarkeit vor "Klugheit": Für operative Prozesse siegen Zuverlässigkeit und Einfachheit über komplexe Automatisierung. Wizard-Flows schlagen oft volle Automatisierungsversuche.
- Status, keine Nachrichten: Bei Rollen, Geld und Fristen als gemanagten Lebenszyklus mit expliziten Status designen.
- Einfachheit als Strategie: Für interne Tools Over-Engineering vermeiden. Minimaler Stack auf bescheidener Hardware gewährleistet Zuverlässigkeit und einfache Wartung.
- Telegram-UX erfordert Disziplin: Bots als Bildschirmsysteme designen, nicht als Nachrichtenströme. Löschen veralteter Elemente und ein einzelner Bildschirm sind entscheidend für die User Experience.
— Editorial Team
Noch keine Kommentare.