我曾通宵用 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 生成的代码,发现自己完全不明白它是怎么运作的?