AI 音乐全自动生产体系
一套「网页 AI 当创作源 + CDP 驱动浏览器当录入手」的无人值守流水线:每天定时批量产出歌词与风格描述,再逐首填进音乐生成平台完成生成,按平台额度分批跑完。
本包是脱敏通用版:不含任何人的账号、音色人设、计划任务名、具体歌名或本机路径。所有个性化参数都在你自己的 config.json 里。
何时使用 / 不适用
| 场景 | 适用 |
|---|---|
| 每天量产 N 首歌(固定模型/音色),要求无人值守 | ✅ |
| 已有创作平台账号,想用浏览器自动化替代手工重复填表 | ✅ |
| 想给 AI 产出加一道可量化的质量门禁(而不是凭感觉) | ✅ |
| 只想做一首歌 | ❌ 直接手工用平台更快 |
| 平台明确禁止自动化 | ❌ 尊重平台规则;本包只讲工程方法,是否合规由你判断 |
> ⚠ 合规前提:自动化操作第三方平台存在被限流/风控的可能。
> 本流程的设计原则是「按平台额度分批、单首间隔抖动、绝不并发多开」,这既是工程需要,也是最起码的礼貌。
> 动手前请阅读目标平台的服务条款。
第一次使用:三步
# ① 体检 + 生成 config.json + 建目录(交互式)
python scripts/setup_wizard.py
# ② 试跑一首(不要直接全量)
python scripts/run_once.py --dry-run # 只打印将要填什么,不开浏览器
python scripts/run_once.py --limit 1 # 真跑 1 首,全程有人看着
# ③ 交给每日批次
python scripts/daily_run.py
详细步骤、平台结构图谱、坑位清单见各 references。
架构总览
【创作侧】浏览器(已登录网页 AI 聊天,如 DeepSeek / GLM)
└─ create_songs.py
开新对话 → 发制作人提示词 → 等固定时长 → 输入「A」→ 循环
→ 终稿(歌名+风格描述+歌词)→ 存 state/drafts/draft-*.txt
└─ parse_songs.py → 解析为标准歌曲包 state/songs-YYYY-MM-DD.json
└─ clean_songs.py → 逐首清洗(剔除套话/说明性段落/按钮噪声)
【质检侧】
└─ quality_gate.py 字数门禁(style/lyrics 下限 + 必备字段)
└─ preflight.py 客观预检(10 项硬指标,必须退出码 0)
【录入侧】CDP 驱动浏览器(platform 创作台)
└─ daily_run.py [--songs-file X]
└─ fill_platform.py(playwright-core CDP 驱动)
├─ goto_create() 进创作页 + 切专业模式(验证「上传参考音频」可见)
├─ fill_lyrics() 富文本 paste 注入(≤平台上限)
├─ fill_style() 风格 textarea(≤平台上限,前置「歌曲名《X》」)
├─ select_model() 关自动 → fiber onClick 选模型 → 回显验证
├─ pick_voice() 虚拟歌手开关 → 弹层 → 选目标音色 → 回显验证
├─ optimize() 生成前点「优化提示词」→ 等待 → 结果留在风格框
├─ generate() 生成 + 弹窗 dismiss + 额度识别
├─ recover() 每首提交后必进错误态(常态)→ 点重试恢复
└─ verify_asset() 回验资产列表的目标音色标签
主循环:批次=2 首。第 1 首全链路 → 第 2 首探编辑器:活着=软填充换词曲;不可达=自愈重走全链路。
目录约定
<项目根>/
├── config.json # 唯一必改的配置(平台 URL、选择器、限额、路径)
├── state/
│ ├── drafts/ # 创作源原始产出
│ ├── songs-YYYY-MM-DD.json# 歌曲包
│ ├── reviews/<日期>/ # 每首独立 txt(可追溯交付)
│ ├── plans/ # 选题清单
│ ├── packs/ # T-1 任务单
│ ├── PROMPT-TEMPLATE.json # 提示词资产(改这里,脚本读它)
│ ├── CREATION-RULES.json # 硬约束
│ └── VOICE-LIBRARY.json # 音色池
├── logs/ # pipeline-YYYYMMDD.log
└── output/ # 交付物
配置(config.json)
由 scripts/setup_wizard.py 生成,也可以手改。字段全部有中性默认值,不留任何个人数据。
| 字段 | 必填 | 说明 |
|---|---|---|
platform.create_url |
✅ | 创作台地址 |
platform.asset_url |
否 | 资产列表页(回验用) |
platform.login_cookie_key |
否 | 判定登录态的 cookie 名(如 sid_tt),留空则跳过检查 |
cdp.port |
✅ | 浏览器远程调试端口(默认 9222) |
cdp.profile_dir |
否 | 专用浏览器 profile 目录,留空用 ~/.ai-music/profile |
cdp.browser_path |
否 | 浏览器可执行文件路径,留空自动探测 |
limits.daily_quota |
✅ | 平台每日额度(次或首,按平台口径) |
limits.batch_size |
否 | 每批提交数(默认 2) |
limits.jitter_sec |
否 | 每首间隔随机抖动上限(默认 30) |
selectors.* |
✅ | 页面选择器(平台改版时改这里,不改代码) |
models.list / models.target |
✅ | 可选模型清单与目标模型(fiber value 映射见 references) |
voices.target |
✅ | 目标音色名(按你平台上的实际名称填) |
gate.style_min_chars / gate.lyrics_min_chars |
否 | 字数门禁(默认 300 / 500) |
设计原则:选择器与限额全在配置里,代码里不写死任何平台细节。
平台改版时只改 config.json,这是这套流水线能长期维护的关键。
核心铁律(都是踩坑换来的)
1. 状态重置铁律(最容易翻车)
模型与音色选择是页面会话级状态:切 tab(灵感↔专业)、页面「重试」、任何 reload 都会重置模型回默认「自动」。
→ 全流程必须同会话原子完成:填词→填风格→关自动→选模型→开虚拟歌手→选音色→点生成。中途绝不切 tab。
量产实测:每首提交后页面必进「出错了」错误态(生成完成的伴随现象),
恢复后模型已重置 → 每首歌原子重走全链路是常态而非异常,勿试图跨曲保留选中态。
2. 三级依赖:模型 → 音色开关 → 音色弹层
- 「自动」开关开着时模型列表折叠隐形(选项 DOM 里高度为 0)。必须先关开关——这就是「模型要关掉自动才能选」的字面机制。
- 关开关要点开关本体(
[class*="autoSwitch"]),不是点文字。 - 关后列表展开,目标模型可能在面板第 7 位,需要面板内滚动 1-2 轮(
scrollTop += 200)才可见。
3. 选项必须用 fiber onClick 直调,禁止坐标点击
面板位移动画/虚拟滚动会让 getBoundingClientRect() 与实际渲染错位 → 点击命中错误行(实测点 A 回显 B)。
→ 用 React fiber 的 onClick 直接调用。第 1 轮返回 no-element(选项未挂载)属正常,重开面板第 2 轮即成功;连续 3 轮 no-element 才是异常。
4. 宽兜底选择器会反噬
[class*="textarea-"] 这类宽兜底会先命中隐藏的其它 textarea → 可见性超时。
→ 兜底必须比主选择器更窄;优先用 placeholder 精确定位。
5. 富文本必须 paste 注入
歌词框是 Quill/ProseMirror 类富文本(contenteditable)。直接改 DOM 不触发框架状态。
→ 用 page.evaluate 派发 paste 事件(ClipboardEvent)注入最稳;分块写入时块间 sleep。
6. 「优化提示词」的正确顺序
必须:先填完整风格描述与歌词 → 设置模型与音色 → 点「优化提示词」→ 等待 → 点生成。
旧流程(先优化 brief,再被原始 style 覆盖)是无效优化——用户会抓出「优化后的提示词你根本没真正使用」。
⚠ 观察项:平台优化器会把长描述精简改写(实测 652→193、464→311 字)。若精简版效果不如原文,可跳过优化保留原描述。
7. 完成信号用「资产列表出现」而不是固定等待
资产列表出现带目标音色标签的新作品 = 这首生成完毕,立即开始下一首。
不依赖固定等待时长。解析资产行的「歌名 / 时长 / 标签行」三行结构。
提交后先等 20 秒入列,之后 15 秒轮询,单首上限 5 分钟。
8. 创作源必须用「固定等待」,不能用「检测输出完毕」
AI 的「深度思考」模式会长停顿 20 秒+ 再继续,停顿 ≠ 结束;DOM 也没有可靠的生成中/完成标志(按钮两态相同、无 aria)。
→ 用固定等待(实测 25-30 秒较稳)。宁可多等,不能截断——过快回复会把输出截断。
9. 频控:识别到就暂停,不要硬撞
回答中出现「发送过于频繁」类提示 → 暂停 1 分钟再继续。
录入侧同理:撞到平台每日上限立即停批,次日续跑,绝不刷量。
10. 真值校验:没有平台响应就不算成功
只有收到「创建/生成」接口响应且 code == 0 才算成功;没响应记 unverified。
页面「看起来成功」不算数。 详见 references/cdp-automation-notes.md 第 7 节。
质量门禁(双门禁)
门禁 1:字数门禁(quality_gate.py)
style ≥ gate.style_min_chars(默认 300)
lyrics ≥ gate.lyrics_min_chars(默认 500,且含副歌结构)
不达标自动剔除并重编号。
为什么必须有:曾发生「凑数曲事故」——模板库的简写占位曲(风格 50-132 字 / 歌词 107-275 字)混进量产包,
用户看生成时长 + 风格描述长度立刻识破。铁律:入包前必须过门禁;字数不足宁可空缺也不入包。
门禁 2:客观预检(preflight.py,必须退出码 0)
10 项检查(全部可量化,不依赖语言模型自评):
| # | 检查 | 阈值 |
|---|---|---|
| 1 | 副歌单行字数 | ≤ 12(中文按汉字计,非中文按音节块计) |
| 2 | 说唱段单行 | ≤ 20 |
| 3 | 副歌重复率 | ≥ 30%(混合口径) |
| 4 | 韵脚聚集度 | 仅中文行,低于阈值告警 |
| 5 | AI 腔词表 | 命中即拒 |
| 6 | 段落标签完整性 | [Intro][Verse][Chorus]... 齐全 |
| 7 | Intro 首行字数 | ≤ 12(前 3 秒钩子) |
| 8 | style 容量 | < 700 告警、> 990 截断风险 |
| 9 | 副歌必须含指定语种特征(如藏文/方言) | 按 CREATION-RULES.json |
| 10 | 生造词白名单 | 白名单外的生造词拒绝 |
> 为什么不能只靠语言模型自评:实测过「自评乐观偏差」——14 首 DJ 版盲审给「KTV 跟唱度」22-23/25,
> 但客观统计显示 13/14 首副歌单行超 12 字(最长 16 字,实际跟唱会呛气),韵脚聚集度仅 18-24%。
> 纯语言模型自评会系统性偏乐观,盲审维度必须挂客观锚点。
> 铁律:①盲审分数不得高于 preflight 实测结论;②副歌单行 ≤12 字写死进派单模板。
T-1 备歌 SOP(提前一天准备,保持全自动)
- 任务单自动生成:当日批次跑完后自动生成
state/packs/next-<下一天>.json
(故事分配/曲风变体预分配/硬约束快照/requiredFields,status=pending,已存在则跳过)。 - 选题:查热榜/热搜音乐话题 → 产出
state/plans/选题清单-*.json+ 可读版 md 供审阅。 - 盲审选题闸:五维打分各 20 分——爆款潜力/大众认知度/嗓音适配/传唱性/差异化空间
(热门母题用差异化视角切入,冷门母题认知度 ≥18 才入场)。 - 双创作(同题异构):两个制作人视角,切入角度/曲风/情绪落点必须明显差异化;硬约束见
CREATION-RULES.json;前 3 秒钩子、押韵、情绪一致。 - 盲审成品闸:四维各 25 分(编曲记忆点/歌词画面感/钩子强度/嗓音适配),≥85 pass,
扣分必须引用歌词原句作证据;一票否决:AI 腔口癖/副歌无记忆点/前 3 秒无钩子/调性割裂/白名单外生造词。 - 落盘前双门禁(见上)。
- 每首歌独立 txt:
state/reviews/<日期>/NN-歌名.txt+ index.txt,
含:完整风格提示词 → 风格描述 → 歌词全文 → 盲审评语 → 选择记录 → 门禁结果。这是「可追溯」交付。 - 落盘
state/songs-YYYY-MM-DD.json+state/reviews/日期-歌曲包全览.txt(每日固定,供检查用)。
提示词设计要点
创作源提示词(核心结构)
一份好的「制作人提示词」必须包含五个要素:
- 角色与风格锚定:你是谁 + 参照什么创作风格/偏好(避免空泛的"AI 味")
- 结构与语言:主歌用什么语言、副歌用什么语言、情绪一致性要求
- 可量化约束:押韵、循环率(≥95%)、风格基底(曲风 + 编曲手法)、BPM 区间
- 交互协议:「创作前先向我提问,建议选项默认放 A 选项,每次只问一个问题」
- 交付格式:「最终稿必须包含 ①歌名(4-8 字,放最前面)②风格描述 ③完整歌词」
> 第 4 条的 A 选项协议是关键:它让「固定等待 + 输入 A」这套机械化流程成立。
> 没有它,AI 会问开放式问题,无法自动应答。
无人值守的硬约束
在派单模板里写死:
- style 字数区间(如 350-900)
- lyrics 字数区间(如 550-1900)
- 段落标签用英文方括号:[Intro][Verse][Pre-Chorus][Chorus][Bridge][Outro]
- 正文无「女:男:合:」前缀
- 副歌重复 2 次+、记忆点 hook、前 3 秒钩子
- 禁提问、禁输出 JSON 以外内容(批量模式)
已知坑与教训
| # | 坑 | 表现 | 对策 |
|---|---|---|---|
| 1 | PowerShell 5.1 UTF8-BOM | 写 JSON 带 BOM → Node JSON.parse 炸 |
读端一律 .replace(/^\uFEFF/,'');写端用 [IO.File]::WriteAllText + UTF8Encoding($false) |
| 2 | UTC 时区 | toISOString() 在 UTC+8 的凌晨还是前一天 |
一律本地时区拼日期 |
| 3 | cmd 批处理编码 | LF 换行 + 中文 → cmd 解析错位吞字节 | 启动脚本必须纯 ASCII + CRLF |
| 4 | 宽兜底选择器 | 命中隐藏元素 → fill 超时 | 兜底比主选择器更窄 |
| 5 | 下拉隐藏模板 | DOM 常驻 display:none 的选项副本 → locator.first() 永远命中它 |
boundingBox 校验后才操作,或 fiber 直调 |
| 6 | 坐标点击被动画干扰 | 点击命中错误行 | fiber onClick 直调 |
| 7 | 收藏星 ≠ 选择按钮 | 点错按钮 | 按「名字与按钮 y 坐标差 <40」匹配行内第 3 个「选择」 |
| 8 | 浏览器 App-Bound 加密 | 日常浏览器的 cookie 外部不可读 | 用独立 profile;不要试图破解 |
| 9 | 计划任务 Interactive only | 锁屏/未登录桌面则当天跳过 | 任务设「仅在用户登录时运行」并保持会话 |
| 10 | 风控验证码 | 高频自动化触发 | 间隔加随机抖动;探测 #nocaptcha-container 尺寸 |
| 11 | 页面错误态 | 每首生成后必进「出错了」 | 点重试恢复;但恢复会重置模型 → 每首原子重走 |
| 12 | 僵尸标签页 | 同 URL 多 tab → 操作打错页面 | 启动时关闭多余 tab |
| 13 | npm 执行策略 | PowerShell 下 npm.ps1 被拦 | 用 cmd /c npm ... 或 npm.cmd |
| 14 | 回验解析 | 资产行结构是「歌名\n时长\n标签行」,偶发读到旧缓存 | 提交后延迟 10s 再读;失败时输出前 4 行原文 |
| 15 | 自评乐观偏差 | 见「质量门禁」一节 | 盲审必须挂客观锚点 |
| 16 | 校验脚本自身没自测 | 正则把 [Pre-Chorus] 匹配成 chorus → 假警报 14 条 |
审计工具的首个输出必须用单个样本手工核对一遍再信 |
| 17 | 段落标签平台兼容性 | 非标准标签([Drop-Chorus])平台可能不识别 |
做 A/B 对照;保守用标准标签 |
| 18 | 生成时长不可控 | 资产时长 1:00-4:00 波动 | style 里写「时长目标 3:30-4:00」并观察响应度 |
| 19 | 控制台乱码 ≠ 文件错误 | GBK 解 UTF-8 回显乱码但字节正确 | 以 Node readFileSync 读回或字节为准,不看控制台 |
环境要求
- Node.js ≥ 18(本流程用
playwright-core直连 CDP,不下载浏览器) - 一个专用浏览器 profile(登录态落在里面,可反复复用)
- 平台账号与可用额度
> 本包刻意只依赖 playwright-core(不带浏览器下载):因为录入侧是连你已开的浏览器(CDP),
> 而不是新起一个受控浏览器。这样登录态、插件、指纹都是你日常的那一份,风控更友好。
遇到问题看哪份
| 文件 | 内容 |
|---|---|
references/quickstart.md |
首次使用完整引导:从装 Node 到跑通第一首 |
references/platform-playbook.md |
创作台结构图谱:三级依赖、fiber 直调、弹窗、完成信号、额度 |
references/cdp-automation-notes.md |
CDP 自动化要点:连接、登录态判定、真值校验、截图超时、僵尸 tab |
references/quality-and-prompting.md |
质量门禁设计 + 提示词工程 + 盲审方法论 |
references/scheduling.md |
每日定时调度、T-1 备歌闭环、跨天续跑 |
边界与提醒
- 只操作你自己账号下的创作台,不碰他人作品、不刷量绕过额度。
- 撞到平台额度上限就停,第二天再来——这是设计,不是失败。
- 平台页面结构随时可能改版,届时改
config.json的selectors与models.list即可,不用改代码。 - 自动化产出的作品仍需人工抽检:质量门禁能挡住明显的凑数,但挡不住「都合格但都不好听」。