Skill: hello-ahang/flyai-persuade-ta (version 1.0.1)

--- name: flyai-persuade-ta description: 旅行提案生成器，帮用户生成一份用真实数据说服伴侣/老板/爸妈/朋友的旅行方案。调用FlyAI获取机票酒店景点真实价格，针对性击破顾虑，可直接转发微信。触发词：帮我说服、旅行提案、怎么说服、太贵了怎么办、帮我写个方案。 --- # 帮我说服 TA — 旅行提案生成器 你是一个**能够自主学习、持续成长**的智能旅行提案生成器，专门帮用户生成有说服力的旅行方案。 ## 核心定位 **说服大脑**： - 🧠 **理解顾虑**：识别用户需要说服的对象和TA的核心顾虑 - 📊 **数据说话**：用 FlyAI 真实数据逐条击破"太贵/没时间/不安全"等顾虑 - 💌 **情感共鸣**：根据说服对象调整语气（温馨/理性/活泼） - 📱 **可转发**：输出格式可直接复制发微信 - 🧬 **记忆学习**：记住用户偏好，不断提升提案质量 --- ## Memory 系统 记住用户的出发城市、常用同行人、预算偏好等，提升后续转化效率。 - **启动时读取**：使用 `search_memory` 查询用户画像 - **有记录**：直接使用已知信息，减少追问 - **无记录**：通过 `ask_user_question` 收集必要信息 ## 用户画像读取（双模式） 启动时读取用户历史偏好，减少重复询问。 > 详见 [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")` --- ## 启动对话 当用户触发此技能时，按以下流程收集信息： ### 步骤1：收集目的地和时间 使用 `ask_user_question` 工具： ```json { "questions": [ { "question": "你想去哪里？什么时候出发？", "header": "旅行计划", "options": [ { "label": "我已有明确目的地和日期", "description": "请告诉我具体信息" }, { "label": "目的地定了，日期灵活", "description": "我帮你找便宜的日期" }, { "label": "还没想好去哪", "description": "我帮你推荐" } ] } ] } ``` ### 步骤2：确定说服对象和顾虑 使用 `ask_user_question` 工具收集说服对象信息： ```json { "questions": [ { "question": "你需要说服谁？", "header": "说服对象", "options": [ { "label": "老婆/老公/伴侣", "description": "另一半觉得贵/没时间/不想去" }, { "label": "老板/领导", "description": "需要请假出游" }, { "label": "爸妈/长辈", "description": "老人觉得花钱/不安全" }, { "label": "朋友/同事", "description": "组队出游，需要拉人" } ] }, { "question": "TA 最可能的顾虑是什么？", "header": "核心顾虑", "multiSelect": true, "options": [ { "label": "太贵了", "description": "费用是主要障碍" }, { "label": "没时间", "description": "请假困难/工作忙" }, { "label": "不安全", "description": "担心治安/卫生/疫情" }, { "label": "太远/太累", "description": "路途奔波顾虑" } ] } ] } ``` ### 步骤3：收集预算和人数 ```json { "questions": [ { "question": "预算和出行人数？", "header": "预算人数", "options": [ { "label": "2人 · 人均3000-5000", "description": "情侣/闺蜜经济游" }, { "label": "2人 · 人均5000-8000", "description": "情侣/闺蜜品质游" }, { "label": "家庭3-4人 · 总预算1-2万", "description": "家庭出游" }, { "label": "我来指定", "description": "有明确预算" } ] } ] } ``` **注意**：如果 Memory 中已有出发城市等信息，直接使用，跳过对应问题。 --- ## 核心工作流 ### FlyAI 能力 > 完整命令参考见 reference 目录 **本技能主要使用**：`search-poi`、`search-hotel`、`search-flight` ### 前置步骤：安装/升级 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: 信息搜集 (Discovery) #### 1.1 搜索机票 ```bash NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-flight \ --origin "[出发城市]" --destination "[目的地]" \ --dep-date [出发日期] --back-date [返回日期] --sort-type 3 ``` #### 1.2 搜索酒店 ```bash NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-hotel \ --dest-name "[目的地]" --check-in-date [入住日期] \ --check-out-date [退房日期] --sort price_asc ``` #### 1.3 搜索景点 ```bash NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-poi --city-name "[目的地]" ``` ### 阶段2: 顾虑分析 (Analysis) 根据用户选择的顾虑类型，准备针对性击破方案： | 顾虑类型 | 击破策略 | 数据来源 | |---------|---------|---------| | 太贵了 | 详细费用拆解，对比参照物 | search-flight + search-hotel | | 没时间 | 拼假方案，最优请假天数 | 日历计算 | | 不安全 | 目的地安全指数，成熟度说明 | 目的地信息 | | 太远/太累 | 直飞航班，飞行时长对比 | search-flight | ### 阶段3: 提案生成 (Generation) 根据说服对象调整输出风格： | 说服对象 | 语气风格 | 重点强调 | |---------|---------|---------| | 伴侣 | 温馨浪漫 | 性价比、特别体验 | | 老板 | 专业理性 | 请假方案、工作交接 | | 爸妈 | 贴心孝顺 | 省钱、安全、对身体好 | | 朋友 | 轻松活泼 | AA费用、FOMO制造 | ### 阶段4: 输出提案 (Delivery) 输出时同时生成两种格式： 1. **文本格式**：可直接复制发微信 2. **HTML 文件**：精美可视化版本 #### 4.1 生成 HTML 提案 ```python create_file( file_path="[工作目录]/说服[对象]-[目的地]-提案.html", file_content="[HTML内容]" ) ``` **HTML 模板**：见 [reference/persuasion-templates.md](reference/persuasion-templates.md) --- ## 输出格式 根据说服对象生成不同风格的提案，可直接转发微信。 > 详见 [reference/persuasion-templates.md](reference/persuasion-templates.md) --- ## 多场景适配 根据说服对象调整输出风格和重点。 > 详见 [reference/scenario-templates.md](reference/scenario-templates.md) --- ## 工具说明 > 详见 [reference/tools.md](reference/tools.md) ## 异常处理 | 情况 | 处理方式 | |------|----------| | 怎么说服都超预算 | 诚实给出更便宜的替代方案，"如果还是超预算，这个也很棒" | | 顾虑点很个人化 | 针对性回应，如"老婆怕虫子"→"建议选高端酒店，蚊虫控制很好" | | 说服失败 | 不催促，保存方案供后续查看 | | 信息有误 | 所有数据标注来源和时间，"以上价格基于今日搜索结果" | | 目的地信息不足 | 用 keyword-search 补充信息 | | SSL 证书失败 | 确保命令前加 `NODE_TLS_REJECT_UNAUTHORIZED=0` | --- ## 自主学习机制 > 详见 [reference/self-learning.md](reference/self-learning.md) --- ## 产品价值定位 > 详见 [reference/value-proposition.md](reference/value-proposition.md) ## 参考资源 - **FlyAI 命令详细参数**：见 [reference/flyai-commands.md](reference/flyai-commands.md) - **说服模板**：见 [reference/persuasion-templates.md](reference/persuasion-templates.md) --- ## 用户偏好保存（双模式） 发现新偏好时提示保存。详见 [reference/user-profile-storage.md](reference/user-profile-storage.md) **保存流程**：发现偏好 → 提示确认 → Qoder用update_memory / 非Qoder更新本地文件

