我不会写代码,但我做出了一个 App:一次对“自然语言编程”的祛魅

文/知奥
我做了一个Android跑步节拍器App,从零到上线GitHub,历时两天,写了17次提交。我不会写代码。以下是这件事的完整复盘。
一、我为什么要做这个App
在《从“抬腿就冲”到“精准燃脂”:我的“小低高”慢跑重生记》文章中,我讲了跑步的步频控制对步幅和心率的重要性。所以我跑步时喜欢跟着节拍配速,但市面上的节拍器App要么界面复杂、要么非得看广告充会员、要么开音乐就被它抢占、要么声音像打鼓——我要的只是一个清脆的滴答声,BPM可以调,放口袋里继续响,其他什么都不要。
需求很简单。但我不会写代码。好在现在有了AI编程,App可以个性化定制了。
于是我打开了Claude Code。
二、过程是怎样的
第一阶段:说清楚你要什么
Claude先问了我一系列问题:
-
想在什么平台使用?(Android手机)
-
想手动设BPM还是自动检测?(手动)
-
反馈方式是声音还是震动?(声音)
-
需不需要记住上次的BPM?(需要)
-
用什么开发语言?(我说我是小白,它推荐了原生Kotlin)
这个问答过程很重要。它不是在走流程,是在逼你把模糊的”我想要一个节拍器”变成具体的技术决策。很多人以为AI能”懂你的意图”,其实它懂的是你说清楚的意图。你越含糊,它越偏。
最终我的需求被整理成:
-
BPM范围100-220,滑块调节,默认170
-
仅声音反馈
-
后台Foreground Service持续播放
-
不抢占音乐App的音频
-
通知栏有Stop按钮
-
深色渐变UI,圆形BPM显示,顶部一行字:”抬腿就跑,干就完了。”
第二阶段:安装编程环境,开手机USB调试
就这样,每一步都是Claude手把手带着走的:创建项目、配置SDK、连接手机。
连手机那步需要开”USB调试”功能,这是一个隐藏在开发者选项里的设置,普通用户根本碰不到。Claude给了我步骤,我照着操作,手机里突然出现了”开发者选项”,有种破除封印的感觉。
在这之前,我一直觉得手机就是个黑箱——App只能从应用商店下载,厂家给什么你用什么。开了USB调试之后,我第一次把自己写的(AI写的)App直接装到手机上,绕过了所有的商店、审核、上架流程。
这个体验本身就值得记录:App其实只是一个文件,手机只是一台可以运行这个文件的计算机。 应用商店是分发渠道,不是唯一入口。你完全可以自己做、自己装、自己用。
第三阶段:搭骨架,基本能跑
Claude生成了完整的项目结构,分成几个文件:
| 文件 | 职责 |
|---|---|
AudioEngine.kt |
生成PCM音频波形 |
TimingEngine.kt |
纳秒级精准计时 |
MetronomeService.kt |
后台Foreground Service |
BpmPreferences.kt |
记住上次BPM |
MainActivity.kt |
界面交互 |
它甚至写了单元测试。整个项目跑起来,基本功能都有了。

这部分很顺,大概用了一个晚上。
第四阶段:遇到真实的问题
然后开始踩坑。
坑1:通知栏没有显示
我安装App后根本看不到通知。Claude解释:Android 13以上需要运行时申请POST_NOTIFICATIONS权限,而且手机默认是禁用的。它修了代码,我手动去设置里打开了权限。
这种问题文档里有,但你不知道你不知道。
坑2:App图标用AI生成的
安装到手机后,图标是Android默认的绿色机器人,很难看。我需要一个自定义图标,于是去Nano Banana Pro(一个AI图像生成工具)生成——提示词是Claude给我的:
“我要给我开发的运动节拍器App生成一个图标图片,要求PNG格式,建议至少512×512像素,正方形。”
生成了一张图之后,在Android Studio里右键点击res文件夹→New→Image Asset,把图片导入进去,它自动帮你生成所有尺寸。图标就换了。

