Een visuele metafoor die een prachtig geschreven maar fictieve reisroute contrasteert met de echte, geverifieerde datasystemen die haar zouden moeten verankeren — specifiek voor het hallucinatieprobleem van reis-AI.
Artificial IntelligenceTravelSoftware Engineering

Je AI-reisagent liegt tegen je — en je merkt het pas als je gestrand bent

Ashutosh SinghalAshutosh Singhal6 februari 202615 min

Een vrouw mailde ons vorig jaar met een screenshot. Ze had een populaire AI-reisplanner gebruikt om een familiereis naar Costa Rica te boeken. De AI had een plek aanbevolen die zoiets heette als "Tabacon Springs Eco-Lodge" — weelderige beschrijvingen, een prijs onder de $200 per nacht, foto's die leken te kloppen. Ze boekte vluchten voor vier personen. Huurde een auto. Vertelde haar kinderen dat ze apen zouden gaan zien vanuit een boomhut.

De lodge bestond niet.

Niet "hij was gesloten" of "hij werd gerenoveerd." Hij bestond letterlijk niet. De AI had details van twee of drie echte Costaricaanse resorts vermengd — de naam van het ene, de voorzieningen van het andere, het prijsniveau van een hostel verderop — en ze aaneengeregen tot één prachtig beschreven pand dat nooit was gebouwd. De boekingslink leidde naar een generieke betaalpagina die haar kaart belastte en niets leverde.

Toen ik die e-mail las, voelde ik geen verrassing. Ik voelde herkenning. Want mijn team bij Veriprajna had maandenlang precies naar deze faalmodus zitten staren, hem uit elkaar getrokken, begrepen waarom hij gebeurt op architectonisch niveau. En het antwoord is zowel simpel als diep ongemakkelijk voor iedereen die AI-producten bouwt in de reisbranche: de populairste AI-systemen in de branche zijn geoptimaliseerd om juist te klínken, niet om juist te zíjn. Dat onderscheid is subtiel in een gedichtengenerator. In reislogistiek is het het verschil tussen een vakantie en een ramp.

Waarom verzint jouw AI hotels die niet bestaan?

Dit is wat de meeste mensen niet begrijpen over grote taalmodellen — GPT-4, Claude, Gemini, allemaal. Ze "weten" dingen niet zoals een database dingen weet. Een hotelreserveringssysteem weet dat kamer 412 in het JW Marriott geboekt is van 3 maart tot 7 maart. Dat is een feit, opgeslagen in een rij, opvraagbaar.

Zo werkt een LLM niet. Hij voorspelt het volgende woord in een reeks op basis van statistische patronen in zijn trainingsdata. Als je hem vraagt om een "luxe eco-lodge in Costa Rica onder de $200," activeert hij clusters van associaties — "Costa Rica" haalt "weelderig," "regenwoud," "eco-lodge" naar boven. Hij begint tekst te genereren die statistisch waarschijnlijk op die woorden volgt. En wanneer hij het pand moet benoemen? Dan vermengt hij. Hij neemt fragmenten uit duizenden reviews die hij heeft gezien en stelt ze samen tot iets dat plausibel klinkt.

In creatief schrijven heet dat vermengen verbeelding. In de reisbranche heet het een hallucinatie. En het model heeft geen manier om het verschil te zien.

Het model optimaliseert voor samenhang, niet voor correctheid. Het is ontworpen om een antwoord te produceren dat eruitziet als een geldig antwoord, niet één dat een geldig antwoord is dat is geverifieerd tegen realtime beschikbaarheid.

Wat dit erger maakt, is hoe deze modellen worden getraind. Tijdens reinforcement learning from human feedback (RLHF) verkiezen menselijke beoordelaars consequent antwoorden die uitgebreid en zelfverzekerd zijn boven antwoorden die zeggen "ik weet het niet." Zo leert het model, op een diep niveau, dat zelfverzekerd gokken wordt beloond en het toegeven van onwetendheid wordt bestraft. Een menselijke reisagent die de beschikbaarheid gokt, wordt ontslagen. Een AI die de beschikbaarheid gokt, wordt geprezen om zijn "vloeiendheid" — totdat de klant in een vreemd land landt zonder plek om te slapen.

De nacht waarop ik besefte dat vloeiendheid het probleem is

Er is een moment waar ik steeds op terugkom. We testten een vroeg prototype — geen product dat we uitbrachten, maar een intern experiment om te begrijpen hoe LLM's reisvragen afhandelen. Ik vroeg het om een hotel voor me te vinden vlak bij Central Park voor onder de $250 per nacht tijdens de Fashion Week in New York.

