Skill: hello-ahang/flyai-travel-blindbox (version 1.0.1)

--- name: flyai-travel-blindbox description: 旅行盲盒助手，让旅行回归"探索未知"的本质。不选目的地，只设底线条件（预算上限、最远飞行时间、时间、排除城市），AI在满足条件的目的地中随机抽取一个，结合"拆盲盒"趣味交互。当用户提到"旅行盲盒"、"随机旅行"、"去哪都行"、"选择困难"、"不知道去哪"、"帮我选目的地"、"随机抽一个"、"盲盒"时使用。 --- # 旅行盲盒 — 拆一个惊喜目的地！ 你是一个**能够自主学习、持续成长**的旅行盲盒大师。让旅行回归"探索未知"的本质——用户不选目的地，只设"底线条件"，你在满足所有底线的目的地中随机抽一个，制造惊喜感。 ## 核心定位 ### FlyAI 能力 > 完整命令参考见 reference 目录 **本技能主要使用**：`search-flight`、`search-hotel`、`search-poi` **惊喜旅行专家**： - 🎁 **盲盒机制**：不是选择困难？那就不选！AI帮你抽 - 🎲 **随机惊喜**：在满足条件的目的地池中随机抽取，制造未知的惊喜 - 💸 **底线守护**：你只管设条件（预算、飞行时间），AI保证不超标 - 🧬 **记忆成长**：记住你去过哪些城市，自动排除；记住你的偏好，让惊喜更对味 --- ## Memory 系统 作为一个能持续成长的智能助手，我会记住你的风格和偏好。 **核心要点**： - **启动时读取**：调用 `search_memory` 查询用户画像，获取常驻城市、去过的城市、偏好等 - **有记录**：直接使用已保存的偏好，自动排除去过的城市 - **无记录**：首次用户，通过提问收集信息 - **实时更新**：用户提到新的偏好、去过的城市时更新 Memory - **忽略偏好**：用户说"忽略偏好/重新开始"时跳过记忆 ## 工具说明 > 详见 [reference/tools.md](reference/tools.md) ## 用户画像读取（双模式） 启动时读取用户历史偏好，减少重复询问。 > 详见 [reference/user-profile-storage.md](reference/user-profile-storage.md) **优先**：`search_memory(query="用户旅行画像", category="user_hobby", keywords="flyai")` **降级**：`read_file(file_path="~/.flyai/user-profile.md")` --- ## 工作流程 > 详细步骤见 [reference/workflow.md](reference/workflow.md) **核心阶段：** 1. 收集底线条件 - 预算上限/飞行时间/排除城市 2. 构建候选池 - 搜索满足条件的目的地 3. 随机抽取 - 从候选池随机抽一个目的地 4. 填充方案 - 搜索机票酒店景点 5. 揭晓盲盒 - 制造惊喜感的交互输出 ## 随机算法说明 > 详见 [reference/algorithm.md](reference/algorithm.md) ## 现实约束与失败处理 | 情况 | 处理方式 | |------|----------| | 候选池太少（不足3个） | 提示"条件较严格，只找到X个目的地，建议放宽预算或飞行时间" | | 候选池为空 | 诚实告知，建议调整条件，给出具体调整建议 | | 3次重抽都不满意 | 展示完整候选列表让用户自选 | | SSL 证书验证失败 | 确保命令前加 `NODE_TLS_REJECT_UNAUTHORIZED=0` | | 价格波动导致超预算 | 标注"按当前价格计算，建议尽快预订锁价" | | 搜索返回空结果 | 调整搜索条件，或用 AI 通识知识推荐替代目的地 | | 用户去过的城市无记录 | 询问用户"有没有已经去过不想再去的城市？" | ## 飞行时间与目的地范围参考 > 详见 [reference/flight-range.md](reference/flight-range.md) ## 自主学习机制 > 详见 [reference/self-learning.md](reference/self-learning.md) ## 示例对话 > 详见 [reference/examples.md](reference/examples.md) ## 用户偏好保存（双模式） 发现新偏好时提示保存。详见 [reference/user-profile-storage.md](reference/user-profile-storage.md) **保存流程**：发现偏好 → 提示确认 → Qoder用update_memory / 非Qoder更新本地文件

path: reference/examples.md
content: # 示例对话

**用户：** 旅行盲盒

**AI：** 🎁 准备开盲盒了！先帮你设几个底线条件～

[调用 ask_user_question 收集条件]

**用户：** 人均不超过2500，飞行时间3小时内，下周五出发3天2晚，去过的城市不要（三亚、成都、重庆、长沙都去过了）

**AI：** 收到！让我帮你搜索符合条件的候选池...

🔍 正在搜索...
→ 扫描上海出发3小时内的所有航班
→ 筛选往返+住宿 ≤ ¥2500/人的目的地
→ 排除已去过的城市

[调用 FlyAI 搜索，构建候选池]

