
前天下午我在 AiPy 的对话框里敲下了一句话“帮我在本地撸一个专属音乐平台。”说句实话敲这句话的时候我没抱多大希望“音乐平台”四个字听起来太大大到后端、数据库、资源版权、播放稳定性这些事全堆在脑门上。但结果有点出乎意料几十秒后 AiPy 给了我一个能直接跑起来的项目骨架再经过三四轮追加提示词的修正我居然真的在浏览器里听到了歌。这件事真正打动我的不是 AI 替我写了几千行代码而是提示词本身变成了一种“可复用的编程接口”。你给它一条清晰的需求它还你一个可运行的产品你给它一句模糊的话它还你一堆需要返工的技术债。这篇文章就从头到尾拆一下我到底怎么组织那条提示词AiPy 生成了一个什么样的音乐平台中间踩了哪些坑以及最后我提炼出的提示词工程套路。如果你也想用 AI 编程工具做点自己的小产品这篇应该可以直接抄作业。1. 项目诞生记一句提示词到底能干到哪一步1.1 把“音乐平台”这个大词拆成能执行的小需求刚开始我一想到“音乐平台”就头大因为这个词背后包含的东西太多了用户系统、推荐算法、评论社区、版权库、直播、会员……真要照着 QQ 音乐或网易云那个规模去做一个人一年都做不完。所以第一件事不是写提示词而是给“专属音乐平台”重新下定义。我给自己的定位是一个跑在本地、给自己听歌用的网页应用。核心就四件事能导入本地音乐、能播放、能建歌单、能搜歌。再多加一个歌词展示和播放队列这是“音乐平台”的仪式感。想清楚这一步之后那条提示词就顺理成章了。AiPy 这类工具最大的价值是你不用自己把每个文件都写出来但你必须告诉它边界在哪里。1.2 为什么选 AiPy 而不是从头手搓我平时也是写代码的Python 和前端都碰过按说这种项目自己搭也不算难。但手搓一个完整应用光初始化前端工程、写后端接口、联调跨域、处理音频文件解析至少一个整天。AiPy 这种 AI 编程工具的优势在于它能把常见的工程结构一次性生成出来我只需要负责验收、修 bug 和按需迭代。我的选择逻辑很简单项目里没有特别复杂的算法没有团队协作需求也没有必须深度定制的底层逻辑这类 CRUD 加播放交互的应用恰好是 AI 编程工具最擅长的场景。如果你要做的项目里有大量你也不太懂的业务规则那还是得靠人慢慢捋AI 只能帮你搭壳子。1.3 提示词本身就是一种编程语言这次体验让我最颠覆的一点是提示词不再是“提问”而更像一种描述性的领域特定语言。你写“底部固定播放器深色主题响应式布局”它真的会生成对应的 CSS 和组件结构你写“解析 MP3 的 ID3 标签”它真的会去查 mutagen 这个库怎么用。换句话说AiPy 提示词的质量直接决定输出代码的质量。它没有“猜猜我的心思”这种功能我前面把需求边界写得越清楚后面返工就越少。这一点在接下来的提示词配方里会反复出现。2. 一条提示词的完整配方我是怎么把需求喂给 AiPy 的2.1 四个要素角色、背景、目标、边界我给 AiPy 写提示词总结下来离不开四个要素角色、背景、目标、边界。角色告诉它它是什么。比如“你是一名资深全栈工程师”目的是调起它生成高质量代码的倾向。背景当前环境是什么。比如“我在本地 Mac 上开发没有 Docker”避免它默认生成依赖容器的东西。目标这个项目要解决什么问题。比如“我要一个能导入本地音乐并在浏览器里播放的应用”。边界有什么不能做、不需要做。比如“不做用户注册不做推荐算法数据只存本地”。边界写得越清楚它越不会自作主张给你塞一堆用不上的功能。很多人写提示词只写目标不写边界结果 AI 帮你把登录注册、权限管理全都生成了一遍看着很唬人但全是技术债。2.2 我的那条提示词原文和逐句拆解下面是我实际发给 AiPy 的提示词稍微整理过格式但内容没变请帮我在本地创建一个网页版音乐播放平台要求如下 1. 技术栈前端用 HTML/CSS/JavaScript Vue 3后端用 Python FastAPI数据用 SQLite 存储 2. 功能模块本地音乐库扫描与导入、搜索歌名/歌手/专辑、歌单新建与编辑、收藏夹、播放队列、歌词展示逐行同步、播放模式顺序/随机/单曲循环、音量与进度控制、封面与专辑信息展示 3. 交互要求左侧导航栏中间歌曲列表右侧播放面板播放器固定在底部深色主题响应式布局支持手机浏览器 4. 数据说明优先读取本地文件夹中的 mp3/flac 文件解析 ID3 标签网络搜索作为备用数据源做成可开关的接口模块 5. 质量要求生成可直接运行的项目包含 requirements.txt、启动脚本 run.sh、README并给出运行说明。逐句拆解一下第 1 条是技术栈定调。我给它的技术栈都是我自己熟悉的因为后续要维护的是我不是 AI。如果你自己不会那个技术栈建议选生态成熟、资料多的方案别盲目追新。第 2 条是功能清单。我故意把功能说得非常具体比如“歌词逐行同步”而不是“支持歌词”因为后者很容易被实现成一个静态文本展示根本不会跟着播放进度滚动。第 3 条是交互和视觉。很多人会忽略这部分觉得 AI 生成的东西长得丑也没关系。但交互布局直接影响“是不是个能用的产品”。我明确说了左侧导航、中间列表、右侧播放面板AiPy 就按这个架子搭了。第 4 条是数据来源。这条最关键。我明确说“优先读取本地文件”因为我不希望它默认去接某个版权受限的在线接口。同时我留了一个“可开关的备用接口”这是给后续扩展用的。第 5 条是交付物。我要求它连启动脚本和 README 一起生成省去了自己摸索启动方式的时间。2.3 用“鹈鹕骑自行车”的思路自测提示词质量圈子里最近流行用“一只鹈鹕骑着自行车”这类提示词测试视频生成模型看它能不能同时处理好动物、动作、交通工具三个元素的组合。这个思路放到代码生成上同样适用好的提示词应该能同时约束多个维度并且这些维度之间是有关联的。我当时给自己设计的“鹈鹕骑自行车”测试是同一句话里同时包含“音乐平台”“本地存储”“可运行”“不做注册登录”四个约束看它会不会跑偏。结果它没有往在线音乐社区的方向跑也没有给你硬塞用户系统说明提示词的结构起到了作用。如果你想验证自己的提示词写得好不好可以准备一个这样的小测试故意在提示词里埋几个互相拉扯的需求比如“页面要很漂亮但不要引入任何 UI 组件库”看看 AI 怎么处理。处理得好的往往能在性能和美观之间找到一个平衡处理得差的要么直接违反约束要么项目复杂到跑不起来。3. AiPy 生成出来的音乐平台到底长什么样3.1 功能清单该有的都有不该有的一个没多项目生成完之后我按提示词里的功能清单逐项验收结果很惊喜。播放器具备完整的控制能力包括播放/暂停、上一首/下一首、进度条拖拽、音量调节以及顺序、随机、单曲循环三种播放模式。音乐库支持扫描指定文件夹能自动读取歌曲的标题、歌手、专辑和封面。搜索功能支持按歌名、歌手、专辑三个维度过滤响应速度很快。歌单系统比我想象的完整可以新建歌单、给歌单添加歌曲、删除歌曲、调整顺序。收藏夹实际上是一个特殊的歌单前端在左侧栏单独展示了一个“我的收藏”。歌词面板支持逐行高亮会自动跟随播放进度滚动如果没有解析到歌词会显示“暂无歌词”的占位提示。3.2 技术栈选型和实际生成的结构它最终生成的目录结构大概是这样的music-platform/ ├── backend/ │ ├── main.py # FastAPI 入口 │ ├── models.py # SQLAlchemy 数据模型 │ ├── api/ │ │ ├── songs.py # 歌曲扫描与列表接口 │ │ ├── playlists.py # 歌单接口 │ │ └── search.py # 搜索接口 │ └── utils/ │ ├── id3_parser.py # ID3 标签解析 │ └── local_scan.py # 本地目录扫描 ├── frontend/ │ ├── index.html │ ├── src/ │ │ ├── main.js │ │ ├── App.vue │ │ ├── components/ │ │ │ ├── PlayerBar.vue │ │ │ ├── SongList.vue │ │ │ ├── PlaylistPanel.vue │ │ │ └── LyricView.vue │ │ └── stores/ │ │ └── player.js ├── data/ ├── requirements.txt ├── run.sh └── README.md这个结构非常接近我自己会搭的样子。FastAPI 负责后端 APISQLite 存歌单和收藏数据前端用 Vue 3 加 Vite 构建。没有引入额外的重型依赖启动脚本也写得直接明了先装依赖再启动后端再启动前端。3.3 数据从哪来本地文件优先接口兜底整个平台的数据核心是本地音乐文件夹。后端用 mutagen 解析 MP3/FLAC 的 ID3 标签把歌手、专辑、封面、时长等信息抽出来写入 SQLite 的一张 songs 表。前端播放时直接通过/api/songs/{id}/stream这个接口拿音频流。网络搜索备用模块默认是关闭的我要求做成可开关的接口原因有两个一是版权风险公开接口不稳定说不定哪天就挂了二是本地音乐平台的核心价值本来就是“私有、干净、没有广告”没必要依赖外部资源。这里要提醒一句不管用什么数据源做出来自用可以真要上线分享版权这道红线段位很高别图省事就往坑里跳。3.4 页面交互和播放链路页面打开后左侧是导航栏包含“全部音乐”“我的收藏”“歌单管理”三个入口中间是歌曲列表展示了封面缩略图、歌名、歌手、专辑、时长右侧是歌词面板底部是固定播放器。整体是深色主题在手机浏览器上会折叠成上下结构体验还不错。播放链路是点击歌曲 - 前端调用后端接口拿到音频流地址 - 触发 Audio 播放 - 同步更新播放器状态 - 歌词面板根据当前时间高亮对应行。这套流程非常标准基本上是把常见音乐播放器的交互逻辑完整复刻了一遍。4. 实操过程从提示词到能听歌踩过的坑和绕过的弯4.1 启动方式跑起来比我想象的顺利按 README 里的说明第一步创建虚拟环境第二步安装依赖第三步运行 run.sh。这里有个容易踩的坑requirements.txt 里的版本号如果很旧可能和你当前的 Python 环境冲突。我当时遇到的是 pydantic 版本和 FastAPI 新版本不兼容报了一堆类型错误。解决方案也不难把 FastAPI 和 pydantic 一起升级到兼容版本然后用 pip freeze 固定下来。这里有一个经验AI 生成项目时给的依赖版本往往是它训练数据里的常见版本不一定是最新的所以启动之前先看一眼版本有没有明显的坑。4.2 关键代码模块播放器、歌词同步、歌单数据结构播放器核心其实是前端一个全局的 Audio 对象放在 Vue 的 store 里统一管理。然后通过 watch 监听 currentTime更新进度条和歌词高亮。有一个细节处理得不错切歌时会先取消上一个音频的监听事件避免多个播放器实例同时响应这在手写代码时很容易漏。歌词同步的实现思路是先把 LRC 格式的歌词按时间戳解析成数组每一行包含时间和文本。播放时每隔 250 毫秒检查一次当前播放时间找到最后一个小于当前时间的歌词行把高亮状态切换过去。这个方案简单可靠没有引入额外的歌词组件库。歌单的数据结构是一个 playlists 表和一个 playlist_songs 关联表采用标准的很多对多关系。歌单和歌曲之间通过 song_id 关联删歌单时用级联删除把关联数据一起清掉避免脏数据。这套设计不复杂但胜在规范。4.3 用追加提示词完成迭代和修 bug第一次跑起来之后问题也跟着来了。我大概发了两三轮追加提示词挑几个典型的记录一下。第一轮我发的是“进度条拖拽到末尾后播放器状态没有自动切到下一首帮我修复。”AiPy 给出的回复是把 ended 事件和 next 函数绑上并在手动拖拽到末尾时也触发一次 ended 逻辑。这个问题本质是事件边界没处理好AI 一找一个准。第二轮我发的是“歌词经常会比对到上一行歌曲刚换时还会闪现上一首歌的歌词请加一个重置逻辑。”它给出的方案是在切歌时清空当前歌词索引并且把歌词解析结果缓存到内存里避免重复解析。这两个问题都属于典型的“状态没有重置”类 bugAI 工具处理这种局部问题非常高效。第三轮我提了一个需求“搜索框输入拼音首字母也能匹配比如输入 Jay 能搜到周杰伦。”这个稍微复杂一点AiPy 建议引入拼音库做索引在后端搜索接口里加一个拼音字段。实测下来能用但会稍微增加匹配耗时所以我给它限定了只对歌名字段做拼音匹配。4.4 配置和参数调整的几条经验调试过程中我调整了几个配置这里给出来供参考。前端和后端默认跑在不同端口所以必须配置 CORS。AiPy 初始用的是“允许所有来源”本地开发没问题但如果你后面想把服务暴露到局域网给手机访问建议把 allow_origins 收紧成具体的局域网 IP避免不必要的暴露。音频流接口我用的是 StreamingResponse这样前端 Audio 标签可以边下边播不用等整个文件加载完。扫描本地目录时如果音乐文件夹特别大同步扫描会把后端卡死。我后来建议 AiPy 改成后台线程扫描状态通过一个扫描进度接口暴露给前端这样体验会好很多。SQLite 数据库文件默认生成在 data 目录下这个目录最好加入 .gitignore否则本地音乐文件路径和缓存数据会被一起提交到仓库里既臃肿又容易泄露隐私。5. 提示词工程方法论从一次生成到可复用技能5.1 同一个提示词为什么不同工具生成结果不一样我在 Cursor 上试过同一条提示词生出来的项目结构完全不同。有人可能觉得这是玄学其实根本原因是不同工具背后的模型能力、上下文窗口和默认行为不一样。有的模型擅长遵循结构化要求有的模型擅长理解口语化描述但忽略细节。所以我的经验是不要指望一条提示词在所有工具里都生效。选定一个主要工具摸清它的脾气再针对它的特点微调提示词。AiPy 给我的感觉是更吃结构化描述它喜欢清晰分条的需求如果是口语化的“帮我搞个听歌的”它也能做但做出来的东西就真的只是一个能听歌的页面。5.2 上下文管理把项目背景带进每一轮对话AI 编程工具有上下文窗口但并不是无限大。这个项目体量不大所以对话能维持住如果项目再大一点它很可能忘记前面说了什么。我的习惯是在每一轮追加提示词之前先用一两句话概括当前项目状态和要做的修改比如“在现有的 Vue 3 FastAPI 项目中请新增一个最近播放列表。”这个习惯不是为了给 AI 看而是为了让它把当前这轮对话锁定在一个正确的上下文中。如果你直接说“帮我改一下播放列表”它可能改到歌单管理的逻辑上而不是最近播放。5.3 提示词失效的典型场景怎么救我遇到过几次提示词看起来合理但生成结果完全跑偏的情况总结下来有三类。第一类是需求和约束互相矛盾。比如我之前让它在保持深色主题的同时“参考 Apple Music 的轻量感”结果它生成了一款灰不拉几的页面既不够深色也不够轻量。这类问题的解法是明确优先级是深色为主还是轻量为主只能选一个。第二类是功能描述太抽象。比如“做个智能推荐”它可能给你生成一个随机播放按钮来糊弄。后来我把“智能推荐”改成“根据播放次数最多的三首歌曲生成一个分级推荐的相似歌单”它才真正做出了点东西。第三类是交付标准不明确。只说“写一个播放器”它可能给你一个没有界面的 JS 组件。后来我所有的提示词都会带一句“生成后我能在浏览器里直接看到并使用”这个隐含约束能有效避免它只生成半成品。6. 常见问题与排查技巧实录6.1 问题排查速查表顺手整理了一份我在这个项目里遇到的典型问题和对应解法直接对照着看就行。现象可能原因排查与解决项目启动报 pydantic 版本错误FastAPI 与 pydantic 版本不兼容升级 fastapi 和 pydantic重新安装依赖前端请求后端接口报跨域错误前端和后端端口不同CORS 未配置在后端 FastAPI 里加 CORSMiddleware允许前端来源播放器点击后没有声音浏览器自动播放策略阻止了播放在用户点击事件里触发 play()不要在初始化时自动播放扫描大文件夹时后端卡死目录扫描阻塞了主线程改成后台线程扫描前端显示扫描进度歌词显示乱码LRC 文件编码可能是 GBK 或其他解析时尝试 UTF-8、GBK 编码加兜底处理刷新页面后歌单没了前端只用内存存储没写入后端检查是否调用后端接口持久化到 SQLite封面图加载不出前端直接访问了本地绝对路径通过后端接口输出图片流前端访问相对 URL6.2 音频文件和标签解析的坑我一开始测试用的 MP3 文件里有一部分是老歌ID3 标签信息不完整有些甚至没有歌手字段。AiPy 生成的解析器对这种情况没有特殊处理直接显示了一个 None。后来我在扫描逻辑里加了兜底没有歌手就用“未知歌手”没有封面就用默认的 SVG 占位图。FLAC 文件也有一点特殊有些是内嵌封面图但封面流不一定放在第一个 block 里解析不对就会拿不到封面。这个问题我没让 AI 处理直接在提示词里写“flac 封面解析失败时忽略不阻塞扫描”因为阻塞一次整批歌曲都进不了库比没有封面更坑。6.3 浏览器兼容和性能问题Audio 标签在桌面浏览器上基本没区别但我传了个 iPad 上测试发现切歌时偶尔会出现 Audio 对象没完全释放导致的卡顿。这个问题在后端改用 StreamingResponse 之后基本消失因为音频流可以被浏览器正确缓存和释放。性能方面歌词逐行高亮用 setInterval 每 250ms 扫描一次在长歌曲、后台标签页场景下会轻微耗电。后来我把监听改成了 requestAnimationFrame在页面不可见时自动暂停更新性能好很多。这种细节不一定需要提示词写但如果你发现 AI 生成的前端不够流畅可以从这个方向去追问。6.4 快速自测清单交付前我在浏览器里逐项过项目彻底搞定前我列了一个自测清单每一项都在浏览器里点了一遍导入 50 首本地歌曲确认扫描时间和入库数量正确搜索歌名、歌手、专辑三个维度确认结果过滤准确新建歌单添加 5 首歌曲刷新页面后确认数据还在顺序播放、随机播放、单曲循环三种模式各跑一遍拖拽进度条到歌曲末尾确认自动切到下一首切歌时确认歌词没有残留上一首的歌词把浏览器窗口缩小到手机尺寸确认播放器没有溢出这套清单虽然简陋但它保证了“能听歌”这个最核心的体验是稳定的。很多 AI 生成的项目代码看着完整一跑起来全是细节问题所以验收环节不能省。我在实际操作中的体会是用 AiPy 这类工具做小项目最大的门槛不是写提示词而是验收和纠偏。它能把 80 分的框架给你搭好剩下 20 分的适配、边界处理和体验打磨还是要靠人一遍遍试。这二十多分的活恰恰是提示词工程真正值钱的地方。你越能准确描述“哪里不对”它就越能精准改到位。这让我觉得AI 编程工具不是替代我做项目而是把我从重复劳动里解放出来去琢磨更该琢磨的事情。最后再分享一个小技巧不管是 AiPy 还是其他 AI 工具建议你把好的提示词保存成模板按“技术栈、功能、交互、数据、交付物”五个模块归档。下次再做别的应用直接替换核心功能描述就行。我就是用这套模板在第二天又“撸”出了一个带时间线的书签管理工具速度比这次还快。