Trip Planner

Dev Tools

Plan trips and build day-by-day travel itineraries, delivered as one polished, standalone HTML page. Use this skill PROACTIVELY for any travel-planning request — trigger on "帮我规划行程 / 旅游攻略 / X日游 / 安排去XX玩 / 做旅行计划 / 行程安排 / 帮我排个行程", on "plan a trip / make an itinerary / X-day trip to a city / things to do in a place", and whenever the user gives a destination plus dates or a duration (e.g. "6月去东京玩5天", "国庆想去成都4天", "trip to Kyoto next month", "下周末杭州两日游"). Always gather requirements first (never jump straight to an itinerary), research transport/weather/opening-hours via web search (query-only — it never books or pays), then output ONE self-contained HTML file with an embedded Leaflet + OpenStreetMap map, per-day timeline cards, transport-segment cards, a budget table, a pre-departure checklist, collapsible sections, hierarchical navigation, scroll-memory, and 注意/必订/避雷 callouts. Do NOT use for academic study notes (use study-notes) or generic business reports (use visual-report).

Install

openclaw skills install trip-planner

Trip Planner Skill

Produces a detailed, realistic, day-by-day travel plan as a single polished HTML file — geographically sensible routing, honest time budgets, verified opening hours and prices, an embedded interactive map, and a pre-trip checklist. The visual design reuses the study-notes HTML output spec (collapsible blocks, hierarchical nav, colored callouts, dark-mode theme, scroll-position memory), retargeted to travel and documented in references/design-system.md.

Audience assumption: the reader is the traveler. Write so they can follow the plan on their phone during the trip — concrete times, addresses, prices, "how to get there", and what to do if it rains.

Environment (Windows / Claude Code). There is no places_search, places_map_display_v0, or weather_fetch tool here. Do research with web_search; render the map by embedding Leaflet + OpenStreetMap in the output HTML (OSM tiles need no API key). For requirements gathering use the AskUserQuestion structured-question tool if available, otherwise ask in plain text — batched by dependency layer, each question carrying a recommended answer (see Step 1).

Browser scraping — read the DOM with javascript_tool, don't screenshot-and-eyeball. 查机票/酒店价、 携程/高德评论时,优先用 javascript_tool 抓 DOM 取结构化 JSON(省 token,且绕开高德 canvas 截图报错—— 评价在 HTML 面板里,JS 抓得到)。探测脚本 + 各站点已复验选择器模板见 references/scraping-method.md; 只在确认加载/需要视觉/canvas 内容时才截图。保存的选择器只是"自检缓存"、会过期——取到 0 条就按该文档 §八 自愈降级(探测脚本 → 锚定内容模式 ¥/HH:MM/日期 → 语义兜底),别干等、别放弃;自愈失败仍取不到,就如实 标「未读到 · 以官网为准」,绝不编。

Output path. Write the final HTML to the current working directory (or a directory the user names). Filename: <目的地><N>日游行程.html (e.g. 东京5日游行程.html).


数据诚信契约(DATA INTEGRITY — 凌驾本文件一切其它规则)

这个 skill 唯一不能破的底线:页面上每一个具体数字/事实,要么本会话真的查到了,要么就别写成具体值。 宁可不写,绝不编。 一次编造的营业时间能把游客送到闭馆的门口,一张编造的"4.8 分 3,201 条点评(已核)" 能让整份行程的可信度归零。这条契约的违反,比任何排版/组件缺失都严重。

浏览器优先,不是浏览器可选。 机票、酒店(价格+评论)都是强制要主动尝试浏览器的项—— 先去连/去查,连不上或用户跳过才退到估价。不许因为"这趟没机票"或图省事,跳过尝试直接走 web_search 估价。

