Prenotazione viaggi con AI agentica per TMC e OTA

La mossa senior per un agente di prenotazione non è un modello più intelligente. È togliere l'LLM dal flusso di controllo.

Abbiamo costruito un agente autonomo di prenotazione viaggi il cui flusso di controllo è Python deterministico. Il modello si limita ad analizzare la richiesta di viaggio e a formulare la risposta. Ogni passo di prenotazione registra un'azione compensativa, così quando una tariffa alberghiera scade dopo che il volo è già stato emesso, l'agente annulla il biglietto nella finestra di 24 ore e consegna al viaggiatore alternative oneste invece di abbandonarlo.

100%

Stato terminale coerente, per costruzione

Batch sintetico a seed fisso di 200 scenari, contro il 65% della baseline LLM-in-control

0 / 0

Viaggiatori abbandonati, prenotazioni inventate emerse

Stesso batch, contro 40 e 30 della baseline

$3.25

Spesa media di ricerca GDS per prenotazione

contro $7.57 della baseline; il GDS addebita per ricerca, Lufthansa ha alzato le commissioni il 1° gennaio 2026

Tutti gli scenari sono sintetici su un GDS e un CRS simulati; i codici aeroportuali e i nomi degli hotel sono fixture di forma reale, non inventario live né prenotazioni reali.

Metti un LLM al comando di una transazione e succedono due cose

Nessuna delle due è un fallimento di QI del modello. Entrambe sono già una classe di bug del 2026.

Abbandona i viaggiatori

L'agente emette il biglietto di un volo, il passo hotel fallisce, e senza logica di compensazione dice comunque "Tutto a posto." Qualcuno resta con un volo e nessuna camera. Un modello perfetto abbandona comunque un viaggiatore se nulla annulla il biglietto.

Fa emergere inventario che non esiste

Inventa un hotel plausibile e lo prenota. La struttura non è mai stata nel CRS. Nulla ha verificato prima che arrivasse al viaggiatore, perché in un ciclo di ragionamento il modello è insieme proponente e giudice.

Il motivo per cui un modello migliore non risolve questo è che i fallimenti sono eventi di infrastruttura e di utilizzo, indipendenti dalla qualità del modello. Una tariffa scade tra due chiamate API. Un hold viene rifiutato dopo che un biglietto è già stato emesso. Una tempesta di ricerche brucia il margine. Il ragionamento stocastico si compone contro questi eventi: dieci passi al 90 percento di affidabilità danno circa il 34 percento da un capo all'altro, e GPT-4 con ReAct completa itinerari reali di più giorni allo 0.6 percento (TravelPlanner, OSU NLP, arXiv 2402.01622). Non si esce dal fallimento stocastico composto a colpi di prompt.

E il deployer è responsabile di ogni dichiarazione che l'agente fa. In Moffatt v. Air Canada (BC Civil Resolution Tribunal, 14 febbraio 2024) la compagnia aerea è stata condannata a pagare $812.02 dopo che il suo chatbot aveva inventato una policy di tariffe per lutto, e l'argomento che l'AI fosse un'entità separata è stato respinto.

Come funziona: gli agenti consigliano, il codice decide

Il flusso di controllo è una macchina a stati Python costruita a mano di circa dieci nodi. L'LLM è confinato a due lavori foglia. Tutto ciò che sta in mezzo è deterministico.

input → extract (LLM leaf) → search → policy gate → verify gate → hold → ticket → hotel-book → commit

Extract, l'unico lavoro strutturato dell'LLM

Il modello analizza l'intento in linguaggio naturale in un oggetto tipizzato con Pydantic TripRequest (origin, destination, date, passengers, cabin, hotel). Quell'oggetto tipizzato è l'unico artefatto strutturato che l'LLM produce. È intercambiabile per provider tramite Pydantic AI e funziona completamente offline con uno stub deterministico quando non è presente alcuna chiave.

Policy compilata in codice

La policy aziendale vive come predicati Python puri: solo economy, un tetto tariffario di $600 per segmento, vettori preferiti (United, American, Delta), un tetto alberghiero di $350 a notte. Le opzioni fuori policy sono fisicamente non presentabili perché vengono filtrate prima di poter essere mostrate, non segnalate dopo. Le famiglie tariffarie sconosciute falliscono in sicurezza, trattate come sopra policy piuttosto che silenziosamente come economy. Senza un volo in-policy, l'agente fa escalation a una coda umana invece di bluffare.

