Frontdesk Agent

Panoramica
Un receptionist multilingue per i messaggi di una clinica e di un negozio: un unico motore Python con adattatori per Instagram e WhatsApp che risponde da informazioni approvate, prenota appuntamenti e passa la conversazione allo staff, senza mai inventare un prezzo, un orario libero o un consiglio medico.
Stack
Python, Pydantic AI, Gemini su Vertex AI (UE), Postgres con pgvector, Cloud Tasks, cal.com, Google Calendar, API di Instagram e WhatsApp, Hypothesis
Cosa ho realizzato
- Regole di sicurezza che girano prima di qualsiasi chiamata al modello: emergenze, richieste di consigli medici e dati personali ricevono risposte fisse e approvate.
- Fatti scritti dal codice: prezzi, orari, medici e stato degli ordini vengono da record approvati, e ogni numero, orario e link in una risposta deve risalire a un fatto, al risultato di un tool o alla conversazione.
- Le risposte dai documenti portano la prova: ogni affermazione è una frase, l'ID di un passaggio e una citazione parola per parola, e il codice verifica la corrispondenza esatta, i numeri, i prezzi, le negazioni e la vicinanza semantica.
- Retrieval ibrido, full-text e pgvector fusi con Reciprocal Rank Fusion, su una conoscenza versionata che passa da bozza ad approvata ad attiva e può tornare indietro.
- Un'inbox su Postgres per entrambi i canali: ogni messaggio salvato una sola volta, un turno per conversazione sotto lease, e ogni risposta registrata prima dell'invio e inviata al massimo una volta.
- Un gateway dei modelli con percorsi approvati per classe di dati, un tetto di spesa giornaliero, una richiesta duplicata quando una chiamata si blocca e il ripiego su un secondo modello.
- Prenotazioni tramite cal.com e Google Calendar. Su WhatsApp lo staff approva una richiesta di prenotazione con un solo tocco.
- 4.155 test con il 97% di copertura dei rami, property test compresi, con regole sugli import, eval offline e un controllo del container in CI.
Scelte chiave
- I fatti li decide il codice. Un modello che scrive e viene controllato dopo può comunque citare il prezzo sbagliato, quindi il modello guida la conversazione e il codice fornisce ogni numero.
- Un'inbox su Postgres invece di Temporal: Temporal Cloud costerebbe circa 100 dollari al mese, mentre il modello costa meno di 0,001 euro a messaggio nelle valutazioni live, e i canali hanno bisogno di scadenze, non di timer.
- Scelte fatte misurando, con l'asticella fissata in anticipo: un embedder in hosting doveva battere quello locale di 10 punti di recall@3, ne ha guadagnati solo 2,8, e il modello locale è rimasto.
- Eval dal vivo su attività demo: superati 55 casi su 56 per la clinica e 23 su 23 per il negozio, nessuna emergenza mancata e nessun fatto inventato passato, con una latenza p95 tra 1,6 e 2,2 secondi.
- Codice e configurazione dei clienti restano separati: un deployment per attività, e tutti i dati nel repository sono sintetici.
Prossimi passi
A seguire: mettere in produzione i canali WhatsApp e Instagram, poi un rilascio limitato alle FAQ e un'estensione graduale.