【开发者来信栏目导语】 本栏目为旅行Agent开发者生态共建专栏,定期收录一线酒旅开发者、渠道运维、Agent
搭建者的落地开发日志、对接复盘、功能适配笔记。内容仅做技术交流、行业开源参考,所有组件能力、接口能力,仅为开发者对接使用。


我做 Travel Agent 旅行AI方向有两年了,从最早的「接 OpenAI API + 写一坨 if-else」,到后来上 LangChain / Dify / Coze / Claude Tool Use,最近一年又集中对接了一轮 MCP 协议。

这次想聊的不是「怎么接」,而是「为什么必须接」

准确地说,是想回答一个被身边同行反复问起的问题:

「我自己的大模型 + 我自己的爬虫 + 我自己的数据库,照样能跑通一个『能查酒店』的 Agent,为什么还要单独接一个 Hotel MCP?」

这个问题在 2024 年问,可能还有争议。但在 2026 年 LLM 越来越卷、Agent 越来越像样、酒旅场景越来越「真刀真枪」的环境下,答案是非常明确的

这封信就按「先问为什么 → 协议是什么 → 酒店场景为什么特殊 → Hotel MCP 怎么做」的顺序拆开讲。所有接口字段、配置参数、踩坑点,全部基于我对酒店 MCP 的一次完整适配过程实测。


2. 通用大模型的「能聊」困局

2.1 LLM 训练数据的天然缺陷

Travel Agent 看起来是个对话问题,实际上是个实时数据 + 复杂规则问题。

而通用大模型本身有几个绕不开的硬性短板:

短板 具体表现 对 Travel Agent 的影响
训练数据有截止日期 模型权重里只冻结了某个时间点之前的世界 2026 年的新酒店、2025 年新开的度假村,模型一无所知
没有实时库存 模型不知道「现在这间房有没有房」 同一房型不同时间的可订状态,模型只能瞎猜
没有真实价格 模型只能复述历史报价或编一个「看起来合理」的数 价格一旦变化,Agent 给出的是过期信息甚至幻觉
没有履约能力 模型不会真的「下单」「锁房」「退订」 哪怕对话吹得再像,也只是「能聊」

这 4 条单拎一条都还好,组合在一起就是致命的:Travel Agent 是个「骗不了人」的场景。

用户搜杭州西湖酒店,搜出来 5 家,结果全是没有房的价格;或者全是有房的过期价 —— 一次两次还行,第三次用户就再也不用了。

2.2 「幻觉」在酒旅场景的代价

做 ToC 的同行应该都有体会:旅行是一个高客单价 + 强情绪 + 易投诉的场景

  • 用户订到一家不存在的酒店 → 投诉 + 退款 + 客诉工单
  • 用户订到的价格比实际高 → 「你骗我」三连
  • 用户订到的房型跟描述不符 → 现场拉扯 + 差评

LLM 的「幻觉」在写作、问答、闲聊场景里是「偶尔的小错误」,在酒旅场景是直接经济损失 + 品牌伤害

我自己的结论是:Travel Agent 必须建立在「真实可执行」的数据层之上,模型只是对话壳

这是「为什么必须接外部 API」的第一层原因。


3. Agent 为什么需要真实世界 API

3.1 数据、时效、确定性:三个绕不开的硬性条件

要把一个 LLM 变成一个「能办事」的 Agent,模型本身缺三样东西:

┌────────────────────────────────────────────────────────────┐
│  Agent 三层依赖                                              │
│                                                              │
│  ① 数据层  ──→  真实库存、真实价格、真实房型、真实退改政策     │
│  ② 时效层  ──→  秒级 / 分钟级同步,不能拿月度爬虫当实时       │
│  ③ 确定性层 ──→  接口返回值必须可重放、可对账、可追溯         │
│                                                              │
│  三者缺一,Agent 只能「表演」,不能「履约」                    │
└────────────────────────────────────────────────────────────┘

