
あなたのAI旅行エージェントは嘘をついている——現地で立ち往生するまで、あなたは気づけない
昨年、ある女性が一枚のスクリーンショットを添えてメールをくれた。彼女は人気のAI旅行プランナーを使って、家族でのコスタリカ旅行を予約したという。そのAIは「タバコン・スプリングス・エコロッジ」のような名前の宿を勧めてきた——豊かな描写、一泊200ドル未満という価格、いかにも一致していそうな写真。彼女は4人分の航空券を予約した。レンタカーも借りた。子どもたちには、ツリーハウスからサルを見に行くのだと話していた。
そのロッジは存在しなかった。
「休業中」でも「改装中」でもない。文字どおり、存在していなかったのだ。AIは実在する2、3のコスタリカのリゾートの情報を混ぜ合わせ——ある宿の名前、別の宿の設備、通り沿いの安宿の価格帯——それらを繋ぎ合わせて、一度も建てられたことのない、美しく描写された一つの物件を作り上げていた。予約リンクは一般的な決済ページに飛び、彼女のカードに請求だけして、何も提供しなかった。
そのメールを読んだとき、私は驚きを感じなかった。感じたのは、既視感だった。というのも、Veriprajnaの私のチームは、まさにこの失敗のあり方を何ヶ月も見つめ、分解し、なぜアーキテクチャのレベルでそれが起こるのかを理解しようとしてきたからだ。そしてその答えは、単純であると同時に、旅行分野でAI製品を作る者にとっては深く不快なものだ——業界で最も普及しているAIシステムは、正しく「あろう」とするのではなく、正しく「聞こえる」ように最適化されている。その違いは、詩の生成器なら微妙なものだ。だが旅行の手配においては、それは休暇か災難かの分かれ目になる。
なぜあなたのAIは存在しないホテルをでっち上げるのか?
大規模言語モデル——GPT-4、Claude、Gemini、そのすべて——について、ほとんどの人が理解していないことがある。それらはデータベースが物事を「知っている」ような形で物事を「知って」いるわけではない。ホテルの予約システムは、JWマリオットの412号室が3月3日から3月7日まで予約済みであることを知っている。それは事実であり、一行のデータとして保存され、問い合わせ可能だ。
LLMはそのようには機能しない。訓練データにおける統計的パターンに基づいて、並びの中の次の単語を予測するのだ。「200ドル未満のコスタリカの高級エコロッジ」を求めると、それは連想のかたまりを活性化させる——「コスタリカ」は「緑豊かな」「熱帯雨林」「エコロッジ」を引き出す。そしてそれらの単語に続く可能性が統計的に高いテキストを生成し始める。そして物件に名前を付ける必要が生じたら? それは混ぜ合わせる。目にしてきた何千ものレビューの断片を取り、それらを組み合わせて、もっともらしく聞こえる何かを合成するのだ。
創作においては、その混ぜ合わせは想像力と呼ばれる。旅行においては、それはハルシネーション(幻覚)と呼ばれる。そしてモデルには、その違いを見分ける術がない。
モデルは正確さではなく、一貫性を最適化している。リアルタイムの在庫と照合して検証された妥当な答えではなく、妥当な答えのように「見える」応答を生み出すよう設計されているのだ。
これをさらに悪くしているのが、こうしたモデルの訓練のされ方だ。人間のフィードバックによる強化学習(RLHF)では、人間の評価者は「分かりません」と言う答えよりも、包括的で自信に満ちた答えを一貫して好む。だからモデルは深いレベルで、自信を持って推測することは報われ、無知を認めることは罰せられると学習する。空室状況を当て推量する人間の旅行代理店員はクビになる。空室状況を推測するAIは、その「流暢さ」を褒められる——顧客が外国に着いて寝る場所がないと分かるまでは。
流暢さこそが問題だと気づいた夜
何度も思い返す瞬間がある。私たちは初期のプロトタイプをテストしていた——出荷した製品ではなく、LLMが旅行のクエリをどう扱うかを理解するための社内実験だ。私はニューヨークのファッションウィーク期間中、セントラルパーク近くで一泊250ドル未満のホテルを探すよう頼んだ。
返ってきたのは3つの選択肢だった。詳細な説明。価格。設備。そのうちの一つには、公園を見渡せる屋上バーまで言及されていた。その言葉づかいはあまりに洗練されていて、あまりに具体的だったので、私の最初の衝動は「予約」をクリックすることだった。
それから、私のエンジニアの一人——物静かで、非常に几帳面な男——が、同じクエリをAmadeus Hotel Search APIに対して実行した。3つのうち2つのホテルは実在したが、ファッションウィーク中は空室がなかった。3つ目のホテルの名前は実在の物件に近かったが、システム内のどのホテルIDにも一致しなかった。あの屋上バーは? 6ブロック離れたまったく別のホテルのものだった。
その夜、私は理解した——危険なのは、明らかに失敗するAIではない。「ご質問が理解できません」と言うチャットボットは、いらだたしくはあっても無害だ。危険なのは、あなたの質問を完璧に理解した上で、雄弁で説得力があり、事実として間違った情報を返してくるAIだ。私たちはこれを、信頼性の「不気味の谷」と呼ぶようになった——システムの言語的知性があまりに高いため、ユーザーは事実確認への警戒を解いてしまうのだ。
エア・カナダのチャットボットの件は、これを法的に具体化した。チャットボットが払い戻しポリシーをでっち上げたのだ。裁判所は、航空会社に責任があると裁定した——AIベンダーでもなければ、「ベータ版ツール」としてのチャットボットでもなく。エージェントを導入した企業が、そのエージェントの主張に対して責任を負うのだ。もしあなたのAIが200ドルで海が見えるスイートを約束したのに、GDSには400ドルの標準的な部屋しかなければ、あなたはその差額の責任を負わされるかもしれない。あるいはもっと悪いことに、台無しになった旅行の責任を。
LLMを「口」ではなく「頭脳」として扱うと何が起こるか?