两类来源,泾渭分明:

  • 实查(可写具体值):本会话真的用浏览器(携程/飞猪/航司官网/高德)或 web_search 读到了, 且就近标了来源——浏览器读的标「实查于 YYYY-MM-DD」/「浏览器实读点评区」/「高德实测」, web_search 读的标「web_search · 未浏览器核实」,火车标「以 12306 为准」。 注意:web_search 只能给价格区间和事实概要,给不了真实评论区——评论结论与评分只有浏览器读得到, web_search 写评论=编造。
  • 没查到(禁止写具体值):没读到就不许填一个看起来合理的数。用不含杜撰细节的 hedge 占位, 例如「营业时间以官网为准」「评分以 App 为准」「打车费用以高德为准」「车次时刻以 12306 实时为准」。

受控『已验证』词表——只有真查到才能用: 已核 / 已核实 / 可信 / 实测 / 实测数据 / 浏览器实读 / 浏览器实查 / 高德实测 / 分布正常 / 不像刷分 / 好评集中在X / 口碑稳 / 活跃真实。这些词只有当本会话确实读到对应内容、且同一处带了来源+日期标记时 才允许出现。同一张卡/同一段里,价格标了「未核实/估价」,就绝不能在别处出现这些词——那是自相矛盾, 是最恶劣的"伪装成已核实"。也不要用同义词(口碑扎实/水分不大/可放心订/评分稳)绕开——任何关于评论区 的结论性判断,没有就近来源标记,一律不写。

按面分项的硬规矩(每一面都管,不只是酒店):

数据实查到 → 可写没查到 → 只能写
酒店评分/点评数具体分+条数+「实查于 日期」留空,或「评分以 App 为准」(禁止任何分数/条数)
评论体检结论读到的真实复发主题+来源标记只写"为什么选它/订前自查"这类连锁常识推荐理由
酒店/机票比价现役平台(携程/飞猪/官网)真实价现役平台估价并标「(估)」;已废平台(去哪儿/美团/同程/艺龙)禁止出现;估价行不得打「✓最低」
门票¥/营业时间/地址实查值就近标「以官网为准」(禁止编逐项联票价并做"单买超¥X"的派生算术)
车次号/分钟级时刻/票价实查值+「以12306为准」不写具体车次号与到发分钟,只写「高铁直达约 Nh · 班次票价以12306实时为准」
预约配额/放号时刻实查值「名额有限 · 配额与放号以官方公众号当日为准」(禁止编"每日2000人/8:00放号")
打车¥/分钟/里程高德路线规划值+「(高德实测)」「打车可达 · 费用时长以高德为准」(短步行腿 ≤2km 可按 70–80 m/min 估距离+步行 min,但一旦出现¥或"打车"就必须高德来源;禁止"步行或打车 N min"这种混写偷渡打车分钟)
步数由实测里程换算(≈1,300 步/km)不标具体步数
天气(>14 天外)——「X月气候典型 约A°/B°(非当日预报,出行前再查)」,不得对多日复制同一具体温度串当各日预报
地图坐标知名点的已知坐标定位不到就降到城区级并注明近似,禁止给定位不到的点编 4 位小数精确坐标
预算派生各项来自上面的实查/估价不得把编造的单价滚成"精确"日小计/总计;header 总价与预算表必须一致

逃生门("你直接安排就行")只放宽提问,不放宽这条契约:缺的偏好按推荐值填、写进顶部假设 callout; 但任何事实仍然遵守上表——没查到就 hedge,绝不因为是非交互模式就开始编数字。

scripts/check_html.py 的第 8–10 检查是这条契约的兜底(抓最常见的编造:无凭据的酒店评分/评论结论、 假"最低"比价、复制粘贴的假天气)。但校验器只是结构兜底、挡不住刻意绕过——真正的防线是你自己守住"宁可 不写绝不编"


Run it as a workflow (plan → research → verify → assemble)