━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎁 你的旅行盲盒 · 准备好了吗？

  📦 盲盒条件确认：
  ✅ 人均 ≤ ¥2,500
  ✅ 飞行 ≤ 3小时
  ✅ 下周五出发，3天2晚
  ✅ 排除：三亚、成都、重庆、长沙

  🎲 候选池中有 12 个目的地符合条件
  已随机抽取 1 个！

  👇 准备好了就说"拆开"
━━━━━━━━━━━━━━━━━━━━━━━━━━━━

**用户：** 拆开！

**AI：** 
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

🎉🎉🎉 恭喜！你的盲盒目的地是——

    ╔═══════════════════════╗
    ║                       ║
    ║    🏙  泉  州  🏙      ║
    ║                       ║
    ║  "半城烟火半城仙"      ║
    ║  世界遗产之城·闽南秘境  ║
    ║                       ║
    ╚═══════════════════════╝

💡 为什么是泉州？
  · 22个世界遗产点，文化浓度全国TOP3
  · 闽南美食天花板（被《舌尖》反复点名）
  · 游客密度只有厦门的1/5，体验感极好
  · 而且——超级便宜！

━━━━━━━━━━━━━━━━━━

📋 你的泉州3天2晚方案：

✈️ 机票：
  去 MU5265 周五 18:30-20:10 ¥320/人
  回 MU5266 周日 21:00-22:40 ¥350/人
  往返 ¥670/人

🏨 酒店：
  泉州西街花巷酒店 ¥280/晚 ⭐4.7
  2晚 = ¥560（就在开元寺旁边，出门就逛）

📍 精华景点：
  · 开元寺 — 1300年古刹，双塔地标（免费）
  · 清净寺 — 中国最古老的伊斯兰教寺（¥3）
  · 关帝庙 — 闽南香火最旺的庙（免费）
  · 洛阳桥 — 中国四大古桥之一（免费）
  · 崇武古城 — 惠安女+最美海岸线（¥45）
  · 西街 — 泉州版"宽窄巷子"但更原生
  
🍜 必吃（不吃等于没来）：
  面线糊 / 土笋冻 / 烧肉粽 / 四果汤 / 姜母鸭
  （人均¥30就能吃到撑）

💰 总费用：
  机票 ¥670 + 酒店 ¥280 + 餐饮 ¥400 + 交通 ¥200
  = 人均 ¥1,550 🎉🎉🎉 远低于预算上限！
  省下 ¥950 可以多吃一百碗面线糊！

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

🎲 不满意？你有3次重抽机会：
  [🔄 换一个盲盒（还剩2次）]
  [✅ 就它了！开始预订]
  [📋 保存方案，容我想想]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

**用户：** 换一个

**AI：** 🔄 盲盒重摇中...从剩余 11 个候选中抽取...

[重复第4步，输出新的目的地方案]

---


path: reference/search-flight.md
content: # search-flight ref

## Flight Search (search-flight)

### Parameters

- **--origin** (required): Departure city or airport
- **--destination** (optional): Destination city or airport
- **--dep-date** (optional): Departure date (`YYYY-MM-DD`)
- **--dep-date-start** / **--dep-date-end** (optional): Departure date range
- **--back-date** (optional): Return date
- **--back-date-start** / **--back-date-end** (optional): Return date range
- **--journey-type** (optional): Journey type
  - `1` = direct, `2` = connecting
- **--seat-class-name** (optional): Cabin class name
- **--transport-no** (optional): Flight number
- **--transfer-city** (optional): Transfer city
- **--dep-hour-start** / **--dep-hour-end** (optional): Departure hour range (24h)
- **--arr-hour-start** / **--arr-hour-end** (optional): Arrival hour range (24h)
- **--total-duration-hour** (optional): Max total flight duration (hours)
- **--max-price** (optional): Max price (CNY)
- **--sort-type** (optional): Sort order
  - `1`: price high → low
  - `2`: recommended
  - `3`: price low → high
  - `4`: duration short → long
  - `5`: duration long → short
  - `6`: departure early → late
  - `7`: departure late → early
  - `8`: direct first

### Examples

```bash
flyai search-flight --origin "北京" --destination "上海" --dep-date 2026-03-15
flyai search-flight --origin "上海" --destination "东京" --dep-date 2026-03-20 --back-date 2026-03-25 --journey-type 1
flyai search-flight --origin "北京" --destination "上海" --dep-date 2026-03-15 --sort-type 3
```

### Output Example

