无疾而终的项目

作为一个产品经理,想要独立开发一款自己的 app,是非常正常且合理的事情。自己设计、自己开发、自己运营,而不是每天忙着做一些项目价值、项目战略之类的狗屁 PPT。

这个项目起源于我个人的一个痛点:我订阅了大量的英文 newsletter,由于英文不好读起来费劲,却又不愿意草草浏览,结果便眼睁睁看着邮箱文件夹的未读邮件数量越积越多。

我想到了借助 AI 来帮我总结邮件,并实现了一个利用 Applescript 从原生邮件 app 获取邮件正文,并调用扣子 API 总结邮件内容的自动化流程。彼时 AI 辅助编程正如火如荼,我决定在此基础上开发一款 macOS app。

项目的核心逻辑非常简单:通过 Applescript 脚本从原生邮件 app 同步邮件信息,并调用扣子的 API 总结和翻译。由于沙盒模式下,应用无法通过脚本与其他应用交互,我设置了引导流程,让用户自己将脚本文件移动到 application script 文件夹下,这一实现方式借鉴了之前开发者的经验。

从2024年10月至2025年5月,我完成了整个项目的开发并提交至 App Store Connect,然而审核人员的回复让项目发布到 App Store 成了不可能的事情:

中译中的意思就是:“我知道你想做什么,但是我不能让你这样做”。看上去苹果的政策变得更加严格了,这种方式当下已经无法通过审核。缺乏脚本导致主流程无法实现,我也没有找到其他的替代方法,整个项目在5月31日这天走到了终点。

项目成本竟高达35.5万元?!

我曾在之前的一篇文章中介绍过,为了防止过于专注导致脑力透支,我自制了一个番茄钟快捷指令来帮助自己调整开发节奏。得益于坚持使用,整个开发过程被如实记录了下来1,形成的记录数据包括:Logseq 的日志、numbers 中的数据和日历中的事项:

借助 numbers 中的数据,可以得到以下的一些分析结果:

  1. 2024年11月24日到2025年5月31日,一共188天,其中有101天有记录,考虑到每周要固定抽出一天陪对象放风,以及元旦、春节、 五一、端午这些节假日,扣去40天后占比大概在70%。也就是说,每10天有7天我都写了一点儿代码,这实际上比我感受的少,总感觉我每天都在写来着;
  2. 共计236个钟,我设置的每个钟是45分钟,换算成工时是177,按照市面上常见的“外包项目”的人工费用 2000/人/工时 来算,人力成本是35.4万元;
  3. 平均每天2.34个钟;1-2个钟的日期最多,有73天(大概率都是我晚上加班的时候摸鱼写的);最多的一天是8个钟,发生在2025年2月25日,居然是周二;
  4. 按照周一到周日汇总番茄钟数量分别是:31、50、33、39、18、24、41(没错,我上班都是在摸鱼)。

 

在日历 app 中插入的番茄钟事项截图,对于自己投入的时间成本分布可以有一个直观的了解:

每次番茄钟结束时我会做一个简短的总结自动插入 Logseq,方便进入下个钟时无缝衔接上进度。浏览自己的日志,能感受到自己一步一个脚印推进项目的过程,以及对于 qos 的问题我是如何从开始解决到彻底放弃的

Logseq 按标签查询时,block 的排序会乱

除去35.4万元的人力成本,我投入的资金成本合计 1194.59 元。费用清单如下:

  1. Apple Developer 会员,688元 - 使用 Apple 提供的登录和 iCloud 服务,以及将应用发布到 app store。我在项目即将完成的4月份开通,目前还剩大半年;
  2. iShot 会员,6元 - 为了套壳截图,准备展示在 app store 上的软件截图;
  3. Cursor 会员,147.03+145.06元 - 先后在1月和5月购买;
  4. 腾讯云轻量服务器,153.6元;域名 + DNS 解析服务,54.9元 - 为了 ICP 备案。

花费35.5万元之巨的项目没能成功发布到 app store,作为独立开发者的第一个项目就这样“胎死腹中”,对我其实是不小的打击。尽管如此,我在整个开发过程中的收获实际上相当之多。

独立开发的体验

独立开发是一种自我实现