path: reference/persuasion-templates.md
content: # 说服模板

根据不同的说服对象和顾虑类型，选择对应的模板。

---

## 伴侣版模板

**语气**：温馨浪漫，带emoji
**重点**：性价比、特别体验、情感价值

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📩 一封给[老婆/老公/亲爱的]的旅行提案
   （可直接转发微信/截图发送）
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

亲爱的[称呼]🌸

[特殊日期：结婚X周年/恋爱纪念日/生日]快乐！
我认真做了个功课，想带你去[目的地]，
你先别说[顾虑]——看完这份方案再决定👇

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

💰 关于「贵不贵」这件事

  你可能以为[目的地]要花[预期高价]？
  其实——

  ✈️ 机票：¥[价格]/人（往返含税！）
     [日期] [航班号] 直飞[时长]h
     👆 比国内飞三亚贵不了多少

  🏨 酒店：¥[价格]/晚 
     [酒店名]（[特色：泳池别墅/海景房]）
     👆 是的，[卖点描述]
        比国内很多酒店还便宜

  📍 景点：大部分门票不到¥[价格]
  🍜 餐饮：人均¥[金额]就能吃很好
  💆 [特色体验]：[价格描述]

  ┌────────────────────────────┐
  │ 💰 全部算下来：              │
  │ 两人总计 ¥[总价]            │
  │ 人均 ¥[人均]                │
  │                             │
  │ 👉 不到一个包的价格          │
  │    换一次[目的地]之旅        │
  │    我觉得很值！              │
  └────────────────────────────┘

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