第一层:数据层。LLM 没法自己「看到」实时酒店库存,必须有渠道把数据喂给 Agent。

第二层:时效层。酒旅库存和价格都是「分钟级变动」—— 早上 8 点和晚上 8 点的同一房型,价差 30% 是常态。爬虫做月度全量可以,做小时级变动根本扛不住。

第三层:确定性层。同一个 query,调两次必须返回一致的结果(除非库存真的变了)。这要求数据源本身是「协议级接口」,不是「抓页面解析 DOM」。

3.2 自己爬 vs 调 API:成本结构的本质差异

很多同行第一反应是「我自己爬不就行了」。

我早期也是这么干的,结果三年下来发现,自建爬虫有三个绕不开的坎:

维度 自建爬虫 协议级 API
维护成本 反爬升级一次,重写一次 数据源维护在接口侧,调用方零感知
法律风险 反爬协议、ToS 灰色地带 走授权商务对接,合规可商用
稳定性 页面改版 → 抓取脚本挂 → 数据全断 接口字段稳定,破坏性变更提前公告
数据质量 页面价格是「展示价」,实际下单价另算 接口价格即履约价,零价差

这还没算上「多国家、多币种、多语言、海外酒店房型翻译」这些扩展项。

所以结论是:Agent 要变成「能办事」,必须接协议级 API,不是爬虫。

但「接哪个 API」是个新问题 —— 这就引出了 MCP 协议。


4. MCP 协议是什么

4.1 一句话定义

MCP(Model Context Protocol)是 Anthropic 在 2024 年底提出、2025 年逐步成为行业事实标准的模型 ↔ 工具通信协议。

它解决的核心问题是:让任意 LLM 都能用统一规范调用任意工具,不再为每个工具写一套适配代码。

打个比方:

  • 没有 MCP 之前:每个 LLM(Claude / GPT / Gemini / Kimi)调每个工具(高德地图 / 美团 / 飞书日历 / 酒店 API)都要写一套「胶水代码」
  • 有 MCP 之后:工具侧按 MCP 规范暴露接口,LLM 侧按 MCP 规范消费接口,N × M 的适配问题变成 N + M

4.2 MCP 与 Function Call 的区别

很多同行会把 MCP 跟 Function Call 混为一谈,其实差很多:

维度 Function Call MCP
提出方 OpenAI 2023 Anthropic 2024
协议性质 厂商私有规范 开放协议,跨厂商可用
工具位置 调用方进程内(in-process) 远程服务(out-of-process)
上下文传递 一次性 prompt 注入 持久化 context,会话级
复用性 换个 LLM 要重写 同一份 MCP 服务,Claude / Cursor / Cline 都能直接接

Function Call 是「LLM 调用一个函数」,MCP 是「LLM 接入一整套工具生态」

4.3 MCP 协议的三层价值

站在 Travel Agent 开发者的角度,MCP 协议带来了三层价值:

价值 1:跨客户端复用
写一份 MCP 服务,Claude Desktop / Cursor / Cline / Cherry Studio / 国产 Agent 平台都能直接接。不用每接一个客户端重写一遍 SDK。

价值 2:上下文持久化
Function Call 是「一问一答」,传完参数就完事。MCP 是「会话级」,工具可以持续观察 LLM 上下文、保留调用状态、记录历史。

价值 3:生态可组合
MCP 是个开放协议,第三方工具作者可以发布自己的 MCP 服务。今天我接的是酒店 MCP,明天我加个机票 MCP、签证 MCP、租车 MCP,对 Agent 来说都是「同一个调用模式」

