← Alle Beiträge

Rückblick, geschrieben nach dem Abschluss der Timeout- und Alarm-Tickets Anfang September.

Acht Monate MitJulia: was man lernt, wenn eine KI für Friseursalons ans Telefon geht

Seit Januar arbeite ich an Julia, der KI-Telefonistin von MitJulia (ehemals Friseurtelefon). Ein Zwischenstand mit Zahlen.

56 abgestürzte Aufrufe in 90 Tagen. Mit dieser Zahl hat letzte Woche ein Ticket angefangen, und sie beschreibt ganz gut, worum es in diesem Job geht.

Seit dem 7. Januar arbeite ich als freier Entwickler für MitJulia, früher Friseurtelefon. Remote, neben dem Studium, in einem kleinen Team. Das Produkt ist Julia, eine KI-Telefonistin für Friseur- und Beautysalons. Sie nimmt Anrufe an, versteht, was jemand will, schlägt Termine vor und bucht, verschiebt oder storniert direkt im Buchungssystem des Salons. Und sie sagt, dass sie eine KI ist. Im August waren über 70 Salons live.

So läuft ein Anruf, und so zeigt es auch die Demo auf dieser Seite, mit Beispieldaten. Twilio nimmt den Anruf an und gibt ihn an einen Sprachagenten bei ElevenLabs weiter, einen pro Salon. Der Agent hört zu, und wenn er etwas wissen oder tun muss, ruft er ein Werkzeug auf: Kundin nachschlagen, freie Termine holen, Preis und Dauer einer Leistung, Termin buchen oder stornieren. Jedes Werkzeug ist eine AWS-Lambda-Funktion. Die spricht über einen Treiber mit dem Buchungssystem des Salons, und weil jeder Anbieter anders funktioniert, hat jeder Treiber dieselben 13 Methoden. Im Dashboard des Salons steht der Termin danach im Kalender und der Anruf im Protokoll.

Live-Demo · Beispieldaten

Live-Anruf

Sa 19:42 · außerhalb der Öffnungszeiten

Sophie Stammkundin · erkannt 01:12

Julia hört zu

Init-Webhook · Kundin erkannt: Sophie

Hallo Sophie, hier ist Julia, die digitale Rezeptionistin vom Salon Beispiel. Wie kann ich dir helfen?

Hi! Ich bräuchte nächste Woche einen Termin, am liebsten Dienstag nach der Arbeit.

Gerne. Wieder Waschen, Schneiden und Föhnen bei Mia?

Ja, genau.

get-appointment-availabilities · Di · Mia → 2 Slots

Am Dienstag hätte Mia um 17:30 oder um 18:30 Uhr Zeit. Was passt dir besser?

18:30 passt super.

create-booking → appointment-booked

Erledigt. Dein Termin ist am Dienstag um 18:30 Uhr bei Mia. Bis dann!

Danke, tschüss!

Letzte 7 Tage

Umsatz

GesamtAußerhalb Öffnungszeiten 2.846 € 612 €

Buchungen

GesamtAußerhalb Öffnungszeiten 47 11

Anrufe

GesamtAußerhalb Öffnungszeiten 1299Σ 2:41h · Ø 75s 31

Buchungssystem · Dienstag

Julia bucht direkt in das Buchungssystem des Salons.

MiaJana 16:0016:3017:0017:3018:0018:3019:0019:30 FärbenSchnittSchnittSträhnenFärbenHochsteckfrisur

Anrufe

DatumUhrzeitDauerNameGrund des AnrufsErgebnis des AnrufsGebuchter Umsatz
Sa17:580:48Paul Änderung Termin verschoben–
Sa16:121:31Emma Weiterleitung Weitergeleitet–
Sa14:400:36Unbekannt Preis Auskunft gegeben–
Demo mit Beispieldaten
Ein Anruf im Salon, vom Klingeln bis zur Buchung: links Live-Transkript und Tool-Aufrufe, rechts das Salon-Dashboard. Wähle selbst einen freien Slot, während Julia Zeiten nennt.

Angefangen habe ich mit Tests. Ich habe einen Simulator neu gebaut, in dem ein Sprachmodell den anrufenden Kunden spielt und ein zweites Modell das Gespräch bewertet: richtig, vollständig, die richtigen Tools benutzt, natürlich. Dazu habe ich die bestehenden 67 Testfälle in 267 kleine, sich nicht überschneidende Tests zerlegt.

Im Sommer kam Belbo als weiteres Buchungssystem dazu. Ich habe einen Driver mit dem kompletten 13-Methoden-Interface geschrieben, rund 9.150 Zeilen, 2.497 Tests grün. Parallel hat ein Kollege eine eigene Belbo-Integration gebaut, die live ging. Am Ende habe ich beide Linien zusammengeführt. Nicht elegant, aber so ist das in einem kleinen Team. Dabei ist ein Datenvertrag mit acht Regeln entstanden, den jeder Buchungs-Driver erfüllen muss. Belbo hat drei davon verletzt.

Und jetzt die 56 Abstürze. Wenn ein Buchungssystem nicht antwortet, wartete unser Code bis zum Lambda-Limit von 30 Sekunden und brach dann ab. Für jemanden am Telefon heißt das: Stille. Jetzt gibt es ein Zeitbudget von 12 Sekunden. Danach kommt ein sauberer Fehler, den Julia dem Anrufer sagen kann. Dazu ein CloudWatch-Alarm, nachdem am 18. August ein Anbieter 68 Minuten ausgefallen war und wir das erst am Morgen gemerkt haben.

Mein Grundsatz bei all dem: im Zweifel durchlassen. Der neue Filter für eingehende Anrufe sperrt bekannte Nummern, aber bei jedem Fehler wird der Anruf durchgestellt. Lieber ein Spam-Anruf zu viel als ein Kunde, der nicht durchkommt.

Und noch etwas, das ich mir angewöhnt habe: Jedes Thema bekommt ein Issue, einen Branch und einen Ordner mit Belegen. Ich arbeite schnell und dokumentiere eher spät. So muss niemand rekonstruieren, wo ich aufgehört habe.

Was ich in diesen Monaten gelernt habe, und womit. Einen Sprachagenten testet man nicht wie eine Funktion. Man braucht simulierte Anrufer, ein Modell, das bewertet, und Testfälle, die sich nicht überschneiden, sonst weiß man bei einem roten Test nicht, was eigentlich kaputt ist. Fremde APIs bekommen einen Vertrag, den man ausführen kann, bevor man ihnen glaubt. Jeder Aufruf nach außen braucht ein Zeitbudget. Und vor einer Änderung schaue ich mir an, welche Salons sie überhaupt betrifft, statt zu raten.

Tools: TypeScript mit bun und Turbo in einem Monorepo, Vitest, AWS Lambda mit SAM, API Gateway, DynamoDB, S3 und CloudWatch, Twilio und ElevenLabs für die Telefonie, React 19 und Express 5 für den Simulator, Linear für die Issues und Claude Code beim Bauen.