整个过程里,图标这件事花了我不到十分钟,完全不需要会PS或者设计。提示词是AI提供的,图片是AI生成的,格式转换是Android Studio完成的。我做的事情只是:去生成、去导入。
坑3:声音像打鼓,不是滴答声
初版声音是80Hz的鼓击。我说不喜欢,想要清脆的。
这个需求来回折腾了7次:
80Hz鼓击 → 1500Hz木鱼 → 2000+3150Hz金属感 → 3500+5200Hz(更难听)→ 回退到1500Hz → 我自己提供参数(2500-3000Hz,快速衰减)→ 2700+5400Hz,40ms(拖沓)→ 调整为25ms,更快衰减,2ms起音(通过)
从Git记录能看出来这段历史有多曲折:
revert: restore 1500Hz crisp tick soundrevert: restore 2000Hz+3150Hz metallic tickfix: brighter shorter tick - 3500Hz+5200Hzfix: metallic tick sound - 2000Hz+3150Hzfix: crisp tick sound (1500Hz)
迭代到第5次还没找到感觉,是因为卡在了一个翻译问题上:我知道我想要什么声音,但我不知道怎么把”听感”翻译成程序参数。
这时候豆包出手了。
豆包是字节跳动的AI助手,有个功能是屏幕共享——打开之后,你手机屏幕上发生的一切它都能看到,可以实时提问。这个用法是AI学习圈的快刀青衣在课上介绍的。
我把声音调试的过程展示给豆包看,问它”怎么才能得到清脆短促的叮叮声”。它没有泛泛地说”提高频率”,而是直接给出了可以喂给Claude的参数:
// 核心参数设置频率:2500-3000 Hz // 高频带来清脆感时长:30-50 ms // 短促不拖沓衰减:快速衰减(时间常数 50-100ms)音色:正弦波 + 轻微谐波
这就是关键的一步:豆包把我的”人话需求”翻译成了”程序语言”。我把这段参数直接复制给Claude,Claude照着实现,几次微调之后声音就对了。
这次经历里最重要的认知更新:人机协作中,参与的AI可能不止一个。
Claude负责写代码,豆包负责实时看屏幕、做解说、做翻译。两个AI在不同的环节发挥了不同的作用,而我在中间负责调度、判断、和最终拍板。这不是”一个AI帮你做事”,而是一套协作系统,你是系统的中心。
坑4:开节拍器,音乐停了
这是最严重的问题。我边跑步边听音乐,打开节拍器,网易云直接被停了。
Claude的第一个方案:把音频焦点从AUDIOFOCUS_GAIN改成AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK。
结果:音乐没停,但被压低了音量,节拍器盖在上面,体验更差。
第二个方案:完全删除音频焦点请求。
代码直接移除了AudioManager和AudioFocusRequest相关的全部代码。
结果:正常了。音乐继续,节拍器叠在上面,互不干扰。
这是一个”不做反而对”的方案,反直觉,但符合实际需求——我只是想加一层声音,不是要”接管”音频系统。
三、整个过程17次提交的时间线
feat: AudioEngine generates 80Hz drum clickfeat: TimingEngine, BpmPreferences, complete appfix: crisp tick sound (1500Hz)fix: metallic tick 2000Hz+3150Hzfix: 3500Hz+5200Hz brighterrevert: back to 2000Hz+3150Hzrevert: back to 1500Hzfeat: 2700Hz+5400Hz 40ms tickfix: shorter 25ms, faster decay, soft attackfix: isPausedBySystem flag, thread joinfix: AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCKfix: remove audio focus entirely, volume 25%feat: custom app icon
17次提交,每一次都对应一个真实的问题或反馈。
这不是AI在自动生产代码,这是一个人机协作的迭代过程。
四、可以复用的经验
1. 需求要具体到可以测试
“我想要清脆的声音”是没用的描述。“2500-3000Hz,30-50ms时长,快速衰减,正弦波加轻微谐波”才是可执行的需求。
如果你不懂技术参数,可以先用模糊描述开始,但要做好多轮反馈的准备。感受类的需求(声音、UI视觉效果)不能指望AI一次命中,本来就需要迭代。
2. 分工要清晰:你是产品经理,AI是工程师
这次合作里,所有”好不好”的判断都是我做的:
-
声音好不好听
-
界面看着舒不舒服
-
功能对不对
所有”怎么实现”的决策是AI做的:
-
用AudioTrack还是MediaPlayer
-
音频焦点策略怎么选
-
线程安全问题怎么处理
越界就会出问题。如果我去干涉线程实现,或者让AI来判断”这个声音好不好”,效率会极低。
3. 出了问题,把现象原文给它
“不好用”没用。“我打开节拍器,网易云音乐立刻停止播放,只有关掉节拍器音乐才恢复”有用。
把你观察到的现象、错误信息、截图原文喂给它,不要自己先”分析原因”再描述。你的分析可能把它带偏。
4. 不需要懂代码,但需要懂你自己要什么
这次全程我没有手写一行代码,但我做了大量的判断:
-
这个声音可以了
-
这个不行,再改
-
音乐被压低了,这不是我要的效果
-
音量还是太大
这些判断是AI替代不了的。你的品味、你的使用场景、你的偏好,这些才是产品里最重要的东西。
5. Git提交是你的进度存档
每次功能稳定就提交,失败了可以回退。这次声音调到最差的时候,直接git revert回到上一个版本,几秒钟的事。
没有版本控制的话,坑填到一半再挖坑,最后什么都不是。
五、对”自然语言编程”的祛魅
“以后不用学编程了,直接跟AI说就能做App”——这句话对,也不对。
对的部分: 你确实不需要学Kotlin语法、不需要理解Android Activity生命周期、不需要记住AudioTrack的API。这些知识Claude都有,你调用它就行。
不对的部分:
-
AI不能替代你感知产品。 声音调了7次,不是因为AI不够聪明,而是”好听”这件事只有你知道。没有你的反馈,它只能在黑暗里猜。
-
你需要会描述问题。 把你的需求、你观察到的现象说清楚,是这项技能里最重要的部分。这不是编程技能,但它需要训练。
-
AI会犯错,会走弯路。 音频焦点那个问题,它给了两个错误方案才找到正确的。你不能无脑执行它的每一步,你需要测试、验证、告诉它结果。
-
复杂项目的天花板仍然存在。 这是一个500行代码的小App。如果是一个有数据库、有后端、有多用户的系统,”自然语言编程”的效率会急剧下降,因为你无法有效描述你不理解的架构决策。
真实的画面是:AI是一个极度高效的实习工程师,而你是产品经理兼测试员。 它能干活,干得很快,但它不理解你的场景,不会主动质疑你的需求,也没有你的感官。你的介入是必要的,不可省略的。
六、GitHub:终于有了自己的作品
我注册GitHub账号很早了,一直不知道它能干什么用。看别人说”上传代码到仓库”,但我没有代码,也不知道为什么要上传。
这次把整个App推送上去之后,我去看了一眼仓库页面:代码、提交记录、每一次改动的说明,全都整齐地排在那里。
这是第一次GitHub对我来说不是一个陌生的概念,而是一个有内容的地方。
仓库地址:https://github.com/sinobiology/-RunMetronome
如果你也想做一个类似的App,可以去看源码。所有的技术细节都在里面,17次提交的历史也完整保留,包括那些走弯路的记录。
七、最后
App 完工了。现在跑步时,节拍器轻盈地叠在音乐之上,每一步都精准踩在鼓点里。
这种‘严丝合缝’的需求,在坐拥百万应用的商店里找不到,但我用两天时间,亲手在数字世界里为自己量体裁衣。

这绝非‘AI 替我写了代码’,而是**‘我借 AI 之手,显化了我的意志’。主体始终是我。当编程的门槛崩塌,App 将不再是货架上千篇一律的工业制成品,而是每个人根据生活缝隙定制的私人化工具。当‘使用者’即‘开发者’,传统软件行业的流水线逻辑确实危险了——因为数字世界的权力,正在回归到每一个有想法的普通人手中。
App仓库:https://github.com/sinobiology/-RunMetronome(源码完整开放,含17次提交历史)
技术栈: Kotlin · Android · AudioTrack · Foreground Service
开发周期: 2天 · 17次提交 · 0行手写代码
往期推荐:
夜雨聆风