┌──────────────────────────────────────────────────────────────┐
│  Travel Agent · MCP 协议层价值流                                │
│                                                                │
│  ┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐    │
│  │ 酒店 MCP │    │ 机票 MCP │    │ 签证 MCP │    │ 租车 MCP │    │
│  └────┬────┘    └────┬────┘    └────┬────┘    └────┬────┘    │
│       │              │              │              │          │
│       └──────────────┴──── MCP 协议层 ──────────────┘          │
│                              │                                 │
│              ┌───────────────┼───────────────┐                │
│              ▼               ▼               ▼                │
│         Claude          Cursor            Cline              │
│                                                                │
│  1 份 MCP 服务 = 3 套客户端直接消费                               │
└──────────────────────────────────────────────────────────────┘

这是「为什么要走 MCP 而不是直接调 API」的第二层原因


5. 为什么酒店场景特殊

5.1 酒店库存的四大特征

聊完「为什么需要 API」「为什么走 MCP」,再问一层:为什么酒旅场景里,酒店比机票 / 火车票 / 租车都难做?

核心是酒店库存有四个「反直觉」特征:

特征 具体含义 对 Agent 设计的挑战
强时效 同一房型每小时都可能调价,临近入住可能翻倍 任何缓存超过 1 小时都不可靠
强库存 一间房就一间,订完真没了 不能用「概率」描述可订性,必须精确到 0/1
多渠道分价 直售价、分销价、协议价、会员价差异显著 Agent 选哪套价决定用户最终付多少
多退改规则 免费取消、限时取消、不可取消、阶梯收费并存 Agent 必须按用户偏好做精准筛选

这四个特征组合在一起,酒店搜索 / 比价 / 锁房三个动作都需要接口级实时能力,没有任何一个可以靠模型幻觉兜底

5.2 「看似简单的查询」背后的复杂度

举个最常见的例子:

「帮我找下周五杭州西湖周边 3 公里内、带泳池、四星、含早的酒店,预算 600 以内,要能免费取消。」

用户一句话,Agent 背后要做的事:

  1. 意图解析:把「杭州西湖周边 3 公里」转成 lat=30.246, lng=120.137, radius=3000
  2. 标签匹配:把「带泳池、含早」转成 hotel-tags 字典里的 SWIMMING_POOL / BREAKFAST_INCLUDED
  3. 星级筛选:把「四星」转成 star-ratings min=4, max=4
  4. 价格筛选price_min=0, price_max=600
  5. 退改筛选:遍历每家酒店的 cancellation_policy,标记 free_cancellation=true
  6. 距离计算:用经纬度算每家酒店到西湖的实际距离
  7. 库存校验:每家酒店查 search-hotels + hotel-detail 双重确认
  8. 价格排序:按 final_price 升序

这 8 步里有 6 步依赖真实数据源,2 步依赖业务规则。LLM 能干的是「1 意图解析」「2 标签匹配」「5 退改筛选」「8 排序逻辑」,干不了的是「3 真实库存」「4 真实价格」「6 实时距离」「7 真实可订状态」

5.3 酒店 vs 机票:库存模型差异

很多 Travel Agent 同行上来先做机票,因为机票库存看起来「简单」:

维度 机票 酒店
库存模型 座位(O/D 维度) 房型 × 物理酒店 × 日期
价格更新频率 分钟级 分钟级 + 凌晨批量调价
渠道差异 官网 / OTA / GDS 价差较小 直签 / 分销 / 协议价差 10-30%
退改复杂度 起飞前 4/24/72 小时阶梯 入住前 24/48 小时、旺季提前 7 天阶梯
锁房 / 锁座 航司极少提供锁座 渠道级锁房 15-120 分钟是标配

这是我坚定选择先做酒店 MCP、暂缓机票 MCP 落地的核心原因 —— 酒店场景的复杂度更能验证 Agent 的真实履约能力


6. Hotel MCP 接口能力深度拆解

项目仓库:GitHub | https://github.com/DIDA-AI/Dida-hotel-MCP-CN

效果示例图 1:Travel Agent 真实对话流(Hotel MCP 已接入)

