Travel Agent
Setup — Credentials
Requires: A SerpAPI key. SerpAPI (serpapi.com) provides access to Google Flights, Google Hotels, and Google Maps Directions. A free tier is available with 100 searches/month. Sign up at: https://serpapi.com
Load the user's SerpAPI key before running any search. Check these locations in order:
- -
~/.serpapi_credentials → INLINECODE1 - INLINECODE2 → INLINECODE3
These are the only local files this skill reads. If neither file is found, ask the user where their SerpAPI key is stored, or whether they would like to create one at https://serpapi.com.
All flight, hotel, and transport searches are sent to serpapi.com using the user's own API key. This skill does not store, transmit, or proxy the key anywhere else.
Step 1 — Gather Trip Details (always first)
Before searching anything, ask a small set of quick questions. Keep it conversational — one message, not a form. Tailor which questions to ask based on what the user hasn't already told you.
Questions to ask (as needed):
- - 👥 How many people? (adults + children)
- ✈ Flying from which airport? (if no default configured)
- 💺 Cabin class? (Economy / Premium Economy / Business / First)
- 💰 Rough budget? (per person, or total — flights + hotel)
- 🏨 Hotel preferences? (e.g. beach, city centre, boutique, pool, specific star rating)
- 🎒 Trip vibe? (relaxing beach, city/culture, adventure, food-focused, nightlife, mix)
- 📍 One place or travel around? If moving around — roughly how many stops, or leave it to you?
- 🗓 Any flexibility on dates or duration?
Skip questions already answered. Keep to 4–6 questions max in a single message.
Step 2 — Determine Mode
Mode A: Dates ✅ + Destination ✅
- - If single stop → go to Step 3
- If multi-stop → go to Step 2M
Mode B: Dates ✅ + Destination ❓
- 1. Read INLINECODE5
- Suggest 3–4 destination options that match the dates (season fit) and the user's vibe
- For each option, include: why it's good then, rough flight time, vibe summary, and whether it suits single or multi-stop
- Wait for user to choose, then return to Mode A or 2M
Mode C: Destination ✅ + Dates ❓
- 1. Check for an installed calendar skill — try
google-calendar, outlook-calendar, or any other calendar skill available. This is an optional convenience: it checks the user's calendar for free windows to suggest good travel dates. If no calendar skill is found (or the user prefers not to use it), fall back to asking the user directly for their available date windows. Never access calendar data without the user's awareness. - Read
references/seasonal-destinations.md for best time to visit that destination - Recommend 2–3 date windows ranked by: season fit + calendar availability
- Present clearly: "Window 1: [dates] — great timing (dry season), you're free. Window 2: ..."
- Wait for user to confirm dates, then go to Mode A or 2M
Step 2M — Multi-Stop Itinerary Planning
Use when the user wants to travel around a country or region rather than stay in one place.
2M-1: Propose a Route
- 1. Read
references/multi-stop-routes.md for regional route suggestions - Based on total duration, vibe, and number of stops, propose a day-by-day route:
- Suggest how many nights per stop (balance: enough time to explore, not rushed)
- Recommend a logical geographic order (minimise backtracking)
- Note highlight of each stop (what it's known for)
- 3. Present as a clear itinerary skeleton, e.g.:
Days 1–3: Tokyo (arrive, recover, explore)
Days 4–6: Kyoto (temples, geisha district, day trip to Nara)
Days 7–9: Osaka (food scene, day trip to Hiroshima)
Day 10: Fly home from Osaka (KIX)
- 4. Invite the user to adjust: swap stops, add/remove places, change durations
2M-2: Confirm the Route
Once the user is happy with the skeleton, confirm:
- - All stop names and exact dates
- Which city to fly into (may differ from first stop)
- Which city to fly home from (may differ from last stop — open-jaw flights)
- Preferred transport between stops (flight / train / bus / hire car)
2M-3: Search All Legs
Run searches for each component in this order:
Flights:
- - Inbound: home airport → first city
- Between stops: if flying (run
search_flights.py per leg) - Outbound: last city → home airport
- Note: for open-jaw (fly into City A, home from City B), search each leg as one-way
Hotels:
- - Run
search_hotels.py for each stop with correct check-in/check-out dates
Internal transport between stops — run BOTH scripts in parallel:
CODEBLOCK1
Present all options in a single combined comparison, grouped by type:
- - ✈ Flights — fastest door-to-door if airports convenient; include airport transfer time in assessment
- 🚄 Train — usually best for city centre → city centre under ~4h; no airport faff
- 🚌 Bus — cheapest, good for budget travellers
- ⛴ Ferry — if applicable (islands, coastal routes)
For each option show: operator, duration, price, booking link.
Recommend the best option based on journey time including transfers, price, and convenience — don't just list them.
Note when advance booking is essential (e.g. Trenitalia, Eurostar, Renfe, Shinkansen).
Present the full itinerary in one structured summary — see Step 5M.
Step 3 — Search Flights (single destination)
Run scripts/search_flights.py:
CODEBLOCK2
For round trips, also run the return leg separately for more options.
Present results as 3–4 options:
- - 💰 Cheapest — lowest price, even if slower
- ⚡ Fastest — fewest stops / shortest duration
- ⭐ Best value — balance of price, airline quality, legroom
- 👑 Premium — best class/airline if budget allows
For each option show: airline + flight number, depart/arrive times, duration, stops, price, aircraft, legroom, any delay warnings.
Step 4 — Search Hotels (single destination)
Run scripts/search_hotels.py:
CODEBLOCK3
Present results as 3 tiers:
- - 🎒 Budget — good rating, lower price
- 🏨 Mid-range — solid choice, best balance
- 🌟 Splurge — top rated, premium amenities
For each: name, stars, rating, price/night, total cost, key amenities, location notes, booking link.
Step 5 — Iterate (single destination)
After presenting options, invite refinement:
- - "Swap to the BA flight instead?"
- "Find something closer to the beach?"
- "What's available in business class?"
- "Show me budget hotels only?"
Re-run the relevant script with adjusted parameters.
Step 5M — Present Full Multi-Stop Itinerary
Once all flights and hotels are searched, present a complete trip summary:
CODEBLOCK4
Invite iteration on any leg:
- - "Upgrade the hotel in City B"
- "Find a cheaper internal flight"
- "Swap City C for City D"
- "Add an extra night in City A"
Step 6 — Lock In & Calendar
Once the user confirms everything:
- 1. Summarise full trip with all costs
- Ask if they'd like the dates blocked in their calendar
- If yes: check which calendar skill the user has installed (e.g.
google-calendar, outlook-calendar, or any other calendar skill) and use that. Do not assume Google Calendar. This access is explicitly user-requested at this step — the user has just asked to add events to their calendar.
- If no calendar skill is found, offer to generate an
.ics file the user can import into any calendar app (Google, Apple, Outlook, etc.)
- 4. Create events for each component:
- Each flight leg: departure datetime → arrival datetime, airline + flight number in title
- Each hotel stay: check-in → check-out date, hotel name + address
- Spanning "Trip to [destination]" event across full duration
- 5. Include booking links in all event descriptions
Notes
- - Always show prices in the user's preferred currency (default GBP if not set)
- SerpAPI free tier = 100 searches/month — multi-stop trips use more quota; heads up if >10 searches in one session
- Open-jaw flights (fly into A, out of B) often work out cheaper than returning to origin — suggest when relevant
- See
references/serpapi.md for full API reference (flights, hotels, transport/directions) - See
references/seasonal-destinations.md for destination/timing guidance - See
references/multi-stop-routes.md for regional itinerary templates
旅行代理
设置 — 凭证
需要: SerpAPI密钥。SerpAPI(serpapi.com)提供Google航班、Google酒店和Google地图导航的访问权限。免费套餐每月提供100次搜索。注册地址:https://serpapi.com
在执行任何搜索前,加载用户的SerpAPI密钥。按顺序检查以下位置:
- - ~/.serpapicredentials → SERPAPIKEY=...
- ~/.travelagentconfig → SERPAPI_KEY=...
这是该技能读取的唯一本地文件。如果两个文件都未找到,询问用户其SerpAPI密钥存储位置,或是否愿意在https://serpapi.com创建一个。
所有航班、酒店和交通搜索均使用用户自己的API密钥发送至serpapi.com。该技能不会在其他任何地方存储、传输或代理该密钥。
步骤 1 — 收集行程详情(始终优先)
在搜索任何内容之前,先快速询问几个问题。保持对话式——一条消息,而非表单。根据用户尚未告知的信息,定制要问的问题。
需要询问的问题(按需):
- - 👥 多少人?(成人数 + 儿童数)
- ✈ 从哪个机场出发?(若未配置默认值)
- 💺 舱位等级?(经济舱 / 高级经济舱 / 商务舱 / 头等舱)
- 💰 大致预算?(每人,或总计——航班 + 酒店)
- 🏨 酒店偏好?(例如:海滩、市中心、精品酒店、泳池、特定星级)
- 🎒 旅行氛围?(放松海滩、城市/文化、探险、美食、夜生活、混合)
- 📍 一个地点还是多地旅行? 若需移动——大致几个站点,或由你决定?
- 🗓 日期或时长是否灵活?
跳过已回答的问题。单条消息最多保持4-6个问题。
步骤 2 — 确定模式
模式A:日期 ✅ + 目的地 ✅
- - 若单站 → 前往步骤3
- 若多站 → 前往步骤2M
模式B:日期 ✅ + 目的地 ❓
- 1. 读取 references/seasonal-destinations.md
- 建议3-4个符合日期(季节适宜性)和用户氛围的目的地选项
- 每个选项包括:为何此时适宜、大致飞行时间、氛围总结、适合单站还是多站
- 等待用户选择,然后返回模式A或2M
模式C:目的地 ✅ + 日期 ❓
- 1. 检查是否安装了日历技能——尝试 google-calendar、outlook-calendar 或任何其他可用的日历技能。这是可选的便利功能:它会检查用户的日历以寻找空闲窗口,从而建议合适的旅行日期。如果未找到日历技能(或用户不愿使用),则回退至直接询问用户可用的日期窗口。未经用户知晓,绝不访问日历数据。
- 读取 references/seasonal-destinations.md 了解该目的地的最佳游览时间
- 推荐2-3个日期窗口,按以下排序:季节适宜性 + 日历空闲情况
- 清晰呈现:窗口1:[日期] — 时机绝佳(旱季),您有空。窗口2:...
- 等待用户确认日期,然后前往模式A或2M
步骤2M — 多站行程规划
当用户希望游览一个国家或地区,而非停留在一个地点时使用。
2M-1:提出路线
- 1. 读取 references/multi-stop-routes.md 获取区域路线建议
- 根据总时长、氛围和站点数量,提出逐日路线:
- 建议每站停留晚数(平衡:有足够时间探索,不匆忙)
- 推荐逻辑上的地理顺序(尽量减少折返)
- 注明每站亮点(以什么闻名)
- 3. 呈现为清晰的行程框架,例如:
第1-3天:东京(抵达、休整、探索)
第4-6天:京都(寺庙、艺伎区、奈良一日游)
第7-9天:大阪(美食、广岛一日游)
第10天:从大阪(KIX)飞回家
- 4. 邀请用户调整:交换站点、增加/删除地点、更改时长
2M-2:确认路线
一旦用户对框架满意,确认:
- - 所有站点名称和确切日期
- 飞入城市(可能与首站不同)
- 飞离城市(可能与末站不同——缺口程航班)
- 站点间的首选交通方式(飞机/火车/巴士/租车)
2M-3:搜索所有航段
按此顺序搜索每个组成部分:
航班:
- - 入境:家 → 首站城市
- 站点间:若乘飞机(每段运行 search_flights.py)
- 出境:末站城市 → 家
- 注意:对于缺口程(飞入A城,从B城回家),每段按单程搜索
酒店:
- - 为每站运行 search_hotels.py,使用正确的入住/退房日期
站点间的内部交通——并行运行两个脚本:
bash
地面交通(火车、巴士、渡轮)
python3 scripts/search_transport.py \
--from 城市A, 国家 --to 城市B, 国家 \
--key $SERPAPI_KEY
国内航班
python3 scripts/search_flights.py \
--from [IATA
A] --to [IATAB] --date YYYY-MM-DD \
--adults N --class economy --currency GBP \
--key $SERPAPI_KEY
将所有选项呈现在一个组合对比中,按类型分组:
- - ✈ 航班——若机场方便,门到门最快;评估中包括机场接送时间
- 🚄 火车——通常最适合市中心到市中心约4小时以内;无机场繁琐
- 🚌 巴士——最便宜,适合预算旅行者
- ⛴ 渡轮——若适用(岛屿、沿海路线)
每个选项显示:运营商、时长、价格、预订链接。
推荐最佳选项,基于包括换乘的行程时间、价格和便利性——不要仅列出。
注明何时必须提前预订(例如:意大利铁路、欧洲之星、西班牙高铁、新干线)。
以结构化摘要呈现完整行程——参见步骤5M。
步骤 3 — 搜索航班(单目的地)
运行 scripts/search_flights.py:
bash
python3 scripts/search_flights.py \
--from [IATA] --to [IATA] \
--date YYYY-MM-DD [--return-date YYYY-MM-DD] \
--adults N [--children N] \
--class economy|premium_economy|business|first \
--currency GBP \
--key $SERPAPI_KEY
对于往返行程,也单独运行回程段以获得更多选择。
呈现3-4个选项:
- - 💰 最便宜——最低价格,即使较慢
- ⚡ 最快——最少经停/最短时长
- ⭐ 最佳价值——价格、航空公司质量、腿部空间的平衡
- 👑 高级——若预算允许,最佳舱位/航空公司
每个选项显示:航空公司 + 航班号、出发/到达时间、时长、经停、价格、机型、腿部空间、任何延误警告。
步骤 4 — 搜索酒店(单目的地)
运行 scripts/search_hotels.py:
bash
python3 scripts/search_hotels.py \
--location [城市] [偏好] \
--check-in YYYY-MM-DD --check-out YYYY-MM-DD \
--adults N [--children N] \
[--stars N] [--amenities pool,beach] \
--sort highest_rating \
--currency GBP \
--key $SERPAPI_KEY
呈现3个档次:
- - 🎒 经济——评分良好,价格较低
- 🏨 中档——可靠选择,最佳平衡
- 🌟 奢华——评分最高,高级设施
每个显示:名称、星级、评分、每晚价格、总费用、主要设施、位置说明、预订链接。
步骤 5 — 迭代(单目的地)
呈现选项后,邀请优化:
- - 换成英航的航班?
- 找更靠近海滩的?
- 商务舱有什么选择?
- 只显示经济型酒店?
使用调整后的参数重新运行相关脚本。
步骤5M — 呈现完整多站行程
搜索完所有航班和酒店后,呈现完整的行程摘要:
🌍 [行程名称] · [日期范围] · [N]人
第1-3天 | 城市A
✈ [入境航班] | [时间] → [时间] | £XX
🏨 [酒店名称] ★★★★ | £XX/晚 | £XX总计
[火车/巴士至城市B — X小时,