像用实习生一样用 AI 辅助你编程

我是不敢让 ai 帮我写程序的,每回问它的问题,十次倒有八次是错的,问完之后还要自己去网上搜一遍,然后反复测试,才敢写进代码。 不知道大家怎么甩手给它的。

——响马

响马毫无疑问是编程高手,几十年的开发经验,另外他写的代码都属于一些底层代码,被训练过的比例极少,AI 大概率写不出来高质量代码,不放心让 AI 帮忙写程序正常。但对于普通程序员来说,不一定要像响马那样,拒绝 AI 的帮助。

比如我就是个普通程序员,写的都是一些简单的前端 UI 代码,或者后端增删改查代码,并没有太高技术含量,就经常让 AI 给我帮忙,还是让我效率提升不少的。我总结下来经验就是:像用实习生一样用 AI 辅助你编程。

在科技公司或者开发团队经常能看到这样的场景:某些资深程序员,写代码特别牛,效率特别高,但是很多活都压在他们身上,成为了团队瓶颈,于是老板说,这样不行,给你几个实习生或者新手程序员帮你分担一些吧。

大多数时候这种提议是被拒绝的,倒不是他们藏私不愿意带人,而是在他们看来,把活交给实习生,一个简单的任务都要花几天时间,自己一小时就做完了,中间还要沟通,做完质量不行还要帮忙擦屁股,花的时间超过自己写的时间,一点都不合算,另可自己做。

这些确实是事实,但是可能忽略了一些问题:

  1. 实习生是会成长的,很多事情教了一遍就不需要再教第二遍了。

  2. 再复杂的程序也是有些“体力活”的,比如说搭个脚手架,新增个模块,简单的重命名/重构,等等。对于资深程序员来说,老是干体力活会倦怠的,但是对实习生来说正好是一个学习的好机会。

  3. 能从实习生身上学习到新的东西。当我们对一门技术太熟悉,会有路径的依赖,不太容易发现或者接受新的技术,同样的任务让实习生做,虽然大多数时候不如你做的,但是也会有眼前一亮的时候,能学到一点新的东西或者开阔一下眼界:原来还可以这样!

  4. 如果你的任务不能交给实习生做,也许架构上存在一些不足,无法合理的将功能拆分。有些程序员的活不能拆分出来,一个原因可能是架构还不够好,模块都在一起,无法拆分。当然即使拆分后肯定还是有些复杂模块是无法进一步拆分的,这不在此列。

我在带实习生上有一些经验,所以在使用 Cursor 或者 GitHub Copilot 的时候,就是把 AI 当成一个实习生用,效果是很好的。

首先体力活都交给 AI 来做

体力活指的是那种重复的、要求不高的、繁琐的工作。比如说:

  • 新建一个页面、一个 API

  • 一个数据库增删改查的模块

  • 单元测试

这些活说难也不难,但是自己写有点麻烦,所以我每次都是 Cursor 里面用 CMD+i 唤出 Composer,把相关代码文件都添加上作为上下文,然后提出要求,一个初始的功能就有了。

比如我要为自己的博客网站增加一个 Sitemap 的功能,我当然可以自己写,但光文件都得创建好几个,还得写一些基本的读取数据库和输出 Sitemap 代码,甚至我还得去查询一下 Sitemap 规范。正因为如此,所以我一直懒得加上这功能。

但现在我有了 AI 这个实习生,那么就可以放心得让它去帮我写,我把数据库访问的代码加入上下文,将功能有些类似的feed.xml 代码也引用了进来了,然后简单的写几行提示词:

为了更好的 SEO,请帮我增加 Sitemap,一些信息:
网址:baoyu.io
主要页面:
首页:/
原创博客:
- 列表:/blog
- 单篇:/blog/[slug]
翻译内容:
- 列表:/translations
- 单篇:/translations/[slug]
获取帖子列表可以参考getPostsWithPagination

很快就帮我把相关文件都创建好了,虽然说 robots.txt 都给我做成动态的有点业余,但是也还好,至少我知道了内容应该是什么,懒一点就让它重新生成个静态文件,勤快一点就手动创建一个。剩下的就是调试一下,没什么问题就可以发布了。

理论上基于这个结果,还可以一直提要求,知道满意为止,或者差不多了自己接管手动修改一下。

