本文翻译自 We Should Revisit Literate Programming in the Agent Era,原载于 Hacker News。
什么是文学化编程?
文学化编程(Literate Programming) 是一种编程范式,其核心理念是:代码应该与散文(prose)交织在一起,使得一个不了解代码的读者也能像阅读叙事文本一样阅读代码库,并理解其工作原理和功能。
虽然我长期以来对这个理念很感兴趣,并在一些不同场景中找到了它的用武之地,但在实践中,我发现文学化编程往往变成了一项繁琐的工作——你需要同时维护两条平行的叙事线:代码本身,以及解释代码的文档。这显然限制了它的广泛采用。
文学化编程的现状
在实践层面,文学化编程最常见的形态是数据科学社区的 Jupyter notebooks,在那里,解释性文字与计算代码及其结果在同一网页中并存。
经常阅读本博客的读者可能知道,Emacs 的 Org Mode 通过 org-babel 包支持多语言的文学化编程,允许在文档中执行任意编程语言并将结果捕获回文档中。但这个模式始终局限于像我这样的小众极客群体。
即使对于像我这样热衷于此模式的人来说,将 Org Mode 作为大型软件项目的”真理来源”也会变得相当繁琐。因为源代码本质上变成了编译输出——每次在 Org 文件中编辑后,代码必须被重新提取(在 Org Mode 术语中称为”tangle”)并放置到目标位置。虽然这可以自动化,但很容易陷入一种恼人的境地:你或你的 Agent 编辑了真正的源代码,然后在下一次 tangle 时被覆盖。
话虽如此,我在使用文学化编程来管理个人配置方面取得了一些成功,以至于即使在大语言模型(LLM)出现之前,我也无法完全放弃这个想法。
一个实用的模式:测试与笔记的结合
在 Coding Agent 出现之前,我一直在尝试一种使用 Org Mode 进行手动测试和记录笔记的模式:
不在命令行中工作,而是在编辑器中编写命令并在那里执行它们。 我会原地编辑每个步骤直到正确,然后原地运行。这样当我完成后,我就有了一份文档,精确地解释了所采取的步骤,无需额外的步骤或专门的笔记记录。
将创建笔记和运行测试的行为结合起来,让你在测试完成时自动获得笔记——完全免费。
Agent 时代的革命性变化
现在有了 Coding Agent,这一切变得更加令人兴奋。
Claude、Kimi 和其他 LLM 都对 Org Mode 语法有很好的理解。这是一种宽容的标记语言,而 LLM 恰好擅长处理这类语言。所有文档都可以在线获取,很可能已经在训练数据中。虽然 Org Mode 的一个主要缺点是语法太多,但这对于语言模型来说根本不是问题。
现在,当我想测试一个功能时,我会让 Agent(作者称之为”clanker”)用 Org 格式为我编写一个 runbook。然后我可以审查它——散文解释了模型对每个步骤意图的理解,而代码块在审查完成后可以交互式执行,要么逐个执行,要么像脚本一样执行整个文件。结果会存储在文档中代码下方,就像 Jupyter notebook 一样。
我可以:
- 编辑散文,让模型更新代码
- 编辑代码,让模型在文本中反映其含义
- 或者让 Agent 同时修改两者
维护平行系统的问题就这样消失了。
Agent 解决了文学化编程的根本痛点
Agent 被告知处理 tangling,提取代码的问题也就随之消失。可以通过 AGENTS.md 文件指示 Agent:
- 将 Org Mode 文件视为真理来源
- 始终用散文解释正在发生的事情
- 在执行前进行 tangle
Agent 非常擅长所有这些事情,而且它永远不会厌倦在代码微调后用散文重新解释。
文学化编程的根本性额外劳动——我认为这也是它没有被广泛实践的原因——被 Agent 消除了。 而 Agent 所利用的正是大语言模型最擅长的能力:翻译和总结。
额外的好处
作为一个额外的好处,代码库现在可以导出为多种格式以便舒适阅读。如果工程师的主要角色正在从编写转向阅读,这一点尤为重要。
虽然没有数据支持,但我也怀疑文学化编程会提高生成代码的质量,因为解释每个代码块意图的散文将与代码本身一起出现在上下文中。
实践中的局限
我个人还没有机会在更大、更严肃的代码库上尝试这种模式。到目前为止,我只在工作流中使用它进行测试和记录手动流程,但我对它在那里的应用感到非常兴奋。
我也认识到 Org 格式是一个限制因素,因为它与 Emacs 紧密集成。然而,我长期以来一直认为 Org 应该逃离 Emacs。我会推广像 Markdown 这样的格式,但 Markdown 缺乏包含元数据的能力。
不过,正如我在关于 Emacs 的文章中一贯强调的:让我兴奋的不是 Emacs 对这个想法的具体实现,而是 想法本身。
核心问题
有了 Agent,拥有可以像叙事文本一样阅读的大型代码库是否变得切实可行?这些代码库的散文是否可以通过不知疲倦的机器与代码变化保持同步?
我认为这是一个引人深思的问题。
我的思考
这篇文章提出了一个很有意思的观点:AI Agent 可能让一个”好但太累”的想法变得实用。
文学化编程的概念其实很早就有了,由 Donald Knuth 在 1980 年代提出。但正如作者所说,它的核心痛点在于”双重维护”——你既要写代码,又要写解释,两者还必须保持同步。这对于已经忙于写代码的工程师来说,往往是不可承受之重。
但现在,Agent 可以:
- 自动生成解释:当你写代码时,Agent 可以自动用散文解释代码意图
- 双向同步:无论你改代码还是改文档,Agent 都能保持另一边同步
- 不知疲倦:Agent 永远不会抱怨”又要写注释”
这让我想到了一些相关的趋势:
- Jupyter Notebook 在数据科学领域的成功,正是因为它自然地将代码和解释放在一起
- Cursor/Copilot 等工具已经开始自动生成代码注释
- Documentation-as-Code 的理念也在推广
也许在 Agent 时代,我们真的可以重新审视那些”理念很好但实践太累”的编程范式。文学化编程可能只是其中之一。
关键启示:AI 不仅是提高效率的工具,更可能让一些”理论上完美”但”实践中困难”的软件工程理念真正落地。