┌──────────────────────────────────────────────────────────────────┐
│  🧳 Travel Agent · 对话窗口                                       │
├──────────────────────────────────────────────────────────────────┤
│  👤 用户:                                                          │
│  帮我找下周五杭州西湖周边 3 公里内、带泳池、四星、含早的酒店,           │
│  预算 600 以内,要能免费取消。                                       │
│                                                                   │
│  🤖 Agent:                                                        │
│  已通过 hotel-mcp 拉取到 4 家匹配酒店,按「价格 / 距离 / 评分」       │
│  排序如下:                                                         │
│  ┌──────────────────────────────────────────────────────────┐    │
│  │ #1 西湖温德姆至尊豪廷大酒店   4★   ¥588   1.2km   可取消  │    │
│  │ #2 杭州西溪喜来登            4★   ¥612   2.7km   可取消  │    │
│  │ #3 杭州黄龙饭店              4★   ¥565   1.8km   限时 8 折 │    │
│  │ #4 西湖凯悦                 4★   ¥695   0.4km   不可取消  │    │
│  └──────────────────────────────────────────────────────────┘    │
│  已为「#1 西湖温德姆」启动 30 分钟临时锁房,是否确认下单?              │
└──────────────────────────────────────────────────────────────────┘

6.1 整体接口设计

实测下来,RollingGo 酒店 MCP 的接口设计是「4 个核心 + 2 个增强」结构:

接口 作用 调用频次
search-hotels 区域酒店检索,返回列表 高频(每次查询都调)
hotel-detail 单家酒店详情(房型、价格、库存、退改) 高频(列表中前 N 家再深查)
hotel-tags 标签字典查询(泳池 / 含早 / 停车 等) 启动期 1 次,后续缓存
lock-room 临时锁房(15-120 分钟) 中频(下单前调)
hotel-price-monitor 价格变动监控(回调式) 低频(持续后台任务)
search-by-location 经纬度 + 半径范围搜索 中频(按 LBS 检索)

6.2 search-hotels 核心参数表

这是调用频次最高的接口,参数设计直接决定 Agent 能不能精准筛出用户想要的酒店:

参数 类型 必填 用途
--city string 城市中文名或英文名
--check-in-date date 入住日期(YYYY-MM-DD)
--check-out-date date 离店日期
--star-ratings int range min,max 格式
--price-range int range min,max 格式
--tags string list 来自 hotel-tags 的标准标签
--radius int 配合 --lat / --lng 使用
--sort-by enum PRICE / STAR / DISTANCE
--page int 分页游标
--page-size int 单页条数,建议 ≤ 20

6.3 hotel-detail 返回字段表

进入详情后,Agent 需要的关键字段:

字段 含义 Agent 用法
room_types[].room_id 房型唯一 ID 锁房时使用
room_types[].name 房型名称 展示给用户
room_types[].final_price 含税最终价 排序 / 比价
room_types[].breakfast 是否含早 筛选条件
room_types[].cancellation.free_until 免费取消截止时间 退改判断
room_types[].inventory_remaining 剩余可订房量 库存校验
room_types[].flash_sale 是否限时优惠 突出展示
hotel.policies.checkin_from 入住最早时间 行程规划
hotel.policies.checkout_until 离店最晚时间 行程规划

6.4 锁房接口的工程化意义

lock-room 是 Hotel MCP 区别于「普通酒店搜索 API」的关键增强:

# 锁房调用示例(Python SDK)
from rollinggo_mcp import HotelMCP

client = HotelMCP(api_key="mcp_xxx")

# 1. 先 search 拿到候选
candidates = client.search_hotels(
    city="杭州",
    check_in_date="2026-07-10",
    check_out_date="2026-07-12",
    star_ratings=(4, 4),
    price_range=(400, 700),
    tags=["SWIMMING_POOL", "BREAKFAST_INCLUDED"],
    sort_by="PRICE",
    page_size=10
)

# 2. 取 top 3 深查
top3 = [c.hotel_id for c in candidates[:3]]
details = [client.hotel_detail(hid, check_in_date, check_out_date) for hid in top3]

