AI 编码助手 2022 年 6 月上线,2023年走进了大家的日常工作中。在一年多的使用时间里,大家最经常用的功能有哪些?
就我个人而言,用得更多的是代码补全功能和代码解释功能、问答助手功能。至于通过写注释来获取编码,真的用的很少。一来常见的代码已经封装到公共库里,二来复杂的业务代码成功率并不高。
现在市面上,都在吹AI能自己写完整个项目,然而那水平也就约等于会写 Demo 的程序员吧。2024 年华为开发者大会中,给出了类似于 AI 自动驾驶的 AI Agent(智能体)的五个级别。要能完整写完项目,起码都是 L3 以上。
最近百度的无人驾驶出租车萝卜快跑在武汉落地了,据说是 L4 级别的。百度从 2017 年的All in AI,到 2024 年,足足用了 6 年。AI 编码目前应该在 L1 和 L2 级别之间,如果要到 L 4 是否也需要相同的时间才能获到相同的成就?
我觉得是要的,理由有几点:
- AI 驾驶需要更多的是图片处理能力,线路规划等推理能力是较弱的;然而 AI 编码需要更多的是推理能力,特别是后端的业务逻辑部分。
- AI 驾驶代替的是一个人的工作;AI 编码要产生成品,至少是 3 - 5 个人的工作,前端、后端、设计、产品和测试,其复杂程度剔除人员的沟通之外,仍然是高于 AI 驾驶的。
- 现在一个系统至少能达到 99% 以上的稳定性才能上线长期运行的,然而现在 AI 估计 80% 都没有。AI 从推理模型理解语义 90% 的准确率到大语言模型涌现到 99%,也至少用了 5 年。
- AI 智能体对算力的要求太高,目前大部分公司无法私有化部署,需要时间把这些成本降下来
既然AI智能体短时间内无法达到理想的状态,那在接下来的时间里,AI 辅助编码仍将是主流,脏活累活还是交到我们一线的代码仔手中,我们能做哪些事情,让AI帮我们做更多呢?
现在 AI 编码有以下两点基本的特点:
- AI 也需要读懂你的代码
- AI 基于项目的全局记忆能力、全局推理能力需要耗费大量的计算资源,短时间内无法解决。
基于这两点给出以下判断:
命名规范更重要了
“代码是写给人看的,顺便给机器运行”,这个话要更新了。你的代码除了被人阅读,现在还多了一个对象——AI。
我们来看两段代码,一段是从老旧代码库里来的,命名比较随意;一段是修改后的代码,让AI分别对其解读及添加注释。
修改前
function addNew() {
const menu = getFunc();
if (menu == null) {
return false;
}
const dataId = newGuid();
const dataUrl = menu.path + menu.module + 'Form.html';
const tabName = menu.name + '-新增';
openBtnTab(dataId, dataUrl, tabName);
}
AI对其的解释是:
这段 JavaScript 代码定义了一个名为
addNew
的函数,该函数的目的是根据某种菜单配置来打开一个带有特定名称和 URL 的新标签页(可能是在一个标签页管理系统或类似的界面中)。下面是对这段代码的逐行解释:...
总结:这段代码定义了一个函数,该函数旨在根据从某个地方(可能是外部定义的
getFunc
函数)获取的菜单配置来打开一个具有特定名称和 URL 的新标签页。这个新标签页可能是用于添加或编辑某种数据的表单。不过,为了完全理解这段代码的目的和行为,你可能还需要查看getFunc
、newGuid
和openBtnTab
这三个函数的定义和实现。
加注释的话是这样的:
/**
* 添加新内容
*
* @returns 如果添加失败则返回false,否则无返回值
*/
很显然,这里的解释和注释都是比较含糊的。
修改后
我们把 addNew
和 getFunc
改成了 addNewTab
和 getMenuInfo
。
function addNewTab() {
const menu = getMenuInfo();
...;
openBtnTab(dataId, dataUrl, tabName);
}
AI 对这段代码的解释是:
这段JavaScript代码定义了一个名为
addNewTab
的函数,该函数主要用于在某种界面(可能是网页或应用程序)上添加一个新的选项卡(tab)。下面是对这段代码的详细解释:...
总结:这个
addNewTab
函数的主要目的是在界面上打开一个新的选项卡,该选项卡可能与某个菜单项相关,并用于添加新的项目或数据。它依赖于其他几个函数(如getMenuInfo
、newGuid
和openBtnTab
)来完成其任务,但这些函数在给出的代码段中没有定义。
加注释的话是这样的:
/**
* 添加新标签页
*
* @returns 如果添加成功返回true,否则返回false
*/
这一段,AI 给出了更简短并更准确的回复。
可见,AI 并不比人聪明多少,他只能减少你读代码的时间,如果代码本身含糊不清,AI 也只能靠猜,回答会带上很多不确定的词。
所以给予更明确的命名还是很有必要的。如果AI猜中了其中意思,也建议及时改名字。
更多地使用公共库
由于 AI 全局推理能力的缺失,所以我们用自己在项目中写的库,并不一定能得到很好的代码片段。除非在你的项目当前文件中出现多次,才有可能被很好的推理出来。
但是使用公共库,AI 学习的知识库本身就包含了这些库,能很方便的帮你完善代码片段。
下面的例子是使用 axios 公共库的截屏,其提示出来除了完整的参数,还有获取到数据后你可能进行的一些操作,弹窗等。
而自己封装之后的 request,只提示一行的参数,还不知道是否准确。
接受更多的冗余代码
同样的,由于 AI 无法从项目全局视角去考虑问题。想实现代码复用,也是很难的事情。
比如一个商城网站,商品的订单页面有一个地址修改弹窗,个人信息页面也有一个地址修改弹窗。两个地方会略有不同:
- 订单页面会提示当前用户购买的商品,个人信息仅展示列表即可。
- 订单页面修改地址之后需要绑定到当前商品,个人信息页面修改地址后就返回个人信息列表。
在程序员看来,只是两个 if/else 的问题,分别写在展示的时候、提交修改的时候即可。
然而,如果基于AI来开发,更建议你写成两个弹窗。
- 分开写之后,逻辑简单了,AI 能更好地帮你生成代码;
- 日后维护起来,对功能进行增改删,AI 不需要判断过多的上下文,单功能的组件也比多功能的组件更好维护。
- 弹窗组件命名上分开,后续 AI 能更好的理解组件的作用;
- 商品页组件跟商品页放在一个文件夹,后续 AI 也能更好地理解当前文件夹的结构。
逐步拆分函数给 AI 填充
在上面的 L2 级别中,AI 执行被分解的任务,那我们人类就要负责把这些分解的任务衔接起来。
在文件内的级别,人类则需要负责好高级函数的书写,并逐步拆分到更细的中低级函数,让AI 完成。
// 入口函数,人类完成
const init = async () => {
const responseData = await getList();
if (response.type === ORDER) {
renderOrderPage(response.addressData, response.orderData);
} else {
renderInfoPage(response.addressData);
}
};
// 中低级函数,人类和AI共同完成, 能让AI写则AI写
const getList = async () => {
// 以下是某AI编码助手真实生成的,修改路径即可
const response = await fetch('http://localhost:5001/api/address?pageIndex=1&pageSize=20');
return response.json();
};
const renderOrderPage = async (addressData, orderData) => {
// 以下是某AI编码助手真实生成的
if (addressData.length > 0) {
// 渲染地址列表
}
if (orderData.length > 0) {
// 渲染订单列表
}
};
const renderInfoPage = async (addressData) => {
// 以下是某AI编码助手真实生成的
if (addressData.length > 0) {
// 渲染地址列表
}
};
从上面 AI 生成的代码,可以看到 AI 基本猜对了我的意图。当我敲完 getList
,整个函数就完成了;当我敲 if
的时候,渲染地址列表的具体代码没出来,但是框架页基本有了。后续还可以拆出来更细的低级函数,一步步让AI 完成。
由此看来,把函数写小未来会非常有用。
架构能力更重要
要更好地分解任务,在项目方面而言,架构能力会变得更重要。
比如:
- 如何划分模块,模块之间的依赖关系如何,模块的颗粒度如何把握,如何保证高聚合、低耦合?
- 项目的全局的状态什么时候使用,如何调用,如何同步更新?
- 项目整体要规划哪些核心类、函数或组件?如何在各业务场景中复用?
架构做得越好,能让 AI 帮你更好更快地填充更准确的内容。架构没做好,很可能连AI都无法读懂你的项目:
把 AI 当成一个初级程序员,而你要帮他把架子搭好,让他帮你完成重复无趣的工作,另一方面也提高了你的自身的架构能力,可谓一举两得。
总结
离 AI 到智能体自主拆分任务完成任务的日子还远,我们站在前线的代码仔,应该更好地利用 AI 帮我们生成代码。站在 AI 的视角上,我们应该学会把控整体的架构设计、更好地拆分任务、甚至是拆分到函数级别的任务,然后把更多的代码交给 AI 完成。
不管 AI 智能体最后能到哪一步,对于我们打工人更重要的一直都是更准时地下班,存好钱,过更好的生活。
祝大家都有美好的未来!
另外补充一下题外话,老板们期望的一句话实现需求,是无法实现的。模糊的定义最后也只会产生模糊的产品,一句话产生的最终产出物,老板们估计是很难接受的。老板来回的提需求,最终只会消耗他更多的金钱来换取算力。(不过王小川在百川大模型中使用的多轮对答,也许能对解决这个问题有所帮助)
至于 SaaS、低代码转 AI,老板们有多喜欢自定义,这件事就有多难。
以上只是个人对近期 AI 编码方面的一些思考,纯粹个人观点不一定对,有考虑不周的地方也欢迎大家斧正。