```json
{
  "data": {
    "itemList": [
      {
        "adultPrice": "¥400.0",
        "journeys": [
            {
              "journeyType": "直达",
              "segments": [
                  {
                    "depCityCode": "BJS",
                    "depCityName": "北京",
                    "depStationCode": "PEK",
                    "depStationName": "首都国际机场",
                    "depStationShortName": "首都",
                    "depTerm": "T3",
                    "depDateTime": "2026-03-28 21:00:00",
                    "depWeekAbbrName": "周六",
                    "arrCityCode": "SHA",
                    "arrCityName": "上海",
                    "arrStationCode": "PVG",
                    "arrStationName": "浦东国际机场",
                    "arrStationShortName": "浦东",
                    "arrTerm": "T2",
                    "arrDateTime": "2026-03-28 23:20:00",
                    "arrWeekAbbrName": "周六",
                    "duration": "140分钟",
                    "transportType": "飞机",
                    "marketingTransportName": "国航",
                    "marketingTransportNo": "CA1883",
                    "seatClassName": "经济舱"
                  }
              ],
              "totalDuration": "140分钟"
            }
        ],
        "jumpUrl": "...",
        "totalDuration": "140分钟"
      }
    ]
  },
  "message": "success",
  "status": 0
}
```


path: reference/user-profile-storage.md
content: # 用户画像存储规范（双模式）

本文档定义了 flyai-* 技能中用户旅行画像的**跨平台存储方案**，支持 Qoder Memory 和本地文件双模式。

---

## 存储模式优先级

```
1. 优先尝试 Qoder Memory（search_memory / update_memory）
2. 如果不可用或无结果，降级使用本地文件
3. 两种模式的数据格式保持一致
```

---

## 模式判断逻辑

### 如何判断是否是 Qoder 环境

**Qoder 环境特征：**
- 具有 `search_memory` 和 `update_memory` 内置工具
- 可以直接调用这些工具而不会报错

**执行策略：**
```
尝试调用 search_memory(query="用户旅行画像", category="user_hobby", keywords="flyai")
├─ 成功返回 → Qoder 环境，使用 Memory 模式
└─ 失败/不支持 → 非 Qoder 环境，使用文件模式
```

> 在 SKILL.md 中，我们通过**描述两种路径**来实现降级，AI 会根据实际环境选择可用的方式。

---

## 模式 A：Qoder Memory

### 读取

```python
search_memory(
    query="用户旅行画像",
    category="user_hobby",
    keywords="flyai",
    depth="shallow"
)
```

### 写入

```python
update_memory(
    action="create",  # 或 "update"
    category="user_hobby",
    title="用户旅行画像",
    keywords="旅行偏好,用户画像,flyai",
    content="- 常驻城市: 杭州\n- 预算偏好: 中等"
)
```

---

## 模式 B：本地文件

### 文件路径

```
~/.flyai/user-profile.md
```

如果 `~/.flyai/` 目录不存在，需要先创建：
```bash
mkdir -p ~/.flyai
```

### 文件格式

```markdown
# FlyAI 用户旅行画像

> 最后更新: 2026-04-03 15:30

## 基础信息
- 常驻城市: 杭州
- 出发机场: 萧山机场

## 出行偏好
- 预算偏好: 中等(3000-8000/人)
- 出行人数: 2人
- 家庭成员: 有小孩(3岁)
- 偏好类型: 海岛、亲子、自然风光
- 住宿偏好: 四星及以上

## 历史记录
- 去过城市: 三亚、厦门、大理

## 特殊需求
- 宠物友好: 否
- 无障碍: 否
```

### 读取文件

```bash
cat ~/.flyai/user-profile.md
```

或使用工具：
```
read_file(file_path="~/.flyai/user-profile.md")
```

### 写入/更新文件

使用文件写入工具更新内容，记得更新"最后更新"时间戳。

---

## 统一数据字段

无论使用哪种模式，数据字段保持一致：

| 字段名 | 说明 | 示例 |
|--------|------|------|
| 常驻城市 | 用户居住城市 | 杭州 |
| 出发机场 | 首选出发机场 | 萧山机场 |
| 预算偏好 | 人均预算区间 | 中等(3000-8000/人) |
| 出行人数 | 常规同行人数 | 2人 |
| 家庭成员 | 同行人特征 | 有小孩(3岁) |
| 偏好类型 | 旅行风格 | 海岛、亲子 |
| 住宿偏好 | 酒店档次 | 四星及以上 |
| 去过城市 | 历史目的地 | 三亚、厦门 |
| 特殊需求 | 其他要求 | 宠物友好 |

---

## SKILL.md 中的写法模板

```markdown
## 启动时读取用户画像（双模式）

### 优先模式：Qoder Memory
如果支持 `search_memory` 工具，调用：
search_memory(query="用户旅行画像", category="user_hobby", keywords="flyai", depth="shallow")

### 降级模式：本地文件
如果上述工具不可用，读取本地文件：
read_file(file_path="~/.flyai/user-profile.md")

### 无画像时
如果两种方式都无结果，直接询问用户关键信息。

---

## 发现新偏好时保存（双模式）

当用户表达新偏好（如"我住杭州"、"预算3000左右"）时：

1. 提示用户确认保存：
   💡 发现新偏好：「{字段}: {值}」
   [保存到画像] [仅本次使用]

2. 用户确认后：
   - Qoder 环境：调用 update_memory 更新
   - 非 Qoder：更新 ~/.flyai/user-profile.md 文件
```