あのテストの夜のあと、私のチームは長い議論を交わした。人々がホワイトボードに書き殴り、互いにかぶせて話すような類の議論だ。問いは単純だった——LLMをより正確にしようとするのか、それともアーキテクチャそのものを変えるのか。
一方の陣営は、より良いプロンプト、より多くのガードレール、検索拡張生成(RAG)を望んだ。旅行データでモデルをファインチューニングしろ、と。もう一方の陣営——私が最終的に加わった側——は、問題はモデルの知識ではないと主張した。問題はモデルの役割だった。私たちはテキスト生成器に、在庫管理者の仕事をさせようとしていたのだ。それは小説家に航空会社の経営を頼むようなものだ。彼らは空を飛ぶ体験を美しく描写できるが、ヒースロー行き午前8時便に空席があるかどうかは教えてくれない。
そこで私たちは、その後に作るすべてを変える決断を下した——LLMは決して旅行情報の情報源にはならない。意図のルーターになるのだ、と。
ユーザーが「セントラルパーク近くのホテルを探して」と言う。LLMの仕事は、その意図を理解し、それを構造化されたパラメータ——場所、日付の範囲、予算、好み——に分解し、それらのパラメータを実在の在庫を照会するツールに渡すことだ。ツールは実際のデータを返してくる。LLMの二つ目の仕事は、そのデータを自然な言葉で提示することだ。だがLLMは決してデータを生成することはない。翻訳するのだ。
私たちは、旅行について「語る」AIを作るのをやめた。旅行を「実行する」AI——実在のシステムを照会し、実際のステータスコードを解釈し、検証できることだけを確定する——を作り始めたのだ。
これは、業界で「LLMラッパー」と呼ばれるものから、エージェント型AIシステムへの移行だ。そしてその違いは漸進的なものではない。種の変化だ。このアーキテクチャについては、私たちの研究のインタラクティブ版で詳しく書いた。
オーケストレーター・ワーカー・パターン:なぜ一つのエージェントでは足りないのか