Il gate di verifica

Ogni hotel è confermato rispetto al CRS tramite property_id. Una struttura che il modello inventa semplicemente non è nel CRS, quindi viene rifiutata e non viene mai mostrata, e la prenotazione raggiunge lo stato terminale abstained. Il gate rifiuta l'inventario non confermato; non chiede al modello di valutare il proprio output.

La Saga, la parte che la maggior parte delle demo salta

Ogni passo in avanti registra la propria azione inversa al momento dell'esecuzione. L'emissione del biglietto, per esempio, registra "void ticket, 24-hour window." In caso di fallimento al passo N, le compensazioni da N-1 fino a 1 girano in ordine inverso, e solo allora l'agente riferisce. È questo che separa una demo da un prodotto, perché è ciò che impedisce a un fallimento parziale di diventare un cliente abbandonato.

Il contatore dei costi GDS e la traccia di audit

Un contatore live traccia la spesa di ricerca GDS a $3.25 per segmento, perché le ricerche sono addebitate, non solo le prenotazioni. Una cache L2B e la ricerca differita la tengono piatta dove un agente speculativo ri-cerca e brucia margine. Ogni prenotazione scrive un log di eventi JSON append-only, esportabile come audit-<pnr>.json, che contiene il modello e la versione, la richiesta di viaggio tipizzata, ogni verdetto di nodo, ogni compensazione Saga, il flag di disclosure dell'EU AI Act Article 50, e lo stato terminale.

Cosa mostra la demo

Quattro pulsanti, affiancati a una vera baseline LLM-in-control sullo stesso scenario. Ogni screenshot sotto è catturato dall'app in esecuzione.

Una prenotazione normale, nodo per nodo

La demo che esegue una prenotazione normale ORD to SFO. A destra, la traccia della pipeline deterministica esegue ciascun nodo a turno, dall'estrazione dell'intento attraverso il gate di policy, la verifica CRS, gli hold, l'emissione del biglietto e il commit dell'hotel, terminando in un PNR confirmed con il contatore di spesa di ricerca GDS a $3.25. A sinistra, il pannello etichettato No Tools and No Verification risponde semplicemente che è tutto prenotato.

"ORD to SFO next Tuesday, one night downtown, company policy." La macchina a stati esegue ciascun nodo, conferma il Hyatt Regency SF rispetto al CRS tramite property_id, e il contatore di ricerca resta a $3.25 su una sola ricerca in cache. Stato terminale: confirmed, con un PNR.

Il gate di verifica rifiuta un hotel che non esiste

Il passo di verifica CRS contrassegnato come fallito. Il pannello di dettaglio indica che Tabacon Springs Eco-Lodge non è nel CRS ed è stato rifiutato, non mostrato. La scheda della struttura è timbrata REFUSED con la nota che il gate di verifica l'ha rifiutata e non è stata mostrata al viaggiatore.

La richiesta nominava una struttura fabbricata, "Tabacon Springs Eco-Lodge," un nome che fonde due resort reali e non ha property_id di proposito. Il gate non trova alcun match nel CRS e rifiuta di mostrarla. L'agente si astiene onestamente, "Non ho potuto confermare quella struttura," invece di inventarne una.

Il rollback della Saga, contro l'LLM al comando

La traccia della pipeline dopo che una tariffa alberghiera è scaduta dopo l'emissione del biglietto. Tre passi di compensazione Saga girano in inverso, e un banner indica che l'hold è scaduto prima del commit e il rollback della Saga sta compensando in inverso. La scheda risultato recita ROLLED BACK, TRAVELER SAFE, con una nota che il biglietto aereo è stato annullato senza addebito e vengono offerti hotel alternativi.

La tariffa alberghiera scade dopo che il volo è già stato emesso. Dal nostro lato scatta la Saga: annulla il biglietto nella finestra di 24 ore, rilascia gli hold, e risponde onestamente che il biglietto è stato annullato senza addebito con alternative allegate. Stato terminale: rolled back, traveler safe. La baseline nello stesso scenario lascia il biglietto emesso, non offre alcuna compensazione, ed emette un falso "Tutto a posto.", che è esattamente il precedente Air Canada in attesa di accadere.

Una traccia di audit esportabile

