通过手动重打 LLM 生成的代码来防止认知债

AI 辅助编程中的认知债问题

允许大语言模型 (LLMs) 自动生成并将大块代码插入到项目中会产生“认知债”——即开发者不再从根本上理解他们自己的软件是如何构建的。虽然 AI 助手可以加速开发的“无聊部分”,但从编写代码到仅仅审查 AI 生成的 pull requests 的转变,往往会导致深度理解力的丧失和系统心理模型的碎片化。

审查 AI 生成的代码通常是一个令人不满意的过程,其特点是需要仔细研究过度防御、注释不足或存在微妙错误逻辑的代码。对于个人项目而言,创作的过程与结果同样宝贵,这种从创造者到审查者的转变剥夺了开发的乐趣,并由于编写了作者无法完全理解的软件而面临职业失职的风险。

解决方案:手动重打

为了对抗认知债,Ankur Sethi 采用了一种工作流,禁止 LLM 直接修改项目文件。相反,LLM 在聊天界面中提出修改建议,然后由开发者手动将这些修改输入到编辑器中。

实现策略

Sethi 为 AI agent 使用特定的系统指令来强制执行这一边界:

我想理解进入这个项目的每一行代码。除非我明确要求,否则永远不要创建、编辑、移动、重命名或删除项目文件。相反,请在聊天中向我展示每一个建议的修改,以便我可以手动输入它们。

除非我明确要求,否则不要运行会修改项目文件、安装依赖或更改 repository 状态的命令。相反,请在聊天中向我展示这些命令,以便我可以手动运行它们。

我是一名经验丰富的开发者。除非明确要求,否则不要解释语法、API、编程概念或实现细节。

手动输入的益处

虽然这种方法降低了 AI 带来的速度提升(从潜在的“10x”提升降至大约“2x”),但它提供了几个关键的认知优势:

  • 心理模型构建: 手动输入每一行代码会迫使开发者构建代码库的空间映射,确切地知道功能所在的位置。
  • 幻觉检测: 强制性的减速使得更容易发现糟糕的设计选择或 AI 幻觉,而这些在快速浏览或 diff review 时可能会被忽略。
  • 主动学习: 这个过程模仿了传统的学习方法——例如在教科书上抄写示例——抄写这一行为鼓励开发者停下来研究不熟悉的 API 或算法。
  • 定制化: 开发者可以在输入代码的同时,实时地进行重构、重新组织并根据自己的品味进行调整。

社区观点与反论点

该提议在开发者之间引发了显著的辩论,揭示了那些优先考虑深度理解的人与那些将编程视为高级编排任务的人之间的分歧。

支持观点

许多经验丰富的开发者指出,这种“慢速编程”习惯在 LLM 时代之前就很常见。

"Back in the days of Stack Exchange I would always type out manually whatever answer I found to make sure I understood WTF I was adding to the system." — @bandrami

其他人引用了“生成效应”,认为与被动阅读相比,产生文本的行为(即使是通过复制)能提高知识保留率。

批判性观点

批评者认为,重打代码是实际推理的低效替代品,如果逻辑并非由开发者原创,那么它并不能防止认知债。

  • 被动消费: 一些人认为重打仅仅是“填色游戏” (paint-by-numbers),真正的学习需要意义的主动构建,而不是转录语法正确但“语义空洞”的响应。
  • 抽象层级转移: 一些开发者认为行业正在向更高层级的抽象迈进,在这种情况下,“逐行”理解变得不再那么关键,引导 AI agent 的能力变得更加重要。
  • 低效性: 批评者指出,如果开发者必须思考到足以重打并修复 AI 代码的程度,他们他们可能不如直接从头开始编写代码,从而完全消除 LLM。

替代缓解方案

为了平衡速度和理解力,提出了几种替代策略:

  • 脚手架搭建: 使用 LLMs 仅生成高层结构(类、接口、函数签名),然后手动实现逻辑。
  • 测试驱动 AI: 要求 LLM 先编写测试(Red tests),然后手动实现代码以使这些测试通过。
  • 混合方法: 使用 LLMs 进行研究和学习,但对实际实现保持严格的“禁止 agentic-coding”规则,以保留“编程品味”。

Sources