聊聊我这一年靠AI写代码踩过的坑和悟出的道
上周五晚上十一点半,我盯着屏幕上 Augment Code 给我生成的一段 React 性能优化代码,突然有点恍惚。
三个月前,我还在为怎么把公司那个祖传的后台管理系统首屏加载时间从 8 秒压到 3 秒以内而焦头烂额。那时候每天下班回到租的小单间,脑子里全是 webpack 的 chunk 拆分策略、路由懒加载的各种奇葩边界 case,还有产品经理那句轻飘飘的"这个需求很简单的,加个按钮就行"。
现在呢?我靠在椅子上,看着 Augment Code 帮我把整个优化方案从分析到代码一步到位地搞定,心里五味杂陈。
先说下我是谁
坐标上海,在一家做 B 端 SaaS 的公司写前端,租的房子离公司骑电动车十分钟,图的就是加班晚了能赶紧滚回去躺着。平时最大的爱好就是参加各种技术分享会,什么掘金的城市聚会、GDG 的 meetup,只要在上海举办的,我基本都会去蹭一蹭。不是为了社交,就是喜欢听别人踩坑的故事,比自己踩坑爽多了——当然,自己踩完坑再讲给别人听更爽。
说回正题。
一切从一场尴尬的面试开始
去年十月份的时候,有个朋友内推我去某大厂面试。我心想自己好歹也写了五六年代码了,性能优化这块也算有点心得,应该问题不大。
结果面试官上来就问了个生成式 AI 相关的问题:
"你平时用 AI 辅助编程吗?怎么评价现在的 AI 编程工具?"
我当时就愣住了。说实话,那时候 Cursor 我刚装上一周,连快捷键都没记全,用的时候磕磕绊绊的,经常生成出来的代码驴唇不对马嘴。我只能硬着头皮说"用过一些,感觉还在早期阶段"。
面试官笑了笑,又问了几个关于 AI 代码生成质量评估的问题,我答得稀烂。
挂了面试之后,我躺在床上翻来覆去睡不着。不是因为面试挂了——好吧,也有一点——主要是觉得,作为一个天天参加技术分享会、自诩紧跟技术潮流的人,居然在 AI 编程这个方向上这么拉胯,说出去都丢人。
于是第二天我就开始认真折腾 AI 编程工具了。
从 Cursor 到 Augment Code,我的 AI 编程进化史
最开始用的是 Cursor,确实惊艳。Cmd+K 直接生成代码,Tab 补全,体验比 VS Code 原生的 IntelliSense 强了不止一个档次。但是用了一段时间之后,我发现几个问题:
- 上下文理解不够深:Cursor 对我整个项目的理解还是停留在文件级别,跨文件的复杂逻辑它经常搞不明白
- 生成式 AI 的通病:有时候会一本正经地胡说八道,给你生成一段看起来非常合理但实际上根本跑不起来的代码
- 大型项目力不从心:我们那个后台系统,光组件就几百个,Cursor 处理起来明显有点吃力
后来在今年二月份的时候,团队里有个哥们推荐了 Augment Code。说实话,一开始我是抱着"再试一个呗,反正也不费事"的心态装的。
结果这一用,就离不开了。
Augment Code 到底改变了什么
先说几个让我觉得"卧槽这也行"的场景。
场景一:跨文件的复杂重构
上个月,产品说要改权限系统的底层逻辑。原来的权限是写死在路由配置里的,现在要改成动态权限,从后端接口获取。这涉及到路由配置、权限校验中间件、侧边栏渲染、面包屑导航等十几个文件的联动修改。
以前这种活儿,我起码得花两三天,还得小心翼翼地改,生怕漏了哪个地方。
这次我直接在 Augment Code 里描述了需求,它居然真的把十几个文件需要改动的地方全给我列出来了,而且每个文件的改动逻辑都是对的。我花了半天时间 review 它的改动,微调了一些细节,就完事了。
// Augment Code 生成的权限校验中间件
// 它居然自动参考了我们的路由配置文件和后端接口文档
import { PermissionService } from '@/services/permission';
import { RouteConfig } from '@/router/types';
export async function checkPermission(
route: RouteConfig,
userId: string
): Promise<boolean> {
const userPermissions = await PermissionService.getUserPermissions(userId);
// 动态权限校验,支持多层级权限继承
const requiredPermission = route.meta?.permission;
if (!requiredPermission) return true;
return userPermissions.some(p =>
p.code === requiredPermission && p.status === 'active'
);
}
看到这段代码的时候,我真的在工位上"卧槽"了一声,旁边同事以为我出什么 bug 了。
场景二:性能优化的智能分析
这就是我开头说的那个场景。我们那个后台系统的首屏加载问题,之前我自己分析了一周,搞了个优化方案,但效果不理想。
Augment Code 帮我做了一次全面的性能分析,它不只是告诉你"这里可以懒加载"、"那里可以代码分割"这种泛泛的建议,而是结合我们项目的实际情况,给出具体的优化路径:
| 优化项 | 优化前 | 优化后 | 耗时 |
|---|---|---|---|
| 首屏加载时间 | 8.2s | 2.1s | - |
| 主 bundle 体积 | 2.3MB | 487KB | - |
| 路由切换耗时 | 1.8s | 0.3s | - |
| 内存占用(初始) | 156MB | 89MB | - |
它帮我识别出了几个我完全没注意到的性能杀手:
- 一个全局的日期处理库,在初始化时就加载了所有语言包,而我们只用中文
- 某个图表组件在挂载时会同步渲染大量 DOM,阻塞主线程
- 一个看似不起眼的工具函数,每次调用都会重新创建一个巨大的正则表达式
// 被 Augment Code 揪出来的性能杀手之一
// 每次调用都重新编译正则,在列表渲染时会被调用上千次
// ❌ 优化前
function validateInput(value: string): boolean {
const pattern = new RegExp('^[a-zA-Z0-9_\\-]{1,50}$');
return pattern.test(value);
}
// ✅ 优化后
const INPUT_PATTERN = /^[a-zA-Z0-9_\-]{1,50}$/;
function validateInput(value: string): boolean {
return INPUT_PATTERN.test(value);
}
这种问题,说实话,靠人眼 review 真的很难发现。代码逻辑没毛病,功能也正常,就是在高并发场景下会拖慢性能。
场景三:帮我准备面试题
对,你没看错。我现在用 Augment Code 来准备面试题。
自从上次面试挂了之后,我就开始认真准备跳槽了(别骂我,程序员不跳槽怎么涨薪)。但是准备面试题这事儿太痛苦了,刷 LeetCode 刷到怀疑人生,八股文背了忘忘了背。
后来我换了个思路,让 Augment Code 根据我的项目经验来生成面试题。比如我跟它说:"我最近做了一个基于 WebSocket 的实时协作编辑器,帮我生成一些相关的面试题和参考答案。"
它不仅生成了常规的题目,还问了一些非常有深度的问题:
"在实时协作编辑器中,如果两个用户同时修改同一段文本,你的冲突解决策略是什么?CRDT 和 OT 算法各有什么优缺点?在你的场景下为什么选择了其中一种?"
这种题目,面试官是真的会问的。而且 Augment Code 给出的参考答案不是那种干巴巴的理论,而是结合了我的项目场景,有具体的代码示例和权衡分析。
这玩意儿用来准备面试题,简直是降维打击。
踩过的坑,流过的泪
当然,AI 编程工具不是万能的。这一年来,我也踩了不少坑。
坑一:过度信任 AI 生成的代码
有一次 Augment Code 帮我生成了一段数据处理的代码,逻辑看起来很完美,我 review 的时候也觉得没毛病,直接就提交了。结果上线之后,测试同学在边界条件下发现了一个 bug——当输入数据中包含 NaN 的时候,排序逻辑会出错。
// AI 生成的排序逻辑,看起来没毛病对吧?
// 但 NaN 的比较结果永远是 false,会导致排序不稳定
function sortByScore(items: DataItem[]): DataItem[] {
return items.sort((a, b) => {
if (a.score > b.score) return -1;
if (a.score < b.score) return 1;
return 0;
});
}
// 修复后
function sortByScore(items: DataItem[]): DataItem[] {
return items.sort((a, b) => {
const scoreA = Number.isNaN(a.score) ? -Infinity : a.score;
const scoreB = Number.isNaN(b.score) ? -Infinity : b.score;
return scoreB - scoreA;
});
}
这个 bug 让我被测试同学嘲讽了一整个星期。从此以后,AI 生成的代码我都要仔仔细细地 review,尤其是边界条件。
坑二:AI 不理解业务上下文
我们项目里有个很特殊的业务逻辑:某些数据字段在特定条件下需要做"软删除",而不是真正的物理删除。这个规则散落在各种文档和口口相传的"祖训"里,代码里并没有完整的注释。
Augment Code 在帮我重构数据层的时候,直接给我生成了物理删除的逻辑。我差点就提交了,幸好最后关头想起了这个"祖训",赶紧改回来。
这就是目前 AI 编程工具的局限性——它们能理解代码,但不理解业务。那些没有写在代码里的潜规则、历史遗留的约定、团队内部的默契,AI 是不知道的。
坑三:生成式 AI 的"幻觉"问题
有次我让 Augment Code 帮我写一个自定义 Hook,它很自信地给我用了一个 React 的 API,但这个 API 根本不存在。它把 useSyncExternalStore 和 useMutableSource 搞混了,生成了一个缝合怪。
当时我看到代码的时候还心想"哇这个 API 好高级我居然不知道",跑了一下直接报错,才反应过来这货在胡说八道。
所以,用 AI 写代码,你自己的技术功底不能丢。你得有能力判断它生成的东西对不对,不然就是给自己埋雷。
一些真实的思考
用了一年多的 AI 编程工具,从最初的尝鲜,到现在的深度依赖,我有一些比较真实的感受。
第一,AI 不会取代程序员,但会淘汰不会用 AI 的程序员。
这话听起来像废话,但真的是实话。我现在写代码的效率,保守估计是去年的两倍。以前需要一天的活儿,现在半天就能搞定。省下来的时间干嘛?思考架构、优化性能、跟产品对需求——这些才是真正有价值的事情。
但我团队里有个同事,到现在还在手动写每一行代码,对 AI 工具嗤之以鼻,觉得"AI 写的代码没有灵魂"。上个月绩效评估,我拿了 A,他拿了 B+。没有灵魂的不是 AI 的代码,是他自己的工作效率。
第二,AI 编程工具正在改变"好程序员"的定义。
以前我们说好程序员,是代码写得漂亮、算法题刷得多、框架源码看得深。现在呢?我觉得好程序员应该是:
- 能准确描述需求,让 AI 生成高质量的代码
- 能快速 review AI 生成的代码,发现潜在问题
- 能把精力放在架构设计和业务理解上,而不是重复的 CRUD
说白了,提示词工程(Prompt Engineering)正在成为程序员的核心技能之一。
第三,生成式 AI 的天花板,取决于你自己的天花板。
这一点我感触最深。Augment Code 再强大,它也是基于你给它的上下文来工作的。如果你自己对项目的理解是模糊的,对技术的认知是浅薄的,那 AI 给你的帮助也是有限的。
就像性能优化那个案例,如果我自己没有做过性能分析,不知道哪些指标是关键的,我连让 AI 帮我分析什么都不知道。AI 是放大器,放大的是你本身的能力。
给想入坑的兄弟们一些建议
如果你还没开始用 AI 编程工具,或者用了但觉得不好用,这里有几条我的经验:
别指望 AI 一步到位。把它当成一个超级快的初级程序员,它写的代码你需要 review、需要调整、需要补充业务逻辑。期望管理很重要。
先从小任务开始。别一上来就让 AI 帮你重构整个项目。先让它帮你写个工具函数、写个单元测试、写个组件,慢慢建立信任。
学会写好 prompt。描述需求的时候,越具体越好。"帮我优化性能"是废话,"帮我把这个列表组件的虚拟滚动实现改成基于 react-window 的方案,要求支持动态行高"才是有效的 prompt。
保持学习能力。AI 能帮你写代码,但不能帮你理解技术。该看的源码还是要看,该学的原理还是要学。不然你连 AI 在胡说八道都看不出来。
多交流多分享。我每次参加技术分享会,都会聊聊 AI 编程的实践。别人的使用场景和踩坑经验,能帮你少走很多弯路。
写在最后
写这篇文章的时候,是周六的下午。我坐在公司楼下的咖啡馆里——租房离公司近的好处就是,周末想加班随时能来,不想加班走两步就到家了。
Augment Code 刚才帮我生成了一份这篇博客的 Markdown 大纲,说实话,结构还挺清晰的。但我没用它的大纲,因为写博客这事儿,还是得有自己的思考和表达。AI 能帮你写代码,但帮不了你思考。
至少目前还不行。
好了,产品经理又在群里 @ 我了,说有个"很简单的小需求"要加。我深吸一口气,打开 Augment Code,准备开始今天的表演。
这年头,不会用 AI 写代码的程序员,就像不会用 Google 的程序员一样——迟早要被淘汰的。
共勉。


评论 0