Vai al contenuto
megapromotingParliamone

Soluzioni · Trasporti e logistica

Quando il cliente chiede dove si trova il pacco, l'agente non indovina: chiama il courier, gli chiede e torna con la risposta.

Lo smistamento vocale, costruito come meccanismo, non come promessa: una tabella con stati espliciti, tre tentativi a due minuti di distanza, il risultato della chiamata scritto in modo strutturato e un filtro che estrae il numero del conducente da tutto ciò che arriva al modello, così che non possa essere dettato al cliente.

Già costruitoMecanismul de dispecerizare e scris și migrat în platforma noastră vocală: tabela `courier_calls` cu șapte stări posibile, trei încercări implicite, pauză de 120.000 ms între ele și rezultatul apelului păstrat structurat, plus cinci funcții de server care o folosesc — inițierea apelului către curier, verificarea rezultatului, mătura pentru apelurile rămase agățate, identificarea celui care sună înapoi și webhookul de după apel. A doua implementare e filtrul de ieșire scris pentru un client din transport, care elimină recursiv câmpurile de contact ale șoferului din rezultatul uneltei, păstrând numerele dispeceratului. Rezerva, spusă înainte să întrebi: partea de telefon trece printr-o gazdă SIP, iar gazda prin care merg liniile noastre de test nu răspunde la data scrierii — nu-ți dăm un număr de demonstrație pe care nu l-am putea ridica în fața ta.

In un'azienda di trasporto o di consegna, la maggior parte delle chiamate in arrivo è la stessa domanda posta da persone diverse: dove si trova la merce, a che ora arriva, perché non è arrivata. La risposta non è in un documento e non è in un sistema — è nella testa del conducente, che guida. Il dispatcher fa il collegamento: prende la chiamata del cliente, chiama il conducente, ritorna al cliente. Questo lavoro occupa un'intera persona e si fa cento volte al giorno, con le stesse tre frasi.

Abbiamo costruito esattamente questa catena, come meccanismo con stati, non come funzione di marketing. Un agente parla con il cliente. Quando ha bisogno di una risposta che non ha, chiama una funzione che avvia una seconda chiamata — verso il courier — collegata alla conversazione da cui è partita. Quella chiamata ha una propria riga in una tabella, con uno status che passa per `calling`, `in_progress`, `retrying`, `completed`, `failed`, `no_answer`, `timeout`, con il numero del tentativo, con un massimo di tre tentativi e una pausa di due minuti tra essi. Il risultato viene scritto in modo strutturato: il riepilogo di ciò che ha detto il courier, il tempo stimato, la posizione.

La parte che si dimentica facilmente e che noi trattiamo come un requisito, non come una precauzione: il numero di telefono del conducente non deve arrivare al cliente. Non è un'istruzione scritta nel prompt dell'agente, perché un'istruzione in un prompt può essere aggirata. È un filtro che percorre ricorsivamente il risultato dello strumento ed elimina i campi di contatto del conducente prima che quel risultato arrivi al modello — mantenendo i numeri dello smistamento. Ciò che è stato eliminato non può essere dettato, indipendentemente da come venga interrogato l'agente.

E il limite più importante è uno di infrastruttura, non di intelligenza: un agente vocale al telefono dipende da un host SIP tra il vostro operatore e la piattaforma. Quando quell'host cade, le chiamate non partono, e la firma del guasto è riconoscibile — richiesta scaduta, identificatore di chiamata vuoto, durata zero. L'host attraverso cui passano le nostre linee di test non risponde alla data di stesura di questa pagina. Sul web, il percorso vocale è verificabile oggi; al telefono, la prima fase di ogni lavoro è stabilire su quale host entrano i vostri numeri.

Cosa comprende

Cosa cambia concretamente nel trasporto e nella logistica

L'agente che parla con il cliente può avviare una seconda chiamata

Quando la risposta non è nell’informazione di cui dispone, l’agente chiama una funzione di server che chiama il courier. La chiamata verso il courier mantiene il collegamento con la conversazione da cui è partita, tramite un identificatore della conversazione-padre — quindi si sa sempre per chi è stata fatta la chiamata e perché. Il contesto dell’ordine viene trasmesso come struttura, dal suo sistema di comandi, non viene dettato.

La chiamata verso il courier ha stati, non solo «è stato chiamato»

