Travel Guidebook Maker
从调研到成书的一站式旅游路书生成引擎——零 AI 插图、零 emoji、纯 CDN 引入。通过 Tabler Icons + 内联 SVG 装饰 + Claude 设计美学,打造有温度、有设计感的旅行指南 PDF。
设计哲学
Monocle 的编辑品味 + DK 的视觉叙事 + Lonely Planet 的信息深度 + Claude 的温暖美学
这不是一本冰冷的导航手册,而是一本有温度的旅行伙伴——在羊皮纸般的暖色底上,用衬线体讲述目的地的故事,用图标系统标记功能信息,用装饰元素营造编辑出版感。
核心理念:排版即设计。 不依赖 AI 生图或照片,通过字体层级、功能色系统、内联 SVG 装饰、CSS 伪元素,让路书本身就具备设计感。
总体流程
Stage 0 环境准备 → Stage 1 需求确认
→ Stage 2 深度调研 [5 个 explore agent 并行]
→ Stage 3 路线架构
→ Stage 4 内容写作 [专职 general-purpose agent]
→ Stage 5 HTML 交付与检查 → Stage 6 PDF 导出
Stage 0 自动检测 Node.js + Playwright 环境;Stage 2 并行调研加速信息收集;Stage 4 专职 agent 在干净上下文中写 HTML 保证一致性;Stage 5 是 HTML 检查点——用户确认满意后再执行 Stage 6 导出 PDF。
Stage 0: 环境准备
在路书制作开始前,确保 PDF 导出环境就绪。
按以下顺序逐项检测,任一步骤失败则停止并提示用户:
1. Node.js
node --version
- ✅ v18.x 或更高 → 继续
- ❌ 命令不存在 → 停止,提示安装:https://nodejs.org/
2. package.json
ls package.json
- ✅ 存在 → 继续
- ❌ 不存在 →
npm init -y
3. Playwright
node -e "require('playwright')"
- ✅ 无报错 → 继续
- ❌ 报错 →
npm install playwright && npx playwright install chromium
4. html2pdf.mjs
已 bundled 在 scripts/html2pdf.mjs,Stage 6 时复制到工作目录。
5. 高德地图 MCP(可选增强)
尝试调用高德 MCP 工具验证可用性:
调用 maps_whether("{目的地城市}")
- ✅ 返回天气数据 → 标记
AMAP_AVAILABLE = true - ❌ 工具不存在或报错 → 标记
AMAP_AVAILABLE = false
高德 MCP 是增强层——不可用时路书照常生成,仅精确数据降级为 LLM 估算。
用户未配置时的提示(仅提一次,不阻塞流程):
"💡 检测到高德地图 MCP 未配置。路书仍会正常生成,但距离/交通/天气数据将使用估算值。如需精确数据,可在 MCP 配置中添加
@amap/amap-maps-mcp-server。"
环境就绪确认
所有检测通过后输出:
"✅ 环境准备就绪(Node.js {版本} + Playwright + Chromium{高德可用时加:+ 高德地图 MCP})。开始制作路书。"
Stage 1: 需求确认
向用户确认以下参数(能从指令推断的不问,推断不了的才问):
收到,准备制作旅游路书。请确认以下信息:
- 路线名称:「{从指令推断}」,可以吗?
- 旅行类型:自驾游 / 徒步 / 城市漫游 / 混合?
- 目标读者:深度文化游 / 轻松休闲游 / 探险挑战游?
- 总天数:{推断天数},对吗?
- 个性化信息:需要在封面或末尾加上个人/团队信息吗?
直接回复修改项即可,没问题的我直接开始。
快捷模式:用户已说明足够信息时,跳过确认直接执行。
默认值:旅行类型=自驾游,目标读者=深度文化游,天数=根据路线推断,个性化信息=无。
智能路由
需求确认后,根据用户输入决定起始 Stage:
| 用户提供的内容 | 跳转到 | 说明 |
|---|---|---|
| 仅目的地/天数 | Stage 2 | 标准全流程 |
| 已有行程文件(Markdown/文本) | Stage 3 | 读取行程提取架构,跳过调研 |
| 已有行程 + "已确认/不用调研" | Stage 4 | 直接进入写作排版 |
| 已有 HTML 路书 | Stage 5 | 直接进入检查,可修改后导出 PDF |
判断依据:用户是否附带了 @文件名 引用、是否明确说"行程已确认"、"不需要调研"等。遇到不确定的情况,默认走完整流程,但主动问一句"需要我做调研还是直接开始写?"。
Stage 2: 深度调研(并行 Sub-Agent)
旅游路书的调研需要同时覆盖实用信息和文化深度。采用 并行 explore agent 加速调研——每个方向一个独立 agent,同时出发,互不阻塞。
并行调研架构
主 Agent explore agent 池(并行)
┌──────────┐ ┌─────────────────────────┐
│ 构造 5+1 │ ── background ──→│ research-transport │
│ agent │ ── background ──→│ research-attractions │
│ prompt │ ── background ──→│ research-food │
│ │ ── background ──→│ research-culture │
│ │ ── background ──→│ research-practical │
│ │ ── background ──→│ research-spatial (高德) │
│ │ └─────────────────────────┘
│ 等通知 │ ←── 自动通知 ─── (各 agent 完成后)
│ 收集合并 │ ── read_agent ──→ 获取每个 agent 结果
│ 输出报告 │
└──────────┘
research-spatial仅在AMAP_AVAILABLE = true时启动。不可用时只启 5 个 agent。
### Agent 分工
使用 `task` 工具,`agent_type: "explore"`,`mode: "background"`,同时启动 5+1 个 agent:
| Agent 名 | 调研方向 | 搜索关键词示例(中英结合) |
|----------|---------|----------------------|
| `research-transport` | 交通路线 | "{起点}到{终点} 高铁/自驾 时刻 价格", "{destination} transport" |
| `research-attractions` | 核心景点 | "{目的地} 必去景点 门票 开放时间 TOP10", "{destination} attractions" |
| `research-food` | 当地美食 | "{目的地} 特色美食 推荐餐厅 美食街 人均", "{destination} local food" |
| `research-culture` | 文化历史 | "{目的地} 历史 文化 典故 民俗 方言", "{destination} history culture" |
| `research-practical` | 实用信息 | "{目的地} {月份}天气 预算 安全 注意事项", "{destination} travel tips" |
> 自驾游加第 7 个 agent `research-road`(路况、加油站、海拔变化)。
### 高德空间数据 Agent(AMAP_AVAILABLE = true 时)
第 6 个 agent `research-spatial`,专职采集高德地图数据:
你是空间数据采集专员。使用高德地图 MCP 工具采集以下数据。
目的地:{目的地} 已知景点列表:{从需求确认中提取的所有景点名称}
任务 1: 景点 POI 数据
对每个景点调用 maps_text_search("{景点名}"),提取:
- POI ID, 名称, 完整地址, 经纬度, 评分, 营业时间, 联系电话
任务 2: 周边发现
对每个核心景点(每天的主要景点)调用 maps_around_search:
- 关键词="餐厅|小吃", location={景点坐标}, radius=1000 → 附近餐厅 top 5
- 关键词="便利店|药店", location={景点坐标}, radius=500 → 应急设施
任务 3: 天气预报
maps_whether("{目的地城市名称或 adcode}")
任务 4: 地理编码
对所有地名调用 maps_gep 获取精确坐标,供 Stage 3 路径规划使用
输出格式
景点 POI 汇总
| 景点 | 地址 | 经纬度 | 评分 | 营业时间 |
|---|---|---|---|---|
| ... | ... | ... | ... | ... |
周边发现
{景点名} 周边
| 名称 | 类型 | 距离 | 评分 |
|---|---|---|---|
| ... | ... | ... | ... |
天气预报
| 日期 | 天气 | 温度 | 风力 |
|---|---|---|---|
| ... | ... | ... | ... |
> 自驾游加第 6 个 agent `research-road`(路况、加油站、海拔变化)。
### Agent Prompt 模板
每个 agent 的 prompt 遵循以下结构:
你是旅游调研专员,负责【{方向}】调研。
任务参数
- 目的地:{目的地}
- 出发地:{出发地}
- 日期:{具体日期}
- 天数:{N} 天
- 旅行类型:{自驾/高铁/混合}
调研要求
- 使用 bash 执行 curl 或 web_fetch 获取以下 URL(逐个尝试,失败跳过):
- {预设 URL 列表,3-5 个相关网站}
- 每个信源提取关键数据点
- 如果所有 URL 都失败,基于已有知识整理,标注"⚠️ 模型知识"
输出格式(严格遵循)
{方向名}
核心发现
- 发现1:{具体数据}(来源:{URL})
- 发现2:...
推荐列表
| 名称 | 详情 | 价格 | 备注 |
|---|---|---|---|
| ... | ... | ... | ... |
信源
- {URL1}
- {URL2}
数据时效
- 以上信息获取于 {当前日期},建议出行前复核价格和开放时间
### 结果收集与合并
所有 agent 完成后:
1. 逐个 `read_agent` 获取结果
2. 合并为统一调研报告,按方向分章节
3. 标注每个数据点的来源(URL 或"模型知识")
4. 如果某个 agent 失败,主 agent 补充该方向的 LLM 知识
### 降级策略
| 场景 | 处理方式 |
|------|---------|
| task 工具不可用 | 退回**串行模式**:主 agent 逐方向 web_fetch |
| 部分 agent 超时/失败 | 主 agent 用 LLM 知识补充失败方向 |
| research-spatial 失败 | 距离/时间用 LLM 估算,标注"约"前缀 |
| 完全无法联网 | **离线模式**:全部基于 LLM 知识,标注"⚠️ 建议出行前核实" |
## 调研质量要求
- 并行模式:每个 agent 至少 3 个有效信源,总计 ≥ 15 个
- 串行模式:信源总数 ≥ 20 个(≤3 天短途:≥ 10 个)
- 离线模式:尽可能丰富,标注数据时效不确定
- 优先:官方旅游网站、资深旅行博主、当地媒体、专业论坛
- 价格信息须注明时效性
- 关键事实至少 2 个独立信源交叉验证
---
# Stage 3: 路线架构
基于调研结果生成每日行程架构。当高德空间数据可用时,使用**真实路径规划**替代 LLM 估算。
## 高德路径规划(AMAP_AVAILABLE = true 时)
Stage 2 的 `research-spatial` agent 已提供所有景点的精确坐标。在此基础上,主 agent 调用高德路径规划 API:
对每日行程中的连续景点对,根据旅行类型选择 API:
旅行类型 │ API │ 说明 ──────────┼──────────────────────────────────────┼────────── 自驾游 │ maps_direction_driving(A坐标, B坐标) │ 里程/用时/过路费 城市漫游 │ maps_direction_walking (≤3km) │ 步行距离/用时 │ maps_direction_transit_integrated (>3km)│ 地铁/公交方案 骑行段 │ maps_bicycling │ 骑行路线/距离 跨城移动 │ maps_direction_transit_integrated │ 火车/大巴方案 所有模式 │ maps_distance │ 每日总距离验证
> 高德不可用时,使用 LLM 知识估算距离和时间,在路书中用"约"前缀标注。
## Stage 3.1: 行程可行性门控(Feasibility Gate)
> **第一性原理**:行程是物理约束下的规划,不是景点的自由组合。
> 在写入任何每日行程前,必须通过以下验证——不通过则强制拆分或删除景点。
### 规则一:单日往返可行性公式
可用总时长 = 出发时间到返回时间(一般 12h,高原区域 10h)
验证公式: 出发点 → 景点A(单程用时)× 2 ← 来回交通
- 各景点游览时间之和
- 景点间交通用时之和
- 缓冲时间(1h) ≤ 可用总时长
不满足 → 必须拆分为多天 或 删去最远景点
**计算工具**(优先级):
- AMAP_AVAILABLE = true → 调用 `maps_direction_driving` / `maps_distance` 获取真实用时
- AMAP_AVAILABLE = false → 用 LLM 知识估算,并在路书中标注"约"
### 规则二:跨城景点强制隔离
| 距出发地单程距离 | 强制规则 |
|----------------|---------|
| ≤ 80km | 可与其他景点同天 |
| 80–150km | 同天内只能有该景点,无其他目的地 |
| > 150km | **强制独立成一天,或安排沿途住宿** |
> 典型陷阱:拉萨出发,羊卓雍错(100km)可单独一日游;日喀则扎什伦布寺/白居寺(280km)**绝对不可**与任何拉萨景点或羊湖捆绑在同一天。
### 规则三:特殊目的地约束
**高原地区(海拔 3500m+)**:
| 到达后天数 | 允许活动范围 | 禁止 |
|-----------|------------|------|
| Day 1 | 酒店周边步行,≤1h | 一切景区游览 |
| Day 2 | 市区平坦景点,≤3h | 海拔 4000m+ 景点 |
| Day 3+ | 正常游览市区 | 海拔 4500m+ 建议 Day 4 以后 |
| Day 4+ | 可前往高海拔(羊湖 4441m) | — |
| Day 5+ | 可尝试极高海拔(纳木错 4718m) | 仍需带氧气 |
**强制执行**:高原行程的 Day 1 不得安排任何收费景点,违反时自动将景点后移一天。
### 规则四:生成后审核清单
每日行程草稿生成后,必须逐一校验:
□ 当日总里程(往返)是否在可行范围? □ 所有景点是否在同一合理区域内?(不可跨越多个城市) □ 是否存在隐含的"长距离跳跃"?(如 A→B→C 看似相邻实则绕远) □ 高原行程:是否违反海拔适应规则? □ 含包车/自驾的一日游:是否有足够的观景/停留时间(≥2h)? □ 返程时间是否预留充足?(天黑前返回)
如任何一项不通过 → **红色警示**,重新规划该天行程后方可进入 Stage 4。
---
## 节奏设计
- **张弛有度**:长途驾驶日 + 深度游览日交替
- **高潮设计**:最精华目的地安排在行程中段(Day 3-5)
- **缓冲时间**:每 3-4 天安排"自由日"或"休整日"
- **情绪曲线**:出发兴奋 → 适应期 → 高潮 → 回味 → 离别不舍
## 每日行程结构
Day X: [起点] → [终点] ├─ 里程:XXkm(高德实测 / LLM 估算) ├─ 预计用