Il fondo della console che mostra il link Export Audit Trail (JSON), accanto al risultato rolled-back che spiega che la tariffa in hold è scaduta prima del commit, il biglietto è stato annullato senza addebito, e vengono offerti due hotel alternativi, con la spesa di ricerca GDS a $3.25.

Un clic esporta audit-<pnr>.json: il modello e la versione, la richiesta di viaggio tipizzata, ogni nodo e il suo verdetto deterministico, ogni compensazione Saga, il flag di disclosure dell'EU AI Act Article 50 (gli obblighi di trasparenza si applicano dal 2 agosto 2026), e lo stato terminale.

Il benchmark di 200 scenari

Il tabellone del benchmark su 200 prenotazioni sintetiche a seed fisso con identici fallimenti iniettati. Quattro riquadri confrontano l'agente deterministico con una baseline LLM semplice: 100 percento contro 65 percento di stato terminale coerente, 0 contro 40 viaggiatori abbandonati, 0 contro 30 prenotazioni inventate, e $3.25 contro $7.57 di spesa GDS media. Una tabella dei risultati elenca gli esiti per scenario, tra cui confirmed, rolled back, abstained, escalated, integrity breach e stranded.

Le stesse 200 prenotazioni sintetiche, un seed fisso (42), e gli stessi fallimenti di infrastruttura iniettati eseguiti su entrambe le architetture. Il mix di scenari è 50 percento happy, 20 percento hotel-fail-after-ticket, 15 percento hallucinated-entity e 15 percento search-storm. Le nostre garanzie tengono per costruzione; i fallimenti della baseline emergono dagli stessi dati.

Flusso di controllo deterministico versus un LLM nel loop

La baseline è un vero agente LLM-in-control in stile ReAct eseguito sugli stessi scenari, un ancoraggio onesto piuttosto che un uomo di paglia. I numeri sotto sono sul batch sintetico a seed fisso di 200 scenari (benchmark.py, seed 42, n=200).

Metrica Agente deterministico (nostro) Baseline (LLM-in-control)
Stato terminale coerente 100.0% 65.0%
Viaggiatori abbandonati 0 40
Prenotazioni inventate emerse 0 30
Spesa media di ricerca GDS per prenotazione $3.25 $7.57

Il 100 percento, lo 0 e lo 0 tengono per costruzione su questo batch sintetico a seed fisso, non come garanzia di produzione in un mondo aperto. La pretesa è stretta e duratura: una prenotazione parziale non viene mai mostrata come confirmed, e un viaggiatore non viene mai abbandonato. Il gap $3.25 contro $7.57 è un numero di margine che tiene a qualsiasi qualità di modello.

Cosa questa demo non fa

  • Non si collega a un GDS, CRS o NDC live. Il GDS e il CRS, l'emissione biglietti IATA e ARC, e il pagamento PCI sono stub e simulati. L'adapter delle fixture è l'integrazione V1; non c'è un account live Amadeus, Sabre o Duffel.
  • Non emette biglietti reali né muove denaro reale, e Veriprajna non è accreditata IATA o ARC. Biglietti e pagamento sono stub.
  • Gli scenari, i PNR, gli hotel e i viaggiatori sono sintetici. "Tabacon Springs Eco-Lodge" è una struttura deliberatamente fabbricata, una dimostrazione della modalità di fallimento. Hotel con nomi reali come Hyatt Regency SF sono inventario di fixture, non prenotazioni reali.
  • Non pretende di prenotare di più, a un costo inferiore o in modo più intelligente di un GDS o di un OTA, e non pretende zero allucinazioni dal modello. L'LLM continua a redigere l'intento; la garanzia è che il gate rifiuta l'inventario non confermato e la Saga ripulisce i fallimenti parziali.
  • Il motore è una macchina a stati Python costruita a mano, non LangGraph. LangGraph è nominato come swap-in di produzione differito. Le chiamate foglia LLM usano Pydantic AI.

Domande che fanno gli acquirenti

Posso fidarmi di un agente AI per prenotare viaggi senza abbandonare i miei viaggiatori?

La garanzia non viene dal fidarsi del modello. In questa demo il flusso di controllo è Python deterministico, e ogni passo in avanti registra un'azione compensativa nel momento in cui gira. Quando un passo fallisce dopo che un biglietto è stato emesso, il motore esegue quelle compensazioni in inverso (una Saga), annulla il biglietto nella finestra di 24 ore, e riferisce onestamente. Un viaggiatore non resta mai con un volo e nessuna camera perché nulla dipende dal modello che decide di ripulire.