我个人是觉得,让 AI 帮忙先实现一个基本的模块,意义不仅仅在于减少了体力活,而是帮你开了个头!万事开头难,很多时候真的就是因为没有一个开头就没继续,当有个初始的结果,哪怕烂一点,再基于它上面修改要简单很多,更容易交付。

给“实习生”一个葫芦,让他们学着画瓢

对于实习生来说,稍微复杂一点任务很难从无到有做出来,但是如果给他们一个已经做好的模块作为参考,照着葫芦画瓢,那么也能做个差不离。

让 AI 帮你编程也是一样的,你不能指望 AI 能像你一样厉害懂你的代码库,但是你可以教它,把一个类似的实现代码给它参考,甚至于写一段伪代码让它实现。

就拿前面 sitemap 的例子,添加到上下文的 feed.xml/route.ts 就是“葫芦”,有了这个“葫芦”,它去“画瓢”就容易多了,它可以从中去学习最佳实践是什么。

设计架构和技术选型的时候,选“实习生”熟悉容易上手的技术

技术选型是一个让人纠结的事情,需要各种考量,现在更是多了一个维度,就是要考虑把 AI 当成你的团队成员,想让 AI 能更好的帮你干活,那么就少造一些轮子,少用一些偏僻的框架或类库,用那种最流行的,训练语料最多的框架和库。

比如我在给自己搭建博客的时候,选的 Nextjs、Tailwindcss、ShadcnUI、D1(Sqlite),这些都是相当流行和容易上手的框架和库,所以我让 AI 帮我实现一个 Sitemap,它能知道在什么创建文件,遵循什么规范,写 UI 也知道如何帮我添加正确的 CSS。

将复杂任务分解成简单的任务,让“实习生”帮你完成小的模块

资深程序员和新手程序员的一个分界,就是能不能将复杂模块拆分成简单的小模块。比如我要搭建一个自己的博客网站,就 AI 现在的能力,是没办法自动完成这样一个项目,但是我可以让它帮我创建一个页面,帮我实现一个数据库读写的功能模块,帮我基于数据库读写模块实现一个 API,而我自己,则可以聚焦于数据库的表设计、系统的架构设计、UI 设计这些事情上。

向“实习生”学习

现在在实现功能的时候,哪怕我比较熟悉的,我会习惯性问一下 AI,让它帮我生成一段代码,虽然大多数时候它不一定比我写的更好,甚至是错误的,但有时候它能提出一种全新的我没考虑过的思路,那我就能从中学习到点什么,以后可能就用的上了。

就像大数学家陶哲轩,也在用 AI 帮忙解决数学问题,并非 AI 数学比他厉害,而是给他提供了不一样的思路。

我曾遇到过一个问题,我尝试了几种方法,但都无法解决。于是,我尝试询问 GPT,你建议我使用什么其他方法来解决这个问题?GPT 给我提供了 10 种可能的方法,其中有 5 种我已经尝试过,或者明显没有帮助。的确,有几种方法并不实用。但其中有一种我还没尝试过的方法,那就是针对这个问题使用生成函数。当 GPT 建议我使用这种方法时,我意识到这就是我漏掉的正确方法。所以,将 GPT 视为一个交流伙伴,它确实具有一定的用处。

——陶哲轩

对“实习生”产出的结果要验证

既然 AI 只是一个实习生,那么就说明它生成的代码是靠不住的,哪怕看起来很好,总是要像对待实习生一样,去对代码做审查,理解它实现的思路,对结果进行测试验证,出现问题让 AI 改进或者手动修复。

如果有人去责怪产品的问题是因为 AI 生成的质量不行,那只能说明是在甩锅,就像你生产环境的故障不能怪这是实习生写的,难道你们不做 Code Review,不做 QA 的吗?

最后

这是我在日常使用 AI 辅助编程的一点经验分享。如果你把 AI 当成一个资深程序员,那么你大概是要失望的,但是如果你把 AI 当作一个实习生,它真的可以做不少事情,让你提升编程效率。

另外一些现在 AI 还不能完全替代专业程序员的地方:

  • 基于业务需求进行抽象和架构设计的能力

  • 对复杂问题进行分解和统筹规划的能力

  • 出现问题定位和调试的能力

  • 当然还有出问题背锅的能力

欢迎分享你的经验!