面向 TMC 与 OTA 的智能体 AI 旅行预订
我们构建了一个自主旅行预订智能体,其控制流是确定性 Python。模型只负责解析行程请求并措辞回复。每一步预订都会登记一项补偿动作,因此当航班已出票后酒店房价过期时,智能体会在 24 小时窗口内作废机票,并向旅客给出如实的备选方案,而不是把他们滞留。
100%
一致的终态,由构造保证
固定种子的 200 场景合成批次,对照 LLM 掌控基线的 65%
0 / 0
滞留旅客、被呈现的虚构预订
同一批次,对照基线的 40 与 30
$3.25
每笔预订平均 GDS 检索花费
对照基线 $7.57;GDS 按次检索计费,汉莎航空于 2026 年 1 月 1 日上调费用
全部场景均在模拟的 GDS 与 CRS 上合成;机场代码与酒店名称为仿真夹具,并非实时库存或真实预订。
两者都不是模型智商失败。两者都已是 2026 年的缺陷类别。
智能体为航班出票,酒店步骤失败,且没有补偿逻辑时,它仍会说「一切就绪。」有人手里只剩机票没有房间。如果没有任何东西作废机票,再完美的模型仍会滞留旅客。
它编造一家看似合理的酒店并预订。该物业从未在 CRS 中。在到达旅客之前没有任何核验,因为在推理循环中,模型既是提议者又是裁判。
更好的模型修不了这一点,是因为这些失败是基础设施与使用事件,与模型质量无关。房价在两次 API 调用之间过期。出票后预留被拒。检索风暴烧掉利润。随机推理会对此叠加:十步各 90 percent 可靠,端到端大约只有 34 percent,而 GPT-4 配 ReAct 完成真实多日行程的成功率仅为 0.6 percent(TravelPlanner,OSU NLP,arXiv 2402.01622)。你无法靠提示词走出叠加的随机失败。
而且部署方对其智能体所说的每一句话负责。在 Moffatt v. Air Canada(BC Civil Resolution Tribunal,2024 年 2 月 14 日)中,该航空公司因其聊天机器人编造丧亲票政策而被判支付 $812.02,且「AI 是独立实体」的抗辩被驳回。
控制流是一台手工构建的、大约十个节点的 Python 状态机。LLM 被限制在两项叶子工作。两者之间的一切都是确定性的。
input → extract(LLM 叶子) → search → policy gate → verify gate → hold → ticket → hotel-book → commit
模型将自然语言意图解析为 Pydantic 类型化的 TripRequest (origin、destination、date、passengers、cabin、hotel)。该类型化对象是 LLM 产生的唯一结构化产物。它通过 Pydantic AI 可替换提供商,并在没有密钥时以确定性桩完全离线运行。
公司政策以纯 Python 谓词存在:仅经济舱、每航段 $600 票价上限、首选承运人(United、American、Delta)、每晚 $350 酒店上限。政策外选项在物理上无法呈现,因为它们在展示之前就被过滤,而不是事后打标。未知票价族按故障安全处理,被当作超政策而非默认为经济舱。若无政策内航班,智能体升级到人工队列,而不是虚张声势。
每一家酒店均对照 CRS 按 property_id确认。模型虚构的物业根本不在 CRS 中,因此被拒绝且永不呈现,预订到达终态 abstained。关卡拒绝未确认库存;它不要求模型给自己的输出打分。
每一步前向操作在执行时登记其反向动作。例如出票会登记「作废机票,24 小时窗口」。当第 N 步失败时,从 N-1 到 1 的补偿按相反顺序运行,然后智能体才报告。这正是演示与产品的分野,因为它防止部分失败变成滞留客户。
实时计数器按每航段 $3.25 跟踪 GDS 检索花费,因为计费的是检索,而不仅是预订。L2B 缓存与延迟检索使其保持平稳,而投机智能体会反复检索并烧掉利润。每笔预订写入仅追加的 JSON 事件日志,可导出为 audit-<pnr>.json,载有模型与版本、类型化行程请求、每个节点裁决、每一次 Saga 补偿、EU AI Act Article 50 披露标志,以及终态。
四个按钮,与同一场景上真实的 LLM 掌控基线并排。下方每张截图均取自正在运行的应用。
「ORD 到 SFO,下周二,市中心一晚,公司政策。」状态机运行每个节点,按 property_id 对照 CRS 确认 Hyatt Regency SF,检索计量器在一次缓存检索上保持 $3.25。终态:confirmed,带有 PNR。
请求点名了一家虚构物业「Tabacon Springs Eco-Lodge」,该名称混合了两家真实度假村,并按设计没有 property_id。关卡找不到 CRS 匹配并拒绝呈现。智能体如实 abstained,「我无法确认该物业」,而不是编造一家。
酒店房价在航班已出票后过期。在我们这边 Saga 触发:在 24 小时窗口内作废机票、释放预留,并如实回复机票已免费作废且附上备选方案。终态:rolled back,旅客安全。同一场景下的基线让机票保持已出票、不提供补偿,并发出虚假的「一切就绪」,这正是等待发生的 Air Canada 先例。
一键导出 audit-<pnr>.json:模型与版本、类型化行程请求、每个节点及其确定性裁决、每一次 Saga 补偿、EU AI Act Article 50 披露标志(透明度义务自 2026 年 8 月 2 日起适用),以及终态。
同样的 200 笔合成预订、一个固定种子(42),以及相同的注入基础设施失败在两种架构上运行。场景组合为 50 percent 顺利、20 percent 出票后酒店失败、15 percent 幻觉实体、15 percent 检索风暴。我们的保证由构造成立;基线的失败从同一数据中涌现。
基线是在相同场景上运行的真实 ReAct 风格 LLM 掌控智能体,是诚实锚点而非稻草人。下列数字来自固定种子 200 场景合成批次(benchmark.py,seed 42,n=200)。
| 指标 | 确定性智能体(我们的) | 基线(LLM 掌控) |
|---|---|---|
| 一致终态 | 100.0% | 65.0% |
| 滞留旅客 | 0 | 40 |
| 被呈现的虚构预订 | 0 | 30 |
| 每笔预订平均 GDS 检索花费 | $3.25 | $7.57 |
100 percent、0 和 0 在此固定种子合成批次上由构造成立,并非开放世界的生产保证。主张狭窄且耐久:部分预订从不以 confirmed 展示,旅客从不会 stranded。$3.25 对 $7.57 的差距是在任何模型质量下都成立的利润数字。
保证并不来自信任模型。在本演示中,控制流是确定性 Python,每一步前向操作在运行的那一刻就登记一项补偿动作。当某步在出票后失败时,引擎按相反顺序运行这些补偿(一次 Saga),在 24 小时窗口内作废机票,并如实报告。旅客从不会只剩机票没有房间,因为清理并不取决于模型决定去做。
否。本演示中的 GDS、CRS、出票与支付全部为桩和模拟。夹具适配器是 V1 集成,背后没有实时的 Amadeus、Sabre 或 Duffel 账户。本演示证明的是控制流架构与补偿逻辑,而不是生产预订流水线。
这正是 Saga 所针对的情形。出票在运行的那一刻登记其自身的反向动作(在 24 小时窗口内作废机票)。若酒店房价在提交前过期,引擎按相反顺序触发补偿,免费作废机票、释放预留,并向旅客给出如实的备选方案。终态是 rolled back,不是 confirmed,也不是 stranded。
核验关卡在物业被展示之前,按 property_id 对照 CRS 确认每一处物业。当请求在我们的演示中点名一家虚构物业时,关卡找不到 CRS 匹配并拒绝呈现,智能体如实 abstained 而不是预订它。关卡不是事后给编造的酒店打标;它使其在物理上无法呈现。
ReAct 风格智能体把 LLM 放在交易的掌控位置,因此由它决定何时检索、预订和出票,并且没有关卡、没有补偿逻辑。在同一固定种子 200 场景合成批次上,该基线呈现了虚构库存,并让机票保持已出票而无回滚,发出虚假的「一切就绪」。在这里,LLM 是只解析意图并措辞回复的类型化叶子节点;确定性代码拥有流程,每一步都带着自己的撤销。
部署方对其智能体所说的每一句话负责。在 Moffatt v. Air Canada(BC Civil Resolution Tribunal,2024 年 2 月 14 日)中,该航空公司因其聊天机器人编造丧亲票政策而被判支付 $812.02,且「都是 AI 干的」抗辩被驳回。本演示导出按预订的 JSON 审计轨迹,载有模型与版本、每个节点裁决、每一次 Saga 补偿,以及 EU AI Act Article 50 披露标志,因此智能体做了什么事后可查。
支撑本演示的研究——架构、核验设计,以及企业蓝图。
完整解决方案
探索智能体 AI 旅行预订解决方案 →滞留旅客和编造酒店的失败是基础设施事件,不是模型智商问题。
如果你的团队正在权衡 LLM 在高风险预订智能体中应处的位置,以及如何防止部分失败变成 Air Canada 式责任,我们真心希望能一起探讨。问题是全行业的,答案也将是。