TMC와 OTA를 위한 에이전틱 AI 여행 예약

예약 에이전트에서 한 수 위의 선택은 더 똑똑한 모델이 아닙니다. LLM을 제어 흐름에서 빼는 것입니다.

우리는 제어 흐름이 결정론적 Python인 자율 여행 예약 에이전트를 구축했습니다. 모델은 여행 요청을 파싱하고 답변을 문장으로 만드는 일만 합니다. 모든 예약 단계는 보상 액션을 등록하므로, 항공권이 발권된 뒤 호텔 요금이 만료되면 에이전트는 24시간 창 안에서 티켓을 무효화하고, 여행객을 고립시키는 대신 정직한 대안을 건넵니다.

100%

설계상 일관된 종료 상태

고정 시드 200개 시나리오 합성 배치, LLM-제어 베이스라인의 65% 대비

0 / 0

고립된 여행객, 노출된 조작 예약

동일 배치, 베이스라인은 각각 40과 30

$3.25

예약당 평균 GDS 검색 비용

베이스라인 $7.57 대비; GDS는 검색마다 과금, Lufthansa는 2026년 1월 1일 수수료 인상

모든 시나리오는 시뮬레이션된 GDS와 CRS 위의 합성이며, 공항 코드와 호텔 이름은 실제처럼 생긴 픽스처이지 라이브 재고나 실제 예약이 아닙니다.

LLM에게 트랜잭션을 맡기면 두 가지가 잘못됩니다

둘 다 모델 IQ 실패가 아닙니다. 둘 다 이미 2026년의 버그 클래스입니다.

여행객을 고립시킵니다

에이전트가 항공권을 발권하고, 호텔 단계가 실패하는데, 보상 로직이 없으면 그래도 "모두 준비되었습니다."라고 말합니다. 누군가는 항공권만 쥐고 방은 없는 상태가 됩니다. 완벽한 모델도 티켓을 무효화하는 것이 없으면 여행객을 고립시킵니다.

존재하지 않는 재고를 노출합니다

그럴듯한 호텔을 지어내고 예약합니다. 그 숙소는 CRS에 한 번도 없었습니다. 여행객에게 닿기 전에 확인한 것이 없습니다. 추론 루프에서 모델이 제안자이자 심판이기 때문입니다.

더 나은 모델이 이것을 고치지 못하는 이유는 실패가 모델 품질과 무관한 인프라 및 사용 이벤트이기 때문입니다. 두 API 호출 사이에 요금이 만료됩니다. 티켓이 발급된 뒤 홀드가 거부됩니다. 검색 폭풍이 마진을 태웁니다. 확률적 추론은 이에 맞서 누적됩니다: 90퍼센트 신뢰도의 열 단계는 종단 간 대략 34퍼센트가 되고, GPT-4와 ReAct는 실제 여러 날 여정을 0.6퍼센트로 완료합니다(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 leaf) → search → policy gate → verify gate → hold → ticket → hotel-book → commit

Extract, LLM의 유일한 구조화 작업

모델은 자연어 의도를 Pydantic 타입의 TripRequest (출발지, 도착지, 날짜, 승객, 캐빈, 호텔)로 파싱합니다. 그 타입 객체가 LLM이 생성하는 유일한 구조화 산출물입니다. Pydantic AI를 통해 공급자를 교체할 수 있으며, 키가 없으면 결정론적 스텁으로 완전히 오프라인 실행됩니다.

코드로 컴파일된 정책

기업 정책은 순수 Python 술어로 존재합니다: 이코노미만, 세그먼트당 $600 운임 상한, 선호 항공사(United, American, Delta), 1박 $350 호텔 상한. 정책 밖 옵션은 보여진 뒤에 플래그되는 것이 아니라, 보여질 수 있기 전에 걸러지므로 물리적으로 제시 불가능합니다. 알 수 없는 운임 패밀리는 페일세이프로, 조용히 이코노미로 취급하지 않고 정책 초과로 취급합니다. 정책 내 항공편이 없으면 에이전트는 허풍을 치는 대신 사람 큐로 에스컬레이션합니다.

검증 게이트

모든 호텔은 CRS에 대해 property_id로 확인됩니다. 모델이 지어낸 숙소는 CRS에 없으므로 거부되어 절대 노출되지 않으며, 예약은 종료 상태인 abstained에 도달합니다. 게이트는 확인되지 않은 재고를 거부합니다. 모델에게 자기 출력을 채점하라고 시키지 않습니다.

Saga, 대부분의 데모가 건너뛰는 부분

