把我的日常开发流程改造成 AI 友好
AI 好不好用,一半取决于项目怎么改造。这篇写我怎么整理目录、维护上下文文件、脚本化重复劳动、模板化提示词,以及需要人工把关的三类产出。
用 AI 写代码这件事上,我踩过的最大的坑是:一直在换工具,从来没改项目。
有一段时间我的流程是——装个新工具,改两个文件,觉得不够聪明,卸载,换下一个。后来我发现:同一个模型,在我那个「文件全堆在 src/ 下、没有测试、风格两掺」的仓库里,和一个结构清晰、有类型检查的仓库里,表现差得非常远。
这不是模型的问题,是环境的问题。这篇写我怎么改造项目和流程。这是我投入产出比最高的一项改造,而且它不随模型换代而失效。
一、先让项目「可被理解」
AI 理解项目的入口,基本就是目录结构、文件名和周边代码。所以先让这三样能传达信息:
# 有问题:职责靠猜
src/
utils.ts # 两千行,什么都有
utils2.ts # 上面那个的补充
# 好一些:职责写在路径里
src/
order/
order.service.ts # 业务编排
order.repo.ts # 数据访问
order.types.ts # 领域类型
前者要求 AI 通读一遍才知道东西在哪,后者可以直接定位。目录结构就是你写给 AI 的第一份文档,只是很多人没意识到自己在写。
第二件事是让项目能一句话说清楚。我的 README 开头固定三行:这是什么、怎么跑起来、用什么命令跑测试。这三行对人有用,对 AI 更有用——它决定了对方能不能自己验证改动。
第三件事是统一代码风格,这一点最容易被低估。AI 会主动模仿它周围的代码。 如果项目里两种错误处理方式各占一半,它新增的代码就会随机选一种,甚至在同一次改动里两种都用。风格混乱不会让它变笨,但会被它原样放大。格式化工具和 lint 规则不是洁癖,是给 AI 的输入做归一化。
最后一件事更重要:类型检查和测试是 AI 的眼睛。 在没有测试的项目里,它改错了自己也不知道,只能等你 review;有类型检查时,它跑一次命令就能看到报错,然后自己改。这个差别不是「快一点」,是「能不能形成闭环」。
二、在仓库里维护一份给 AI 看的上下文文件
我在仓库根目录放一份约定文件(常见叫法有 AGENTS.md、CLAUDE.md 等,具体以各家官方说明为准),内容是约束,不是知识库。
写什么:项目一句话定位与技术栈;常用命令(安装、测试、类型检查、格式化);目录职责地图;代码约定(命名、错误处理、日志);明确的禁区;以及历史上踩过、看起来反直觉的坑。
不写什么:会频繁变化的细节(版本号、接口字段),让它去读代码;README 的复制品;大段业务背景;以及「请写出高质量代码」这类没有可执行含义的话。
# AGENTS.md(示例)
## 项目
Node.js + TypeScript 后端服务,处理订单业务。
## 命令
- 类型检查:pnpm typecheck
- 测试:pnpm test(改动完成前必须全绿)
- 格式化:pnpm format
## 目录
- src/order/:订单领域逻辑,改动前先读 order.types.ts
- src/legacy/:历史代码,**不要改动**
## 约定
- 不使用默认导出
- 错误统一抛 AppError,不要抛裸字符串
- 时间一律用 UTC,只在展示层做时区转换
- 新增依赖前必须先问我
## 已知的坑
- order.repo.ts 的 status 字段历史值是字符串,改造需保持兼容
- 测试文件名与用例名不要改,CI 里有依赖
这份文件我改过很多版,最有用的其实是最后两节。「不要动 src/legacy/」这种一条禁令,能省掉一整轮返工。
三、把重复劳动脚本化,让 AI 能一键验证
这是我认为收益最大、但最少人做的改造。
原因是:AI 的自纠错能力取决于它能否方便地拿到反馈。如果验证一次要先猜测试命令、再从一堆无关输出里找结论,它就会倾向于「跳过验证,直接说改好了」。
所以我做了一件事:把验证收敛成固定名字的脚本。
{
"scripts": {
"typecheck": "tsc --noEmit",
"lint": "eslint . --max-warnings 0",
"test": "vitest run",
"verify": "pnpm typecheck && pnpm lint && pnpm test"
}
}
verify 是专门为 AI 准备的:一条命令、非零退出码即失败、输出集中。 我在约定文件里写明「改动完成前跑 pnpm verify」,它就会自己跑、自己看报错、自己修。这个循环一旦成立,同一个任务上我要介入的次数会明显下降。
反过来,如果项目里没有可自动执行的验证手段,AI 的产出就只能是「看起来对」,你只能逐行读代码兜底。这种情况下 AI 的真实提效是负的——读别人的代码比写自己的慢。
四、把常用提示词模板化
我以前每次都要重新组织措辞,后来固化成文件放在仓库里。好处有三个:不用重复组织语言、模板能随踩坑迭代、换工具时可以直接搬过去。
# .ai/prompts/review.md —— 代码审查
审查当前分支相对 main 的改动,按严重程度分级:
[阻断] 正确性、安全问题、破坏对外契约的改动
[建议] 可读性、命名、重复代码
[提问] 我可能有意为之,但需要我确认的地方
每条给出文件、问题、为什么是问题、建议怎么改。
不确定的地方标为 [提问],不要直接下判断。
# .ai/prompts/test.md —— 补测试
为 <目标模块> 补充测试:
1. 优先覆盖边界与异常路径,不要只写 happy path。
2. 用例名说明它验证的行为,不要叫 test1 / test2。
3. 不修改任何已有断言;发现断言有问题,单独列出来告诉我。
# .ai/prompts/commit.md —— 生成提交信息
根据暂存区改动生成提交信息:
- 首行不超过 50 字,动词开头,说明做了什么
- 正文分点说明「为什么这么改」,不要复述改了什么
第二个模板里的第 3 条是我在一次翻车之后加的:它为了让测试通过而放宽了断言。模板的价值不在于让 AI 变聪明,而在于把踩过的坑固化成一条不会再忘的约束。
五、必须人工把关的三类产出
我基本信任 AI 写的业务逻辑初稿,但有三类产出,无论看起来多合理,我都会逐行看:
- 安全相关:鉴权判断、密钥处理、拼接的 SQL、文件路径、加解密。这类代码「看起来对」的比例极高,问题藏在边界条件里——越权、注入、路径穿越,不专门看发现不了。
- 数据迁移:不可逆、影响面大。我会要求它额外说明三件事:能不能重复执行、怎么回滚、怎么对账。它默认写的脚本经常缺其中两点。
- 对外接口变更:字段增删、类型变化、错误码语义调整,一改就可能打到所有调用方。这类改动我会自己对照契约逐条确认,而不是看它的总结。
我的做法不是「不让它碰」,而是让它写初稿和检查清单,签字的人是我。这三类任务上,它省掉的是查资料和写样板的时间,不是判断的时间。
六、一个诚实的结论
改造完之后,我的真实感受是:AI 提升的是「从想法到初稿」的速度,初稿之后的质量仍然取决于我的判断力。
它没有让我少读代码,只是把「从零写」变成「读并修改」;它对不确定的地方依然会自信地编,依然要我用验证手段兜底。如果对代码质量的判断力不够,AI 只会让你更快地写出更多你判断不了的东西。
但我还是认为值得做,因为它可累积:模型会换代,工具会过时,而目录结构、verify 脚本、约定文件、提示词模板都还在,换任何工具都能接着用。模型是会过期的资产,流程不是。
改造清单
| 改什么 | 为什么 | 收益 |
|---|---|---|
| 目录按职责分层 | AI 靠路径定位,不靠通读 | 减少无谓的全文搜索 |
README 写清三行 | 决定它能否自己跑起来验证 | 减少来回确认的往返 |
| 统一格式化与 lint | AI 会模仿周边代码,混乱会被放大 | 新代码风格一致,评审更省力 |
| 补充类型与测试 | 这是 AI 的反馈来源 | 从「看起来对」变成「能自证对」 |
固定 verify 脚本 | 一条命令拿到明确反馈 | 自纠错闭环成立 |
维护 AGENTS.md | 把约定从对话搬进仓库 | 新会话不必重新解释背景 |
| 模板化常用提示词 | 措辞固定、可持续迭代 | 踩过的坑不再犯 |
本文由 Kyne 撰写,采用 CC BY-NC-SA 4.0 许可,转载请注明出处。