我曾通宵用 AI 构建某个东西,让一堆功能跑了起来,然后才意识到自己其实解释不清刚建好的东西里有一半是什么。
也有些夜晚,我花好几个小时去搞明白一个愚蠢的小问题,结果不知怎么的,从中学到的比前一整晚学到的还多。
想想还挺有意思的。两次我都很有产出。两次我都得到了能跑的代码。但我从每次经历中实际学到的东西却完全不同。
我最近写了一篇文章,讲 AI 如何让逃避思考变得太容易了,这让我开始反思自己的习惯。因为我一直在用 AI 编程工具。我喜欢它们。它们帮我构建了一些否则我可能根本不会去尝试的东西。
但我也仍在学习。学很多。
而仅仅让某个东西跑起来,和真正理解它是如何运作的,之间有着巨大的差别。
仅仅因为我听懂了讲解,并不意味着我理解了代码
这种情况可能发生在我们所有人身上,比我们愿意承认的还要多。
我可能会让 AI 解释某个东西,它会给我一个完全合理的拆解。一切都很说得通。我能跟上思路,我理解每个部分在做什么,然后我想,好,懂了。
然后 3 天后我需要改点东西,突然我就盯着代码,像从没见过它一样。
显然,当有人手把手带我走完整个讲解时,我理解得挺好。
不过,那和真正掌握它并不是一回事。
我不是在说记住语法或记住每一个 API 细节。我一直在查东西,我觉得这没什么问题。
我说的是理解某件事为什么要用某种方式来做。
如果关于某个功能我能记住的只有“AI 写的,而且能跑”,那我其实没从中学到多少。
有时候有趣的部分是你不知道其存在的问题
我一直在做一个文本编辑器,叫Slate,对我来说这是一段非常有意思的学习经历。
有一件事我以前没怎么想过:当你在还在编辑文件的时候保存它,实际会发生什么。
我的意思是,保存文件听起来挺简单的,对吧?把内容写入磁盘,标记为已保存,搞定。
但问题是,如果用户在保存进行的同时继续输入,会发生什么?
正在写入的文件包含的是旧内容,但编辑器现在有了更新的改动。所以如果保存完成、编辑器清除了未保存标记,这基本上就是在告诉用户一切都已保存,而实际上并没有。
Slate 使用基于修订版本的保存跟踪来处理这个问题。当保存开始时,它会记住正在保存的是文档的哪个修订版本。这样一来,保存过程中所做的任何改动就不会被误标记为已保存。
其实 AI 本可以帮我把这些全都实现好。我本可以测试一下保存按钮,看到它能用,然后继续过我的日子。
但理解为什么这种修订跟踪很重要,才是它对我有用的原因。
这其实跟代码本身没多大关系。关键在于认识到,一个操作从开始到结束之间,某些东西可能会发生变化。
而这个问题可能出现在各种应用中,不只是文本编辑器。
这才是我希望从一个项目中学到的东西。
真正动手实验会带来巨大的差别
我在使用本地 AI 模型时也注意到了同样的事情。
假设我运行一个模型,它完成某件事需要 30 秒。
好吧,那它很慢,对吧?
嗯,也许吧。但到底是什么花了 30 秒?
大部分时间是不是花在把模型加载到内存上?实际处理是不是很慢?再运行一次会不会明显更快?
这些都是我可以测试的东西。
而且我发现,真正动手实验比只是让 AI 解释发生了什么,能让我学到更多。
再运行一次。分别测量各项。改动一些东西。看看会发生什么。
有时候结果完全符合我的预期。另一些时候则相差甚远,而通常正是这种时候事情才变得有意思。
我很喜欢能用 AI 帮我弄清楚事情。我可以问还应该尝试什么,或者为什么结果和我想的不一样。
这让学习不熟悉的东西变得容易多了。
但 AI 告诉我某件事为什么会发生,和我真正看到发生了什么,这两者之间有很大差别。
而且有时候 AI 的解释也是错的。我相信大家都知道这一点。
我不一定记得代码,但我记得问题本身
我觉得这大概是我注意到的最重要的一点。
当我真正花时间去理解某件事时,我之后可能不记得具体的实现方式。但我记得我当时想解决的问题,以及我为什么那样解决。
而这会延续到其他项目中。
也许我会开始想,某个异步操作是否可能在用户已经改了某些东西之后才完成。
或者某个性能问题其实是个启动问题。
又或者我是不是存了某份状态,而它其实可以从别的东西算出来。
我可能还是需要去查资料。我可能还是会让 AI 帮我写实现。
但至少我知道自己在找什么,以及它为什么重要。
如果我只是不加思考地接受生成的代码,那这一切我都错过了。解决方案就摆在我的项目里,但我在别处遇到同样的问题时,可能根本认不出来。
考虑到我开新项目的频率,我很可能会在别处再遇到它。大概就在下周。
当然,我不需要把每件事都变成一次学习经历
我也觉得这里需要一种平衡。
有时候我只想让 AI 修一下按钮的内边距。
我不需要花 45 分钟去研究 CSS 间距的底层原理。我只想让按钮看起来正常。
有很多事情我很乐意交给 AI 处理。样板代码、重复性的改动、我已经做过一百遍的事,或者只是我不想干的枯燥工作。
这也是我一开始就用这些工具的部分原因。
但当我构建不熟悉的东西,或者在做我明知以后需要维护的功能时,我会尽量多参与一些。
有时候这意味着只是问问题。
其他时候我可能就直接动手改点东西,看看会发生什么。
我认为,哪怕是像在运行前预测某个改动会带来什么这样简单的事,也能带来不同。因为如果结果不是我预期的,那我现在就有东西可以调查了。
我每次都这么做吗?绝对不是。
有时候我盯着某个东西看了两个小时,AI 终于把它跑通了,而我整个思路基本上就是“谢谢,终于好了,继续下一个”。
我不会假装不是这样。
但我正试着更清楚地意识到,什么时候我是在真正学习,什么时候我只是在把事情做完。
因为这两者并不总是一回事。
把东西跑通,和学会它如何运作,并不是一回事
AI 编程工具最让我喜欢的一点是,我更愿意去尝试那些我几乎一无所知的东西。
我尝试过各种语言、框架、本地模型、桌面应用,以及各种各样我以前大概会一直拖着不碰的东西。
倒不一定是因为我学不会它们,而是因为从零开始接触完全陌生的东西可能非常费劲。
AI 把最初那道门槛降得低多了,我觉得这真的很棒。
但也有一种诱惑,就是一直不停地往下做。一个功能跑通了,你就去做下一个。然后再下一个。不知不觉间,你已经有了一个完整的应用,却对其中一些相当重要的部分只有模糊的理解。
而人太容易把所有这些进展误当成学习。
我肯定干过这种事。
我觉得最能留在我记忆里的,通常是那些我不得不稍微调查一下的东西。某个东西的表现和我预期的不一样,或者我对它为什么以某种方式运作产生了好奇,于是我花了一些时间去弄明白。
有时候这种调查只需要几分钟。有时候它会把我带进一个兔子洞,耗掉我整晚的时间。
不管怎样,相比那些第一次就完美跑通的功能,我往往更记得住这些经历。
这是我在继续用 AI 构建东西的过程中想记住的一点。
我不想停止使用这些工具,也不想故意给自己把一切都弄得更难。
我只是不想过于沉迷于自己能构建多少东西,以至于忘了留意一路上学到的东西。
那么……你呢?你在用 AI 构建的过程中有没有学到一些有用的东西,现在能自己排查问题或解释清楚?或者你有没有回头看过 AI 生成的代码,发现自己完全不明白它是怎么运作的?