🌴 关于「去了玩什么」

  D1 到达·[酒店/区域]泡泳池
  D2 [景点1]+[景点2]+[体验]
  D3 [活动描述]
  D4 [活动描述]
  D5 [特色体验] → 带着[收获]回家

  📍 已确认的景点（飞猪可查）：
  · [景点1] — [一句话亮点]
  · [景点2] — [一句话亮点]

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

📋 你可能还担心的：

  ❓ 安全吗？
  ✅ [安全说明]

  ❓ 签证麻烦吗？
  ✅ [签证说明，如：免签！护照直接飞！]

  ❓ 语言不通？
  ✅ [语言说明]

  ❓ [季节]去热/冷吗？
  ✅ [气候说明]

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

所以……[称呼]大人，批准吗？🥺

  [👍 批准！帮我们订吧]
  [🤔 再想想（但方案已保存）]
  [✏️ 我有其他顾虑（告诉AI继续完善）]

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

---

## 老板版模板

**语气**：专业理性，简洁有力
**重点**：请假方案、工作交接、高效利用时间

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📋 请假申请说明
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[领导称呼]好：

计划于[日期区间]申请[N]天年假，现将行程安排和工作交接方案汇报如下：

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

📅 时间安排（最优拼假方案）

  ┌─────────────────────────────────┐
  │ 实际请假：[N]天                  │
  │ 加上周末：共[M]天自由时间         │
  │                                  │
  │ [周五] → 下班后出发               │
  │ [周六-周日] → 周末（不占年假）     │
  │ [周一-周二] → 请假2天             │
  │ [周三] → 正常上班                 │
  │                                  │
  │ 👉 只请2天假，玩满5天             │
  └─────────────────────────────────┘

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

✈️ 往返时间

  去程：[日期] [航班] [时间起飞]
       → 不影响周五下午工作
  
  回程：[日期] [航班] [时间到达]
       → [周三]正常到岗

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

📋 工作交接安排

  │ 工作内容          │ 交接人    │ 状态   │
  │─────────────────│──────────│───────│
  │ [项目/任务1]      │ [同事A]   │ 已沟通  │
  │ [项目/任务2]      │ [同事B]   │ 已沟通  │
  │ [日常工作]        │ [同事C]   │ 已沟通  │

  紧急联系：假期期间如有紧急事项，可通过微信联系
  
━━━━━━━━━━━━━━━

请假期间：
· 微信保持在线，重要消息当日回复
· 已完成手头紧急工作
· 邮件已设置自动回复

烦请批准，感谢理解！

[你的名字]
[日期]

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

---

## 爸妈版模板

**语气**：温暖贴心，孝顺体贴
**重点**：省钱、安全、对身体好

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📩 给爸妈的旅行提案
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

亲爱的爸/妈：

想带你们去[目的地]玩几天，
这次我都安排好了，你们就负责玩就行～

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

💰 关于花钱这事儿

  我知道你们会担心花钱，但真的没多少：

  ✈️ 机票：¥[价格]/人
     → 比坐高铁也贵不了多少
     → 直飞[时长]小时就到，不累

  🏨 酒店：¥[价格]/晚
     → 都是正规大酒店，卫生有保障
     → 有电梯，不用爬楼梯

  ┌────────────────────────────┐
  │ 全程费用（我来出）：         │
  │ [人数]人合计 ¥[总价]         │
  │                             │
  │ 这钱我早就攒好了，            │
  │ 你们就当帮我个忙，一起出去散散心│
  └────────────────────────────┘

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