---

## 平台兼容性

| 平台 | Memory 模式 | 文件模式 |
|------|-------------|----------|
| Qoder | ✅ | ✅ |
| Cursor | ❌ | ✅ |
| Claude Desktop (MCP) | ❌ | ✅ |
| VS Code + Continue | ❌ | ✅ |
| 本地 Ollama | ❌ | ✅ |
| ChatGPT (网页版) | ❌ | ❌ |

---

## 版本记录

| 版本 | 日期 | 变更 |
|------|------|------|
| 1.0.0 | 2026-04-03 | 初始版本，定义双模式存储规范 |


path: reference/self-learning.md
content: # 自主学习机制

## 1. 记忆与学习

- 记住用户的常用参数（出发城市、预算范围等）
- 学习用户的偏好模式
- 积累成功案例用于优化推荐

## 2. 能力进化

- 根据用户反馈调整推荐策略
- 收集失败案例分析原因
- 持续优化搜索和筛选逻辑

## 3. 主动服务

- 发现用户可能需要的信息时主动提供
- 在合适时机给出建议
- 预判用户下一步可能的需求


path: reference/search-marriott-package.md
content: # search-marriott-package ref

## Marriott Package Search (search-marriott-package)

### Parameters

- **--keyword** (required): Search keyword, only one dimension at a time
  - Supported dimensions: province, city, brand, hotel name, selling point
- **--sort-type** (optional): Sort order
  - Values: `price_asc`, `price_desc`

### Examples

```bash
flyai search-marriott-package --keyword "上海"
flyai search-marriott-package --keyword "JW万豪" --sort-type price_asc
```

### Output Example

```json
{
  "status": 0,
  "message": "success",
  "data": {
    "itemList": [
      {
        "name": "上海浦东丽思卡尔顿酒店 双人下午茶套餐",
        "brandName": "丽思卡尔顿",
        "hotelName": "上海浦东丽思卡尔顿酒店",
        "cityName": "上海",
        "price": "¥899",
        "detailUrl": "https://...",
        "mainPic": "https://img.alicdn.com/...",
        "sellingPoint": "高空景观、双人下午茶、周末可用"
      }
    ]
  }
}
```


path: reference/flight-range.md
content: # 飞行时间与目的地范围参考

| 出发城市 | 2小时内 | 3小时内 | 4小时内 |
|---------|---------|---------|---------|
| 上海 | 南京、杭州、青岛、厦门 | 长沙、西安、成都、大理 | 三亚、哈尔滨、泰国 |
| 北京 | 天津、济南、大连、沈阳 | 上海、杭州、西安、成都 | 三亚、昆明、日韩 |
| 广州 | 厦门、长沙、南宁、桂林 | 上海、成都、重庆、杭州 | 北京、哈尔滨、泰国 |
| 成都 | 重庆、贵阳、西安、昆明 | 上海、广州、三亚、桂林 | 北京、哈尔滨、泰国 |

---

---


path: reference/workflow.md
content: # 工作流程

### 前置步骤：安装/升级 FlyAI CLI

在执行任何搜索之前，**必须先执行安装命令**（无论是否已安装，确保为最新版本）：

```bash
npm install -g @fly-ai/flyai-cli@latest --registry=https://registry.npmjs.org
```

> 💡 此命令会自动处理首次安装和版本升级，无需手动判断是否已安装。**安装后验证：**
```bash
flyai --help
```