각 전진 단계는 실행 시점에 자신의 역방향 액션을 등록합니다. 예를 들어 발권은 "티켓 무효화, 24시간 창"을 등록합니다. 단계 N에서 실패하면 N-1부터 1까지 보상이 역순으로 실행되고, 그다음에야 에이전트가 보고합니다. 이것이 데모와 제품을 가르는 지점입니다. 부분 실패가 고립된 고객이 되지 않게 하는 것이기 때문입니다.

GDS 비용 미터와 감사 추적

라이브 카운터가 세그먼트당 $3.25로 GDS 검색 비용을 추적합니다. 검색에도 요금이 부과되며, 예약만 그런 것이 아닙니다. L2B 캐시와 지연 검색이 비용을 평탄하게 유지하는 반면, 추측형 에이전트는 재검색하며 마진을 태웁니다. 모든 예약은 추가 전용 JSON 이벤트 로그를 기록하며 audit-<pnr>.json으로 내보낼 수 있고, 모델과 버전, 타입된 여행 요청, 모든 노드 판정, 모든 Saga 보상, EU AI Act Article 50 공시 플래그, 종료 상태를 담습니다.

데모가 보여주는 것

같은 시나리오에서 실제 LLM-제어 베이스라인과 나란히 네 개의 버튼. 아래 스크린샷은 모두 실행 중인 앱에서 캡처했습니다.

정상 예약, 노드별로

데모가 정상적인 ORD에서 SFO로 예약을 실행하는 모습. 오른쪽에서는 결정론적 파이프라인 추적이 의도 추출부터 정책 게이트, CRS 검증, 홀드, 티켓 발급, 호텔 커밋까지 각 노드를 차례로 실행하고, GDS 검색 비용 미터가 $3.25를 가리키는 confirmed PNR로 끝납니다. 왼쪽의 No Tools and No Verification이라고 적힌 패널은 모든 것이 예약되었다고만 답합니다.

"다음 화요일 ORD에서 SFO로, 시내 1박, 회사 정책." 상태 기계가 각 노드를 실행하고, Hyatt Regency SF를 property_id로 CRS에 대해 확인하며, 검색 미터는 캐시된 검색 한 번에 $3.25를 유지합니다. 종료 상태: confirmed, PNR 포함.

검증 게이트가 존재하지 않는 호텔을 거부합니다

실패한 것으로 표시된 CRS 검증 단계. 상세 패널은 Tabacon Springs Eco-Lodge가 CRS에 없어 거부되었으며 노출되지 않았다고 읽습니다. 숙소 카드는 REFUSED 스탬프와 함께, 검증 게이트가 거부하여 여행객에게 노출되지 않았다는 메모가 있습니다.

요청이 조작된 숙소 이름 "Tabacon Springs Eco-Lodge"를 지정했습니다. 두 실제 리조트를 섞은 이름이며 설계상 property_id가 없습니다. 게이트는 CRS 일치를 찾지 못해 노출을 거부합니다. 에이전트는 하나를 지어내는 대신 정직하게 기권합니다. "해당 숙소를 확인할 수 없었습니다."

Saga 롤백, 제어하는 LLM과의 대비

티켓 발급 후 호텔 요금이 만료된 파이프라인 추적. 세 개의 Saga 보상 단계가 역순으로 실행되고, 배너는 커밋 전에 홀드가 만료되어 Saga 롤백이 역순으로 보상 중이라고 읽습니다. 결과 카드는 ROLLED BACK, TRAVELER SAFE이며, 항공권이 무상으로 무효화되었고 대체 호텔이 제시된다는 메모가 있습니다.

항공권이 이미 발권된 뒤 호텔 요금이 만료됩니다. 우리 쪽에서는 Saga가 작동합니다: 24시간 창 안에서 티켓을 무효화하고, 홀드를 해제하며, 티켓이 무상으로 무효화되었고 대안이 첨부되었다고 정직하게 답합니다. 종료 상태: rolled back, 여행객 안전. 같은 시나리오의 베이스라인은 티켓을 발급된 채로 두고, 보상을 제공하지 않으며, 거짓된 "모두 준비되었습니다"를 내보냅니다. 바로 일어나기를 기다리는 Air Canada 선례입니다.

내보낼 수 있는 감사 추적

콘솔 하단의 Export Audit Trail (JSON) 링크, 옆에 rolled back 결과가 홀드된 요금이 커밋 전에 만료되었고 티켓이 무상으로 무효화되었으며 대체 호텔 두 곳이 제시되고 GDS 검색 비용이 $3.25라고 설명합니다.