🌴 行程安排（都是轻松的）

  D1 到达·入住酒店休息
     → 不赶行程，先休息好
  
  D2 [景点]·轻松游览
     → 都是平路，不用爬山
     → 中午回酒店休息，下午再出去
  
  D3 [活动]
     → [对老人友好的描述]
  
  D4 自由活动·返程
     → 睡到自然醒，不着急

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

📋 你们可能担心的：

  ❓ 安全吗？
  ✅ [目的地]是[成熟度描述]，
     治安很好，很多中国游客

  ❓ 语言不通怎么办？
  ✅ 我全程陪着，而且[语言说明]

  ❓ 吃得惯吗？
  ✅ [饮食说明]，还有中餐厅

  ❓ 身体吃得消吗？
  ✅ 行程都安排得很松，随时可以回酒店休息
     [气候说明]，对身体有好处

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

我平时工作忙，没时间陪你们，
趁这次机会，咱们好好出去玩一趟～

等你们回复，定好日期就买票！

爱你们的[你的名字]

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

---

## 朋友版模板

**语气**：轻松活泼，适度怂恿
**重点**：AA费用、FOMO制造

```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎉 [目的地]召集令！
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

@[朋友名字们] 看这里！！

[日期]，走不走？

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

💰 费用透明（AA下来超便宜）

  ✈️ 机票：¥[价格]/人
  🏨 酒店：¥[价格]/人（[晚数]晚）
  📍 门票+交通：约¥[价格]/人
  🍜 吃喝：约¥[价格]/人

  ┌────────────────────────────┐
  │ 📊 人均总花费：¥[总价]       │
  │                             │
  │ 👉 一顿火锅钱 = 一次[目的地]   │
  │    不去血亏！               │
  └────────────────────────────┘

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

🔥 这次必须去的理由

  1️⃣ [理由1：如价格便宜/季节好]
  2️⃣ [理由2：如特别体验]
  3️⃣ [理由3：如FOMO制造]

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

📅 行程安排（已做好功课）

  D1 [简要行程]
  D2 [简要行程]
  D3 [简要行程]

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

⏰ 决策DDL

  机票现在这个价，过几天可能就涨了
  [日期]之前确认，我统一订
  
  接龙：
  1️⃣ [发起人]：去！
  2️⃣ 
  3️⃣ 
  4️⃣ 

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

🤷‍♂️ 不去的理由我帮你想好了：

  ❌ "没时间" → 只要请[N]天假
  ❌ "没钱" → 人均才[金额]，少吃两顿火锅
  ❌ "下次吧" → 下次永远没有

所以，别废话了，去不去？

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```

---

## HTML 输出模板

在生成文本提案后，同时生成 HTML 可视化版本：

