AI 写代码总跑偏?我逼它回到“函数级颗粒度”

一、AI 编码的真相:它是个"跑偏大师"

我用 AI 写代码快一年了,发现一个残酷的事实:

AI 在"写 Demo"上无敌,在"写能用的系统"上拉胯。

你让它"写一个智能家居控制页面",它能 30 秒给你一个漂亮的 Vue 组件。你让它"把这个模块对接你的三层缓存架构",它就开始跑偏了------变量命名乱飞、边界条件漏掉、错误处理全靠 console.log。

更致命的是,AI 总是想"多写一点"。你让它写 tap 函数,它顺手把 swipe、longPress、drag 全写了。看起来省事,但当你发现 tap 的坐标校验有问题时,你已经不忍心删掉它写的另外 200 行代码了。

AI 的创造力,在 Demo 阶段是优势,在系统构建阶段是灾难。

二、我的反制策略:复古到"函数级颗粒度"

在被 AI 气到无数次之后,我选择了一个"复古"的策略:

不再让 AI 写模块,只让它写函数。

一个模块一个模块地生成 → 跑偏率 60%。

一个文件一个文件地生成 → 跑偏率 30%。
一个函数一个函数地生成 → 跑偏率降到 5% 以下。

为什么?

因为"写一个函数"对 AI 来说,是没有歧义的确定性任务。

任务 AI 的理解 跑偏概率
帮我写一个设备管理模块 模糊,需要 AI 自己设计边界 极高
帮我写 device.ts,包含注册和发现 较清晰,但内部结构仍需 AI 决定 中等
帮我写 registerDevice(id, driver, config) 函数,要求返回 Device 对象 完全确定,AI 只需要翻译签名 极低

函数是 AI 编码的"最小确定性单元"。

三、我的 Spec 怎么写:先写验收标准,再写函数签名

我现在写 Spec,不再是"功能描述",而是"函数清单"。

每个函数在 Spec 里长这样:

markdown

复制代码
## 函数:registerDevice

### 签名
registerDevice(id: string, driver: Driver, config: DeviceConfig): Device

### 职责
向设备注册表添加一个新设备,返回注册后的 Device 对象。

### 边界条件
- id 为空 → 抛出 `InvalidDeviceIdError`
- id 已存在 → 抛出 `DeviceAlreadyExistsError`
- driver 未初始化 → 抛出 `DriverNotReadyError`

### 验收标准(测试用例)
1. 正常注册 → 返回 Device 对象,`device.id` 等于传入 id
2. id 为空 → 抛出指定错误
3. id 重复 → 抛出指定错误
4. driver 未连接 → 抛出指定错误

这不是文档,这是合同。

AI 生成代码后,我只需要跑四个测试用例。全过了,验收通过。有一个没过,AI 重写。

我把这叫做 "验收驱动开发"------不是先写代码再补测试,而是先定义验收标准,再让 AI 写代码。

四、文件预估行数:强制单一职责的紧箍咒

在我的 Spec 里,每个文件都标注了预估行数:~150行、~200行、~250行。

这不是炫技,是给 AI 套上的紧箍咒。

当你告诉 AI "写一个 device.ts",它可能给你生成 800 行,从注册到发现到状态同步全塞进去。

当你告诉 AI "写 device/registry.ts,约 200 行,只负责设备注册",它就被限制住了。

行数限制是强制单一职责的手段。

我的 Spec 里有这样的目录结构:

text

复制代码
device/
├── index.ts           # 导出入口(~50行)
├── types.ts           # 类型定义(~150行)
├── registry.ts        # 设备注册(~200行)
├── discovery.ts       # 设备发现(~250行)
├── state-manager.ts   # 状态管理(~250行)
└── ttl-manager.ts     # TTL 管理(~200行)

每个文件只做一件事。一个文件超了 300 行,立刻拆。

AI 在"小文件"里跑偏的概率,远低于"大文件"。

五、核心原则验收表格:AI 无法绕过的护栏

我把项目的核心原则,全部变成了验收表格:

原则 说明 验收标准
三层意图缓存 L1→L2→L3 逐层降级 L1 < 10ms, L2 < 100ms, L3 < 3s
本地优先 SQLite 存储,断网可用 无外部数据库依赖
一切皆 CLI 每个能力是独立命令行工具 可单独测试、可管道组合
文件细颗粒度 每个文件 300 行左右 单一职责,高内聚低耦合

这张表的作用是:任何 AI 生成的代码,都必须能通过这张表的验收。

不符合"文件细颗粒度"?拆。不符合"一切皆 CLI"?重写。

验收标准不是注释,是测试用例。Spec 不是文档,是合同。

六、组装:从函数到系统的逆向工程

函数级颗粒度有一个"副作用":你需要自己组装。

但这不是负担,是控制权。

AI 写好了 50 个纯函数,每个都有独立的测试用例。你要做的,是用这些函数拼出你的系统。

registerDevice + discoverDevices + getDeviceState → 设备管理模块。
matchRule + searchExperience + reactLoop → 三层意图引擎。

组装的过程,就是你理解系统的过程。

以前 AI 帮你写了整个模块,你根本不知道里面有什么。现在 AI 只写了函数,你亲自把它们拼起来,每一行代码的来龙去脉你都知道。

七、这套方法的收益

我用这套方法重构了 HomeSense 的 graph.ts------从 1400 行拆成 8 个文件,每个文件 150-250 行。

指标 重构前 重构后
总行数 1400 1100(拆开后更清晰)
单文件最大行数 1400 250
测试覆盖率 未知 80%+
AI 跑偏率 高(每次都要修) 低(基本直接可用)

省下的不是 Token,是"修 AI 代码"的心力。

八、写在最后

AI 时代的开发,最大的陷阱是"快"。

AI 能在 30 秒生成一个模块,但你花 3 小时修它的 bug。

我的方法是"复古":回到函数级颗粒度,先写验收标准,再让 AI 生成代码,最后自己组装。

慢了,但稳了。

Demo 可以快,系统必须稳。

如果你想用 AI 写出"能用的系统",而不是"炫技的 Demo",试试这套方法:

  1. 先写 Spec,颗粒度到函数

  2. 每个函数配验收标准

  3. 文件预估行数,强制单一职责

  4. 核心原则表格化,逐条验收

  5. 自己组装,掌控每一行代码

AI 是你的"函数工人",你才是"系统建筑师"。

相关推荐
九卷8 小时前
企业级Agent系统整体技术架构介绍
ai·架构·大模型·llm·agent·智能体
Csvn9 小时前
提示词即代码:有版本、能评审、可回滚(R01)
人工智能·aigc·agent
浮生望10 小时前
Agentic RAG(下):ES + Milvus 多路召回,再用 Rerank 去噪
llm·agent
杨杨杨大侠10 小时前
从一次请求讲透 A2A:Agent 怎么选、怎么协作、记忆放在哪里
人工智能·agent
后端小肥肠10 小时前
做公众号漫画还在纯手搓?这套工具从选题到复刻任意热门漫画一键搞定
人工智能·aigc·agent
俊哥V11 小时前
每日 AI 研究简报 · 2026-10-12
人工智能·ai
阿里云云原生11 小时前
让 Agent 学会判断:从 JEV 接入到完整 Harness 决策流程
agent
阿里云云原生12 小时前
阿里云 AgentCore 产品负责人解读产品全景
云原生·agent
10年前端老司机12 小时前
我用 Vue3 + LangGraph 做了个心理咨询 AI,踩了 9 个坑后总结出来的实战经验
前端·langchain·agent
空堂与归13 小时前
REA登顶GitHub:AI如何逆向一切软件
ai·大模型·agent