Het kwam terug met drie opties. Gedetailleerde beschrijvingen. Prijzen. Voorzieningen. Een ervan noemde zelfs een rooftopbar met uitzicht op het park. De taal was zo verzorgd, zo specifiek, dat mijn eerste ingeving was om op "boeken" te klikken.

Toen liet een van mijn engineers — een rustigere man, zeer methodisch — dezelfde zoekopdracht los op de Amadeus Hotel Search API. Twee van de drie hotels bestonden, maar hadden geen beschikbaarheid tijdens de Fashion Week. De naam van het derde hotel leek op een echt pand, maar kwam met geen enkele hotel-ID in het systeem overeen. De rooftopbar? Die hoorde bij een compleet ander hotel zes straten verderop.

Dat was de nacht waarop ik begreep dat het gevaar niet de AI is die duidelijk faalt. Een chatbot die zegt "ik begrijp je vraag niet" is frustrerend maar onschadelijk. Het gevaar is de AI die je vraag perfect begrijpt en reageert met welbespraakte, overtuigende, feitelijk onjuiste informatie. We begonnen dit de "Uncanny Valley" van betrouwbaarheid te noemen — de verbale intelligentie van het systeem is zo hoog dat gebruikers hun waakzaamheid over feitelijke verificatie laten varen.

De zaak rond de chatbot van Air Canada maakte dit concreet in juridische termen. Een chatbot hallucineerde een terugbetalingsbeleid. De rechter oordeelde dat de luchtvaartmaatschappij aansprakelijk was — niet de AI-leverancier, niet de chatbot als een "bètatool." Het bedrijf dat de agent inzette, was verantwoordelijk voor de beweringen van de agent. Als jouw AI een suite met zeezicht voor $200 belooft en het GDS alleen een standaardkamer voor $400 heeft, kun jij opdraaien voor het verschil. Of erger, voor de verpeste reis.

Wat gebeurt er als je de LLM behandelt als het brein in plaats van de mond?

Een diagram dat de architectonische verschuiving toont van een LLM Wrapper (waarbij de LLM reisgegevens direct genereert) naar een Agentic AI-systeem (waarbij de LLM intentie routeert naar echte inventarissystemen en alleen geverifieerde gegevens presenteert).

Na die testnacht had mijn team een lange discussie. Het soort waarbij mensen op whiteboards tekenen en door elkaar heen praten. De vraag was simpel: proberen we de LLM nauwkeuriger te maken, of veranderen we de architectuur volledig?

Het ene kamp wilde betere prompts, meer guardrails, retrieval-augmented generation. Fine-tune het model op reisgegevens. Het andere kamp — waar ik uiteindelijk in belandde — betoogde dat het probleem niet de kennis van het model was. Het probleem was de rol van het model. We vroegen een tekstgenerator om het werk van een inventarisbeheerder te doen. Dat is als een romanschrijver vragen een luchtvaartmaatschappij te runnen. Ze kunnen de ervaring van het vliegen prachtig beschrijven, maar ze kunnen je niet vertellen of er een stoel is op de vlucht van 8 uur naar Heathrow.

Dus namen we een beslissing die alles veranderde wat we daarna bouwden: de LLM zou nooit de bron van reisinformatie zijn. Hij zou de router van intentie zijn.

De gebruiker zegt "Zoek een hotel voor me bij Central Park." De taak van de LLM is die intentie te begrijpen, hem op te splitsen in gestructureerde parameters — locatie, datumbereik, budget, voorkeuren — en die parameters te overhandigen aan een tool die echte inventaris bevraagt. De tool komt terug met daadwerkelijke gegevens. De tweede taak van de LLM is die gegevens in natuurlijke taal te presenteren. Maar hij genereert de gegevens nooit. Hij vertaalt ze.

We stopten met het bouwen van AI die praat over reizen. We begonnen AI te bouwen die reizen dóét — echte systemen bevraagt, echte statuscodes interpreteert en alleen bevestigt wat hij kan verifiëren.

Dit is de verschuiving van wat de branche een "LLM Wrapper" noemt naar een Agentic AI-systeem. En het verschil is niet incrementeel. Het is een verandering van soort. Ik schreef uitgebreid over deze architectuur in de interactieve versie van ons onderzoek.

Het orkestrator-worker-patroon: waarom één agent niet genoeg is

Een gelabeld architectuurdiagram dat het orkestrator-worker-patroon toont met de orkestrator in het midden die gespecialiseerde workers aanstuurt die elk verbinding maken met specifieke GDS-systemen.