Sette stati scritti come vincolo nel database: `calling`, `in_progress`, `retrying`, `completed`, `failed`, `no_answer`, `timeout`. Più il numero del tentativo corrente. La differenza tra «non ha risposto» e «il sistema è andato in crash» è visibile nei dati, non dedotta dai log — e questo conta quando domani qualcuno chiede perché il cliente non ha ricevuto una risposta.

I nuovi tentativi sono configurati, non improvvisati

Per impostazione predefinita: tre tentativi, con 120.000 millisecondi — due minuti — tra di essi, entrambi scritti come valori predefiniti nella tabella e nella configurazione del processo. Un autista che guida su una strada senza segnale non risponde al primo. Un sistema che chiama una sola volta e dichiara fallimento è inutile proprio nel caso per cui è stato costruito.

Il risultato della chiamata ritorna strutturato, non come racconto

Ciò che ha detto il courier viene scritto come riepilogo, tempo stimato e posizione, in un campo strutturato collegato alla riga della chiamata. Da lì può proseguire: verso l’agente che parla con il cliente, verso la centrale operativa, verso il suo sistema. Un webhook dopo la chiamata e una funzione di pulizia per le chiamate rimaste bloccate completano la catena, così che una chiamata persa non resti nello stato `calling` all’infinito.

Il numero dell’autista non può essere dettato, perché non arriva al modello

Il filtro di output percorre ricorsivamente il risultato dello strumento e rimuove i campi di contatto dell’autista, mantenendo i numeri della centrale operativa. È scritto nel codice, applicato puntualmente sull’integrazione dove appare il problema. Il motivo è semplice: l’interfaccia del fornitore restituiva i numeri degli autisti nella risposta, e la politica dell’azienda vietava che l’agente li desse ai clienti. Un’istruzione nel prompt si sarebbe potuta aggirare con una domanda ben formulata; un campo rimosso non si può aggirare.

Chi richiama viene riconosciuto dal numero

Il courier che richiama viene identificato da una funzione dedicata, quindi non entra nel flusso generale dei clienti e non gli viene letto il menu dall’inizio. Sembra un dettaglio; è la differenza tra un sistema che gli autisti usano e uno che aggirano chiamando direttamente la centrale, il che annulla tutto il lavoro.

Passaggio alla centrale operativa, a portata di chi parla

Trasferimento cieco tramite `##` e trasferimento assistito tramite `*2`, con contesto di atterraggio nel piano di chiamata che distingue le estensioni interne a quattro cifre dai numeri esterni. Quando il cliente chiede con insistenza una persona — e nel trasporto lo chiede, perché la sua merce è in ritardo — il trasferimento non deve passare attraverso un menu.

L’agente può essere interrotto, e questo si regola con numeri

Nel percorso OpenAI Realtime: rilevamento semantico del parlato con soglia 0,5, buffer di 300 ms, 500 ms di silenzio, interruzione consentita per impostazione predefinita. Nel percorso ElevenLabs, l’evento di interruzione viene trasmesso alla centrale per interrompere la riproduzione. `turn_timeout` viene impostato per ogni agente. In una chiamata di trasporto, dove l’interlocutore si trova spesso in una cabina rumorosa, queste soglie valgono metà della qualità percepita.

Cosa non fa un agente vocale nel trasporto

Non decide il percorso e non riottimizza le consegne. Non fornisce una tariffa se non è collegato alla fonte che la calcola. Non sa dove si trova la merce se nessuno glielo ha detto — né il courier, né il suo sistema. E non sostituisce la centrale operativa: prende le sue chiamate ripetitive e le lascia le eccezioni, che sono esattamente la parte per cui viene pagata.

Traseul

Come passa una richiesta attraverso il sistema.

01

Stabiliamo prima su quale host SIP entrano i suoi numeri

La prima fase non è lo сценарio dell’agente, ma la telefonia: tramite quale trunk entra il numero, chi lo controlla, cosa succede quando l’host non risponde. Forniamo una verifica scritta del percorso e, se il percorso non è sicuro, lo diciamo prima di costruire qualcosa sopra di esso. Un agente eccellente su un host che va in crash è un agente che non risponde.

02

Scriviamo lo scenario del dispacciamento, con le sue eccezioni

Che cosa chiede l’agente al corriere, in quale ordine, che cosa fa quando il corriere non risponde al terzo tentativo, che cosa succede quando la risposta è poco chiara, quando trasferisce al dispatcher umano. Consegnamo lo scenario scritto e l’elenco degli stati in cui può arrivare una chiamata — comprese quelle brutte.

03

Connettiamo la fonte degli ordini e applichiamo i filtri in uscita

