AI 写代码的边界:哪些它能做,哪些你必须自己来
起因
自从用 AI 辅助做了发型 App 和企业知识库项目之后,有好几个人问我同一个问题:"AI 写代码到底靠不靠谱?哪些场景能用,哪些不能用?"
这个问题很难一两句话说清楚。因为"靠不靠谱"取决于你让它干什么。
这篇文章我想结合自己这几个月的真实经验,把 AI 辅助编程的边界画清楚——不是那种"AI 很好但也不能完全依赖"的废话,而是具体到"这件事交给 AI 行不行"的判断标准。
先说结论:AI 不是"能不能写代码"的问题,是"写什么层次的代码"的问题
AI 写代码的能力,按我这几个月的体验,可以分成三个层次:
第一层:模板代码和脚手架 —— AI 写得又快又好,几乎不需要改 第二层:有业务逻辑的业务代码 —— AI 能写框架,但细节需要你填 第三层:架构设计和关键决策 —— AI 写不了,只能你来做
下面一个个说,每个层次都拿真实项目里的代码举例。
第一层:模板代码,AI 闭着眼睛写都行
什么叫模板代码?就是那些有固定模式、不需要业务判断、换个项目也差不多的代码。
具体例子
1. React 组件的骨架
export function LivePreview() {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const hairId = searchParams.get('hair');
const videoRef = useRef<HTMLVideoElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
const [isLoading, setIsLoading] = useState(true);
const [selectedHair, setSelectedHair] = useState<Hairstyle | null>(null);
// ...
}
这种代码 AI 生成出来基本可以直接用。因为 useRef、useState、useNavigate 的用法是固定的,AI 训练数据里有成千上万个这样的例子,生成的质量很高。
2. 权限服务封装
initializePermissions() {
return Camera.requestPermissions({
permissions: ['camera', 'photos'],
});
}
这种代码的特征是:调用一个已知的 API,包装成方法,返回结果。AI 对这类代码的准确率接近 100%。
3. 配置文件
capacitor.config.ts、tailwind.config.js、postcss.config.js——这些文件 AI 写得比人还快,因为配置项是标准化的,AI 只需要根据你描述的需求填对参数。
判断标准
如果你要写的代码符合以下特征,放心交给 AI:
- 你在别的项目里写过类似的
- 用的是标准 API(React hooks、Capacitor 插件、浏览器 API 等)
- 不涉及你的业务逻辑(没有"如果用户年龄大于 X 则 Y"这种判断)
- 写错了也不会导致严重问题(顶多编译报错)
这类代码我基本不动手了,告诉 AI 需求,它生成,我扫一眼,直接提交。
第二层:业务代码,AI 能写骨架,肉得你自己填
业务代码的特征是:有具体的业务规则、需要根据实际数据调整、写错了用户会感受到问题。
例子 1:发型锚点计算
这是我做发型 App 时踩的最深的一个坑。
AI 帮我写了人脸检测的完整代码框架,包括 MediaPipe 初始化、摄像头循环、关键点提取。但在"发型图片应该放在脸的哪个位置"这个核心问题上,AI 给的计算逻辑是:
// AI 最初生成的代码
const anchorY = (forehead.y + noseTip.y) / 2;
逻辑上看没问题——取额头和鼻子的中点。但跑出来一看,发型图片直接压到了鼻子以下。
原因很简单但 AI 想不出来:发型是长在头上的,锚点应该在额头以上,而不是额头和鼻子之间。
最后是我自己试出来的方案:
// 实际能用的方案
const hairAnchorY = forehead.y - height * 0.35;
这个 0.35 是怎么来的?不是算出来的,是我盯着手机屏幕,从 0.15 调到 0.2、0.25、0.3、0.35,一个个试出来的。AI 给不了这个值,因为它没见过实际效果。
例子 2:向量维度对齐
在做企业知识库项目时,要同时支持 OpenAI(1536 维)和百度千帆(1024 维)的 embedding 模型。AI 帮我写了向量存储和检索的完整代码,但入库的时候报错了——数据库字段是 PGvector(1536),1024 维的向量塞不进去。
AI 给的第一个方案是"把数据库字段改成动态维度",但 PostgreSQL 的 PGvector 插件不支持动态维度,这个方案直接走不通。
最后是我自己写了一个 VectorResizer,把 1024 维的向量补零到 1536 维:
public static float[] resizeVector(float[] originalVector, int targetSize) {
float[] resizedVector = new float[targetSize];
System.arraycopy(originalVector, 0, resizedVector, 0,
Math.min(originalVector.length, targetSize));
Arrays.fill(resizedVector, originalVector.length, targetSize, 0);
return resizedVector;
}
这段代码本身不复杂,但**"需要用补零来对齐维度"这个决策,是 AI 没想到的**。它给出的方案都是教科书式的(改数据库结构、统一模型),不考虑实际环境的约束。
判断标准
如果你要写的代码符合以下特征,AI 能帮你写骨架,但你需要把关细节:
- 涉及具体的业务规则("年龄小于 21 岁的用户不发回复")
- 需要根据实际运行效果调参(锚点偏移量、重试延迟、chunk 大小)
- 写错了用户能感知到(页面白屏、图片位置不对、搜索结果不准)
- 依赖你团队特有的环境约束(国内网络环境、特定数据库版本)
这类代码我的做法是:让 AI 先写一版,然后我逐行看,找出所有需要调整的地方,告诉它改,改完再自己跑一遍验证。
第三层:架构和关键决策,AI 写不了
这是最关键的边界。架构决策不是"代码怎么写"的问题,是"整个系统怎么组织"的问题。
例子:规则引擎 + LLM 的架构选择
在做 aics 智能客服项目时,团队面临一个选择:对话流程是用 Agent 框架让 AI 自主决策,还是用规则引擎精确控制每一步?
当时市面上流行的做法是 LangChain / AutoGPT,让 AI 自主决定下一步做什么。但我们最终选了规则引擎 + 可插拔 Handler 的老派架构。
原因有几个:
- 客服场景里某些步骤的顺序是业务强制的,AI 自主决策会带来不可预期的行为
- 每轮对话都调 LLM 很贵,固定回复不需要 AI 参与
- 出问题时需要能精确定位到哪条规则出了问题
这个决策 AI 做不了。 如果你问 AI"客服对话系统用什么架构",它大概率会给你列出 LangChain、AutoGPT、Rasa 等一堆框架的对比,但不会告诉你"在你的具体场景下,老派的规则引擎反而更合适"。
因为它不了解你的业务约束:你需要精确控制对话流程、你有成本考量、你的团队需要对系统有完全的可观测性。
另一个例子:Canvas 渲染循环的生命周期管理
发型 App 里有一个 Canvas 渲染循环,负责把发型图片画到视频帧上。AI 帮我写了完整的渲染逻辑:
const detectFrame = () => {
if (!this.faceLandmarker || !videoElement.videoWidth) {
this.animationFrameId = requestAnimationFrame(detectFrame);
return;
}
// ... 渲染逻辑
this.animationFrameId = requestAnimationFrame(detectFrame);
};
this.animationFrameId = requestAnimationFrame(detectFrame);
代码本身没问题。但我后来发现一个严重问题:用户从页面返回后,摄像头关了,但 requestAnimationFrame 的循环还在跑,一直往已经销毁的 Canvas 上画东西,内存泄漏。
问题的根因是:AI 写的 detectFrame 函数只管"继续下一帧",不管"什么时候应该停"。停止的逻辑需要在你自己的代码里处理——调用 cancelAnimationFrame(this.animationFrameId)。
这个生命周期管理的问题,AI 不会主动想到,因为它不知道你的页面什么时候会销毁、摄像头什么时候会关。这需要你对整个组件的生命周期有清晰的理解。
判断标准
以下这些场景,AI 给不了靠谱的答案,必须你自己来:
- 系统架构:整个项目怎么分层、模块之间怎么通信、数据流怎么走
- 技术选型:用 A 框架还是 B 框架,这不是看文档能决定的,要看你的团队能力、项目周期、运维成本
- 边界场景处理:用户拒绝权限后怎么办、低端设备性能不足怎么降级、网络断了怎么恢复
- 生命周期管理:资源什么时候创建、什么时候释放、异常路径怎么清理
一个经常被忽视的问题:AI 写得越快,改起来越慢
这个体验很反直觉,但真实存在。
AI 生成一段 50 行的 Canvas 渲染代码,只要 3 秒。但这段代码出了问题(比如上面的 animationFrameId 泄漏),排查起来可能要半小时。
为什么?因为你得先读懂这 50 行代码在干什么,搞清楚它是按什么逻辑组织的,然后才能定位到问题在哪。如果是你自己写的 50 行代码,你可能 5 分钟就找到了。
"读代码"的时间成本,经常被低估。 AI 帮你省了"写"的时间,但没省"读"的时间,甚至因为你没有从头写过,读起来更费劲。
所以我的经验是:AI 写完的代码,每一段都要自己过一遍,搞清楚它在干什么。 这不是浪费时间,是在给未来省时间。否则出了问题你查半天查不到,才是真的浪费时间。
一张表总结
| 代码层次 | AI 能不能做 | 你需要做什么 |
|---|---|---|
| 模板代码(脚手架、组件骨架、配置) | 能,质量很高 | 扫一眼,直接提交 |
| 标准 API 调用(权限、网络、DOM 操作) | 能,基本不需要改 | 确认 API 版本匹配 |
| 业务逻辑(规则判断、数据处理) | 能写框架,细节需要你填 | 逐行看,调参,跑测试验证 |
| 架构设计(系统分层、技术选型) | 不能,给出的都是泛泛的对比 | 你自己决策,AI 可以当搜索工具 |
| 边界场景(异常处理、降级、生命周期) | 不能主动想到 | 你主动问它,或者自己写 |
最后说点实在的
AI 辅助编程不是"能不能用"的问题,是"用在什么地方、怎么用"的问题。
用它写模板代码,你的一天能从写 100 行变成写 500 行。但如果你让它做架构决策,你的一天可能花在跟它反复解释"不是这个意思,我说的是另一种情况"上。
AI 让"从 0 到 1"变快了,但"从 1 到 1.1"——小修小改、测试验证、排查 bug——花的时间一点没少。 甚至因为你没有从头写过,改起来更慢。
所以核心就一条:让 AI 干它擅长的活(模板、脚手架、标准 API),你自己守住关键决策和边界场景。剩下的,跑测试、看效果、改 bug,这些活谁也替不了你。
tangyuewei,从后端出发,用 AI 拓展到全栈的工程师。