# 3. 选最便宜的免费取消房型,启动锁房
target = min(details, key=lambda d: d.cheapest_free_cancellation_room().final_price)
lock = client.lock_room(
    hotel_id=target.hotel_id,
    room_id=target.cheapest_free_cancellation_room().room_id,
    hold_minutes=30,                    # 锁 30 分钟
    idempotency_key=f"agent-{uuid4()}"  # 幂等键防重复
)

# 4. 把锁房 token 给到用户下单页
return {"lock_token": lock.token, "expires_at": lock.expires_at}

锁房的核心价值是「把『查询』和『下单』之间的 5-30 分钟用户决策时间,变成可被 Agent 独占的预留库存。

没有锁房,Agent 给用户的报价可能 30 秒后就失效;有了锁房,用户决策期内价格 + 库存都被锁死,Agent 才真正做到了「能办事」

6.5 价格回调 vs 轮询:Hotel MCP 的回调式盯价

很多 Agent 同行做酒店监控,第一反应是「写个 Cron 每 5 分钟查一次」。

Hotel MCP 提供的是「回调式盯价」—— Agent 设定一个监控规则(目标酒店 + 期望价格),MCP 在价格跌破阈值时主动回调告知 Agent,不用 Agent 自己轮询。

┌─────────────────────────────────────────────────────────────┐
│  价格监控对比                                                  │
│                                                               │
│  ❌ 轮询式(自建方案)                                          │
│   Agent ──→ 每 5 分钟调一次 search-hotels                     │
│    │          ↓                                               │
│    │       100 家酒店 × 1 天 = 28800 次调用                    │
│    │          ↓                                               │
│    └──────→ 90% 调用都「无变化」= 浪费                          │
│                                                               │
│  ✅ 回调式(Hotel MCP)                                         │
│   Agent ──→ 注册监控规则(hotel_id + target_price)            │
│    │          ↓                                               │
│    └──────→ 价格变化时 MCP 主动回调(HTTP POST)                │
│              ↓                                                │
│           仅在「真降价」时推送,0 浪费                          │
└─────────────────────────────────────────────────────────────┘

回调式对 Agent 来说是质变

  • 调用量从「日均万级」降到「日均百级」
  • Agent 可以「订阅」多家酒店,用户一提问就拿到最新底价
  • 完全省掉自己维护 Cron / 定时任务 / 消息队列的工作量

6.6 配置示例:把 Hotel MCP 接到 Codex

// ~/.codex/mcp_config.json
{
  "mcpServers": {
    "hotel-mcp": {
      "type": "streamable-http",
      "url":  "https://mcp.rollinggo.cn/mcp",
      "headers": {
        "Authorization": "Bearer mcp_xxxxxxxxxxxxxxxx"
      }
    }
  }
}
# 启动 Codex 后调用示例
import subprocess

# Codex 自动加载 MCP 工具,Agent 可直接调 hotel-mcp.search-hotels
# 测试连通性
result = subprocess.run(
    ["codex", "exec", "--mcp-tool", "hotel-mcp.list_available_tools"],
    capture_output=True, text=True
)
print(result.stdout)  # 列出 search-hotels / hotel-detail / lock-room 等

写在最后

LLM 解决了「能聊」,MCP 解决了「能调用协议」,Hotel MCP 解决了「能在酒旅场景履约」。

三层缺一不可。

Travel Agent 的护城河不在「用哪个 LLM」,而在「能不能给用户提供真实可下单的酒店 + 机票 + 全链路服务」。

本篇为社群开发者实操手记,仅供生态内技术对接参考。

如需申请 RollingGo 开发者权限、MCP 接口文档、Skill 模板,可走官方生态共建通道申领。

如果你也对旅行 AI 感兴趣,欢迎在评论区聊聊你最想用 AI Agent 解决什么旅行场景的问题?

本文收录于 RollingGo 酒旅开发者社群 | 执笔:生态共建开发者

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