Il contesto dell’ordine proviene dal vostro sistema, e prima che il risultato di uno strumento arrivi al modello passiamo attraverso l’elenco dei campi che non hanno il permesso di uscire. Consegnamo l’integrazione, l’elenco scritto dei campi filtrati e la prova che il filtro si applica al risultato, non alle istruzioni.

04

Eseguiamo su un volume ridotto, con i transcript letti da una persona

Partiamo su una parte delle chiamate, con il trasferimento al dispatcher configurato in modo ampio, e leggiamo i transcript. Da lì si regolano le soglie di interruzione, `turn_timeout`, la formulazione delle domande e la soglia a partire dalla quale l’agente rinuncia. Consegnamo il rapporto di queste chiamate, con le decisioni di regolazione, non solo l’agente avviato.

1Clientul întreabă2agentul cheamăfuncția de apel3apel către curier, custare proprie4până la treiîncercări, la douăminute5rezultat structurat(rezumat, timpestimat, poziție)6răspuns la client, cunumărul șoferuluifiltrat din drum
Traseul, în 6 pași

I dati

Cosa tocchiamo, dove risiedono e quanto rimangono

Le regole variano da un’industria all’altra. Queste sono quelle che si applicano a transport & logistică.

Il numero dell’autista è un dato personale di una persona, non un campo tecnico
Un corriere o un autista subappaltato è una persona fisica. Il suo numero, la sua posizione e la registrazione della sua voce sono i suoi dati. Per questo il filtro di uscita non è un capriccio di sicurezza, ma minimizzazione applicata alla sorgente: il campo non arriva al modello, quindi non può arrivare nella conversazione né nel transcript.
Che cosa si conserva di una chiamata
Il numero del chiamante e il numero chiamato, il momento, la durata, l’esito, la registrazione audio, il transcript e l’analisi post-chiamata. Per le chiamate non prese esistono numero, momento e motivo della mancata risposta — l’audio non esiste, perché non si è prodotto. Tutto è collegato allo spazio di lavoro della vostra azienda; non esiste un archivio comune tra clienti.
L’annuncio all’inizio della chiamata è una vostra decisione, non un’impostazione
Che l’interlocutore stia parlando con un sistema automatico, che la chiamata sia registrata e su quale base — si stabiliscono insieme a voi e entrano nello scenario, in entrambe le direzioni: sia verso il cliente, sia verso il corriere. Il corriere chiamato da un agente deve sapere con che cosa sta parlando tanto quanto il cliente.
La cancellazione su richiesta esiste; la cancellazione automatica alla scadenza ancora no
Lo diciamo così com’è, perché è la differenza tra una promessa e una funzione. La cancellazione su richiesta è implementata: una funzione dedicata elimina gli oggetti dall’archivio file, richiama la procedura di eliminazione dal database e invalida le sessioni. La retention configurabile per spazio di lavoro non è implementata — compare in un documento di progettazione, in nessuna migrazione. Fino a quando non lo sarà, la cancellazione a termine avviene tramite procedura.
Dove stanno i dati
PostgreSQL tramite Supabase su infrastruttura propria, con migrazioni versionate, di cui una parte attiva l’isolamento per riga. I file — registrazioni, documenti di conoscenza, campioni vocali — stanno in archivi separati, con il percorso che inizia con l’identificatore dello spazio di lavoro.

Un caso

Una chiamata che ha uno stato, non solo un esito

La situazione

In un flusso di consegna, la domanda „dove si trova il mio ordine” non ha risposta in nessun sistema: la risposta è dal corriere. La variante semplice — l’agente scrive al corriere un messaggio e spera — cade al primo corriere che guida e non guarda il telefono.

Cosa abbiamo costruito

Abbiamo costruito la dispatching come tabella, non come funzione. Ogni chiamata al corriere ha una riga con sette stati possibili, il numero del tentativo, massimo tre tentativi, una pausa di due minuti tra uno e l’altro e il risultato conservato in modo strutturato — riassunto, tempo stimato, posizione. La riga conserva il legame con la conversazione del cliente da cui è partita. Intorno alla tabella: la funzione che avvia la chiamata, quella che verifica il risultato, la routine per le chiamate rimaste appese, l’identificazione del corriere che richiama e il webhook dopo la chiamata.

Cosa è emerso

Si può rispondere, in qualsiasi momento e a partire dai dati, alle domande che una centrale operativa riceve ogni giorno: è stata effettuata la chiamata, quante volte, cosa ha risposto, perché non è stata effettuata la chiamata. Una chiamata persa non resta più bloccata in uno stato intermedio, perché c’è chi la spazza.