Don't free-write a plan in one pass. The quality comes from the structure:

  1. Plan — gather requirements (Step 1), then sketch the day count, geographic clusters, and which stops need booking. Nothing is researched yet; this is the skeleton.
  2. Research (fan-out) — for each day/cluster, look up transport, weather, opening hours, closure days, and prices with web_search (Steps 2–3). For a big trip you may run parallel subagents, one per day or per city.
  3. Verify (the decisive step) — enforce the 数据诚信契约 above: every specific number/fact is either actually verified this session (with a source marker) or written as a hedge that carries no invented specifics — never a plausible-looking number. This applies to every surface, not just hotels: 票价/营业时间/地址/车次/时刻/船票/打车费/里程/步数/预约配额/坐标/天气. Re-check that no stop is scheduled on its closing day and that intercity connections leave realistic buffers.
  4. Assemble — build the HTML per references/design-system.md, then run the checker (scripts/check_html.py).

The six steps below are mandatory and in order. Do not skip Step 1.


Step 1 — 需求采集(GRILL,问透为止 — never skip, never jump straight to an itinerary)

This is the most common failure mode: producing a generic itinerary before knowing who's traveling and what they want. Don't. 需求采集采用 grill 式访谈(方法源自 grill-me): 沿着决策树把每一个分支问到底,直到没有任何一项需求是靠猜的。四条铁律:

  1. 问透为止,不设问题数上限。 下面清单里的每一项,要么用户答了,要么用户明确同意用推荐值—— 没有第三种状态。一轮 3–4 问、按依赖顺序分多轮(用 AskUserQuestion,没有就纯文本编号提问), 问完一层再问下一层,直到清单清零。
  2. 每问必附推荐答案。 每个问题给出你基于已知信息的推荐选项和一句理由(放在选项第一位), 用户嫌烦可以整轮"都按推荐"。
  3. 能查的绝不问。 凡是 web_search/浏览器能查到的(天气、闭馆日、签证政策、有没有直达高铁), 自己查;只问存在于用户脑子里的事(偏好、约束、已订了什么)。
  4. 先读 prompt,绝不重问已知。 开场先把用户已给的信息抽出来打勾,只 grill 缺口。

需求决策树(按依赖顺序分层 grill)

第 1 层 · 骨架(决定一切的硬事实)

  • 目的地 + 出发地(精确到城市/机场)
  • 日期 / 天数(精确日期;驱动天气、节庆、闭馆、票价)
  • 大交通是否已订? 已订 → 拿到具体班次/车次时刻,行程以它为锚,Step 2 只做接驳; 未订 → Step 2 全流程实查比价
  • 城际出行方式偏好 — 飞机 / 高铁 / 自驾 / 不限(价格 vs 时间怎么权衡;红眼/早班能不能接受)
  • 时间硬约束 — 出发日最早几点能出门?返程当天必须几点前到家?行程中间有无固定事项(会议/探亲/复诊)
  • 证件 — 身份证/护照在不在有效期?出境/港澳台需要的签证签注办了吗(政策本身自己查,证件状态问用户)

第 2 层 · 人和钱(决定行程形态)

  • 同行构成 — 人数;亲子(孩子年龄)/ 银发(体力、无障碍)/ 情侣 / 朋友 / 独行 / 商务+休闲
  • 健康与体力 — 每天能走多少步?爬山/楼梯行不行?需不需要午休?晕车船/高反史?常用药?
  • 预算口径 — 总预算还是人均/天?机酒大头含不含在内?有没有不能破的硬上限?
  • 节奏 — 暴走 / 适中 / 悠闲(每天少而精)
  • 兴趣偏好 — 自然 / 历史人文 / 美食 / 购物 / 艺术展馆 / 夜生活 / 亲子乐园 / 摄影出片
  • 必去 / 避雷清单 — 点名要去的,和明确不想要的类型

第 3 层 · 落地细节(决定每张卡片怎么填)

  • 住宿 — 已订(给地址)还是待选?几间房、什么床型?品牌偏好/忌讳?要不要含早?位置偏好 (市中心 / 枢纽旁 / 景区附近)
  • 市内交通方式 — 地铁公交 / 打车 / 自驾租车 / 步行为主
  • 行李 — 有无托运需求(廉航是否适配)?婴儿车 / 轮椅?
  • 餐饮 — 忌口、过敏、清真/素食?辣度接受度?有没有必吃清单?
  • 天气与弹性 — 雨天还出门吗?高温耐受?行程有变数吗(要不要退改弹性/保险提醒)?