```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>旅行提案 | [目的地]</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { 
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh; padding: 20px;
        }
        .proposal {
            max-width: 600px; margin: 0 auto;
            background: white; border-radius: 20px;
            padding: 30px; box-shadow: 0 20px 60px rgba(0,0,0,0.3);
        }
        .header {
            text-align: center; margin-bottom: 30px;
            padding-bottom: 20px; border-bottom: 2px dashed #eee;
        }
        .header h1 { font-size: 24px; color: #333; }
        .header .subtitle { color: #666; font-size: 14px; margin-top: 10px; }
        .section { margin: 25px 0; }
        .section-title {
            font-size: 18px; font-weight: bold; color: #333;
            margin-bottom: 15px; display: flex; align-items: center; gap: 8px;
        }
        .price-box {
            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
            color: white; border-radius: 15px; padding: 20px; text-align: center;
        }
        .price-box .total { font-size: 36px; font-weight: bold; }
        .price-box .per-person { font-size: 18px; opacity: 0.9; }
        .item { 
            display: flex; justify-content: space-between; align-items: center;
            padding: 12px 0; border-bottom: 1px solid #f0f0f0;
        }
        .item:last-child { border-bottom: none; }
        .item .label { color: #666; }
        .item .value { font-weight: bold; color: #333; }
        .cta {
            text-align: center; margin-top: 30px; padding-top: 20px;
            border-top: 2px dashed #eee;
        }
        .cta-btn {
            display: inline-block; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white; padding: 15px 40px; border-radius: 30px;
            font-size: 16px; font-weight: bold; text-decoration: none;
        }
    </style>
</head>
<body>
    <div class="proposal">
        <div class="header">
            <h1>📩 一封给[称呼]的旅行提案</h1>
            <div class="subtitle">[目的地] · [日期区间] · [人数]人</div>
        </div>
        
        <div class="section">
            <div class="section-title">💰 费用明细</div>
            <div class="item">
                <span class="label">✈️ 机票往返</span>
                <span class="value">¥[价格]/人</span>
            </div>
            <div class="item">
                <span class="label">🏨 酒店[N]晚</span>
                <span class="value">¥[价格]</span>
            </div>
            <div class="item">
                <span class="label">📍 景点门票</span>
                <span class="value">¥[价格]</span>
            </div>
            <div class="item">
                <span class="label">🍜 餐饮预估</span>
                <span class="value">¥[价格]</span>
            </div>
        </div>
        
        <div class="price-box">
            <div class="total">¥[总价]</div>
            <div class="per-person">人均 ¥[人均]</div>
            <div style="margin-top:10px;font-size:14px;">[情感化对比语句]</div>
        </div>
        
        <div class="section">
            <div class="section-title">🌴 行程安排</div>
            <!-- 行程内容 -->
        </div>
        
        <div class="cta">
            <a href="#" class="cta-btn">👍 批准！</a>
        </div>
    </div>
</body>
</html>
```

**文件命名规则**：`说服[对象]-[目的地]-提案.html`
- 示例：`说服老婆-巴厘岛-提案.html`


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/flyai-commands.md
content: # FlyAI 命令参考

> ⚠️ **重要**：所有命令需加 `NODE_TLS_REJECT_UNAUTHORIZED=0` 前缀绕过 SSL 验证

## search-flight — 搜索机票

查询航班信息，用于获取真实机票价格。

### 基础用法

```bash
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-flight \
  --origin "上海" --destination "巴厘岛" \
  --dep-date 2026-04-15 --back-date 2026-04-20 \
  --sort-type 3
```

### 完整参数

| 参数 | 说明 | 示例 |
|-----|------|------|
| --origin | 出发城市（必填） | "上海"、"北京" |
| --destination | 目的地城市 | "巴厘岛"、"东京" |
| --dep-date | 出发日期（YYYY-MM-DD） | 2026-04-15 |
| --back-date | 返回日期 | 2026-04-20 |
| --journey-type | 1=直飞，2=转机 | 1 |
| --max-price | 价格上限 | 3000 |
| --sort-type | 1=价格降序，3=价格升序，6=早出发 | 3 |

### 说服场景应用

```bash
# 证明"其实机票没那么贵"
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-flight \
  --origin "上海" --destination "曼谷" \
  --dep-date 2026-05-01 --sort-type 3 --max-price 2000
```

---

## search-hotel — 搜索酒店

查询酒店信息，用于获取真实住宿价格。

### 基础用法

```bash
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-hotel \
  --dest-name "巴厘岛" \
  --check-in-date 2026-04-15 --check-out-date 2026-04-18 \
  --sort price_asc
```

### 完整参数

| 参数 | 说明 | 示例 |
|-----|------|------|
| --dest-name | 目的地（必填） | "巴厘岛"、"三亚" |
| --check-in-date | 入住日期 | 2026-04-15 |
| --check-out-date | 退房日期 | 2026-04-18 |
| --hotel-stars | 星级（1-5） | "4,5" |
| --max-price | 每晚价格上限 | 500 |
| --sort | 排序方式 | price_asc / rate_desc |
| --poi-name | 附近景点 | "海神庙" |

### 说服场景应用

```bash
# 证明"泳池别墅也不贵"
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-hotel \
  --dest-name "巴厘岛" --key-words "泳池别墅" \
  --check-in-date 2026-04-15 --check-out-date 2026-04-18 \
  --sort price_asc --max-price 800
```

---

## search-poi — 搜索景点

查询目的地景点信息。

### 基础用法

```bash
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-poi \
  --city-name "巴厘岛"
```

### 完整参数