In het begin probeerden we alles door één enkele agent te laten lopen. Eén prompt die vluchten, hotels, autoverhuur, dieetbeperkingen en zakenreisbeleid afhandelde. Het bezweek onder zijn eigen gewicht. Het contextvenster raakte vol. Instructies botsten. De agent boekte een hotel voordat de vluchtdata bevestigd waren en moest dan alles weer terugdraaien.

Dus bouwden we wat wij het orkestrator-worker-patroon noemen. Zie het als een senior reisadviseur die nooit een toetsenbord aanraakt en een team van specialisten aanstuurt die elk één ding uitzonderlijk goed doen.

De orkestrator is een sterk redenerend model — GPT-4o of Claude 3.5 Sonnet — dat met de gebruiker praat, de gespreksgeschiedenis bijhoudt en beslist wat er moet gebeuren. Het raakt het GDS niet rechtstreeks aan. Daaronder zitten gespecialiseerde workers: een Flight Worker die Amadeus Air API's spreekt en IATA-codes begrijpt, een Hotel Worker die Sabre's Content Services for Lodging spreekt en het verschil kent tussen een aanbetaling en een garantie, een Policy Worker die zakenreisregels controleert voordat er iets gepresenteerd wordt.

Wanneer een gebruiker zegt "Boek een vlucht naar NYC volgende dinsdag en een hotel bij Central Park," splitst de orkestrator dat op in twee taken, herkent dat de hotelzoekopdracht afhangt van de aankomsttijd van de vlucht, start eerst de Flight Worker en daarna de Hotel Worker met de juiste data. Als de Hotel Worker faalt, presenteert de orkestrator nog steeds de vluchtopties en vraagt of de gebruiker het opnieuw wil proberen met andere hotelcriteria. Niets crasht. Niets hallucineert.

Het cruciale inzicht was het scheiden van het denken van het doen. De orkestrator denkt. De workers doen. En geen van beide doet zich voor als de ander.

Waarom "200 OK" ons bijna om de tuin leidde

Een diagram dat het cruciale onderscheid toont tussen succes op HTTP-niveau (200 OK) en boekingsstatuscodes op GDS-niveau, en de Verificatielus illustreert die valse bevestigingen voorkomt.

Hier is een verhaal waar ik nog steeds van ineenkrimp. We zaten diep in de integratietests met de boekings-API's van Sabre. Onze Hotel Worker stuurde een boekingsverzoek, kreeg een HTTP 200-respons terug — wat in webontwikkeling "succes" betekent — en gaf dat door aan de orkestrator. De orkestrator vertelde de gebruiker: "Je bent geboekt!"

Behalve dat ze dat niet waren. Niet altijd.

Het kostte ons een gênant lange tijd om dit te vangen. De HTTP-respons was 200 omdat het bericht succesvol was afgeleverd. Maar binnen in de responsbody was de GDS-segmentstatuscode UC — Unable to Confirm. Het hotel had het verzoek afgewezen, meestal omdat de gecachete beschikbaarheid verouderd was. De kamer was verkocht in de milliseconden tussen de zoekopdracht en de boekingspoging.

De ontkoppeling tussen de transportlaag en de applicatielaag is een klassieke valkuil, en we liepen er recht in. Een 200 OK op HTTP-niveau zei "je bericht is aangekomen." Een UC op GDS-niveau zei "je boeking is mislukt." Ons systeem las de envelop en negeerde de brief erin.

Toen implementeerden we wat ik nu beschouw als het belangrijkste onderdeel van onze architectuur: de Verificatielus. Elke boekingsrespons passeert een aparte verificatiestap — ofwel een deterministische codecontrole of een gespecialiseerde prompt die fungeert als kwaliteitscontroleur — voordat enige bevestiging de gebruiker bereikt. De regel is absoluut:

Een AI-agent mag nooit een bevestigingsbericht uitvoeren tenzij hij de specifieke GDS-segmentstatuscode heeft geparseerd en gevalideerd als HK — Holding Confirmed. Al het andere is een mislukking, ongeacht wat de HTTP-header zegt.

HK betekent dat de inventaris is veiliggesteld. UC betekent dat het hotel je heeft afgewezen. NN betekent dat het verzoek in behandeling is — beloof nog niets. NO betekent dat er geen actie is ondernomen. Deze codes zijn het verschil tussen een geboekte kamer en een gestrande reiziger, en de meeste AI-reissystemen parseren ze niet eens.