一个产品经理能独自掌控一款产品实际上是一件非常幸福的事情。我想要设计一款属于我的产品,不需要多少用户,但是能切实提供价值或帮助,我渴望用户的反馈,期待与产品一同成长。然而对于我这种在互联网行业下行周期入行、又从事 B 端产品设计的产品经理来说,几乎没有这样的机会。

AI 在编程领域的发展,让我能够以极低的成本、不那么费力的方式尝试独立开发。它是我在独立开发路上的老师、顾问和助手,衷心感谢 AI,感谢科技的发展,让我有能力做出这样的尝试,就好像我在本地创建的文件夹名称“The long way”,长路漫漫,哪怕前路无果,我也愿意保持在路上。

给生活找点乐子

随着年岁的增长,看视频、看比赛、打游戏、买买买等等消费行为给我带来的快乐在慢慢减少。相反,创造能给我带来更持久的满足感。自从在我派发布文章以来,不管是创作的过程,还是文章发布后与读者的互动,都比单纯的消费要让我快乐。

编程与写作相似,但又不完全相同。写作是输出的过程,将自己的想法总结凝炼,形成观点,梳理成通顺的文字,是与自我的交流。编程是与计算机的交流,用代码指挥计算机,告诉它在不同的场景下应该怎样做,像是在搭积木,将一行行代码拼接起来,组装出 app 的模样。

对我来说,除了创造这件事,提高快捷键的使用熟练度也很有趣。command + p 快速切换文件,command + shift + p 快速执行命令,command + 1 切换到代码文件,command + L 切换到 AI 对话窗口,必不可少的,我也在学习使用 VIM 编写代码,在 Cursor 里让 cursor 上下跳跃像是在打游戏,有种高手般的操作感。

每天都写一点儿

“不积跬步,无以至千里”。老祖宗的这句话,我有了亲身的领悟。

独立开发实际上是一个人的游戏,没有队友可以交流,靠的是自己的信念与坚持。特别在项目开发的后期,随着热情衰退,推进项目变得相当困难。项目的主流程都已实现,再没有项目开始时的热情和功能实现后的兴奋劲,剩下的是查漏补缺,测试和优化。当时的感觉就像是在泥潭里跋涉,每前进一步都要耗费全身的力气。

对此我能做的是把待办事项一一列到清单上,排好优先级,每次只解决眼前的问题。看着项目在一个钟接一个钟的努力下慢慢完整,直至最终完成提交至 App Store Connect 那一刻,我的心情相当平静。因为我知道还会继续走下去,而走下去这件事对我来说不再是困难,只要坚持走就好了。

与AI协同编程的经验

这是一个产品经理的编程经验😛,若有不对之处,还请在评论区指出。

永远记得审核 AI 生成的代码

这是最重要的一点。

从 Cursor + Claude-sonnet-3.5 的组合开始,AI 已经可以准确领悟你的意图,做到跨多个文件一次性生成全部代码,并且没有任何语法问题可以直接运行。Agent 模式下 AI 还能直接帮你修改全部文件,并且执行命令行运行程序完成测试,也就是说,你只需要输入指令,剩下的事 AI 都帮你做了。这是相当可怕的。

最初我是将代码粘贴到网页对话框里,通过对话的方式让 AI 协助编程。在我拿不定主意的时候,我会同时打开 ChatGPT、Gemini、grok、DeepSeek 和 Claude,让它们回答同一个问题,对比各个方案,有不懂的地方还要进一步追问。在这一阶段,我能理解每一句代码的含义,也知道每个功能模块是怎么运作的。然而之后当我开通 Cursor 的会员,享受最顶尖的 AI 模型+编程工具带来的便利时,人与生俱来的惰性反而让我不再关注 AI 生成的每一行代码,只要最终的结果能让我满意就行。

这导致我背负了大量的“技术债务”,我不理解功能背后的运作逻辑,甚至连代码也看不明白。当问题出现时,我只能两眼一抹黑地将报错信息直接粘贴给 AI,而 AI 反复修改也无法解决时,开发过程就陷入僵局,我与 AI 大眼瞪小眼。最后只好在 AI 辅助下将所有代码重新理解了一遍。特别在我还没学会使用 cursorrules 来约束 AI 之前,大模型编程很喜欢使用一些高级方法,生成的代码又长又复杂,复盘过程让人绝望,真真是血泪教训。