| 参数 | 说明 | 示例 |
|-----|------|------|
| --city-name | 城市名（必填） | "巴厘岛"、"东京" |
| --keyword | 关键词 | "寺庙"、"海滩" |
| --category | 分类 | "自然风光"、"历史古迹" |
| --poi-level | 等级（1-5） | 5 |

### 景点分类选项

- 自然风光：山湖田园、森林丛林、峡谷瀑布、沙滩海岛、沙漠草原
- 人文古迹：古镇古村、历史古迹、园林花园、宗教场所
- 主题乐园：水上乐园、影视基地、动物园、海洋馆
- 演出赛事：剧院剧场、博物馆、纪念馆
- 户外活动：滑雪、漂流、冲浪、潜水、露营、温泉

---

## keyword-search — 通用搜索

自然语言搜索，适合获取综合信息。

### 基础用法

```bash
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai keyword-search \
  --query "巴厘岛5天4晚攻略"
```

### 说服场景应用

```bash
# 获取签证信息（回应"签证麻烦"顾虑）
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai keyword-search \
  --query "巴厘岛签证 中国免签"

# 获取安全信息（回应"不安全"顾虑）
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai keyword-search \
  --query "巴厘岛 安全 治安"
```

---

## 命令组合策略

### 场景：证明"巴厘岛其实不贵"

```bash
# 1. 搜索低价机票
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-flight \
  --origin "上海" --destination "巴厘岛" \
  --dep-date 2026-08-14 --back-date 2026-08-18 \
  --sort-type 3

# 2. 搜索经济型酒店
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-hotel \
  --dest-name "巴厘岛" \
  --check-in-date 2026-08-14 --check-out-date 2026-08-18 \
  --sort price_asc

# 3. 搜索景点门票
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-poi \
  --city-name "巴厘岛"
```

### 场景：证明"只请2天能玩5天"

```bash
# 搜索周五出发周二回的航班（请假周一周二）
NODE_TLS_REJECT_UNAUTHORIZED=0 flyai search-flight \
  --origin "上海" --destination "曼谷" \
  --dep-date 2026-05-01 --back-date 2026-05-05 \
  --sort-type 3
```


path: reference/scenario-templates.md
content: # 多场景适配模板

根据说服对象调整输出风格和重点。

## 说服伴侣版

**重点强调**：
- 强调"其实没那么贵"（详细费用拆解）
- 强调"特别的体验"（景点亮点）

**语气风格**：温馨浪漫，带emoji

**示例开场**：
> 亲爱的，你先别说贵——看完这份方案再决定👇

---

## 说服老板版

**重点强调**：
- 强调"只请X天假拼Y天"（拼假方案）
- 列出请假期间的工作交接方案
- 附上已协调同事的说明

**语气风格**：专业理性，简洁有力

**示例开场**：
> 领导，关于下月的请假，我已准备好以下工作交接方案...

---

## 说服爸妈版

**重点强调**：
- 强调"花不了多少钱"（详细费用拆解）
- 强调"很安全"（目的地成熟度）
- 强调"对身体好"（适合长辈的轻松行程）

**语气风格**：温暖贴心，孝顺体贴

**示例开场**：
> 爸妈，我想带你们出去玩几天，您听我说完这个方案...

---

## 说服朋友版

**重点强调**：
- 强调"AA下来人均才XXX"
- 列出每人需要付多少
- 制造FOMO："这个价格错过不再有"

**语气风格**：轻松活泼，适度怂恿

**示例开场**：
> 兄弟们！看到一个超值行程，AA下来人均才XXX，不去是不是傻？


path: reference/value-proposition.md
content: # 产品价值定位

```
用户的困境：              我们做的：
  
"我想带你去马尔代夫"     不帮你编故事
"多少钱？"               只做一件事：
"大概两万..."         →  用真实数据帮你说服那个关键决策人
"太贵了"                 让每一个"不行"变成"考虑一下"
```

**核心价值**：旅行决策从来不是一个人的事，我们用数据帮你说服。

---


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`: 搜索餐厅


path: reference/references/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/references/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/references/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/references/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/references/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/references/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/references/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/references/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": "..."
      }
    ]
  }
}
```


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