AI 播放器 · 踩坑复盘
30 多天里我做了 3 次 AI 私人电台。前两次都死了,第三次靠 5 天密集迭代和 13 次独立审计才扛下来。但回头看,根因不是技术——是每次开工我都以为目标够清楚,做到一半才发现根本没想清楚。
为什么我做了 3 次
目标从一开始就没变过:把"周一早晨 安静"这句话变成一段 30 分钟、像电台一样的节目。有 DJ 说话、歌之间有过渡、不让我选歌。同一件事我做了三遍。
踩坑的原因有几个
3 次的坑摊开,反复出现的就这 4 个。
第一,我还没哼出"DJ 该是什么味",就开始装 TTS 库了。第二次项目叫 omnivoice,目标就一件事——装一个开源 TTS(Text-to-Speech,文字转语音)库,看能不能给电台当嗓子。装包、跑通 MPS(Apple 芯片的 GPU 接口)、调通命令行,最后卡在 HuggingFace(最大的开源模型仓库)下不来——6GB 模型停在 12% 不动。表面上是网络死的。但就算模型顺利下来、声音跑出来,我也判断不了"这是不是我要的"——装库之前,我根本没在心里哼过一遍"我要的 DJ 该是什么味"。是央视播音员那种字正腔圆?是凌晨电台主播那种沙哑温柔?还是邻家女孩跟你闲聊?我没想过。模型卡死那一刻不过是给了我一个借口:反正下一步我本来也答不出。
第二,"播放器"和"电台"我一开始没分清。网易云、Spotify 的中心是用户选歌——点歌、加心、做歌单、跳过下一首。电台不是,它到点就响,DJ 自己说话、自己接歌,不让你选。第一次项目叫 yuns-radio,做着做着 UI 上自然长出"上一首""下一首""喜欢"这几个按钮,我才反应过来——这又变成一个音乐 app 了。但当时整个代码已经按"用户主导"的逻辑搭好了,再改伤筋动骨。cc_claudio 第三次重做,第一条规则就是"用户不选歌,用户给一个意图"——比如"周一早晨 安静"——剩下的归大脑和派遣器去管。
第三,"我电脑上能跑"不等于"它独立跑也能跑"。我自己电脑上 shell 默认走代理(HTTPS_PROXY 那个环境变量),调 claude CLI、下 HuggingFace 模型都顺。omnivoice 那天 6GB 模型卡 12%,不过是我没挂代理,国内 IP 直连 HuggingFace 慢得没法看。cc_claudio 后来更狠——claude CLI 遇到国内 IP 直接 403。两次同一类:开发时一切正常,独立跑起来就挂。LaunchAgent(macOS 的开机后台服务)起的子进程根本看不见我 shell 里的代理设置,它是个干净环境。但我开工时从没想过"它独立跑起来环境是什么样的"。
第四,做到"能演示一遍"就停了,没追问"我真的会用吗"。yuns-radio 我做到一个能在浏览器里点一遍的页面就停了。按按钮能听到 DJ 说话(虽然是 TEMP_FALLBACK 占位文本)、能听到歌(虽然只有 30 首示例)、能 pause / skip。在我面前过了一遍,看起来挺像那么回事。但我自己每天早晨真用它听新闻了吗?没有。我让别人试过吗?也没有。我做到"演示给自己看"那一刻,潜意识里觉得"先这样吧"——然后再也没回去。omnivoice 装到命令行 --help 能跑就觉得"基本盘有了"——下一步本来就没答案,所谓"基本盘"也是错觉。
4 个坑其实是同一个:目标没想清楚就开工
4 条坑摊开看,没有一条是"代码写错了"。嗓音不是 TTS 引擎选错了,是我根本不知道我要什么嗓音。播放器和电台不是 UI 写错了,是我根本没分清在做哪种产品。"我电脑能跑"不是代理配错了,是我没想过这个东西独立跑起来会身处什么环境。"能演示"不是测试少了,是我根本没定义过"做完了"是什么样子。
我原来以为开工时目标已经清楚——"做一个 AI 私人电台",这句话听起来够具体了。但它什么都没说。嗓音什么味?产品是工具还是节目?独立跑起来环境是什么?做到什么程度算完?这四个问题我一个都没回答,就开工了。每跑两天,就被一个之前没回答的问题撞回来。
3 次失败的根因不是技术深浅、不是经验多少。是我每次都跳过了"把目标拆到能回答"的那一关。
这类工程未来应该怎么做
现在我手上有一份开工清单,4 件事,写第一行代码之前必须有答案。
核心交付物长什么样?不是抽象描述,是能哼能画能演的具象。AI 播放器的核心交付物是 DJ 的嗓音——能哼出 30 秒就行。这一条没做到,引擎选型全是瞎选。
不做什么先写下来。"做什么"清单里漏掉的东西会被默认补回来。yuns-radio 没写"不让用户选歌"这条边界,UI 就自己长出了一堆点歌按钮——不是我决定要做,是默认就长出来了。
它独立跑起来时环境是什么?装到 LaunchAgent 里、装到别人电脑上、装到我没守着的状态下——它能看见什么、看不见什么。代理在不在?环境变量带不带?依赖装没装?写代码之前就要列清楚。两次国内出口的坑都因为我没列这一条。
"做完了"在我嘴里到底指什么?能演示?能在我不看的时候活下来?连续 7 天不出事?想清楚,写下来。cc_claudio 装好 LaunchAgent 那天晚上我没动它,让它早晨 6 点自己醒过来给我发第一条 DJ 早报。第二天早上看到那条消息从手机锁屏弹出来——那一刻才是这次的"做完了"。和"能在浏览器里点一遍"完全是两个标准。
cc_claudio 现在能跑、能用、能扛重启,但远不是"做完了"。9T 索引因换机器停在 stage 13B,新加的歌进不来。fish-speech 真克隆的 reference 一直没找对,5 个候选还躺在桌面上。Settings、Mini player、Lock Screen 的 Now Playing 都没做。5 天密集迭代的节奏不可持续——下一步是让它在我不动的状态下跑几个早晨和几个深夜,让真使用本身把下一批问题长出来。
3 次尝试 30 多天换来的不是一个 .app,是上面那份开工清单。这份清单大概率还会继续长——下次踩到一个之前没列的坑,我就再加一行。