从这一角度来说 Vibe Coding 实际上是个一次性的工程,只能做一些精巧的小玩意儿。如果开发者自己不能掌握项目代码,是不存在进一步的迭代和维护的。手底下人事情搞砸了,啥也不懂的领导还能甩锅开人,AI 写了一堆屎山代码,我不仅没法甩锅,为了解决问题,还得一口一口吃到肚子里消化了。

为 AI 提供足够多的上下文和准确的 prompt

很多时候,AI 模型的上限不在于模型、不在于软件,而在于使用者输入的信息质量。能否准确地描述自己的需求,或是给出清晰的指令,能决定一个人使用 AI 的能力高低。(实际上语言本身就存在局限性,很多人也不具备描述问题、准确表达的能力。可能脑机接口才是最终的归宿。)

我曾看到公司的程序员使用 Cursor 改 Bug 的方式是引用有问题的整个代码文件,发给 AI 的 prompt 只有三个字:“有问题”,多一个字都不肯写。这种质量的输入,怕是最先进的模型的能力也要大打折扣。

编程之所以成为 AI 发展最先进、前景最好的领域之一,就是因为在使用 AI 编程时:

  1. 编译环境能提供最直接的反馈。对就是对、错就是错,AI 有明确的参照标准。
  2. 有定义清晰的术语,即代码语言。使用术语与 AI 沟通,确保 AI 能准确理解并执行你的指令。
  3. 能快速便捷地提供上下文。在如 Cursor 一类的 IDE 软件里,除了能便捷地引用项目内的代码文件,还能设置 .cursorrules 文件来约束模型行为,使用 notepad 来存储常用的 prompt,以及支持为互联网资源建立索引。这些功能可以让 AI 得到足够多的信息来完成你的指令。

Claude Code Best Practices这篇文章中,对于好的 prompt 有很好的举例:

PoorGood
add tests for foo.pywrite a new test case for foo.py, covering the edge case where the user is logged out. avoid mocks
why does ExecutionFactory have such a weird api?look through ExecutionFactory's git history and summarize how its api came to be
add a calendar widgetlook at how existing widgets are implemented on the home page to understand the patterns and specifically how code and interfaces are separated out. HotDogWidget.php is a good example to start with. then, follow the pattern to implement a new calendar widget that lets the user select a month and paginate forwards/backwards to pick a year. Build from scratch without libraries other than the ones already used in the rest of the codebase.

使用最好的模型和工具

不同的模型辅助编程的效果不是好和坏的区别,而是0和1的区别。

顶尖模型能真正解决问题,普通模型只能给出看似能解决问题的方案。对于同一个问题,顶尖模型“啪!”一个答案给到你,你分析之后没问题直接就用。普通模型“啪!”一个答案给到你,你分析之后发现 AI 要么是没理解问题、要么是生成的代码有错误,多次追问之后也许解决了问题,也许还是不行,反而要耗费更多的时间。特别对于我这样无法一眼分辨代码好坏的编程小白,这两者的使用体验、使用效率上的差异,不可同日而语。

工具也是同理。这就是为什么 trae 月费只有 Cursor 一半,而我仍然酷酷给 Cursor 充钱的原因。

别做奴隶主

AI 是很好的助手,是不知疲倦的执行人,但是需要有技巧地使用。若是你只知道挥舞鞭子,大声吼着“给老子干!”,那我只能在硅基统治世界的时候祈祷你活得久一点了😊。

大问题拆成小问题。AI 在一次性生成大量代码时容易出错,并且 Cursor 还有单次代码生成的上限。对于一个从0开始的项目,可以先让 AI 将项目按模块拆解,并生成待办事项文档,之后让 AI 根据每个模块的待办事项依次生成代码。同时在 .cursorrules 里要求 AI 每次执行前都要阅读待办文档,并在执行后更新文档内容。保证 AI 按照文档内容有规划地生成代码,避免一次性生成过量的代码,

先 chat,再 agent。先把问题聊明白了再执行,比直接使用 agent 的效果要好。在 trae 还没开通会员功能,每次提问不用排队100多名的时候,我会先在 trae 里让 Claude 分析问题,给出两个方案并对比好坏,再到 Cursor 里执行。一方面是 Cursor 的执行能力是 trae 的好几倍,另一方面 Cursor 每个月的 fast requests 也就500次,能省则省。