初期には、すべてを単一のエージェントで処理しようとした。一つのプロンプトで、フライト、ホテル、レンタカー、食事制限、企業の出張規定を扱う。それは自らの重みで崩壊した。コンテキストウィンドウが埋まりきった。指示が衝突した。エージェントはフライトの日付を確定する前にホテルを予約し、そのあとすべてを巻き戻さなければならなくなる。
そこで私たちは、いわゆるオーケストレーター・ワーカー・パターンというものを作った。キーボードには決して触れないシニアの旅行コンサルタントが、それぞれ一つのことを極めて上手くこなす専門家チームを束ねている——そんなふうに考えてほしい。
オーケストレーターは高い推論能力を持つモデル——GPT-4oやClaude 3.5 Sonnet——で、ユーザーと対話し、会話履歴を保持し、何をすべきかを判断する。GDSに直接触れることはない。その下には専門のワーカーが控えている。Amadeus Air APIを操りIATAコードを理解するフライト・ワーカー、SabreのContent Services for Lodgingを操りデポジットと保証(ギャランティ)の違いを知るホテル・ワーカー、そして何かが提示される前に企業の出張規定をチェックするポリシー・ワーカーだ。
ユーザーが「来週の火曜にNYC行きのフライトと、セントラルパーク近くのホテルを予約して」と言うと、オーケストレーターはそれを二つのタスクに分解し、ホテル検索がフライトの到着時刻に依存することを見極め、まずフライト・ワーカーを、続いて正しい日付でホテル・ワーカーを起動する。もしホテル・ワーカーが失敗しても、オーケストレーターはフライトの選択肢は提示したうえで、別のホテル条件で再試行したいかをユーザーに尋ねる。何もクラッシュしない。何もハルシネーションを起こさない。
重要な気づきは、「考えること」を「実行すること」から切り離すことだった。オーケストレーターは考える。ワーカーは実行する。そしてどちらも、相手のふりをしない。
なぜ「200 OK」に危うく騙されかけたのか

