歌词本制作(Lyrics Book Builder)
把一份歌单做成一本可直接打印的歌词本。本 skill 沉淀了完整生产流程与验证过的脚本,产出的 DOCX 满足:A5 纸、双面打印、一页左右两栏各一首歌、歌不跨页不跨栏、每首带序号且与目录对应、重复副歌只留一遍、字号随歌词行数自适应。
核心工作流
用户要求做歌词本 → ⓪ 引导式确认需求 → ① 提取歌曲列表 → ② 整理去重(+延伸补歌) → ③ 联网抓歌词(三级兜底)
→ ④ 清洗去重核对 → ⑤ 生成A5两栏DOCX → ⑥ 制作专辑拼贴封面 → ⑦ 校验交付清理 → ⑧ AI专家自检(用户确认后)
⓪ 引导式确认(开始前必须问用户)
不要拿到歌单就闷头做,先花 1-2 轮对话确认以下关键需求:
1. 目标歌曲数量:歌单现有多少首?想要最终做多少首?(如歌单只有 100 首但想要 200-300 首,就需要延伸补歌)
2. 重点歌手/方向:有没有特别想突出的歌手或风格?(如"TFBOYS 的歌放前面"、"林俊杰的歌多放一些")
3. 是否延伸补歌:如果歌单数量不够目标数量,是否需要根据已有歌单的歌手/风格推荐类似歌曲补入?(用户同意才延伸,不擅自加歌)
4. 是否需要封面:默认必须做封面(专辑封面拼贴),除非用户明确说不要。不要只做歌词本不做封面——封面和歌词本是一套交付物。
5. 标题名称:歌词本封面上写什么名字?(默认按用户称呼,注意大小写,如「cosinX 的歌词乐理本」)
把确认结果记下来,后续步骤按用户要求执行。用户明确说"直接做不用问"时跳过此步。
① 提取歌曲列表(三种输入形态)
- 歌单链接:运行
scripts/fetch_playlist.py "<分享链接>" -o songs.json。输出带incomplete标记:true表示脚本只拿到部分歌曲(酷狗常见),必须先用内置浏览器补全再继续。 - 单曲链接:同样用
fetch_playlist.py,自动识别平台(QQ/网易云脚本支持;酷狗/汽水/酷我提示浏览器);多个单曲链接逐条解析后合并。 - 歌单截图:用视觉逐行读取歌名+歌手(详见
references/input-forms.md),模糊项标注待确认,不凭印象编。 - 平台支持如实声明(实测 2026-09):QQ音乐、网易云音乐脚本可直接完全识别所有歌曲;汽水音乐、酷我音乐必须用 agent 内置浏览器识别;酷狗音乐暂时只能识别分享链接内嵌的前 10 首,全量需登录态或浏览器手动提取。
浏览器兜底(必须用 agent 内置沙箱浏览器 + PC 桌面模式)
当脚本返回 incomplete=true 或平台不支持时,必须使用 AI agent 自带的浏览器自动化工具(如 browser-use、seed_browser_use、mac_computer_use_tool(plane="bu") 等沙箱浏览器),在 agent 内部完成页面操作,不要调用用户本地系统浏览器,不要让用户手动打开网页。
必须用 PC 桌面模式访问(桌面 User-Agent,如 Chrome on macOS/Windows),不要用手机移动模式——移动模式下很多歌单只显示部分歌曲或要求登录,PC 网页版通常能直接看到完整列表。
标准流程:
1. 用内置浏览器 navigate(分享链接),设置桌面 UA,等待页面加载。
2. 循环 scroll 滚动到列表底部,直到歌曲数量不再增加(酷狗/汽水都是懒加载分页)。
3. 用结构化读取(read_all / get_page_text / DOM 提取)逐条拿到歌名 + 歌手。
4. 与页面显示的歌单总数核对,数量一致后写入 songs.json(incomplete: false)。
5. 如果内置浏览器也被登录墙挡住,才向用户说明并请用户提供歌单截图或歌曲列表。
详见 references/playlist-sources.md。
② 整理歌曲列表
- 按归一化歌名分组 + 歌手集合重叠去重(歌名相同且歌手集合有交集,或任一方歌手为空,即视为同一首;解决不同平台首歌手不同导致的漏去重,如《我爱你但是我要回家》首歌手分别为邵甲天/ET/无面小生),保留歌词最多的版本。
- 用户未指定语言时默认偏好中文歌曲;纯外文歌先问用户或按歌单实际内容保留。
- 若歌单为空或解析数量异常(明显少于页面显示),改用浏览器核对,不要凭空补歌。
- 延伸补歌(仅用户同意后执行):如果⓪步确认歌单数量不够目标数量,根据已有歌单的歌手和风格推荐类似歌曲补入(如用户喜欢林俊杰就补林俊杰其他热门歌),补歌前给用户看补歌清单确认。用户没说要延伸就不补。
③ 联网抓取歌词(三级兜底)
按以下优先级逐级兜底,必须联网获取,禁止凭记忆写歌词:
1. 脚本抓取:运行 scripts/fetch_lyrics.py songs.json -o lyrics.json --workers 3(QQ音乐公开接口,逐首搜索→取歌词,输出带 status 和 source_artist 供核对)。
2. 其他公开接口:脚本 status=problem 的歌,尝试网易云/酷狗等其它歌词接口单独补(如网易云 /api/song/lyric?id=、酷狗歌词接口)。
3. 网络搜索兜底:仍拿不到的,用 general_search 搜「歌名 歌手 歌词」,从结果页提取原文。
- 歌手有多个版本(翻唱/原唱)时以用户点名的歌手为准(如宠爱=TFBOYS、最好的安排=曲婉婷);务必核对 source_artist 与目标歌手一致,不一致时退回重选。
④ 歌词清洗(去重 + 清理 + 核对)
按 references/lyrics-quality.md 执行,核心规则:
1. 重复副歌只留一遍:完全相同的连续块(4-12行)只保留第一遍;每遍词不同的段落保留。脚本 build_lyrics_book.py 默认自动去重,可用 --keep-dups 关闭。
2. 清理分唱标记:删除单独成行的「源:/凯:/玺:/合:/男:/女:/rap:/Bridge:/Chorus:/TFBOYS:/王源:」等标记行。
3. 错字/漏句修正:抽查关键行与原歌词比对;用户重点点名过的歌必须逐字核对。
⑤ 生成 A5 两栏 DOCX
运行 scripts/build_lyrics_book.py lyrics.json -o 歌词本.docx --title "cosinX 的歌词乐理本"。
常用可选参数:
- --size a5|b5|a4:纸张尺寸,默认 a5
- --keep-dups:保留全部重复副歌(默认自动去重只留一遍)
- --no-chorus-mark:不在被删重复副歌位置插入「(副歌 ×2)」标记
- --keep-full:不自动精简超长歌(默认自动截断到 ≤62 行防跨栏)
默认 A5(148×210mm)。生成结构:标题页 → 目录页(两列无边框表格,序号固定宽度右对齐)→ 正文两栏,每首歌前插分栏符 + 段落 keep_together/keep_with_next,保证一栏一首、绝不串栏、不跨页;歌名前带序号与目录一致;字号按行数自适应。
内置自动处理:
- 歌手集合重叠去重:按归一化歌名分组,组内歌手集合有交集即视为同一首,保留歌词最多的版本。
- 重复副歌只留一遍,被删位置插入灰色斜体「(副歌 ×2)」标记(--no-chorus-mark 关闭)。
- 超长歌自动精简:超过 62 行的歌自动删纯语气词行、截断到核心段落加「……」,保证不跨栏(--keep-full 关闭,关闭后仅警告)。
- 空歌词歌自动跳过并警告。
格式细节见 references/format-spec.md。
⑥ 封面(必做,与歌词本一起交付)
封面和歌词本是一套交付物,不能只交歌词本不交封面。 除非用户在⓪步明确说不要封面,否则必须做。
- 用真实专辑封面(从歌词本曲目里挑代表性的歌,image_search 下载对应专辑封面),PIL 拼贴成 A5(148×210mm 即 1240×1754px @216dpi)图。
- 风格:错落堆叠、带旋转和阴影、铺满但不遮挡标题;标题按用户指定(如「cosinX 的歌词乐理本」,注意大小写)。不要 AI 生成整图、不要整齐网格。
- 参考脚本:scripts/make_cover.py(可改标题/背景/排列)。封面图和 DOCX 一起用 present_files 交付。
⑦ 校验、交付与清理
- 校验(对生成结果执行以下检查,全部通过才算完成):
- 歌数 = 歌单歌曲数:
python3 -c "from docx import Document; d=Document('歌词本.docx'); print(sum(1 for p in d.paragraphs if p.text[:2].rstrip('.').isdigit()))" - 页尺寸 A5 两栏:
python3 -c "from docx import Document; d=Document('歌词本.docx'); print(round(d.sections[1].page_width.mm), round(d.sections[1].page_height.mm), d.sections[1]._sectPr.xpath('.//w:cols')[0].get('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}num'))" - 无 <6pt 小字:脚本保证歌手行 ≥6pt、空歌词歌跳过并警告、超长歌自动精简(
--keep-full模式下才警告),确认运行日志无异常。 - 抽查 2-3 首歌词与来源比对无错字。
- 交付:最终 DOCX(和封面图)用
present_files交付;用户手机端时改用FileBatchUpload传下载链接。 - 清理:任务全部完成后,删除中间文件(songs.json、lyrics.json、check_*.json、测试图等)与旧版本,只保留最终版(如
歌词本_最终版.docx)。清理前必须先确认任务已完成。
⑧ AI 专家自检(用户确认后执行,可选)
当用户明确要求"质检/自检/检查一遍"时,派发多个专家并行检查:
1. 歌词核对专家:随机抽 10-20 首歌,联网搜索原歌词逐字比对,报告错字/漏句/版本错误。
2. 排版专家:检查 DOCX 目录序号对齐、一栏一首不跨页、字号 ≥6pt、分栏符数量正确。
3. 完整性专家:核对歌单歌曲数 = 正文歌数 = 目录条目数,报告被跳过/去重/精简的歌曲清单。
4. 汇总自检报告给用户,有问题则修正后重新生成。
未明确要求时不执行此步(避免过度耗时)。
关键质量红线
- 歌词必须联网来源,禁止凭记忆生成。
- 歌名序号 = 目录序号 = 正文序号,三者一致。
- 任何一首歌都不得跨页或串栏;脚本默认自动精简超长歌到 ≤62 行,
--keep-full模式下仍放不下则必须人工精简。 - 重复副歌默认只留一遍并标记(用户唱歌本用途),除非用户明确要完整版。
- 酷狗全量需登录态,无登录时只能取前 10 首,必须明确告知用户,不得假装全量。
- 封面必须和歌词本一起交付,不能只交 DOCX 不交封面(用户明确说不要封面除外)。
- 开始前必须引导式确认(数量/重点歌手/是否延伸/是否封面/标题名),用户说"直接做"才跳过。
脚本清单
| 脚本 | 作用 |
|---|---|
scripts/fetch_playlist.py |
歌单/单曲链接 → 歌曲列表 JSON(带 incomplete 完整性标记) |
scripts/fetch_lyrics.py |
歌曲列表 → 联网歌词 JSON(QQ音乐接口,歌手版本匹配) |
scripts/build_lyrics_book.py |
歌词 JSON → A5两栏 DOCX(归一化去重/副歌标记/自动精简/字号自适应/序号/不跨页) |
scripts/make_cover.py |
专辑封面 → A5 错落拼贴封面图(跨平台字体探测) |
依赖
- Python 库:
python-docx、Pillow、pycryptodome(网易云 weapi 加密接口必需;缺失时网易云自动降级 v6 接口并警告 incomplete)。缺失时pip install python-docx pillow pycryptodome。 - 网络:QQ音乐公开接口(c.y.qq.com)与网易云 weapi 通常可用;酷狗/汽水/酷我需浏览器兜底。
- 说明:字号自适应表按 A5 校准;用
--size b5/a4时字号档位不变(结果偏保守、更清晰),如需更密排版请人工调参。