**安装失败处理：**
| 情况 | 处理方式 |
|-----|---------|
| npm 未安装 | 提示用户先安装 Node.js (https://nodejs.org/) |
| 权限不足 | 建议使用 `sudo npm install -g @fly-ai/flyai-cli@latest --registry=https://registry.npmjs.org` 或使用 nvm 管理 Node |
| 网络问题 | 建议用户检查网络或使用国内镜像 `npm config set registry https://registry.npmmirror.com` |

**注意：** 此步骤只在首次使用时执行，后续调用会直接跳过已安装的情况。

### 第1步：读取 Memory 并收集盲盒条件

**1.1 读取用户记忆**

首先调用 `search_memory` 查询用户是否有历史偏好：

```python
search_memory(
  query="用户旅行偏好、常驻城市、去过的城市",
  keywords="旅行,盲盒,偏好,去过,城市",
  category="user_hobby",
  depth="shallow"
)
```

**1.2 收集盲盒底线条件**

使用 `ask_user_question` 收集用户的底线条件。

**必须收集的条件**：
1. **人均预算上限** - 如"不超过3000"
2. **最长飞行时间** - 如"3小时内"
3. **出行时间** - 如"下周五出发，3天2晚"

**可选收集的条件**：
4. **出发城市** - 如果 Memory 中没有记录
5. **硬性排除** - 如"不去海边"、"去过的城市不要"

**提问示例**：

```json
{
  "questions": [
    {
      "question": "🎁 准备开盲盒了！先设个底线——人均预算上限是多少？",
      "header": "预算上限",
      "options": [
        { "label": "¥1500以内", "description": "经济实惠型盲盒" },
        { "label": "¥2000以内", "description": "舒适体验型盲盒" },
        { "label": "¥3000以内", "description": "品质优选型盲盒" },
        { "label": "¥5000以内", "description": "豪华惊喜型盲盒" }
      ]
    },
    {
      "question": "飞多久你能接受？（影响能抽到的目的地范围）",
      "header": "飞行时间",
      "options": [
        { "label": "2小时内 ✈️", "description": "周边城市，轻松出行" },
        { "label": "3小时内 ✈️✈️", "description": "国内主流目的地" },
        { "label": "4小时内 ✈️✈️✈️", "description": "覆盖全国+东南亚" },
        { "label": "不限 🌏", "description": "全球盲盒，惊喜更大" }
      ]
    },
    {
      "question": "什么时候出发？玩几天？",
      "header": "出行时间",
      "options": [
        { "label": "这周末·2天1晚", "description": "说走就走" },
        { "label": "下周末·3天2晚", "description": "短途度假" },
        { "label": "小长假·4-5天", "description": "深度体验" },
        { "label": "我来指定日期", "description": "自定义时间" }
      ]
    },
    {
      "question": "有什么地方是绝对不要的吗？（多选）",
      "header": "排除条件",
      "multiSelect": true,
      "options": [
        { "label": "去过的城市不要 🚫", "description": "追求新鲜感" },
        { "label": "不要海边 🚫🏖️", "description": "不喜欢沙滩" },
        { "label": "不要爬山 🚫🏔️", "description": "腿不想累" },
        { "label": "都可以，全凭缘分 🎲", "description": "真正的盲盒精神" }
      ]
    }
  ]
}
```

### 第2步：搜索候选目的地池

根据用户设定的底线条件，调用 FlyAI 搜索所有可能的目的地。

**2.1 广泛搜索候选目的地**

```bash
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai keyword-search \
  --query "[出发城市]出发 飞行[X小时]内 [天数]天 人均[预算]以内"
```

**2.2 对候选目的地搜索机票价格**

对每个候选目的地，搜索往返机票：

```bash
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-flight \
  --origin "[出发城市]" --destination "[候选目的地]" \
  --dep-date [出发日期] --back-date [返回日期] \
  --sort-type 3 --journey-type 1
```

**2.3 筛选符合条件的目的地**

计算每个目的地的预估总花费（机票+酒店+基本开销），筛选出：
- 总花费 ≤ 用户预算上限
- 飞行时间 ≤ 用户设定的上限
- 不在用户排除列表中

**2.4 排除用户去过的城市**（如果用户设定了此条件）

从 Memory 中读取用户去过的城市，从候选池中排除。

### 第3步：盲盒交互 — 准备揭晓

当候选池确定后，输出盲盒准备界面：

```markdown
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎁 你的旅行盲盒 · 准备好了吗？

  📦 盲盒条件确认：
  ✅ 人均 ≤ ¥[预算上限]
  ✅ 飞行 ≤ [X]小时
  ✅ [出发日期]出发，[天数]天[晚数]晚
  ✅ 排除：[排除条件列表]

  🎲 候选池中有 [N] 个目的地符合条件
  已随机抽取 1 个！

  👇 准备好了就说"拆开"

  [🎁 拆盲盒！]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

**注意**：在用户说"拆开"之前，不要透露抽中的目的地。

### 第4步：拆盲盒 — 揭晓目的地

用户确认后，从候选池中**随机抽取**一个目的地，然后：

**4.1 搜索抽中目的地的详细信息**

```bash
# 搜索酒店
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-hotel \
  --dest-name "[抽中城市]" \
  --check-in-date [入住日期] --check-out-date [退房日期] \
  --max-price [预算/晚数/60%] --sort rate_desc

# 搜索景点
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-poi --city-name "[抽中城市]"
```

**4.2 输出盲盒揭晓 + 完整方案**

```markdown
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

🎉🎉🎉 恭喜！你的盲盒目的地是——

    ╔═══════════════════════╗
    ║                       ║
    ║    🏙  [城市名]  🏙     ║
    ║                       ║
    ║  "[城市标语/特色]"     ║
    ║  [城市一句话描述]       ║
    ║                       ║
    ╚═══════════════════════╝

💡 为什么是[城市名]？
  · [亮点1]
  · [亮点2]
  · [亮点3]
  · 而且——[预算优势]！

━━━━━━━━━━━━━━━━━━

📋 你的[城市名][天数]天[晚数]晚方案：

✈️ 机票：
  去 [航班号] [日期] [时间] ¥[价格]/人
  回 [航班号] [日期] [时间] ¥[价格]/人
  往返 ¥[总价]/人

🏨 酒店：
  [酒店名称] ¥[单价]/晚 ⭐[评分]
  [晚数]晚 = ¥[总价]（[酒店亮点]）

📍 精华景点：
  · [景点1] — [一句话描述]（[门票价格]）
  · [景点2] — [一句话描述]（[门票价格]）
  · [景点3] — [一句话描述]（[门票价格]）
  · [景点4] — [一句话描述]（[门票价格]）
  
🍜 必吃美食：
  [当地特色美食列表]
  （人均¥[金额]就能吃到撑）

💰 总费用预估：
  机票 ¥[金额] + 酒店 ¥[金额] + 餐饮 ¥[金额] + 交通 ¥[金额]
  = 人均 ¥[总价] 🎉
  [与预算对比，省了多少钱]

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

🎲 不满意？你有3次重抽机会：
  [🔄 换一个盲盒（还剩2次）]
  [✅ 就它了！开始预订]
  [📋 保存方案，容我想想]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

### 第5步：重抽机制

如果用户不满意，提供最多 **3次重抽机会**：

- 每次重抽从**剩余候选池**中随机抽取
- 重抽时输出："🔄 盲盒重摇中...从剩余 [N-1] 个候选中抽取..."
- 3次都不满意 → 展示完整候选列表让用户自选

```markdown
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📋 盲盒模式结束 — 以下是所有符合条件的目的地：

  1️⃣ [城市A] — 往返¥[价格] | [特色标签]
  2️⃣ [城市B] — 往返¥[价格] | [特色标签]
  3️⃣ [城市C] — 往返¥[价格] | [特色标签]
  ...

  👉 选一个数字，我帮你生成完整方案
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

---

---


path: reference/search-marriott-hotel.md
content: # search-marriott-hotel ref

## Marriott Hotel Search (search-marriott-hotel)

### Parameters

- **--dest-name** (required): Destination — must be a country, province, city, or district
- **--key-words** (optional): Search keywords
- **--poi-name** (optional): Nearby attraction name, used to filter by surrounding POI
- **--hotel-brands** (optional): Marriott hotel brands, comma-separated
- **--hotel-name** (optional): Exact or fuzzy hotel name
- **--hotel-bed-types** (optional): Bed type, comma-separated
  - Values: `大床房` (king), `双床房` (twin), `多床房` (multi)
- **--max-price** (optional): Max price per night (CNY)
- **--sort** (optional): Sort order
  - Values: `distance_asc`, `rate_desc`, `price_asc`, `price_desc`, `no_rank`
- **--check-in-date** (optional): Check-in date, format `YYYY-MM-DD`
- **--check-out-date** (optional): Check-out date, format `YYYY-MM-DD`

### Examples

```bash
flyai search-marriott-hotel --dest-name "上海" --hotel-brands "万豪酒店,喜来登" --check-in-date 2026-03-20 --check-out-date 2026-03-22
flyai search-marriott-hotel --dest-name "杭州" --hotel-name "杭州JW万豪酒店" --sort price_asc --max-price 1200
```

### Output Example

```json
{
  "status": 0,
  "message": "success",
  "data": {
    "itemList": [
      {
        "address": "延安中路1218号",
        "brandName": "JW万豪",
        "interestsPoi": "近静安寺商圈",
        "latitude": "31.224612",
        "longitude": "121.442115",
        "mainPic": "https://img.alicdn.com/...",
        "detailUrl": "...",
        "name": "上海明天广场JW万豪酒店",
        "price": "¥1288",
        "review": "地理位置优越，服务稳定",
        "score": "4.8",
        "scoreDesc": "很棒",
        "shId": "12345678",
        "star": "豪华型"
      }
    ]
  }
}
```


path: reference/search-hotel.md
content: # search-hotel ref

## Hotel Search (search-hotel)

### Parameters

- **--dest-name** (required): Destination — must be a country, province, city, or district
- **--key-words** (optional): Search keywords
- **--poi-name** (optional): Nearby attraction name, used to filter by surrounding POI
- **--hotel-types** (optional): Hotel type
  - Values: `酒店` (hotel), `民宿` (homestay), `客栈` (inn)
- **--sort** (optional): Sort order
  - Values: `distance_asc`, `rate_desc`, `price_asc`, `price_desc`, `no_rank`
- **--check-in-date** (optional): Check-in date, format `YYYY-MM-DD`
- **--check-out-date** (optional): Check-out date, format `YYYY-MM-DD`
- **--hotel-stars** (optional): Star rating, comma-separated
  - Range: 1–5
- **--hotel-bed-types** (optional): Bed type, comma-separated
  - Values: `大床房` (king), `双床房` (twin), `多床房` (multi)
- **--max-price** (optional): Max price per night (CNY)

### Examples

```bash
flyai search-hotel --dest-name "杭州" --poi-name "西湖" --check-in-date 2026-03-10 --check-out-date 2026-03-12
flyai search-hotel --dest-name "三亚" --hotel-stars "4,5" --sort rate_desc --max-price 800
```

### Output Example

```json
{
  "status": 0,
  "message": "success",
  "data": {
    "itemList": [
        {
          "address": "环城西路2号",
          "brandName": "雷迪森",
          "decorationTime": "2014",
          "interestsPoi": "近杭州西湖风景名胜区",
          "latitude": "30.259204",
          "longitude": "120.159246",
          "mainPic": "https://img.alicdn.com/...",
          "detailUrl": "...",
          "name": "杭州望湖宾馆",
          "price": "¥618",
          "review": "西湖边的位置，家庭出游首选",
          "score": "5.0",
          "scoreDesc": "超棒",
          "shId": "10021423",
          "star": "豪华型"
        }
    ]
  }
}
```


path: reference/algorithm.md
content: # 随机算法说明

为了增加盲盒的惊喜感，采用**加权随机**算法：

| 目的地类型 | 权重 | 说明 |
|-----------|------|------|
| 小众目的地 | 1.5x | 游客少，惊喜感强 |
| 热门目的地 | 1.0x | 标准权重 |
| 超热门目的地 | 0.7x | 降低抽中概率 |

目标：让用户更容易抽到"没想到但很惊喜"的地方，而不是总抽到大家都去的热门城市。

---


path: reference/ai-search.md
content: # ai-search ref

## AI Search (ai-search)

### Parameters

- **--query** (required): Full natural-language query for semantic search
  - Supports hotels, attractions, flights, trains, and mixed travel intent
  - Can include complex constraints such as destination, date, budget, companions, preferences, and scenario

### Examples

```bash
flyai ai-search --query "五一去杭州玩三天，预算人均2000，想住西湖附近，推荐行程和酒店"
flyai ai-search --query "下周从上海去东京，优先直飞，帮我找性价比高的航班和酒店"
```

### Output Example

```json
{
  "status": 0,
  "message": "success",
  "data": "..."
}
```


path: reference/search-poi.md
content: # search-poi ref

## POI / Attraction Search (search-poi)

### Parameters

- **--city-name** (required): City name where the attraction is located
- **--poi-level** (optional): Attraction level
  - Range: 1–5
- **--keyword** (optional): Attraction name keyword
  - e.g. `西湖`, `故宫`, `长城`
- **--category** (optional): Attraction category (single select only)
  - Values: `自然风光` (nature) · `山湖田园` (lake & countryside) · `森林丛林` (forest) · `峡谷瀑布` (canyon & waterfall) · `沙滩海岛` (beach & island) · `沙漠草原` (desert & grassland) · `人文古迹` (cultural heritage) · `古镇古村` (ancient town) · `历史古迹` (historic site) · `园林花园` (garden) · `宗教场所` (temple) · `公园乐园` (park) · `主题乐园` (theme park) · `水上乐园` (water park) · `影视基地` (film studio) · `动物园` (zoo) · `植物园` (botanical garden) · `海洋馆` (aquarium) · `体育场馆` (sports venue) · `演出赛事` (shows & events) · `剧院剧场` (theater) · `博物馆` (museum) · `纪念馆` (memorial) · `展览馆` (exhibition hall) · `地标建筑` (landmark) · `市集` (market) · `文创街区` (creative district) · `城市观光` (city sightseeing) · `户外活动` (outdoor activities) · `滑雪` (skiing) · `漂流` (rafting) · `冲浪` (surfing) · `潜水` (diving) · `露营` (camping) · `温泉` (hot spring)

### Examples

```bash
flyai search-poi --city-name "杭州" --keyword "西湖" --category "山湖田园"
flyai search-poi --city-name "北京" --poi-level 5
flyai search-poi --city-name "西安" --category "历史古迹"
```

### Output Example

```json
{
    "data": {
      "itemList": [
        {
          "address": "陕西省西安市莲湖区北院门...",
          "id": "177224",
          "mainPic": "https://img.alicdn.com/tfscom/...",
          "jumpUrl": "...",
          "name": "西安钟鼓楼",
          "freePoiStatus": "...",
          "ticketInfo": {
              "price": null,
              "priceDate": "2026-03-19",
              "ticketName": "西安鼓楼门票 成人票"
          }
        }
      ]
    },
    "message": "success",
    "status": 0
}
```


path: reference/keyword-search.md
content: # keyword-search ref

## Keyword Search (keyword-search)

### Parameters

- **--query** (required): Search keywords, supports natural language queries for hotels, flights, etc.
  - Choose the best-matching query pattern from below:
  - **Location / Nearby**: e.g. "nearby attractions", "restaurants near {POI}"
  - **POI general**: e.g. "{POI} free travel", "{POI} routes"
  - **Attractions / Activities**: e.g. "attraction tickets", "photo tours near {POI}"
  - **Destination**: e.g. "destination guide", "destination hotels"
  - **Entertainment / Experiences**: e.g. "hot spring spa", "skiing"
  - **Tours / Packages**: e.g. "group tour", "custom tour"
  - **Food & Dining**: e.g. "food guide", "buffet"
  - **Visa / Documents**: e.g. "visa", "travel insurance"
  - **Telecom / Connectivity**: e.g. "wifi rental", "SIM card"
  - **Cruise**: e.g. "cruise", "ocean sightseeing"
  - **Other**: e.g. "time-based queries", "shopping district {POI}"

### Examples

```bash
flyai keyword-search --query "France visa"
flyai keyword-search --query "Hangzhou group tour"
flyai keyword-search --query "Hangzhou 3-day trip"
flyai keyword-search --query "Shanghai cruise"
flyai keyword-search --query "Hong Kong SIM card"
```

### Output Example

```json
{
    "data": {
      "itemList": [
        {
          "info": {
              "jumpUrl": "...",
              "picUrl": "...",
              "price": "...",
              "scoreDesc": "",
              "star": "...",
              "tags": ["..."],
              "title": "..."
          }
        }
      ]
    },
    "message": "success",
    "status": 0
}
```


path: reference/search-train.md
content: # search-train ref

## Train Search (search-train)

### Parameters

- **--origin** (required): Departure city or station
- **--destination** (optional): Destination city or station
- **--dep-date** (optional): Departure date (`YYYY-MM-DD`)
- **--dep-date-start** / **--dep-date-end** (optional): Departure date range
- **--back-date** (optional): Return date
- **--back-date-start** / **--back-date-end** (optional): Return date range
- **--journey-type** (optional): Journey type
  - `1` = direct, `2` = transit
- **--seat-class-name** (optional): Seat class name, comma-separated
  - Example values: `second class`, `first class`, `business class`, `hard sleeper`, `soft sleeper`
- **--transport-no** (optional): Train number(s), comma-separated
- **--transfer-city** (optional): Transfer city(s), comma-separated
- **--dep-hour-start** / **--dep-hour-end** (optional): Departure hour range (24h)
- **--arr-hour-start** / **--arr-hour-end** (optional): Arrival hour range (24h)
- **--total-duration-hour** (optional): Max total travel duration (hours)
- **--max-price** (optional): Max price (CNY)
- **--sort-type** (optional): Sort order
  - `1`: price high -> low
  - `2`: recommended
  - `3`: price low -> high
  - `4`: duration short -> long
  - `5`: duration long -> short
  - `6`: departure early -> late
  - `7`: departure late -> early
  - `8`: direct first

### Examples

```bash
flyai search-train --origin "北京" --destination "上海"
flyai search-train --origin "北京" --destination "上海" --dep-date 2026-03-15
flyai search-train --origin "上海" --destination "杭州" --dep-date 2026-03-20 --journey-type 1 --seat-class-name "second class"
flyai search-train --origin "北京" --destination "上海" --dep-date 2026-03-15 --max-price 800 --sort-type 3
```

### Output Example

```json
{
  "status": 0,
  "message": "success",
  "data": {
    "itemList": [
      {
        "adultPrice": "¥553.0",
        "journeys": [
          {
            "journeyType": "直达",
            "segments": [
              {
                "depCityName": "北京",
                "depStationName": "北京南",
                "depDateTime": "2026-03-15 08:00:00",
                "arrCityName": "上海",
                "arrStationName": "上海虹桥",
                "arrDateTime": "2026-03-15 12:28:00",
                "duration": "268分钟",
                "transportType": "火车",
                "marketingTransportNo": "G11",
                "seatClassName": "二等座"
              }
            ],
            "totalDuration": "268分钟"
          }
        ],
        "jumpUrl": "..."
      }
    ]
  }
}
```


path: reference/tools.md
content: # 工具说明

## ask_user_question 工具

用于向用户提出选择题，快速收集信息。

**格式要求**：
- question: 清晰的问题文案
- header: 简短标签（≤12字符）
- options: 2-4个选项，每个包含 label 和 description

**示例**：
```json
{
  "questions": [{
    "question": "你从哪个城市出发？",
    "header": "出发城市",
    "options": [
      { "label": "上海", "description": "长三角出发" },
      { "label": "北京", "description": "华北出发" }
    ]
  }]
}
```

## FlyAI 核心能力

使用 `npx @anthropic-ai/flyai-cli@latest` 调用飞猪数据。

**常用命令**：
- `search flights`: 搜索航班
- `search hotels`: 搜索酒店
- `search attractions`: 搜索景点
- `search restaurants`: 搜索餐厅


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)