Si collega ad Amadeus, Sabre o Duffel?

No. Il GDS, il CRS, l'emissione dei biglietti e il pagamento sono tutti stub e simulati in questa demo. L'adapter delle fixture è l'integrazione V1, e non c'è un account live Amadeus, Sabre o Duffel dietro. La demo prova l'architettura del flusso di controllo e la logica di compensazione, non una pipeline di prenotazione in produzione.

Cosa succede se l'hotel fallisce dopo che il volo è già stato emesso?

È esattamente il caso per cui è costruita la Saga. L'emissione del biglietto registra la propria azione inversa (annulla il biglietto nella finestra di 24 ore) nel momento in cui gira. Se la tariffa alberghiera scade prima del commit, il motore lancia le compensazioni in ordine inverso, annulla il biglietto senza addebito, rilascia gli hold, e consegna al viaggiatore alternative oneste. Lo stato terminale è rolled back, non confirmed e non stranded.

Cosa impedisce all'agente di inventare un hotel che non esiste?

Un gate di verifica conferma ogni struttura rispetto al CRS tramite il suo property_id prima che possa essere mostrata. Quando la richiesta nominava una struttura fabbricata nella nostra demo, il gate non ha trovato alcun match nel CRS e ha rifiutato di mostrarla, e l'agente si è astenuto onestamente invece di prenotarla. Il gate non segnala un hotel inventato dopo il fatto; lo rende fisicamente non presentabile.

In cosa è diverso dal mettere GPT-4 in un loop di agente con tool?

Un agente in stile ReAct mette l'LLM al comando della transazione, quindi decide quando cercare, prenotare ed emettere, e non ha gate né logica di compensazione. Sullo stesso batch sintetico a seed fisso di 200 scenari, quella baseline ha fatto emergere inventario inventato e ha lasciato biglietti emessi senza rollback, emettendo un falso Tutto a posto. Qui l'LLM è un nodo foglia tipizzato che analizza solo l'intento e formula la risposta; il codice deterministico possiede il flusso e ogni passo porta il proprio undo.

Chi è responsabile se l'agente dice al viaggiatore qualcosa di sbagliato?

Il deployer è responsabile di ogni dichiarazione che il suo agente fa. In Moffatt v. Air Canada (BC Civil Resolution Tribunal, 14 febbraio 2024) la compagnia aerea è stata condannata a pagare $812.02 dopo che il suo chatbot aveva inventato una policy di tariffe per lutto, e la difesa «era l'AI» è stata respinta. La demo esporta una traccia di audit JSON per prenotazione con il modello e la versione, ogni verdetto di nodo, ogni compensazione Saga, e un flag di disclosure dell'EU AI Act Article 50, così ciò che l'agente ha fatto è ispezionabile a posteriori.

Ricerca tecnica

La ricerca dietro questa demo — l'architettura, il design della verifica e il blueprint per l'impresa.

Valuti un livello di prenotazione agentica su cui non puoi scommettere l'azienda?

I fallimenti che abbandonano i viaggiatori e inventano hotel sono eventi di infrastruttura, non problemi di QI del modello.

Se il tuo team sta pesando dove deve stare l'LLM in un agente di prenotazione ad alta posta in gioco, e come impedire a un fallimento parziale di diventare una responsabilità in stile Air Canada, ci farebbe davvero piacere confrontarci. Il problema è di tutto il settore e lo saranno anche le risposte.

Revisione dell'architettura dell'agente

  • ✓ Mappa dove si trova l'LLM nel tuo flusso di controllo oggi
  • ✓ Identifica i passi che necessitano di un'azione compensativa
  • ✓ Metti sotto pressione le modalità di fallimento: scadenza tariffa, hold post-biglietto, tempeste di ricerca
  • ✓ Definisci gli stati terminali di cui un operatore può fidarsi

Costruzione di un agente deterministico

  • ✓ Una macchina a stati che possiede ricerca, policy ed emissione biglietti
  • ✓ Un gate di verifica e un motore di compensazione Saga
  • ✓ Policy compilata in codice, con default fail-safe
  • ✓ Una traccia di audit esportabile con un flag di disclosure Article 50
Social

Pubblicato anche su