主动在 prompt 中引用相关的代码文件。虽然 Agent 可以根据 prompt 自己搜索相关的代码并修改,但是经常会漏掉或是错改文件,主动指定可以避免这样的问题。

使用 cursorrules 能够让 AI 戒掉坏习惯,养成好习惯。以下是我从一个 YouTuber 那里借鉴的规则,供大家参考:

# Fundamental Principles

- ALWAYS speak in keep the language of the conversation in Chinese
- Write clean, simple, readable code
- Implement features in the simplest possible way
- Keep files small and focused (<200 lines)
- Test after every meaningful change
- Focus on core functionality before optimization
- Use clear, consistent naming
- Think thoroughly before coding. Write 2-3 reasoning paragraphs.
- ALWAYS write simple, clean and modular code.
- use clear and easy-to-understand language. write in short sentences.

# Error Fixing

- DO NOT JUMP TO CONCLUSIONS! Consider multiple possible causes before deciding.
- Explain the problem in plain Chinese
- Make minimal necessary changes, changing as few lines of code as possible
- in case of strange errors, ask the user to perform a Perplexity web search to find the latest up-to-date information

# Build's Process

- Verify each new feature works by telling the user how to test it
- DO NOT write complicated and confusing code. Opt for the simple & modular approach
- when not sure what to do, tell the user to perform a web search

# Comments

- ALWAYS try to add more helpful and explanatory comments into our code
- NEVER delete old comments - unless they are obviously wrong / obsolete
- Include LOTS of explanatory comments in your code. ALWAYS write well-documented code.
- Document all changes and their reasoning IN THE COMMENTS YOU WRITE
- when writing comments, use clear and easy-to-understand language. write in short sentences.
- always writing these infomation on the top of the file when creating new file:
    - path of the file
    - project name
    - "Created by" Author name

持续学习

虽说有了 AI 辅助,程序员以后可能都不需要手敲代码了,但就好像从士兵升到了将军,运筹帷幄的能力仍然是不可或缺的。

这里指的不光是高屋建瓴设计系统架构的能力,也包括对于方法和工具的掌握,一个将军打仗,至少要知道部队里有哪些兵,哪些装备。不管是哪一种代码语言,都有很多封装好的方法,包括 GitHub 上也有很多优秀的第三方库,但是大模型在生成代码时,有时会选择自己造轮子,而不是使用现有的功能,造成很多不必要的开销。此时如果知道已经有这么一个轮子,并且在 prompt 里要求 AI 把轮子用起来,就能避免这种问题。

另一方面,训练模型的知识库始终是落后于现实世界的发展的。比如苹果在 macOS 14.0 里更新了 onChange 语法,然而 Claude-sonnet-3.7 每次生成的代码中都在使用老的语法。如果盲目让 AI 修复,只会在错误的道路上越走越远。这时候就需要我们有知识的储备,为 AI 指引方向。

说到底,AI 只能是提供方案的助手和听从指令的执行工具,真正的决策者仍然是我们自己。持续不断地学习,提升技术能力,做掌舵的人,剩下的交给 AI。

迈向下一个目标

事已至此,眼见着上架 App Store 已然是不可能的事情,倒不如及时止损,开始新的目标。

在我开发项目的过程中,自制的番茄钟发挥了巨大的作用,帮助我保持节奏,记录每个钟的数据。而市面上又没有满足我需求的 app,那么就把它做成 app 吧。果然待办事项、番茄钟、记账工具三大件是独立开发者的宿命😜。

至于我无疾而终的邮件 AI 小助手,我考虑把它改成一个开源的 GitHub 项目,只要填写自己的 apikey,用户就能同步并总结和翻译原生邮件 app 的邮件内容。让它能为有需要的人提供一点帮助。

随着 AI 编程领域的不断发展,未来的独立开发者完全可以兼顾多个 app 的开发工作,做面对细微市场痛点的、真正的“小而美”的 app 会是一个很好的选择。做自由而独立的开发者,让自己的想法变成现实,这是我对未来的期许。