第 4 层 · 收口

  • 最后一问固定是:「还有什么硬要求是我没问到的?」 答"没有"才算 grill 结束。
  • 结束后回读一遍完整需求清单(含所有推荐值的采纳情况)让用户确认,再进 Step 2。

Escape hatch:用户说"你直接安排就行 / just decide for me"时不再追问,全部缺口按推荐值填——但 整张假设清单必须原样写进 HTML 顶部的 info callout(已有机制),并在回复里提醒"按这些假设排的, 不符再说"。


Step 2 — 机票 / 火车票查询(只查询,不下单)

Fit the itinerary to real arrival/departure times — but only read, never book.

  1. First pass — web_search. Find candidate 班次/航班 (times, duration, rough price range, train/flight number). Examples: "上海 到 成都 航班 时刻", "北京 西安 高铁 时刻表 票价". Capture 2–3 candidates. For trains, a fare/区间 from web_search or 12306 is enough — stop here (12306 is the single source of truth; use a browser only if you need live 余票/具体车次).
  2. Flights — browser price check is MANDATORY (机票必须用浏览器查一遍). A flight fare moves too much for a web_search number to be trusted, so for every air leg you must open the booking sites in a browser — Claude in Chrome / Windows-MCP / Desktop Commander, whichever is connected — and read the live fare for the chosen flight/date on several platforms: 携程 / 飞猪 / 航司官网(必查: 东航/国航/南航等实测可查,官网有券时更低)(去哪儿/美团/同程/艺龙已废,别浪费时间——平台真值表见 references/research-playbook.md)。International: add Google Flights / Skyscanner (no login). 国内机票全平台列表价均为裸价——无一例外,航司官网也是(个别官网页面标着「含税总价」,订单页实测 仍另加机建+燃油,别被页头骗了)。预算必须用含税总价 = 裸价 + 机建费 + 燃油附加费;燃油费率随油价 频繁调价,先 web_search 最新标准再折算并注明执行日期;要看真实税费可进订单第一步的价格明细页(只读, 绝不提交)。读不到就标「票面价 · 燃油/机建另计,以出票页为准」,不许编税费。 Put those real, same-session prices + the exact query time into the .price-compare block, cheapest tagged. This is query-only — obey the prohibitions below.
    • At a login wall / captcha — defer it, don't block; batch all logins into ONE prompt. You never enter passwords or solve captchas yourself. When a platform throws a login/captcha wall, don't stop and wait there. Instead: read whatever shows without logging in (e.g. a price-calendar lowest), leave that tab open and navigate it to its login page so it's ready for the user, add it to a "needs-login" list, and move on — open and read every other platform (incl. login-free ones like Google Flights) first. Only after all platforms are queried, if the needs-login list is non-empty, ask the user once, listing them, e.g.: "这几个要登录才能看完整价: 飞猪、某航司官网。我已把每个标签页都停在登录页了——请你一次性全部登录(我不会替你输密码或过验证码),都登好 告诉我,我再回去逐个读价。" Wait for one confirmation, then go back and read the now-accessible fares on each previously-walled tab. (Batching beats pausing per-platform — the user logs in once, not N times.)
    • Fall back per-platform as a last resort — no browser connected, or the user skips / can't log into a given site. For just those, use web_search ranges and label them "web_search 估价 · 未浏览器 核实,请在购票平台确认". Never present an estimate as a browser-verified price; keep the platforms you did read live as the real comparison.
  3. Hard prohibitions — what YOU never do (the user may do these manually):
    • You never log in or type passwords. (If login helps, the user logs in manually, then you resume reading — see the login-wall step above.)
    • You never read, solve, or bypass CAPTCHAs / 验证码 / 滑块. (The user clears it themselves.)
    • ❌ Never place an order, reserve, or pay — booking is always the user's, not yours.
  4. Integrate the chosen transport into the plan:
    • The arrival time anchors Day 1 (don't schedule a 9 AM museum if the flight lands at 13:00).
    • The departure time caps the last day (leave time to get to the airport/station + check-in).
    • Between cities, leave a generous 赶车 / 赶飞机 buffer (airport: arrive ~2–3h before international / ~1.5h domestic; train: ~30–45 min at a big station).
    • Put each leg in a transport-segment card (times, price range, booking link) — see the design system. The link is for the user to book; the skill never books.

More detail and copy-paste search patterns: references/research-playbook.md.


Step 3 — 天气 + 真实数据

  • Weather: web_search the destination + travel dates — typical seasonal weather and, if the dates are within ~10–14 days, the forecast. This drives clothing notes, the energy curve, and rain Plan B.
  • Season-specific facts: festivals/events on those dates, peak-season crowds, closure days (many museums close Mondays; some attractions close for holidays), and ticketing windows (timed-entry, sells-out-early).
  • Per-place facts — verify, never fabricate: opening hours, closing day, address, and ticket price for every attraction and recommended restaurant. If a fact can't be confirmed, mark it "以官网为准" rather than inventing it. Wrong hours that send the traveler to a closed door are the worst failure this skill can produce.
  • 小红书攻略 — 每趟都搜一遍,不是可选项(用户反复要求,且产物里经常被漏掉)。 至少跑一次 web_search "<目的地> 攻略 小红书" / "<目的地> <主题/人群> 避雷 小红书",捞本地玩法、出片机位、 排队/避坑、亲子或银发实操。但必须鉴别软广:通篇只夸、出现「合作/赞助/探店/团购券/到店报暗号」、 统一话术配统一滤镜、引导私信下单的当广告打折;只采被多篇独立笔记重复印证的具体经验(如"X点后不排队"), 单篇热帖不作准,硬事实(票价/时间)仍以官网为准。把采到的写进相关 POI 的 poi-tiptip callout。 详见 references/research-playbook.md §1 的鉴别清单。

Step 4 — 行程编排逻辑(核心)

This is what separates a real plan from a list of famous places. Apply all of it:

  • 地理聚类: group each day's stops by proximity so the route is a smooth line, not zig-zag backtracking. One neighborhood/area per half-day where possible. The embedded map makes bad routing obvious — use it as a check.
  • 时间预算: for each stop budget 停留时长 + 点间通勤 + 缓冲. Be honest about transit time between points. Aim for 2–4 主要点 per day — fewer for 悠闲/银发/亲子, more only for 暴走. Don't cram.
  • 点间通勤 + 步数 (标在卡片上): between consecutive stops, state the commute (mode + distance + time, e.g. 🚶 600 m · 步行 8 min or 🚇 3 站 · 12 min) as a transit connector, and it must match the day's route on the map. Sum each day's walking into a 步数估算 (≈ 1,300 步/km) shown in the day's overview line. Keep walking legs short for 银发/亲子 and call it out. 跨片区/打车腿的里程·时长·过路费必须真的去高德路线规划跑一遍(浏览器已连时这是强制动作,标「(高德 实测)」;不是写个「以高德为准」就算完——那只是连不上浏览器时的退路)。纯步行短腿(≤2km)可按 70–80 m/min 估,但出现打车¥或分钟就必须有高德来源。
  • 餐饮卡位: place 午餐 / 晚餐 at a spot that's on the route at the right time, near the stop you'll be at — not a detour across town.
  • 硬约束:
    • Skip any stop on its closing day; reorder days to fit.
    • Use 日出 / 日落 times for viewpoints, photo spots, night views.
    • Flag every stop that needs advance booking / 预约 / timed ticket with a must callout and a checklist item.
  • 体力曲线: keep the arrival day and departure day light; put the most demanding day in the middle. Don't schedule a dawn hike the morning after a red-eye.
  • 天气备选 (Plan B): for outdoor-heavy days, give an indoor alternative (museum, mall, aquarium, café district) in a weather callout, so rain doesn't wreck the day.

Deeper heuristics (time-budget rules of thumb, clustering, multi-city pacing): references/research-playbook.md.


Step 5 — 住宿备选(选酒店:看评论、偏连锁、多平台比价)

This step is NOT optional, and it is the one most often silently dropped. The final HTML must contain a 住宿备选 section with at least 3 .hotel cards in every plan — including when the user never mentioned hotels, and including non-interactive / "你直接安排就行" runs (pick the area from the itinerary's geographic clusters and state your assumption, e.g. "按 市中心+近地铁 选了3家,已订可忽略"). The only exception: the user explicitly says accommodation is already settled (已订酒店 / 住朋友家 / 公司安排). Then replace the section with a single 已订住宿 card (their hotel's name/address if given, map pin, transit from it to each day's first stop) and add data-hotels="user-booked" on that section so the checker knows the omission is deliberate. check_html.py fails the build if neither is present.

Give the user at least 3 hotel options (备选), not one — placed near the itinerary's geographic clusters / transit and matching their 住宿位置偏好 from Step 1.

浏览器核实对酒店是强制项,和机票同级——必须主动去连、去查,不是"有机票才连浏览器"。 (这是真实翻车点:一次纯火车的行程里,agent 以为"机票才是 skill 强制要浏览器的那项",于是压根没去连 Chrome,酒店直接走了 web_search 估价。错。)只要本行程要选酒店(非"已订"),你就必须主动尝试启动/连接 浏览器(Claude in Chrome / Windows-MCP / Desktop Commander,哪个连着用哪个),对价格和评论都实查—— 和 Step 2 机票一字不差的纪律。有没有机票,与酒店要不要连浏览器,毫无关系。

  • 价格:浏览器读现役平台(携程/飞猪)实时价。只有在真的尝试过、确认没有浏览器可用(没连上 / 用户 跳过)时,才退到 web_search 区间,并标「web_search 估价 · 未浏览器核实」。默认就走估价、不去连浏览器 = 违规。
  • 评论:评论只能靠浏览器(携程/高德点评区)——web_search 给不了真实评论区,硬写就是编造。 没浏览器读到评论时,遵守数据诚信契约.h-rating 写「评分以 App 为准」(不写任何分数/条数), .review-check 只写连锁常识推荐理由,绝不写"可信/已核/分布正常/好评集中在X"这类结论
  • A missing browser never justifies skipping the section; it only downgrades prices to labeled estimates and strips the review verdict — it never licenses a web_search「估价」shortcut that skips the attempt, nor a fabricated rating.

Selecting a hotel is otherwise the same discipline as flights: research, don't trust the listing; compare prices across platforms; read the actual review section; never book.

  • Read the reviews, NOT the marketing blurb (硬性要求). A pretty listing and a high headline score mean nothing on their own. Open the actual review section (大众点评 / 携程 / 去哪儿 / 小红书 / Google / Booking) and read recent and negative reviews, then judge whether the review area looks normal:

    • Healthy signs: a large review count, recent activity (reviews in the last weeks), specific praise (mentions 隔音/早餐/前台/床), and a believable mix — 100% 5★ is a red flag, not a green one.
    • Avoid / warn (recurring serious complaints): 卫生差 / 有虫 / 隔音差 / 不安全 / 偷换房型 / 强制消费 / 前台态度 / 与图片不符. If the same serious complaint repeats across recent reviews → drop it.
    • Fake-review tells: a burst of identical, generic, dateless 5★; a score wildly out of line with the written complaints; or all reviews old/stale. Treat these as untrustworthy.
    • 评论必须双信源:携程 + 高德,缺一不可。 单一平台不够可信——携程好评偏光鲜、运营痕迹重,高德 POI 评价更接近真实住客口碑。流程:携程筛「4.7 分以上」找候选连锁、读携程评论 → 同一家再去高德读一遍amap.com/search?query={城市}{酒店名} → 点搜索按钮 → 点 POI →「评价」)→ 交叉比对,携程光鲜但 高德有复发吐槽(旧/吵/窗户/卫生),信高德.review-check 写清两边各自说了什么。
  • Prefer chains (连锁) when they fit — especially for 银发/亲子 (consistent cleanliness, standards, easy recourse): 华住会 (汉庭/全季/桔子/星程/宜必思/美居), 锦江 (锦江之星/7天/维也纳), 首旅如家 (如家/和颐). But a chain is not an auto-pick — a specific branch with bad recent reviews is still out; reviews override the brand. A boutique/民宿 is fine if its reviews are strong, specific, and authentic and it suits the trip — just flag the higher variance.

  • 价格和评论是两套独立的多源要求,都要做——别混为一谈(真实翻车点)。 一次运行里 agent 把"评论双信源 携程+高德"当成了"查两家就完事",于是只碰了携程和高德,把飞猪价格比价整个丢了。记牢这张表,三个平台 都要碰:

    维度必查平台为什么不能互替
    价格比价.price-compare携程 + 飞猪(国际加 Booking/Agoda)高德没有房价,不能当价格源
    评论核验.review-check携程 + 高德飞猪评论不顶替高德;高德 POI 口碑更真

    → 一张合格的酒店卡 = 携程(价+评)+ 飞猪(价)+ 高德(评)三次浏览器读。查了携程+高德 ≠ 完成,飞猪价格 仍要查;只有飞猪真的连不上/验证码墙/未读到,才在那一行如实标「飞猪 · 验证码墙未读」并退到 web_search 估价 (标「估」),绝不是默认不查飞猪check_html.py 会 FAIL 任何「飞猪只写了"订前自己比"却没真查」的酒店卡。

    • 一个源失败,绝不连累另一个(真实翻车点)。 一次运行里高德评论没加载出来,agent 就写「高德/飞猪我没 核到」——把价格源飞猪和评论源高德捆在一起一起放弃了。高德(评论源)失败,与飞猪(价格源)该不该查, 毫无关系;反之亦然。一个挂了就单独如实标它挂了,另一个照查。
    • 高德评论是懒加载——别太早下"没评价"的结论。 点开 POI 后 wait 3–5s、必要时在详情面板内下滚一下再读; 搜索若默认跳了北京=没解析到城市,把城市名加进 query 重搜+点搜索按钮。「高德没返回评价」十有八九是没等够。
  • 别默认「集团 App 会员价更低」——实测未必,且华住会官网查不到价;会员价只有真读到才写。Use the same defer-and-batch login handling and the query-only prohibitions from Step 2 (never log in / solve captchas yourself, never book). Trains/flights/hotels all share that flow.

  • Output each option as a hotel card (chain badge, 评分 + 点评数, 区域/到地铁/到当天景点群的距离, a short 评论体检 note saying what reviews actually say, the multi-platform .price-compare, and a booking link). Pin the top pick on the map. Mark a 推荐 vs 次选/备选 if helpful. See references/design-system.md (hotel card) and references/research-playbook.md (vetting method).


Step 6 — 输出(沿用 study-notes 的 HTML 规范,按旅行场景改造)

Read references/design-system.md and follow it exactly. Build ONE standalone HTML file containing:

  • Themed hero header (required, on every trip): a gradient banner keyed to the trip's subject (theme-night/ocean/sunset/forest/city/sakura/snow/desert, optional deco-stars/deco-glow, or a custom gradient from the destination's palette), with the headline facts wrapped as translucent .tag pills (3–6: 天数 / 核心体验 / 预算档 / 节奏 / 人数). Use .chip pills elsewhere to wrap short item lists (必吃、亮点、随手鸟点). See "Themed hero header" in the design system.
  • Embedded Leaflet map (#map + the TRIP data object) showing each day's stops as numbered pins and the day's route as a colored dashed line. Every stop needs lat/lng (look them up; district-level is an acceptable fallback). OSM tiles, no key.
  • Per-day timeline: one .sec-COLOR section per day, opening with a daily overview line (.day-meta: 当日花费 + 步数 + 主要点数). Each stop is a POI card showing 名称 / 到达时间 / 停留时长 / 票价 / 营业时间 + a one-line poi-tip, with a collapsible <details> for "如何前往 / 周边吃喝". Between consecutive cards put a transit connector (.transit: 步行/地铁/打车 + 距离 + 时间) = the route to the next point.
  • Transport-segment cards: 航班 / 车次, times, price range, booking link. For flights, include a .price-compare multi-platform comparison (去哪儿/携程/飞猪/官网…, cheapest tagged).
  • 住宿备选 section (.hotel cards, ≥3 options): chain badge, 评分 + 点评数, 区域/距离, a 评论体检 note (what the reviews actually say — not the listing blurb), a multi-platform per-night .price-compare, and a booking link. Prefer chains; reviews override the brand. Pin the top pick on the map.
  • Budget table (.budget) with per-day subtotals (fixed 大项 grouped, then one block per day, each day's subtotal = that day's 当日花费 chip) and a grand .total row + pre-departure checklist (.checklist, persists ticks in localStorage) covering 订票 / 证件 / 预约 / 必带物.
  • Kept mechanisms: collapsible sections, hierarchical TOC + floating sub-heading navigator, scroll-position memory, dark-mode theme. Callouts carry travel meaning: must = 必订/必约, warn = 注意/赶车/闭馆, avoid = 避雷, tip = 省钱省时, weather = 雨天 Plan B, info = 须知.

Build + check (before presenting)

After assembling the HTML, run the static checker and fix anything it flags:

python3 scripts/check_html.py <output>.html
# or on Windows: py scripts\check_html.py <output>.html

It verifies <div> balance, that the Leaflet CDN + #map + a non-empty TRIP object are present, that every map stop has numeric coordinates, that no leftover KaTeX $$…$$ math slipped in from the template's study-notes lineage, and that the travel components actually landed: ≥3 .hotel cards (or the explicit data-hotels="user-booked" marker), a .budget table, and the localStorage-backed .checklist. Re-run until clean, then tell the user where the file is.


Output spec summary (the retargeted規范, for quick reference)

The full spec is in references/design-system.md. In brief, what changed from study-notes:

study-notestrip-planner
KaTeX math, .fbox/.big-formula, math macros, error bannerremoved
(no map)Leaflet + OSM map with per-day numbered pins + route polylines
concept section per topicday section per travel day (.sec-COLOR cycled by day)
worked-example cardsPOI cards (time / 停留 / 票价 / 营业时间 / tip + collapsible details)
transport cards, budget table, localStorage checklist
callouts: note/tip/warn/exam/mistake/intuitioncallouts: info/tip/warn/must/avoid/weather
collapse, hierarchical TOC+nav, scroll memory, dark modekept verbatim

Test prompts

After building the skill, try these (they exercise requirements-gathering, English input, and the train-query path):

  1. 下个月中旬带爸妈去成都玩4天,从上海出发,预算中等,想看大熊猫、吃地道川菜,老人家走不动太多路,节奏悠闲点,帮我做个行程。 — 银发亲子 + most info given; should confirm only the few missing bits, then plan light-paced days with low-walking routing and an indoor Plan B.

  2. Plan a 5-day Tokyo itinerary for the two of us in early July, flying from Shanghai. We love food and anime (Akihabara), want one day-trip outside the city, mid-range budget, and don't mind a packed schedule. — English, couple, fast pace; should fit flights to Day 1 / Day 5, cluster by district, and map it.

  3. 9月23到26号去西安,兵马俑、城墙、回民街都想去,顺便帮我看下从北京出发的高铁大概几点有车、大概多少钱。 — destination + dates + a transport-query ask; should still gather missing prefs (同行/预算/节奏), web_search the 北京→西安 高铁 options into a transport card (query-only), and avoid any closure-day clashes.