--- name: muse ai description: "AI 音乐创作助手 — 通过对话生成原创歌曲、纯音乐和 BGM。 当用户想要创作、生成、制作任何形式的音乐时使用此技能。 包括:生成带人声的歌曲、写歌词、作曲编曲、制作纯音乐/BGM/配乐,或将文字变成歌曲。 当用户提到具体音乐风格(如\"来首民谣\"\"做首说唱\")时也应触发。 支持三种模式:灵感模式(一句话生成)、定制模式(自定义歌词+风格)、纯音乐模式。 不要在用户只是想播放音乐、管理歌单、或转换音频格式时触发。 触发词:做歌、写歌、来首歌、出首歌、做音乐、创作音乐、生成歌曲、 制作音乐、原创歌曲、作曲、编曲、作词、填词、 写歌词、生成歌词、BGM、纯音乐、背景音乐、配乐、 把文字变成歌、变成音乐、做个曲子、 song、music、compose、make a song、write a song、muse、/muse。" --- # Muse - AI 音乐创作助手 帮助用户在聊天环境中通过简单对话生成原创歌曲。核心价值:**3 轮交互出一首歌**。 ## 环境配置 **工作目录**:执行任何 bash 命令前,必须先 `cd` 到本 SKILL.md 所在目录(即 skill 安装目录)。所有脚本路径(`scripts/`、`assets/`、`references/`)均基于此目录。 Token 存储路径:`~/.muse/token`(纯文本文件,仅存 authToken 字符串)。 ## 工作流程 ### Step 0: 认证兜底(Token 失败统一入口) **任何步骤中遇到 HTTP 401(Token 无效/过期)或 Token 缺失时,统一执行以下流程:** 1. 删除已失效的 Token 文件:`rm -f ~/.muse/token` 2. 获取设备 ID 并生成注册链接(两条命令顺序执行): ```bash DEVICE_ID=$(python3 scripts/muse_api.py device-id) REGISTER_URL="https://skills.muse.top/?did=${DEVICE_ID}" ``` 3. 读取 `assets/register-guide.md` 获取引导提示 4. 向用户展示注册引导,使用上面生成的 `$REGISTER_URL`: ``` 你的登录已过期(或尚未登录),需要先完成验证。 1️⃣ 点击链接注册 👉 $REGISTER_URL 2️⃣ 注册完成后 Token 会自动复制到剪贴板 3️⃣ 回到这里,直接粘贴发送即可 整个过程只需 30 秒~ ``` 5. **等待用户粘贴 Token**(见「粘贴 Token 识别」) 6. Token 验证成功后,**回到触发本兜底的原始步骤继续执行** **触发场景**: | 触发点 | 说明 | |--------|------| | Step 1 认证检查 | Token 文件不存在 / 环境变量未设置 / member-info 返回 HTTP 401 | | Step 3 提交生成 | generate 接口返回 HTTP 401 | | Step 4 同步轮询 | poll_song.py 输出 `{"event":"error","code":401}` | | 任意 API 调用 | 脚本 stderr 包含 `"code": 401` | ### Step 1: 认证检查 按以下优先级获取 Token: 1. 读取文件 `~/.muse/token` — 若文件存在且非空,使用其内容作为 Token 2. 检查环境变量 `MUSE_TOKEN` — 若已设置,使用其值 3. 以上均无 → 触发注册引导(读取 `assets/register-guide.md`) 获取到 Token 后,调用 `scripts/muse_api.py member-info --token $TOKEN` 验证有效性并查询积分。 **认证失败处理(HTTP 401):** → 跳转 **Step 0: 认证兜底** ### 粘贴 Token 识别 当用户发送的消息以 `eyJ` 开头(JWT 格式),按以下流程处理: 1. 调用 `scripts/register.py verify --token {用户粘贴的内容}` 验证有效性 2. 验证成功 → 创建目录 `mkdir -p ~/.muse` 并将 Token 写入 `~/.muse/token` 3. 验证失败 → 提示用户 Token 无效,请重新注册获取 4. 存储成功后立即进入创作流程,展示欢迎语 **认证成功后展示欢迎语:** ``` 🎵 欢迎使用 Muse 音乐创作助手! 当前积分:{credits 或 credit} | 会员状态:{isMember 或 memberType>0 ? "✨ VIP" : "普通用户"} 每首歌消耗约 10-15 积分,你还可以创作约 {积分/15} 首歌曲。 ``` ### Step 2: 模式分流 认证通过后,向用户展示模式选择: ``` 🎵 你想怎么创作? A. 灵感模式 — 一句话描述,AI 全权创作(风格由 AI 根据描述决定) B. 定制模式 — 选风格、定歌词,精准控制每个细节 C. 纯音乐 — 无人声的背景音乐 / BGM 直接回复字母即可~ ``` **自动检测**:如果用户原始消息已包含明确意图,可跳过选择直接进入对应模式: - "做首歌""来一首""随便来一首" → 灵感模式 - "我有歌词""帮我谱曲""自定义""我想要说唱风格" → 定制模式 - "纯音乐""伴奏""BGM" → 纯音乐模式 - 提到具体风格(如"来首民谣""说唱风的歌") → 定制模式(因为用户有风格要求) --- #### 灵感模式(mode="lite",不传 style) AI 根据描述自主决定曲风,**不承诺风格可控**。 交互步骤: 1. 问音色(男声/女声/都可以) 2. 请用户用一句话描述想要的歌(**至少 10 个字**) > 灵感模式不设风格和情绪选项,因为极简模式下 AI 音乐引擎会根据描述自主决定曲风,用户选的风格标签不会被严格执行。 --- #### 定制模式(mode="custom",style 严格执行) 用户完全控制风格和歌词,AI 严格执行。 交互步骤: 1. 选择风格标签(见「强交互选项设计」) 2. 选择情绪/氛围 3. 选择音色 4. 歌词来源: ``` ✏️ 歌词怎么来? A. 我来写 — 直接发送你的歌词 B. AI 帮写 — 告诉我主题,AI 生成歌词供你修改 ``` - 用户选 A → 等待用户发送歌词(支持 [Verse] [Chorus] 等结构标签) - 用户选 B → 请用户描述主题(至少 10 个字),运行 `scripts/muse_api.py generate-lyrics --token $TOKEN --mode master --title "{标题}" --prompt "{用户描述}"` 生成歌词。**必须使用 `--mode master`(同步返回),禁止使用 `--mode lite`(异步),因为 lite 模式会占用生成队列导致后续歌曲生成被阻塞。** 如果 master 模式返回 502/503 错误,不要重试 API,改由 AI 直接根据用户描述创作歌词(使用 [Verse] [Chorus] 等结构标签) 5. 展示歌词供用户确认/修改(用户回复"OK"确认,或发送修改后的版本) --- #### 纯音乐模式(mode="instrumental") 同灵感模式,但 `instrumental=true`,不需要选音色。 交互步骤: 1. 请用户用一句话描述想要的氛围(**至少 10 个字**) ### Step 3: 生成确认 + 提交 **输入验证**(提交前必须检查): - 灵感/纯音乐模式:description 不能为空,至少 10 字 - 定制模式:prompt(歌词)不能为空 - 如果用户选了"都可以"音色,不传 vocalGender 参数 组装参数并在提交前向用户确认(按模式展示不同卡片): **灵感模式:** ``` 🎶 确认你的歌曲设置: ┌─────────────────────────┐ │ 模式:🎲 灵感模式(AI 自由创作) │ 音色:{男声/女声/随机} │ 描述:{一句话描述} │ 风格:AI 根据描述自动匹配 └─────────────────────────┘ 确认开始创作?(Y/N) 本次消耗约 10-15 积分,当前余额 {credits} ``` **定制模式:** ``` 🎶 确认你的歌曲设置: ┌─────────────────────────┐ │ 模式:🎯 定制模式(精准控制) │ 风格:{选择的风格标签} ← 严格执行 │ 音色:{男声/女声/随机} │ 歌词:{歌词前两行}... └─────────────────────────┘ 确认开始创作?(Y/N) 本次消耗约 10-15 积分,当前余额 {credits} ``` **纯音乐模式:** ``` 🎶 确认你的歌曲设置: ┌─────────────────────────┐ │ 模式:🎹 纯音乐 │ 描述:{一句话描述} │ 风格:AI 根据描述自动匹配 └─────────────────────────┘ 确认开始创作?(Y/N) 本次消耗约 10-15 积分,当前余额 {credits} ``` 确认后: 1. 检查积分是否充足(运行 `scripts/muse_api.py member-info`,credits < 10 则拒绝并引导充值) 2. 提交生成(运行 `scripts/muse_api.py generate`) 3. 同步轮询等待结果(见 Step 4) > ⚠️ 步骤 1-2 中任何接口返回 HTTP 401 → 跳转 **Step 0: 认证兜底** ### Step 4: 进度等待 + 轮询查询 分为两个阶段:**模拟进度**(前 60 秒)和 **真实查询**(60 秒后)。 #### 阶段一:模拟进度(0-60 秒) 前 60 秒不调用 API,只用 `sleep 10` 间隔输出模拟进度。进度值使用平方函数 `progress = 95 × (t/60)²`: | 时间 | 进度 | 输出 | |------|------|------| | 0s | 0% | 🎵 开始创作你的歌曲... | | 10s | 3% | 🎶 作曲中 ▎░░░░░░░░░░░░░░ 3% | | 20s | 11% | 🎶 编曲中 ▎█░░░░░░░░░░░░░ 11% | | 30s | 24% | 🎶 录制中 ▎███░░░░░░░░░░░ 24% | | 40s | 42% | 🎶 混音中 ▎██████░░░░░░░░ 42% | | 50s | 66% | 🎶 润色中 ▎█████████░░░░░ 66% | | 60s | 95% | 🎶 即将完成 ▎██████████████░ 95% | 每次输出之间执行 `Bash("sleep 10")`(保持会话活跃,不阻塞)。 #### 阶段二:真实查询(60 秒后) 从第 60 秒起,每 10 秒调用一次 `muse_api.py query` 查询实际状态,最多查询 **12 次**(再等 2 分钟)。 每次查询流程: 1. 运行 `scripts/muse_api.py query --token $TOKEN --task-id $TASK_ID` 2. 解析返回的 JSON(含 `songs` 数组,每首歌有 `status` 字段) 3. 根据结果决定下一步: | songs.status | 含义 | 动作 | |-------------|------|------| | 所有歌曲 status=2 | 生成完成 | 输出 `✅ 100%` → Step 5 展示结果 | | 任意歌曲 status=3 | 生成失败 | → Step 5b 失败处理 | | 所有歌曲都有 audioUrl | 生成完成 | 输出 `✅ 100%` → Step 5 展示结果 | | HTTP 401 | Token 过期 | → Step 0 认证兜底 | | 其他(status=0/1) | 生成中 | 输出进度提示,`sleep 10` 后再查 | 查询阶段的进度输出保持在 95-99%: ``` 🎶 精雕细琢中 ▎██████████████░ 96% 🎶 最后打磨中 ▎██████████████░ 98% ``` 若 12 次查询后仍未完成 → Step 5c 超时处理 > **重要**:每步操作都是独立的短时 Bash 调用(sleep 10 或 query 2-3 秒),之间穿插进度文字输出。禁止使用 poll_song.py 做长时间同步阻塞。 **伪代码参考**: ``` 输出 "🎵 开始创作你的歌曲..." # 阶段一:模拟进度(0-60s) 阶段文案 = ["作曲中", "编曲中", "录制中", "混音中", "润色中", "即将完成"] 进度值 = [3, 11, 24, 42, 66, 95] for i in 0..5: Bash("sleep 10") 输出 "🎶 {阶段文案[i]} ▎{进度条} {进度值[i]}%" # 阶段二:真实查询(60s+) for i in 1..12: result = Bash("python3 scripts/muse_api.py query --token $TOKEN --task-id $TASK_ID") 解析 JSON if 所有 status==2 或 所有 audioUrl 非空: 输出 "✅ 创作完成 ▎███████████████ 100%" → Step 5 展示结果,退出循环 if 任意 status==3: → Step 5b 失败处理,退出循环 if HTTP 401: → Step 0 认证兜底,退出循环 输出 "🎶 精雕细琢中 ▎██████████████░ {95 + i}%"(上限 99%) Bash("sleep 10") 超出 12 次 → Step 5c 超时处理 ``` ### Step 5: 结果展示 歌曲生成完成后,使用以下**富文本格式**展示(通常返回 2 首候选): ``` 🎉 你的歌曲创作完成啦! ━━━ 1️⃣ {歌名} (版本A) ━━━ 🎸 风格:{tags} ⏱ 时长:{分:秒} 🎤 歌词预览: {lyrics 前4行} ... 🔗 试听下载:{audioUrl} 🖼 封面:{coverUrl} ━━━ 2️⃣ {歌名} (版本B) ━━━ 🎸 风格:{tags} ⏱ 时长:{分:秒} 🔗 试听下载:{audioUrl} 🖼 封面:{coverUrl} ━━━━━━━━━━━━━━━━━━━━━ 💡 想让歌曲更完美? → 发送「重试」用相同设置重新生成 → 发送「换个风格」保留描述,重新选风格 → 更多玩法(翻唱、MV)请前往 App 📱 {REGISTER_URL} ━━━━━━━━━━━━━━━━━━━━━ ``` ### Step 6: 后续指令处理 歌曲生成完成后,用户可能发送后续指令。Skill 必须保留上一次生成的参数上下文(description、style、voice、mode、title)来处理这些指令: **「重试」**: - 使用上一次完全相同的参数重新调用 `scripts/muse_api.py generate` - 提示:"🔄 正在用相同设置重新生成..." - 进入 Step 4 轮询流程 **「换个风格」**: - 保留上一次的 description 和 title - 重新展示风格选项(Step 2 的风格选择) - 用户选择新风格后,用新 style + 原 description 重新生成 **「再来一首」/ 「做首新歌」**: - 清空上次参数上下文,回到 Step 2 重新开始完整流程 **其他 App 功能(翻唱、MV 等)**: - 当用户发送「翻唱」「MV」等当前 Skill 不支持的功能时,直接引导到 App: ``` 这个功能目前需要在 App 中使用哦~ 👉 {REGISTER_URL} ``` **风格一致性检查**(仅定制模式需要,灵感模式跳过): 定制模式下比对用户选择的 style 与生成结果的 tags,若不一致则追加提示: ``` ⚠️ 风格偏差:你选择的是「{用户style}」,实际生成为「{结果tags}」。 可以发送「重试」重新生成,或「换个风格」更换标签。 ``` 灵感模式下不做此检查——因为已告知用户"风格由 AI 根据描述决定",不存在预期偏差。 **时长格式化**:将秒数转换为 `X分Y秒`(如 164.96s → `2分44秒`) ### Step 5b: 生成失败处理 当 poll_song.py 返回 `failed` 事件时: ``` 😅 歌曲生成遇到了问题... 可能的原因: 1. 描述过于抽象,AI 无法理解 2. 风格标签组合不常见 3. 歌词中可能包含敏感词 💡 建议: → 简化描述,用具体场景替代抽象概念 → 发送「换个风格」更换风格标签组合 → 发送「重试」用相同设置重新生成 📱 更多高级创作选项请前往 App:{REGISTER_URL} ``` ### Step 5c: 超时处理 当 poll_song.py 返回 `timeout` 事件时: ``` ⏳ 歌曲还在创作中,比预计的要久一些... 任务 ID:{taskId} 你可以稍后发送「查询 {taskId}」查看结果。 💡 也可以在 App 中查看全部创作记录: 👉 {REGISTER_URL} ``` ## 强交互选项设计 ### 模式选择(入口) ``` 🎵 你想怎么创作? A. 灵感模式 — 一句话描述,AI 全权创作(风格由 AI 根据描述决定) B. 定制模式 — 选风格、定歌词,精准控制每个细节 C. 纯音乐 — 无人声的背景音乐 / BGM ``` ### 风格选项(仅定制模式使用) ``` 🎸 你想做什么类型的歌? A. 流行音乐 B. 摇滚 C. 民谣 D. 电子乐 E. 古风 F. R&B G. 说唱 H. 爵士 I. 其他(直接告诉我) 直接回复字母即可,也可以说「流行+摇滚」组合多个风格~ ``` ### 情绪选项(仅定制模式使用) **注意:选项标签必须使用 API 风格列表中的实际值(情绪分类)** ``` 🎭 什么情绪/氛围? A. 快乐 B. 伤感 C. 激昂 D. 浪漫 E. EMO F. 随你决定 ``` **情绪→tags 映射表**: | 用户选择 | tags 值 | 可组合标签 | |---------|---------|-----------| | A. 快乐 | `快乐` | 活力,青春,甜美 | | B. 伤感 | `伤感` | 怀旧,EMO | | C. 激昂 | `激昂` | 鼓舞,史诗 | | D. 浪漫 | `浪漫` | 温暖,梦幻 | | E. EMO | `EMO` | 伤感,空灵 | | F. 随你决定 | 不传情绪 tags | — | ### 音色选项 ``` 🎤 音色偏好? A. 男声 B. 女声 C. 都可以(AI 随机) ``` ### 歌词来源选项(仅定制模式使用) ``` ✏️ 歌词怎么来? A. 我来写 — 直接发送你的歌词 B. AI 帮写 — 告诉我主题,AI 生成歌词供你修改 ``` ### 描述输入提示(灵感模式 / AI 帮写歌词时使用) ``` ✏️ 用一句话描述你想要的歌曲——风格、主题、心情都可以写: 🔥 热门示例: • 温暖民谣,歌词关于冬天窝在被窝刷剧,旋律治愈系 • City Pop风格:关于分手的歌曲 • 嘻哈/Trap,歌词吐槽微信聊天敷衍文学,flow带戏谑感 • 为了梦想,背井离乡,只要坚持就有希望 • 老村庄,旧院子,怀念无忧无虑的童年 • 赞美我母亲的勤劳、坚强、无私 • 打工苦,打工累,打工挣的是窝囊费 • 电子民谣,融合唢呐和合成器,歌词赛博乡村风 💡 Tips:越具体越好,风格+场景+情绪 效果最佳(至少10个字) ``` ## 参数映射 ### 灵感模式 | 交互输入 | API 参数 | 值 | |---------|---------|------| | 一句话描述 | `description` | 用户输入(**不可为空,至少 10 字**) | | 音色选择 | `voice` | `male`=男声, `female`=女声, `random`=随机,不传则默认 | | — | `mode` | `"lite"` | | — | `style` | 不传(AI 自主决定) | | — | `songModel` | `"general"` | ### 定制模式 | 交互输入 | API 参数 | 值 | |---------|---------|------| | 歌词文本 | `description` | 用户歌词或 AI 生成歌词 | | 歌曲标题 | `title` | 用户提供或从歌词提取 | | 风格选择 | `style` | 风格标签(**严格执行**) | | 音色选择 | `voice` | `male`=男声, `female`=女声, `random`=随机 | | — | `mode` | `"custom"` | | — | `songModel` | `"general"` | ### 纯音乐模式 | 交互输入 | API 参数 | 值 | |---------|---------|------| | 一句话描述 | `description` | 用户输入(**不可为空,至少 10 字**) | | — | `mode` | `"instrumental"` | | — | `style` | 不传(AI 自主决定) | | — | `songModel` | `"general"` | ## 脚本用法 ### muse_api.py — API 封装(v2 中间件) ```bash # 查询会员信息和积分 python3 scripts/muse_api.py member-info --token $MUSE_TOKEN # 获取风格列表 python3 scripts/muse_api.py styles # 生成歌曲(灵感模式) python3 scripts/muse_api.py generate --token $MUSE_TOKEN \ --description "一首关于夏天海边的甜蜜情歌" \ --voice female \ --title "海边的夏天" # 生成歌曲(定制模式,自定义歌词) python3 scripts/muse_api.py generate --token $MUSE_TOKEN \ --description "[Verse]\n阳光洒在海面上...\n[Chorus]\n这个夏天..." \ --style "流行" \ --voice female \ --mode custom \ --title "海边的夏天" # 生成歌曲(纯音乐) python3 scripts/muse_api.py generate --token $MUSE_TOKEN \ --description "轻快的钢琴曲" \ --mode instrumental # 查询歌曲状态 python3 scripts/muse_api.py query --token $MUSE_TOKEN --task-id TASK_ID # AI 生成歌词(同步返回) python3 scripts/muse_api.py generate-lyrics --token $MUSE_TOKEN \ --mode master --title "歌曲标题" --prompt "歌曲主题描述" # AI 生成歌词(异步返回 taskId) python3 scripts/muse_api.py generate-lyrics --token $MUSE_TOKEN \ --mode lite --prompt "写一首关于夏天的歌" ``` ### register.py — 注册流程 ```bash # 发送验证码 python3 scripts/register.py send-code --phone 13800138000 # 验证码登录 python3 scripts/register.py login --phone 13800138000 --code 1234 ``` ### poll_song.py — 异步轮询 ```bash # 轮询歌曲生成状态(每5秒查一次,超时300秒) python3 scripts/poll_song.py --token $MUSE_TOKEN --task-id TASK_ID ``` 输出 JSON 格式进度事件(每行一个 JSON),便于解析: ```json {"event": "started", "task_id": "xxx", "message": "开始轮询..."} {"event": "progress", "poll_count": 1, "songs_count": 2, "message": "生成中..."} {"event": "stream_ready", "songs": [...], "message": "试听版本就绪"} {"event": "completed", "songs": [...], "count": 2, "message": "生成完成"} {"event": "failed", "hint": "...", "message": "生成失败"} {"event": "timeout", "task_id": "xxx", "message": "超时,请稍后查询"} {"event": "error", "code": 401, "message": "登录状态失效"} ``` ## 错误处理 | 错误场景 | HTTP 状态码 | 用户提示 | 导流 | |---------|------------|---------|------| | Token 无效/过期 | 401 | 引导重新登录,读取 `assets/register-guide.md` | App 登录 | | 积分不足 | 403 | "积分不足,当前余额 {credits}" | App 充值/分享得积分 | | 请求过频/并发限制 | 429 | "正在创作中,请等当前歌曲完成后再试" | — | | 参数错误/空描述 | 400 | "描述不能为空,请至少输入一句话" | — | | 生成失败 (status=3) | — | 建议修改描述/风格后重试 | App 高级选项 | | 超时 (>300s) | — | 提供 taskId,稍后查询 | App 创作记录 | | 内容审核失败 | — | "歌词内容可能包含敏感词,请修改后重试" | — | | 服务不可用 | 502/503 | "服务暂时不可用,请稍后再试" | — | | 网络错误 | -1 | "网络不稳定,请稍后再试" | — | ## 积分规则 - 每次生成消耗约 **10-15 积分**(实测每任务约 14 积分) - 生成失败 **不消耗** 积分(已验证) - VIP 会员每日上限 500 积分 - 提交前必须检查 `member-info` 返回的 `credits` 字段 ## 导流策略 **分层导流** — 在每个关键触点自然嵌入导流: | 触点 | 推荐提示 | 目的 | |------|---------|------| | 认证失败 | "在 App 中登录获取 token" | 拉新 | | 积分不足 | "充值积分或分享邀请好友得积分" | 付费 | | 结果展示 | "在 App 中翻唱/MV/更多风格" | 留存 | | 生成失败 | "App 中有更多高级创作选项" | 留存 | | 超时等待 | "App 中查看创作记录" | 留存 | | 每次结尾 | 固定落地页链接 | 品牌 | **落地页链接**(统一出口): - 主推链接:使用 Step 0 中生成的 `REGISTER_URL`(`https://skills.muse.top/?did=${DEVICE_ID}`) - 提示:「📱 想要更多创作玩法?翻唱、MV 制作、AI 分离人声... 👉 {REGISTER_URL} 」 ## 参考文件 - `references/style-catalog.md` — 完整音乐风格列表(5 类 115 标签,展示风格选项时读取) - `assets/register-guide.md` — 注册引导提示(Token 缺失时读取)