Cosa non dice il caso

Il meccanismo è scritto e migrato nella piattaforma; la parte telefonica dipende da un host SIP, e quella attraverso cui passano le nostre linee di test non risponde alla data di redazione. Non presentiamo il dispatching come qualcosa che si possa provare chiamando oggi un nostro numero.

Domande

Che cosa chiede chi lavora nel transport & logistică

L’agente chiama da solo il courier o gli invia solo un messaggio?

Chiama. Esiste una funzione server che avvia la chiamata al courier, legata alla conversazione da cui è partita, con il contesto dell’ordine trasmesso come struttura. La chiamata ha la propria riga in una tabella, con stato, numero di tentativo e risultato — quindi si può rispondere in qualsiasi momento alla domanda «è stato chiamato, e che cosa ha detto».

Che cosa succede se l’autista non risponde?

Si ritenta. Di default tre volte, a due minuti di distanza, valori scritti nella tabella e nella configurazione del processo. Se nemmeno alla terza volta risponde, la chiamata resta nello stato `no_answer` — uno stato distinto da `failed`, che significa che qualcosa è caduto da noi. Questa distinzione è il motivo per cui vale la pena usare una tabella, non un journal.

L’agente può dare al cliente il numero dell’autista?

No, e non perché gli abbiamo detto di non farlo. I campi di contatto dell’autista vengono rimossi ricorsivamente dal risultato dello strumento prima che quel risultato arrivi al modello. I numeri del centralino restano. Ciò che non arriva al modello non può essere dettato, per quanto abile sia formulata la domanda.

Può dire dov’è il pacco in questo momento?

Può dire che cosa gli ha detto il courier nell’ultima chiamata, con l’ora di quella chiamata, oppure che cosa legge dal vostro sistema se è collegato a esso. Quello che non fa — ed è una decisione, non una limitazione — è stimarlo da solo. Una stima inventata da un agente diventa una promessa che l’autista si prende sulla porta.

Posso chiamare ora un numero demo?

Non oggi. La parte telefonica passa attraverso un host SIP, e l’host attraverso cui passano le nostre linee di test non risponde alla data di redazione di questa pagina. Non mettiamo sul sito un numero che non potremmo alzare di fronte a voi. Il percorso vocale sul web è un’altra storia: lì si può verificare subito.

Parla russo con il cliente e romeno con il centralino?

La configurazione dell’agente supporta 32 lingue, e il romeno è la lingua predefinita di un nuovo agente. La lingua si imposta per agente, quindi l’agente che parla con il cliente e quello che chiama il courier possono essere configurati in modo diverso. Da sapere: per la sintesi vocale in lingue diverse dall’inglese, il modello predefinito è quello rapido, mentre la variante di qualità migliore è visibilmente più lenta — il compromesso si sceglie consapevolmente.

Che cosa succede quando il cliente lo interrompe?

Si ferma. Il rilevamento semantico della voce ha soglia 0,5, buffer di 300 ms e 500 ms di silenzio, e l’interruzione è consentita di default; sull’altro percorso, l’evento di interruzione viene trasmesso alla centrale per tagliare la riproduzione. Se un agente non può essere interrotto, non è un problema di tono, ma di configurazione — e di risposte troppo lunghe.

Per quanto tempo vengono conservate le registrazioni delle chiamate con gli autisti?

Stabili ciò che stabilisci, perché sei tu l’operatore dei dati. Ciò che devi sapere sullo stato attuale della piattaforma: la cancellazione su richiesta è implementata come funzione, mentre la cancellazione automatica a termine, configurabile per area di lavoro, non lo è — avviene tramite procedura. Preferiamo che tu lo sappia da noi, non da un audit.

Sostituisce il dispatcher?

No. Gli toglie la parte ripetitiva — la stessa domanda, la stessa chiamata, la stessa risposta — e gli lascia le eccezioni. Il passaggio a lui resta a un codice dalla tastiera, e nel trasporto le eccezioni sono frequenti: merce rifiutata, indirizzo sbagliato, cliente che non risponde. Lì serve una persona, ed è meglio che sia una persona che non abbia già risposto cento volte a «dov’è il pacco».

Cosa vorresti che funzionasse meglio?

Raccontaci il tuo processo. Insieme stabiliamo cosa vale la pena costruire, cosa possiamo collegare e come verifichiamo il risultato.

Parliamone