한 번의 클릭으로 다음을 내보냅니다 audit-<pnr>.json: 모델과 버전, 타입된 여행 요청, 모든 노드와 그 결정론적 판정, 모든 Saga 보상, EU AI Act Article 50 공시 플래그(투명성 의무는 2026년 8월 2일부터 적용), 종료 상태.

200개 시나리오 벤치마크

동일한 주입 실패와 고정 시드로 200건의 합성 예약에 대한 벤치마크 스코어보드. 네 개의 타일이 결정론적 에이전트와 일반 LLM 베이스라인을 비교합니다: 일관된 종료 상태 100퍼센트 대 65퍼센트, 고립된 여행객 0 대 40, 조작 예약 노출 0 대 30, 평균 GDS 비용 $3.25 대 $7.57. 결과 테이블은 confirmed, rolled back, abstained, escalated, integrity breach, stranded를 포함한 시나리오별 결과를 나열합니다.

같은 200건의 합성 예약, 하나의 고정 시드(42), 같은 주입된 인프라 실패가 두 아키텍처를 통과합니다. 시나리오 구성은 정상 50퍼센트, 발권 후 호텔 실패 20퍼센트, 환각 엔티티 15퍼센트, 검색 폭풍 15퍼센트입니다. 우리의 보장은 설계로 성립하고, 베이스라인의 실패는 같은 데이터에서 나옵니다.

결정론적 제어 흐름 대 루프 안의 LLM

베이스라인은 같은 시나리오에서 실행되는 실제 ReAct 스타일 LLM-제어 에이전트이며, 허수아비가 아니라 정직한 앵커입니다. 아래 수치는 고정 시드 200개 시나리오 합성 배치에 대한 것입니다(benchmark.py, seed 42, n=200).

지표 결정론적 에이전트(우리) 베이스라인(LLM-제어)
일관된 종료 상태 100.0% 65.0%
고립된 여행객 0 40
노출된 조작 예약 0 30
예약당 평균 GDS 검색 비용 $3.25 $7.57

이 고정 시드 합성 배치에서 100퍼센트, 0, 0은 설계로 성립하며, 개방 세계 프로덕션 보장이 아닙니다. 주장은 좁고 견고합니다: 부분 예약이 confirmed로 표시되지 않으며, 여행객이 고립되지 않습니다. $3.25 대 $7.57 격차는 어떤 모델 품질에서도 성립하는 마진 수치입니다.

이 데모가 하지 않는 것

  • 라이브 GDS, CRS, 또는 NDC에 연결하지 않습니다. GDS와 CRS, IATA와 ARC 티켓 발급, PCI 결제는 스텁이며 시뮬레이션됩니다. 픽스처 어댑터가 V1 통합이며, 라이브 Amadeus, Sabre, 또는 Duffel 계정은 없습니다.
  • 실제 티켓을 발급하거나 실제 돈을 움직이지 않으며, Veriprajna는 IATA 또는 ARC 인가를 받지 않았습니다. 티켓과 결제는 스텁입니다.
  • 시나리오, PNR, 호텔, 여행객은 합성입니다. "Tabacon Springs Eco-Lodge"는 의도적으로 조작된 숙소이며 실패 모드의 시연입니다. Hyatt Regency SF와 같은 실제 이름의 호텔은 픽스처 재고이지 실제 예약이 아닙니다.
  • GDS나 OTA보다 더 많이, 더 싸게, 더 똑똑하게 예약한다고 주장하지 않으며, 모델의 환각이 0이라고 주장하지도 않습니다. LLM은 여전히 의도를 초안합니다. 보장은 게이트가 확인되지 않은 재고를 거부하고 Saga가 부분 실패를 정리한다는 것입니다.
  • 엔진은 직접 구축한 Python 상태 기계이며 LangGraph가 아닙니다. LangGraph는 미뤄 둔 프로덕션 교체로 이름만 올립니다. LLM 리프 호출은 Pydantic AI를 사용합니다.

구매자가 묻는 질문

AI 에이전트가 여행객을 고립시키지 않고 여행을 예약하도록 믿을 수 있습니까?

보장은 모델을 신뢰하는 데서 오지 않습니다. 이 데모에서 제어 흐름은 결정론적 Python이며, 모든 전진 단계는 실행되는 순간 보상 액션을 등록합니다. 티켓이 발급된 뒤 단계가 실패하면, 엔진은 그 보상을 역순으로 실행하고(Saga), 24시간 창 안에서 티켓을 무효화하며, 정직하게 보고합니다. 모델이 정리를 결정하는 것에 아무것도 의존하지 않으므로, 여행객이 항공권만 있고 방은 없는 상태로 남지 않습니다.

