去年七月我写下一篇评测,结论是:别让 AI 写完整功能。它能写,但你 review 的时间够自己写一遍了。
那之后我又写了四篇 AI 工具文章。五篇下来,每一篇都停在同一个地方:我写「它帮我做了什么」,但从不写「我用它完整做成了什么」。
不是没东西写。是我没舍得把一个完整项目交给 AI。
怕它搞砸,怕收拾的功夫比自己做还久,怕半路发现它理解错了需求,进退两难。
直到这个月,我把博客的一次迭代整个交给了它。
这次迭代是什么
Grove 是我的 Astro 博客,跑了两年,版本从 0.1 走到 1.7,一百多篇文章。这次做的是 v1.7.2,三件事:
第一,文章早就支持预排发布日期,但静态站只在构建时生成页面。到了发布时间,没人触发构建,文章就不会上线。当时有 4 篇文章排在 8 月发布,构建系统不管的话,它们到点不会出现。
第二,每天凌晨自动扫描一次文章状态,该上线的上线,把结果写进日志。
第三,顺手把分类从 10 个精简到 6 个,合并掉 7 篇文章的分类。
约束很明确:不引入后端,不换构建平台,所有改动都要落在 GitHub Actions 加 Cloudflare Pages 这条现有链路上。
预期结果写成一句话:未来日期的文章不生成页面、不进索引、不进 RSS;每天北京时间零点自动构建;分类合并干净。
这个需求在 todo 里躺了挺久。不是难,是碎。13 个页面要逐个接入,一个 workflow 要写,一个 bash 脚本要写,全是我不想动手的活。
这次我决定:全交给 AI,我只做拆解和 review。
需求拆解
第一步是把「到点自动上线」拆成可执行的子任务。我给了 AI 一句话,它还给我 9 条清单。
有两条是我没想到的:RSS 要过滤,搜索索引要过滤。我只想到了列表页和详情页。
清单我自己过了一遍,删掉两条不需要的,补上一条它不知道的约束:构建必须在北京时间零点之后跑,因为所有发布时间都写在东八区。
拆完之后我有个感受:AI 拆需求不是帮你思考,是帮你把漏掉的角度补上。前提是你自己得先想一遍,不然你连它漏了什么都不知道。
上下文管理
我提前把三样东西喂给 AI:项目结构说明、utils.ts 里现有工具函数的写法、内容集合的 schema。
还有一份我自己整理的约定清单:函数要短、注释用中文、日期一律带时区。这些是项目里已经存在的风格,我不说,AI 就会按它自己的习惯来。
13 个页面的文件路径我也列了进去,按目录分组。工具函数怎么写、schema 长什么样,它看一眼就能学会。真正要喂的是约定。
每个会话开头,我都重新贴一遍。麻烦,但值得。后面会讲为什么必须这样。
代码生成与 Review
AI 写的 filterPublished 只有 4 行:
// 过滤掉发布日期在未来的文章(构建时静态判断)
export function filterPublished(posts) {
const now = Date.now();
return posts.filter(post => post.data.pubDate.valueOf() <= now);
}这 4 行我一眼就接受了。风格和项目里其他工具函数一致,注释格式也对。这是 AI 最顺手的场景:小函数,约束清楚,照着现有代码写。
问题出在接入那一步。AI 第一次只改了 8 个页面,漏了 archive 页和两个动态路由页。我没骂它,因为我给的清单里就写着「接入所有列表页」——是我自己的需求模糊。
第二次我换了说法:「13 个页面,逐个列出文件名,改一个勾一个。」它全改完了,但我在 diff 里发现它把 tags 页改了两次,series 页没动。
Review 不是可选项。 这句话我一年前就写过,这次是第一次严格执行。
调试与修复
定时构建的 workflow 第一次跑就失败了,卡在脚本里。
AI 写的 scan-posts.sh 有 85 行,逻辑大体对,但有一个问题:它用 UTC 日期和文章的发布时间比较。文章写的是北京时间,两边差 8 个小时,凌晨构建会误判。
我追问了一句:「如果构建发生在北京时间 8 月 27 日 23,会发生什么?」
它自己算了一遍,承认错了,改成统一用 TZ=Asia/Shanghai 取时间。
这个坑我在需求拆解时其实踩过一遍——我补的那条约束就是「北京时间零点后构建」。但 AI 写脚本时忘了,我也忘了检查。上下文窗口不是无限的,AI 会遗忘。 这是这次迭代最贵的一课。
Review 环节
能跑之后,我又花了一晚上查隐患,查出两个。
第一个还是时区。filterPublished 里 Date.now() 是 UTC 时间,如果 frontmatter 里写的是 2026-08-28 这种裸日期,JS 会把它当成 UTC 零点解析,换算成北京时间是当天早上 8 点。也就是说,定时构建凌晨 0 点跑的时候,这篇文章还「没到期」,要晚一天才上线。
修复方式:所有 frontmatter 的 pubDate 统一写成带时区后缀 +08:00,构建脚本里也按同一时区判断。
第二个隐患在脚本里。它用字符串比较日期:[[ "$PUBDATE" > "$TODAY" ]]。这个写法只有在格式永远统一时才安全,哪天少个前导零,判断就错了。我给 AI 加了一条硬规则:脚本里所有日期必须用 date +"%Y-%m-%d" 输出,不许手写。
另外 review 时还发现 workflow 有个细节:定时任务在日志没有变化时不会产生 commit,Cloudflare Pages 就不会重建,文章还是上不了线。我让 AI 给 commit 加了 --allow-empty,保证每天都会触发一次构建。
三条约定,全部写进了项目说明文件。AI 下次不会再犯,我下次也不会忘。
结果与反思
时间账
整个迭代,从拆需求到上线,六个小时,分三个晚上。
AI 生成代码的时间大概占一个半小时,剩下四个半小时是我在拆需求、喂上下文、review、排查时区。
对照手动做的估算:13 个页面接入约两小时,workflow 加 bash 脚本约四小时(我最不熟的部分),分类合并约四十分钟,加起来七个多小时。实际省了两三成的量,不算多。
但账不能只算时间。分类合并 7 篇文章这种活,AI 十分钟干完,我 review 一眼就过。13 页接入这种活,换作手动我会拖到周末,AI 做完当晚就上线了。它把「不想动手」变成了「顺手就做」,这个价值比省几个小时大得多。
多出来的麻烦也有:review 清单变长了,AI 每次会话开始都会「失忆」,我得重复贴约定。这些麻烦真实存在,但可控。
AI 最擅长什么
机械接入和第一版骨架。13 个页面的重复改造、85 行 bash 脚本的初稿、7 篇文章的批量分类替换。这类活它又快又稳,人做反而容易手滑。
AI 最不擅长什么
隐含约定。时区、命名规范、构建链路的顺序、哪些页面「必须」接入。这些不在代码里的约束,它看不见,看见了也会忘。
一个真实教训
跨会话的 AI 会遗忘。第二个会话开始五分钟,它就把第一个会话里定的「日期统一带时区」忘了,生成的代码又用裸日期。我贴回约定,它说「明白」,第三个会话又忘一次。
不是它笨。是它每次都是新的。这件事逼出我一个习惯:任何约定,写进文件,不写进对话。写进对话的约定不算约定。
从评测到落地
五篇评测文章告诉我的是:工具能做什么。
这次迭代告诉我的是另一件事:让 AI 参与一个完整项目,难点不在技术,在于你舍不舍得把过程交给它。
评测是旁观,落地是共事。把项目拆清楚,把约定写下来,把 review 当工序,它不只是「写代码的工具」,还是「项目参与者」。
去年我说别让它写完整功能。这句话到今天依然成立。更准确的说法是:别让它一个人写完整功能。全程参与、每段有人把关,性质完全不同。
我花了两年才真正做到。