今でも思い出すと顔をしかめてしまう話がある。私たちはSabreの予約APIとの統合テストに深く取り組んでいた。ホテル・ワーカーは予約リクエストを送り、HTTP 200のレスポンス——ウェブ開発では「成功」を意味する——を受け取り、それをオーケストレーターに渡す。オーケストレーターはユーザーにこう告げる。「予約完了しました!」
ところが、そうではなかった。少なくとも、いつもではなかった。
これに気づくまで、恥ずかしくなるほど長くかかった。HTTPレスポンスが200だったのは、メッセージが正常に届いたからだ。しかしレスポンス本文の中では、GDSのセグメント・ステータスコードはUC——Unable to Confirm(確認不可)だった。ホテルがリクエストを拒否したのだ。たいていはキャッシュされた空室情報が古くなっていたためだ。検索から予約試行までのミリ秒の間に、その部屋は売れてしまっていた。
トランスポート層とアプリケーション層のあいだの断絶は典型的な落とし穴であり、私たちはまさにそこにはまり込んだ。HTTPレベルの200 OKは「あなたのメッセージは届いた」と言っていた。一方、UCはGDSレベルで「あなたの予約は失敗した」と言っていた。私たちのシステムは封筒を読んで、中の手紙を無視していたのだ。
そのとき私たちは、今では私たちのアーキテクチャで最も重要な要素だと考えているものを実装した——検証ループだ。すべての予約レスポンスは、確定がユーザーに届く前に、独立した検証ステップ——決定論的なコードチェック、または品質監査役として働く専用のプロンプトのいずれか——を通過する。そのルールは絶対だ。
AIエージェントは、具体的なGDSセグメント・ステータスコードを解析し、それがHK——Holding Confirmed(確保済み)——であると検証しない限り、確定メッセージを出力することを決して許されない。それ以外はすべて、HTTPヘッダーが何と言おうと、失敗である。
HKは在庫が確保されたことを意味する。UCはホテルがあなたを拒否したことを意味する。NNはリクエストが保留中であることを意味する——まだ何も約束してはいけない。NOは何の処理も行われなかったことを意味する。これらのコードは、予約できた部屋と、立ち往生した旅行者との分かれ目であり、ほとんどのAI旅行システムはそれらを解析すらしていない。
私たちのステータスコード処理と検証アーキテクチャの完全な技術的解説については、私たちの研究論文をご覧いただきたい。
AIエージェントは「その部屋はたった今売れました」にどう対処するのか?
ここでこそ、エージェント型システムはその価値を証明する。「検索から予約まで(Look-to-Book)」の食い違いは旅行につきものだ——検索して、空室を見て、予約をクリックすると、部屋はもうない。繁忙期には絶えず起こる。ラッパー型のAIには、この状況を表す語彙がない。「予約しました!」(間違い)か「失敗しました」(役に立たない)のどちらかしか言えない。「たった今まではありましたが、誰かが先に取ってしまいました——こちらが次善の選択肢です」とは言えないのだ。
私たちのエージェントは言える。予約がUCを返すと、システムは自動的に同じホテルの新たな空室検索を起動する。別の部屋や料金が空いていれば、その選択肢を提示する。「以前の料金は売り切れましたが、10ドル高い同様の部屋を見つけました」。何も空いていなければ、元の検索結果から次善のホテルを引き出し、代わりにそれを提案する。これには、エージェントが状態——すでに何を検索したか、ユーザーがすでに何を却下したか、代替案が何であったかの記憶——を保持することが求められる。ラッパーはステートレスだ。これができない。毎回ゼロから始めるか、あるいは連続性をハルシネーションで捏造する。
誰も語らない正規化の問題
私を驚かせた——本当に驚かせた——ことの一つは、AmadeusとSabreとでデータ構造がどれほど違うかということだった。Amadeusは価格を基本料金、合計、税に分けて、厳密に入れ子になったJSONで返す。Sabreは料金プランによって、税を含めたり含めなかったりする。フィールド名も異なる。amountは一方のシステムでは、他方ではtotalPriceとなる。
両方の生のレスポンスをLLMに渡してホテルを比較させると、混乱する。Amadeusからの税抜き価格とSabreからの税込み価格を引用し、実際には20ドル高いのに、Amadeusのホテルが50ドル安く見えてしまうかもしれない。私たちはテスト中にこれが起こるのを目にしたが、これはユーザーがほとんど気づきようのない種類の誤りだ。
そこで私たちは正規化ワーカーを作った——両システムからのばらばらなJSONを受け取り、単一の標準化されたスキーマに変換する決定論的なコード層だ。オーケストレーターが生のGDSデータを目にすることは決してない。目にするのは、整然とした一貫性のあるフィールドだ——名称、税込みの合計価格、星の評価、ユーザーの関心地点からの距離。LLMはこの正規化されたデータを提示する。生のAPIレスポンスを解釈するのではない。精選された事実を翻訳するのだ。
「GPTを使えばいい」——そして投資家が言うその他のこと
なぜ検索拡張生成(RAG)を使わないのか——ホテルのデータをベクターデータベースに取り込み、LLMにそれを検索させればいい——と、人々は絶えず私に尋ねる。あるいは旅行データでモデルをファインチューニングすればいい、と。あるいは単に、より良いシステムプロンプトを加えればいい、と。
ある投資家は私に、単刀直入にこう言った。「良いプロンプトでGPTを使えばいい。モデルは十分に賢いんだから」。その直感は尊重する——それは最もシンプルな解決策であり、シンプルな解決策はたいてい正しい。だが、ここでは違う。失敗のあり方が、空港で眠る家族であるときには。
RAGは静的な知識には役立つ——「タイのビザ政策は?」——が、AA123便に空席があるかどうかは教えてくれない。それも、今この瞬間に。ファインチューニングは口調やドメインの語彙には役立つが、モデルをライブの在庫につなぐことはない。より良いシステムプロンプトは書式には役立つが、どのGDSにも存在しないホテル名をモデルが生成するのを防ぐことはできない。
旅行においてハルシネーションを防ぐ唯一のものは、AIの出力を、記録システムに由来するリアルタイムの検証済みデータに接地(グラウンディング)させることだ。そのシステムこそがGDSだ。それ以外はすべて飾りにすぎない。
制約のない創造性は混沌だ。旅行における制約は現実だ——存在するかしないかの航空座席、空いているかいないかのホテルの部屋。中間はなく、AIは中間があるふりをするのをやめなければならない。
遅さの問題はどうなのか?
エージェント型システムが速いふりをするつもりはない。一つのユーザーリクエストが、四つのツール呼び出し——検索、価格確認、規定確認、応答の合成——を引き起こすこともある。それには10〜15秒かかることがある。eコマースにおいては、それは永遠にも等しい。
私たちはこれに三つの方法で対処する。第一に、エージェントの推論をユーザーにストリーミングする。「Amadeusでフライトを検索中…」「企業の出張規定を確認中…」。作業を見せることで、体感される遅延は劇的に減る。第二に、ワーカーを並列で動かす——フライト・ワーカーとホテル・ワーカーを順番にではなく同時に検索させ、総待機時間をおおよそ半分に削る。第三に、空室結果をRedisに15分間キャッシュする。ユーザーが「あの二つ目のホテルをもう一度見せて」と言っても、私たちは再びGDSに問い合わせない。キャッシュから引き出すのだ。
2秒で答えをでっち上げるラッパーと同じくらい速いか? いや、そうではない。では、本物の答えを求めるユーザーにとって必要なだけの速さはあるか? ある。
まだできないことを認める部分
あらゆるケースに対応できるAIシステムはない。ビザの依存関係を伴う複雑な複数区間の旅程、マイナーな航空連合、交渉料金を必要とする団体予約——こうしたものは今なお破綻を招く。私たちがこれを知っているのは、そのための検知機能を作ったからだ。エージェントが解決できずにループしたり、感情分析がユーザーのいらだちを検知したりすると、システムは私たちが「コパイロット・モード」と呼ぶものに切り替わる。人間の旅行代理店員に警告を出し、会話の構造化された文脈をすべて引き継ぎ、人間がエージェントの準備したツールを使って予約を完了する。
これは失敗なのかと人々は私に尋ねる。私は逆だと思う。最も危険なAIとは、いつ止まるべきかを知らないAIだ。自らの限界を知り、優雅に引き継ぐことは、バグではなく機能だ。「専門家におつなぎします」と言うエージェントは、自信満々に推測し続けるエージェントよりも信頼できる。
これから先どこへ向かうのか
私たちが今日築いているのは土台であって、天井ではない。私たちが「レベル3」の自律性と呼ぶ段階にいる——エージェントは特定のタスクを実行するが、お金が動く前にユーザーが確認する。この先の道のりには、表示された価格を予約するだけでなく数量割引を求めてホテルのAPIに問い合わせる交渉エージェント、フライトとホテルを管理されたマージンでカスタム商品に束ねる動的パッケージングエンジン、そして先回りの障害対応——フライトの状況を24時間監視し、キャンセルが発生したときには、旅行者が何かおかしいと気づく前に、すでに次善の選択肢の座席を確保しているエージェント——が含まれる。
そのいずれも、ラッパーの上では不可能だ。システムがハルシネーションを起こせば、どれも機能しない。それらの能力の一つひとつが、私たちが築いてきた、状態を保持し、検証済みで、ツールに接地されたアーキテクチャを必要とする。
旅行業界は転換点にある。AI導入の第一波——ラッパー、チャットボット、「とにかくGPTを足せ」という実験——は、魅惑的で危険なものを生み出した。あなたが今まで会った中で最高の旅行代理店員のように聞こえるのに、実際には部屋一つ予約できないシステムだ。次の波は、より難しく、より華やかでない問いによって定義されるだろう——「AIは美しい旅程を書けるか?」ではなく、「AIはその旅程のすべての項目が、今この瞬間に、提示した価格で実際に存在することを確認できるか?」という問いだ。
コスタリカのあの家族は、美しく書かれた作り話より良いものを受け取るに値した。すべての旅行者がそうだ。推測するAIの時代は終わった。次に来るのは、確認するAIだ——そして、確信できるときにのみ語るAIだ。