Voor de volledige technische uiteenzetting van onze statuscodeafhandeling en verificatiearchitectuur, zie ons onderzoekspaper.

Hoe gaat een AI-agent om met "De kamer is net verkocht"?

Dit is waar agentic systemen hun waarde bewijzen. De "Look-to-Book"-discrepantie is endemisch in de reisbranche — je zoekt, ziet beschikbaarheid, klikt op boeken, en de kamer is weg. Gebeurt voortdurend tijdens het hoogseizoen. Een op wrappers gebaseerde AI heeft geen vocabulaire voor deze situatie. Hij zegt of "Ik heb het geboekt!" (fout) of "Het is mislukt" (nutteloos). Hij kan niet zeggen "Het was er een seconde geleden nog, maar iemand anders heeft het weggekaapt — hier is je op één na beste optie."

Onze agents wel. Wanneer een boeking UC retourneert, triggert het systeem automatisch een nieuwe beschikbaarheidszoekopdracht voor hetzelfde hotel. Als er een andere kamer of tarief beschikbaar is, presenteert het de optie: "Het vorige tarief is uitverkocht, maar ik heb een vergelijkbare kamer gevonden voor $10 meer." Als er niets beschikbaar is, haalt het het op één na beste hotel uit de oorspronkelijke zoekresultaten en biedt dat in plaats daarvan aan. Dit vereist dat de agent toestand bijhoudt — een geheugen van wat hij al heeft gezocht, wat de gebruiker al heeft afgewezen, wat de alternatieven waren. Wrappers zijn toestandsloos. Zij kunnen dit niet. Ze beginnen elke keer opnieuw vanaf nul, of ze hallucineren continuïteit.

Het normalisatieprobleem waar niemand over praat

Eén ding dat me verraste — echt verraste — was hoe verschillend de datastructuren zijn tussen Amadeus en Sabre. Amadeus retourneert prijzen opgesplitst in basis, totaal en belastingen in een strikte geneste JSON. Sabre bundelt de belasting soms mee, soms niet, afhankelijk van het tariefplan. Veldnamen verschillen. amount in het ene systeem is totalPrice in het andere.

Als je beide ruwe responsen aan een LLM voert en hem vraagt hotels te vergelijken, raakt hij in de war. Hij zou de prijs vóór belasting van Amadeus kunnen citeren en de prijs ná belasting van Sabre, waardoor het Amadeus-hotel $50 goedkoper lijkt terwijl het eigenlijk $20 duurder is. We zagen dit gebeuren tijdens het testen, en het is het soort fout dat vrijwel onmogelijk voor een gebruiker is om op te merken.

Dus bouwden we een Normalisatie-Worker — een deterministische codelaag die de ongelijksoortige JSON's van beide systemen neemt en ze omzet naar één gestandaardiseerd schema. De orkestrator ziet nooit ruwe GDS-gegevens. Hij ziet schone, consistente velden: naam, totaalprijs inclusief belasting, sterrenclassificatie, afstand tot het interessepunt van de gebruiker. De LLM presenteert deze genormaliseerde gegevens. Hij interpreteert geen ruwe API-responsen. Hij vertaalt gecureerde feiten.

"Gebruik gewoon GPT" — en andere dingen die investeerders zeggen

Mensen vragen me voortdurend waarom we niet gewoon retrieval-augmented generation gebruiken — hotelgegevens in een vectordatabase trekken en de LLM erin laten zoeken. Of een model fine-tunen op reisgegevens. Of gewoon een betere systeemprompt toevoegen.

Een investeerder zei me botweg: "Gebruik gewoon GPT met een goede prompt. Het model is slim genoeg." Ik respecteer die ingeving — het is de simpelste oplossing, en simpele oplossingen hebben meestal gelijk. Maar niet hier. Niet wanneer de faalmodus een gezin is dat op een vliegveld slaapt.

RAG helpt met statische kennis — "Wat is het visumbeleid voor Thailand?" — maar het kan je niet vertellen of vlucht AA123 op dit moment stoelen beschikbaar heeft. Fine-tunen helpt met toon en domeinvocabulaire, maar het verbindt het model niet met live inventaris. Een betere systeemprompt helpt met opmaak, maar het voorkomt niet dat het model een hotelnaam genereert die in geen enkel GDS bestaat.

Het enige dat hallucinatie in de reisbranche voorkomt, is het verankeren van de output van de AI in realtime, geverifieerde gegevens uit het systeem van registratie. Dat systeem is het GDS. Al het andere is decoratie.