Amadeus, Sabre, 또는 Duffel에 연결합니까?

아니요. 이 데모에서 GDS, CRS, 티켓 발급, 결제는 모두 스텁이며 시뮬레이션됩니다. 픽스처 어댑터가 V1 통합이며, 그 뒤에 라이브 Amadeus, Sabre, 또는 Duffel 계정은 없습니다. 데모가 증명하는 것은 제어 흐름 아키텍처와 보상 로직이지, 프로덕션 예약 파이프라인이 아닙니다.

항공권이 이미 발권된 뒤 호텔이 실패하면 어떻게 됩니까?

그것이 바로 Saga가 만들어진 경우입니다. 발권은 실행되는 순간에 자신의 역방향 액션(24시간 창 안에서 티켓 무효화)을 등록합니다. 커밋 전에 호텔 요금이 만료되면, 엔진은 보상을 역순으로 발동하고, 티켓을 무상으로 무효화하며, 홀드를 해제하고, 여행객에게 정직한 대안을 건넵니다. 종료 상태는 rolled back이며, confirmed도 stranded도 아닙니다.

존재하지 않는 호텔을 에이전트가 지어내는 것을 무엇이 막습니까?

검증 게이트가 보여지기 전에 모든 숙소를 property_id로 CRS에 대해 확인합니다. 데모에서 요청이 조작된 숙소를 지정했을 때, 게이트는 CRS 일치를 찾지 못해 노출을 거부했고, 에이전트는 예약하는 대신 정직하게 기권했습니다. 게이트는 지어낸 호텔을 사후에 플래그하지 않습니다. 물리적으로 제시 불가능하게 만듭니다.

도구가 있는 에이전트 루프에 GPT-4를 넣는 것과 무엇이 다릅니까?

ReAct 스타일 에이전트는 LLM에게 트랜잭션을 맡기므로, 언제 검색하고 예약하고 발권할지를 결정하며, 게이트도 보상 로직도 없습니다. 같은 고정 시드 200개 시나리오 합성 배치에서 그 베이스라인은 조작 재고를 노출하고 롤백 없이 티켓을 발급된 채로 두며, 거짓된 "모두 준비되었습니다"를 내보냈습니다. 여기서 LLM은 의도만 파싱하고 답변을 문장으로 만드는 타입된 리프 노드입니다. 결정론적 코드가 흐름을 소유하고 각 단계는 자신의 실행 취소를 가집니다.

에이전트가 여행객에게 틀린 말을 하면 누가 책임집니까?

배포자가 자기 에이전트가 하는 모든 진술에 책임을 집니다. Moffatt v. Air Canada (BC Civil Resolution Tribunal, 2024년 2월 14일)에서 항공사는 챗봇이 사별 운임 정책을 지어낸 뒤 $812.02를 지급하라는 명령을 받았고, AI 탓이라는 항변은 기각되었습니다. 데모는 예약마다 모델과 버전, 모든 노드 판정, 모든 Saga 보상, EU AI Act Article 50 공시 플래그가 담긴 JSON 감사 추적을 내보내므로, 에이전트가 한 일을 사후에 검사할 수 있습니다.

기술 연구

이 데모 뒤의 연구 — 아키텍처, 검증 설계, 엔터프라이즈 청사진.

회사를 걸 수 없는 에이전틱 예약 계층을 평가하고 계십니까?

여행객을 고립시키고 호텔을 지어내는 실패는 인프라 이벤트이지, 모델 IQ 문제가 아닙니다.

팀이 고위험 예약 에이전트에서 LLM이 어디에 있어야 하는지, 부분 실패가 Air Canada식 책임이 되지 않게 하는 방법을 저울질하고 있다면, 그 생각을 진심으로 맞춰 보고 싶습니다. 문제는 산업 전반의 것이고 답도 그럴 것입니다.

에이전트 아키텍처 리뷰

  • ✓ 오늘 제어 흐름에서 LLM이 어디에 있는지 매핑
  • ✓ 보상 액션이 필요한 단계를 식별
  • ✓ 실패 모드를 압박 테스트: 요금 만료, 발권 후 홀드, 검색 폭풍
  • ✓ 운영자가 믿을 수 있는 종료 상태를 정의

결정론적 에이전트 구축

  • ✓ 검색, 정책, 발권을 소유하는 상태 기계
  • ✓ 검증 게이트와 Saga 보상 엔진
  • ✓ 코드로 컴파일된 정책, 페일세이프 기본값
  • ✓ Article 50 공시 플래그가 있는 내보낼 수 있는 감사 추적
소셜

다른 채널에도 게시됨