9 月 1 日,我在 WorkBuddy 里说了第一句话:帮我做一个家庭记账小程序。
9 月 8 日,首版提审。现在它是 22 个页面、69 个接口、19 张数据表、18160 行代码,微信里能搜到「掌上账本」。
数字我其实没那么在意。真正变了的不是代码量,是我的角色——我不写代码了。我提需求,做决策,验收。
这篇把 18 天里我认为值钱的东西写下来:方案怎么拆、任务怎么分、质量怎么守、钱怎么省。
一、五步范式:先分析,再动手
很多人用 AI 写代码还是「提问、复制、粘贴」那三板斧。这个项目从第一天就换了干法,我把它总结成五步:
| 步骤 | 谁做 | 做什么 |
|---|---|---|
| ① 提需求 | 我 | 用大白话讲,不写需求文档 |
| ② 先分析 | 它 | 先读代码,回来报现状、给几种改法、推荐一种 |
| ③ 实现 | 它 | 大改动自动拆成几轮 |
| ④ 汇报就绪 | 它 | 自己跑语法检查和单测,全绿才说可以部署 |
| ⑤ 部署 + 验收 | 我点部署,它跑验收 | 验收结果是我唯一的放行依据 |
第一步的要求很反直觉:不要写需求文档。我给的是「首页要能一眼看出这个月花了多少」这种话,而不是一页 FR 清单。需求文档是给人看的,AI 需要的是意图。
第二步是整套方法的核心,也是铁律:
直接让它写,它会按想象重写;先分析再写,它改的才是真实存在的代码。
区别在于它必须先去读真实代码。写计划书是凭想象生成,读代码后的分析有事实约束。前者会给你一个漂亮但不存在于你项目里的方案。
五步里我只干两件事——点头和部署。但这两件事不能省。
二、任务不是一次性拆完的
一个常见误解:把任务拆完,然后照着做。那是瀑布,不是 AI 协作。
我这 8 天几乎一天换一个角度去审:需求 → 架构 → 验收体系 → PRD 字面核对 → 合规 → 成本 → 发布就绪 → 提审冲刺。
只在三处停顿说细节:
- 架构定形那天:什么新功能都没加,只是把目录重构、把前端四组接线接上,就暴露了 3 个隐藏的 P0——时区错月、加入后端必炸、余额公式符号反。
- PRD 字面核对那天:功能验收已经全绿了,我还是拿 PRD 的 26 条 FR 逐条对字面,又找出 6 处缺口。
- 成本那天:我本来打算砍功能省钱,量化之后发现方向完全错了(后面第九节展开)。
规律挺扎心:每个阶段换一个角度去看系统,都会发现上一阶段没发现的问题。单轮「全面验收」是幻觉,多轮换角度才是真的。
有人会问这样是不是很慢。反过来算:这些缺口如果留到上线后,每一处的修复成本都比当场发现高一个量级。8 天里 12 个真实缺陷全部在发布前暴露——这是收益,不是开销。
三、规划里最贵的三个决定
决定一:单云函数 × action 路由
不是「一个接口一个云函数」,而是一张路由表。好处是冷启动面最小、前端请求层只封装一次、鉴权与埋点收口在入口,新 action 只写业务。
代价是路由表会膨胀。但解法不是拆函数,而是按业务域拆文件 + 机器比对。
决定二:契约三处同步,是纪律不是选项
后端 index.js 路由表 == 前端 Action 联合类型 == 页面实际 call()
我们对出来的数字是:后端 40 / 前端 35 / 实际调用 35。前端是后端的真子集,任何越界调用编译期就炸。
这类会漂移的事实,人记不住,必须用脚本对账。
决定三:三条「不可协商」的约定
- 金额一律用**分(整数)**存储,前后端转换收敛到一个模块;
- 时区固定 +8,不用
Date.UTC——否则北京 9 月 1 日凌晨的账会被归到 8 月; - 净额公式全局唯一实现并抽成纯函数。
顺带补一个「最便宜的架构投资」:把云依赖改成函数内 lazy require,纯逻辑就能脱离云环境本地直跑。这一改,直接换来了第五节里第一层防线的可行性。
四、四个事故:全都发生在「就绪」之后
先给一句定调:这四个事故,全都发生在它汇报「就绪」之后。
事故一:搜索上线就坏
它写了个 db.command.regExp——这个 API 根本不存在。
真正让人后背发凉的不是笔误,是本地四道检查一道都没拦住:语法检查不管对象上有没有这个方法;模块加载不执行函数体;未定义标识符检查不认方法;而单测——把错误的 API 名写进了断言里,测试跟着错误一起通过了。
最后是用户点的那一下,帮我测出来的。
事故二:首页金额恒 ¥0.00
后端输出映射只保留 4 个字段,漏发 4 个金额字段;前端读到 undefined,兜底成 0,不报错。
教训:冒烟只断言了净额和状态,从不断言金额字段。字段漏发型的 bug,要测「契约全字段」才抓得到。
事故三:一条永不通过的断言
断言写的是:
status === 'OK' || 'SKIP'
而系统里只有 RUNNING / SUCCESS / ERROR。一条从不会红的断言,等于没有断言。
事故四:1122 变 1046
汇总脚本注释写着「兼容全角半角冒号」,实际写法在 macOS 的 sed 下全角占 3 个字节,字符类永远匹配不上。少掉的 78 项,正好来自两份全角输出的套件。
注释承诺了、代码没做到,比没有注释更危险——因为后来的人会相信它。
五、四层验收防线
这四个事故的共同点不是「代码写错一行」,而是**「没有任何东西能告诉我它错了」**。所以我做了四层:
| 层 | 规模 | 抓什么 | 备注 |
|---|---|---|---|
| ① 本地单测 | 3 个文件 / 46 条断言 | 纯逻辑方向错(均分尾差、余额公式、时区月界) | 秒级 |
| ② 离线门禁 | 27 套 / 1326 条断言 / 0 失败 | 契约、字段、统计口径 | 一条命令跑完 |
| ③ 云端真跑 | 7 套 / 176 条断言 | 真云环境、真数据库 | 事故一和事故二只有这一层能在上线前抓住 |
| ④ UI 自动化 | 4 套 | 真实交互链路 | 驱动真的微信开发者工具 |
两条纪律:
- 分层是为了用最便宜的一层拦住最贵的错误。本地单测秒级,云端跑一轮要真调云函数、真读写数据库,成本完全不同。
- 第 4 层不在离线门禁里。改任何被锚定的文件之后,必须单独跑对应的自检。一个测试的边界如果不说清楚,下一个人会以为它覆盖得更多。
六、怎么证明「绿灯」不是假的
绿灯能证明什么?什么都不能。它只能证明「这条断言这次没红」。
做法是在 27 套离线门禁里混进 5 套缺陷注入自检——它们不检查业务,而是故意往代码里注入一个已知 bug,然后跑前面那些断言。如果断言没红,说明这条断言是假的。
三种典型的「假绿」:
- 断言里写了系统里不存在的值 → 永远不通过,也永远不报错(事故三);
- 只测业务值不测契约全字段 → 字段漏发照样全绿(事故二);
- 统计口径本身漏了 → 1122 项只数到 1046 项,脚本还宣称「0 失败」(事故四)。
第三点值得单独记住:门禁的计数逻辑,本身也必须被门禁覆盖。
收益很实在:现在我可以让 AI 一天部署验证 3 次以上,还敢改核心的余额和分摊逻辑——因为改错了,会有人拦我。
七、UI 自动化:真实与边界
它的价值一句话:替代「人肉点 UI」。
踩过的坑:DOM 通道(page.$$、el.tap、el.text)在这个环境里会挂起,改成「页面方法直调」。好处是页面逻辑、setData、云函数、数据库全是真的;代价是 wxml 事件绑定那一层不被覆盖。我把这条限制写进了脚本头部注释。
环境坑清单(高成本低信息量,记下来一次省后面十次):
- 服务端口要手动开,且重启才生效;
- 运行要带
NODE_PATH; - 下拉刷新会被状态机吞掉首次请求;
- 长脚本 flaky,要用短脚本组合替代。
八、「部署成功」是需要被验证的主张
云开发的常规部署是右键「上传并部署」。问题不是麻烦,是它只告诉你「操作完成了」,不告诉你「线上真的换了」。
我遇到过不止一次:本地改了、部署了、提示成功,实际调的还是旧代码。
解法是在云函数里放一组只读探针,用 action 反推线上版本。问线上三个问题:
- 查一个不存在的文档,抛异常还是返回空?(区分新旧两版行为)
- 只读角色能写入吗?(应该不能)
- 这个 action 注册了吗、会不会报 1006?(判断整张路由表在不在)
「部署成功」是一个需要被验证的主张,不是一个事实。
还有个半截自动化值得记:命令行部署不会上传定时触发器,触发器得在图形界面里单独操作一次。这种做了一半的自动化,不写清楚就是下一任的坑。
九、成本:先量化,再动手
计费口径先对齐:云数据库按「返回文档数」计费,云函数按调用次数加资源使用量。
我原本以为免费额度的头号消耗是「功能多」。量化之后发现是三处无谓的全量读,加上前端没有缓存:
| 问题 | 放大方式 |
|---|---|
统计接口二次全库读,where 没有月份过滤 | 随账龄无限放大 |
| 月度聚合把整月明细拉到云函数内存里做 JS 聚合 | 随当月笔数线性涨 |
| 每次进页面都重拉,切 tab 再重拉一次 | 整体放大 2–4 倍 |
而「砍功能」能省多少?不到 5%——因为除首页外几乎都是低频主动操作。
真正的落地动作只有两个:删掉一次冗余全库读 + 前端 120 秒 TTL 缓存(写操作成功后自动全失效)。实测切 tab 的只读云函数调用,从 6 次 / 往返降到 1 次 / 往返,读量降约 83%。
方法论:降本先量化「钱花在哪」,再决定动架构还是动功能。多数时候直觉方向是错的。
顺带一提结构性的省钱:后端跑在微信云开发上,不用买服务器、不用配域名;登录纯静默,只用 wx.login 加 openid 映射,不调头像昵称接口——顺带把隐私声明那一整套链路也省掉了。
十、可以直接抄走的十条
- 先分析再动手——让它读完代码再给方案,别让它凭想象重写。
- 多轮换角度验收——单轮「全面验收」是幻觉。
- 契约三处同步用脚本对账——会漂移的事实,人记不住。
- 金额为分、时区固定 +8、净额公式唯一实现——三条不可协商。
- 断言要能被证明会红——混进缺陷注入自检。
- 冒烟要测契约全字段——不只测业务值,字段漏发才会暴露。
- 云端真跑不可替代——有些错只有真环境能抓。
- 测试边界写进注释——不说清楚,下一个人会误以为覆盖更多。
- 部署后反推线上版本——「部署成功」是主张,不是事实。
- 降本先量化——先算钱花在哪,再决定砍功能还是改架构。
最后:我的价值在哪
开头那个问题的答案,我到现在才说得清楚:
代码的生产成本归零之后,剩下的价值全在判断——它写得对不对,该不该上线,用户到底要什么。
AI 可以一夜写完 1.8 万行,然后告诉你「已完成」。
而你要问出下一个问题:你怎么知道?