Creativiteit zonder beperking is chaos. In de reisbranche is de beperking de werkelijkheid — de vliegtuigstoel die bestaat of niet, de hotelkamer die beschikbaar is of niet. Er is geen tussenweg, en de AI moet stoppen te doen alsof die er wel is.

En het trage gedeelte dan?

Ik zal niet doen alsof agentic systemen snel zijn. Eén enkel gebruikersverzoek kan vier tool-aanroepen triggeren — zoeken, prijscontrole, beleidscontrole, responssynthese. Dat kan 10–15 seconden duren. In e-commerce is dat een eeuwigheid.

We pakken dit op drie manieren aan. Ten eerste streamen we het redeneren van de agent naar de gebruiker: "Amadeus doorzoeken voor vluchten…" "Zakenreisbeleid controleren…" Het werk tonen vermindert de gevoelde latentie dramatisch. Ten tweede laten we workers parallel draaien — de Flight Worker en Hotel Worker zoeken gelijktijdig in plaats van na elkaar, wat de totale wachttijd ongeveer halveert. Ten derde cachen we beschikbaarheidsresultaten 15 minuten in Redis. Als de gebruiker zegt "Laat me dat tweede hotel nog eens zien," bevragen we het GDS niet opnieuw. We halen het uit de cache.

Is het zo snel als een wrapper die in twee seconden een antwoord verzint? Nee. Is het zo snel als het moet zijn voor een gebruiker die een écht antwoord wil? Ja.

Het deel waar ik toegeef wat we nog niet kunnen

Geen enkel AI-systeem handelt elk geval af. Complexe reisroutes met meerdere trajecten en visumafhankelijkheden, obscure luchtvaartallianties, groepsboekingen die onderhandelde tarieven vereisen — die laten dingen nog steeds stukgaan. We weten dit omdat we er detectie voor hebben gebouwd. Wanneer de agent in een lus blijft hangen zonder tot een oplossing te komen, of wanneer sentimentanalyse gebruikersfrustratie signaleert, schakelt het systeem terug naar wat wij de "Copilot-modus" noemen. Het waarschuwt een menselijke reisagent, geeft de volledige gestructureerde context van het gesprek door, en de mens voltooit de boeking met de tools die de agent heeft voorbereid.

Mensen vragen me of dit een mislukking is. Ik denk dat het het tegenovergestelde is. De gevaarlijkste AI is degene die niet weet wanneer hij moet stoppen. Je grenzen kennen en gracieus overdragen is een feature, geen bug. De agent die zegt "Laat me je in contact brengen met een specialist" is betrouwbaarder dan degene die zelfverzekerd blijft gokken.

Waar dit naartoe gaat

Wat we vandaag bouwen is het fundament, niet het plafond. We zitten op wat ik Level 3-autonomie zou noemen — de agent voert specifieke taken uit, maar de gebruiker bevestigt voordat er geld beweegt. Het pad vooruit omvat onderhandelingsagents die niet alleen vermelde prijzen boeken maar hotel-API's bevragen voor volumekortingen, dynamische pakketmotoren die vluchten en hotels bundelen tot maatwerkproducten met beheerde marges, en proactief verstoringsbeheer — agents die de vluchtstatus rond de klok monitoren en, wanneer er een annulering plaatsvindt, al een stoel op de op één na beste optie vasthouden voordat de reiziger zelfs maar weet dat er iets is misgegaan.

Niets daarvan is mogelijk op een wrapper. Niets ervan werkt als het systeem hallucineert. Elk van die capaciteiten vereist de toestandsbewuste, geverifieerde, tool-verankerde architectuur die we hebben gebouwd.

De reisbranche staat op een kantelpunt. De eerste golf van AI-adoptie — de wrappers, de chatbots, de "voeg gewoon GPT toe"-experimenten — creëerde iets verleidelijks en gevaarlijks: systemen die klinken als de beste reisagent die je ooit hebt ontmoet, maar niet daadwerkelijk een kamer kunnen boeken. De volgende golf zal worden bepaald door een hardere, minder glamoureuze vraag: niet "Kan de AI een prachtige reisroute schrijven?" maar "Kan de AI bevestigen dat elk item op die reisroute daadwerkelijk bestaat, op dit moment, tegen de prijs die het opgaf?"

Dat gezin in Costa Rica verdiende beter dan een prachtig geschreven fictie. Elke reiziger verdient dat. Het tijdperk van de AI die gokt is voorbij. Wat hierna komt is de AI die controleert — en alleen spreekt wanneer hij het zeker weet.

Related Research

Also Published On