反思在 AI 普及时代,教学过程中的 friction 可能是有益特性。对编程教育工作者有启发,但非直接的技术内容。
关注过我的读者会知道,教学和指导对我来说意义重大。
在进入科技行业之前,我是一名教师,现在仍然从心底里认为自己是教育者。在我看来,做教师和导师从来不与成为一个优秀程序员和工程师相分离;相反,教学是一种工具,帮助我在这段旅程的每个阶段不断精进。
但在过去几年中,特别是最近几个月,教学和学习的生态以令人恐惧的速度在变化。LLM 和"AI"编码助手的出现从根本上改变了我们获取工程技能的方式,而我们显然还没有为此做好准备。
这一切引发了我许多思考和讨论,我希望在这篇博客文章中总结其中的一些内容。
以塔木德传统的方式,这篇文章没有太多答案,希望能给你留下比开始时更多的问题。但提出问题正是我们开启这些对话的方式,而如果我们要为下一代程序员和工程师做正确的事,这些对话是必须发生的。
作为学生,无论是在犹太学府(Yeshiva)时,我曾花费数小时每天钻研深奥的塔木德法律辩论和深邃的哈西德哲学,或者后来在 Flatiron 编程学校学习 Rails 和 React 时,我很快就意识到了关于技能获取的一个令人不适的真相。
我最好的、最深刻的学习从来不是在课程进行顺利的时候发生的;它发生在我痛苦地被卡住的时候,要么对着莫测高深的错误信息猛敲脑袋,要么苦恼地思考某个概念为什么就是想不通(通常在凌晨两点,靠着冷咖啡和纯粹的固执熬着)。
一旦你去掉那种挣扎,你也就去掉了成长。没有了成长,学习就根本不会发生。
即使你强行死记硬背足以通过考试,那也是"来得快去得也快"。没有那种认知摩擦,知识在你关上编辑器的那一刻就蒸发了。
我遇到的最优秀的教师和导师从直觉上理解这一点。当我盯着一个有问题的脚本,知道可能有个简单得要命的修复方案时,他们不会突然冲进来把解决方案直接甩到我的屏幕上(尽管我那个睡眠不足的脑子会大声抱怨)。
相反,他们灵活运用了苏格拉底法这样的工具。他们会指向代码的某一行,然后开始提出温和、深入的问题,来揭露我那些有缺陷的假设。
他们主动拥抱这种摩擦,为我创造足够的认知空间,让我自己把点连起来。
他们理解我们教学工作的一条基本法则:优秀的指导并不是为了得到代码。目标不仅仅是让测试在今天转绿;目标是构建所需的心理韧性,以便应对明天不可避免的下一个失败。
这些技能正是我在轮到我成为教师时所带走的,无论是在犹太在线学校教二年级学生,还是在 Flatiron 担任助教,或是指导加入我团队的新队友。
快进到今天,我们的行业基本上已经把初期指导外包给了 LLM 和编码助手。这里是令人不适的真相:AI 是一个糟糕的苏格拉底导师。
如果你花过相当长的时间与现代 LLM 配对编程(甚至只是聊天),你就会知道它们是病态的"好好先生"。告诉 AI 你想为一个只有十来个活跃用户的待办事项应用架构一个分布式微服务网格,它不会反驳。它会附和说"这是个天才想法!"并立刻吐出 400 行的样板代码。
AI 默认盲目信任。它很少质疑错误的假设,当你问它为什么某个堆栈追踪在爆炸时,它会立刻给出一个可以复制粘贴的修复,而不是帮你理解潜在的 bug。
通过表现得像一个算法自动售货机(error_in => fix_out),AI 系统性地从开发过程中移除了所有认知摩擦。
在我们争相追求 10 倍速度的匆忙中,我们忘记了技能获取的一条基本法则:摩擦是一个特征,不是 bug。那是一个承重的摩擦,我们把它拆除了!
这不仅仅是哲学上的猜测;有硬数据支持这一点。Anthropic 最近的一项研究(或者如果你喜欢解析方法论,可以深入这篇论文)将 52 名学习陌生编程库的软件工程师分成两组:一组有 AI 编码助手,一组手工编码。
总体结果既令人沮丧,也不令人惊讶。使用 AI 编码助手的工程师在概念掌握和调试技能上下降了 17%(相当于整整下降两个字母等级!),通常完成任务的速度并不比手工对照组快多少。
为什么?因为当你把痛苦地陷入困境这种认知摩擦外包出去时,你的大脑永远无法构建评估生成代码是否真的好用所需的深层神经通路。
现在,公平地说,数据中有些细微差别:少数 AI 辅助的工程师实际上表现超过了手工对照组。但他们是谁呢?他们是那些拒绝盲目信任 AI 的开发者。他们把 LLM 当作学习伙伴,提出探索性的后续问题,并手动地把摩擦重新注入这个过程。
对于其他所有人来说,自动好好先生只是静悄悄地摧毁了他们的理解。
这种动态让初级开发者陷入了一个巨大的困境。
职业生涯较早的朋友和学员抱怨说他们感到陷入了令人沮丧的两难之地:
一方面,他们必须务实地接受 AI 不会消失的现实。如果一个 LLM 能从一个 prompt 生成可用的样板代码,你不能只是固执地拒绝使用它。完全忽视 AI 似乎是不负责任的,考虑到你会在日常工作流中大量使用这些工具。
但另一方面,如果你盲目地依赖那个自动完成,你就会陷入所谓的"表面学习"。你得到一个快速答案,能让你通过测试套件或获得 PR 批准,但完全没有真正理解底层的机制。你错过了"深度学习",那才是真正的、能维持职业生涯的成长发生的地方。
根据我的经验,这种肤浅性是导致开发者焦虑和冒充者综合症的直接途径。真正的专业自信不是来自按 Tab 键接受一个 prompt;它来自代码所有权和密集的脑力劳动。
为了生存下来,勤奋的学习者现在被迫手动地把摩擦重新注入他们的工作流中,以防止他们的大脑关闭。
我一个初级开发者朋友被迫明确地用护栏指令来 prompt 他们的 IDE,比如:"我想学会自己编码,而不是复制粘贴,所以无论如何都要启用那个。"
他们用手工做笔记(是的,真的是纸和笔!),设置物理计时器只是为了重新创造主动倾听的保障措施,而一个为即时满足而设计的工具系统性地试图绕过这些保障。
这种自我施加的挣扎需求在你看过 Emily Bender 和 Alex Hanna 的书《The AI Con》时就完全讲得通了,它强调了为什么信息获取中的摩擦实际上是个特征,不是 bug。
想象一下当你用搜索引擎手工寻找一个深奥的 bug 时会发生什么。
你阅读混乱的文档,扫描十几条评论的 GitHub issue 线程(通常以维护者在 2014 年关闭为"不是 bug"作为结尾),权衡 Stack Overflow 上相互矛盾答案的可信度,并沿途偶然发现相关的陷阱。
那个混乱的元信息网络正是构建真正工程背景的地方。
AI 聊天机器人把所有那些丰富的、令人沮丧的挣扎压扁成一个单一的、听起来权威(有时"幻觉")的摘要。它给你解决了你眼前问题的答案,同时剥夺了你的大脑所需的周围生态系统知识来解决下一个问题。
这让我想起了一个古老的教学法模式,直到今天仍然在世界各地的犹太学府(Talmudic academies)中幸存,而软件工程现在急切需要这个。
在传统的犹太学府中,你很少看到人们在安静隔离中独自读书或被动地听讲座。相反,房间很嘈杂、充满活力,到处是成对的人在激烈地争论。
这种学习伙伴系统被称为 Chavrusa(来自阿拉姆语"朋友"或"伴侣"的词)。
当你与 Chavrusa 一起学习时,你的伙伴不是来给你朗读文本的,他们也不会点头认可并献殷勤地断言你的理论有多聪明。真正的 Chavrusa 会定期挑战你的逻辑,戳破你的论点中的漏洞,反驳摇摇欲坠的假设,总体上拒绝让你逃脱智力懒惰。
你不是通过读悬崖笔记或听精妙讲座来掌握塔木德的(虽然有一些这样的东西);你是通过 Yegiah(一个希伯来词,翻译为密集的脑力劳动和汗水)来掌握它的。
如果你想想的话(正如我在 2021 年 RailsConf 演讲中提到的),配对编程就是科技行业对 Chavrusa 的重新创造。
这个系统最重要的部分是:在真正的 Chavrusa 中,不仅仅是配对中的初级成员在学习。
无论你是与一个有 10 年经验的高级工程师配对,还是与一个刚从编程学校毕业的初级开发者配对;学习总是一条双向的街道!
当你的伙伴充当对抗性的橡皮鸭(一个真的会说话的!)时,他们会强迫你放慢速度,表达你隐藏的假设,从头到尾为你的代码逻辑辩护。你们两人都从那种摩擦中获益,你们都会走开,拥有一个比开始时好得多的心理模型。
Rabbi Ḥama,Rabbi Ḥanina 之子,说:这个写着的东西的意义是什么:"铁磨铁,磨出刀锋;人磨人,磨出才华"(箴言 27:17)?这节经文是来告诉你,就如铁刀片相互摩擦时互相磨利一样,托拉学者一起学习时也是互相磨利的。
在我们争相追求 10 倍速度的匆忙中,我们试图用 AI copilot 来取代人类配对编程。但这样做,我们忘记了一个关键的依赖:我们用一个献殷勤的机器鸭交换了对抗性的 Chavrusa 和 Yegiah。
我从科技人群那里听到的一个常见回应是:"好吧,让我们用更好的 system prompt 来解决这个问题!让我们建立护栏,指示 AI 表现得像苏格拉底导师,而不仅仅是放弃答案!"
现在有很多工具试图这样做,但我对技术护栏能否解决根本上是人性问题深感怀疑。
首先,依靠 prompt 来扣住答案需要精英学习者的纪律。有些学生能坚持,但那种意志力水平很罕见,特别是当你的认知电池快要耗尽时。
当一个初级开发者在凌晨两点盯着一个难以理解的 NullPointerException,他们的脑子已经炸掉时,一个要求他们"反思对象的生命周期"的 prompt 会立刻被绕过。如果只要输入 /solution 或打开一个新浏览器标签就能得到可复制粘贴代码的多巴胺快感,我认识的不多有人会坚持下去。
更重要的是,LLM 在架构上就是为了取悦。即使你工程化提示让他们成为强硬的苏格拉底导师,他们的核心调优意味着一旦用户表达真正的沮丧,AI 就像一把廉价折椅一样折叠,无论如何都会交出语法。
为什么?因为 LLM 缺少教育者最重要的品质:同理心。
指导是一种人性的教学平衡行为。伟大的导师理解生产性挣扎和令人沮丧痛苦之间的微妙界限。好的教育者能读懂现场。他们注意到沉重的叹气、积聚的恐慌和纯粹的疲惫。
当然,作为学生,当我被赋予自己解决问题的工具时,我学得最好。但有时我把我的精力全部用在那个愚蠢的错误信息上,我的导师问的所有引导性问题对我来说感觉就像是在让我绕圈子,绕着那唯一能让一切都说通的见解绕,一个我的大脑就是想不到的见解。
那是一个好教师知道退一步、微笑、说"嘿,JavaScript 有时候就是很奇怪",然后交给我那一行我需要的确切代码以便我终于能去睡觉的点。
一个算法无法读出学习者的情绪状态。它无法在具有挑战性的对手和支持性安全网之间动态切换。代码永远无法复制那种关系。
那这让我们处于什么位置呢?如果我完全诚实的话,我现在的问题远比答案多(这肯定不是你想从一个科技博客听到的,我知道!)。
我们正处于一个巨大的、行业范围的两难之地:
一方面,禁止初级开发者使用 AI 将几乎是职业不当行为。它是现代 IDE(回到我学习编码的时候,守门人争论初级开发者不应该使用那个——我那时不同意,现在也不同意)。如果初级开发者将来在工作中被期望使用这些工具,那就几乎没有意义不训练他们有效地使用它们。
另一方面,在不引入架构破坏性 bug 的情况下获得那种大规模 10 倍速度提升的工程师是那些在没有它的情况下花费数年编写代码的高级开发者。
我们知道 LLM 何时在错误前提上无所事事,因为我们有一个内置的 BS 检测器,通过多年的手工调试而艰苦地挣来。
没有那种 AI 前经验的人今天怎么构建那个直觉呢?他们不会从献殷勤的 yes-man 聊天机器人助手那里得到它。而手动发明你自己的认知摩擦需要在紧张的截止期限下很难维持的那种自律。
也许未来的入职依赖于加倍投入于人类配对编程——让初级开发者跟随高级开发者数月,通过代理来吸收那种 AI 前直觉。毕竟,配对编程一直是最好的入职方法之一,甚至在 Claude 之前。但不是每个公司都是 Pivotal,也不是所有公司都对在一个经常痴迷于昨天就要交付的行业中全职配对所需的投资感兴趣。
我知道的是,我们不能忽视这个问题或假定更好的 LLM 模型会神奇地修复我们的人才管道。
如果我们只是给初级开发者一个神谕,而不保留 Chavrusa 的同理心、严格的挣扎,我们会在几年后醒来面临一个可怕的系统错误:一个拥有大规模 AI 生成代码库要维护,但没有足够的高级工程师知道如何维护它的行业。
你和你的团队在做什么来保持生产性摩擦的活力?我很想听听你的想法。