为什么读 diff 的方式最先失效
diff 是逐行列出代码在哪里、怎么变了的清单。人手小步修改的年代,读这份清单就等于评审:改动小,而且改动出自你自己,光看清单脑子里就能还原全貌。
智能体开始写代码后,这两个前提同时崩塌。一次改动涉及几十个文件,而且不是你写的。清单翻到底却什么都没留下,原因不是信息不足,而是顺序不符合理解的需要。
这里有个常见误解:以为人需要理解代码是为了"验证"——智能体会犯傻,所以人得盯着。但验证恰恰是智能体越来越擅长的部分。给它测试和验证回路,判断对错这件事机器做得更稳。
真正的理由在别处:理解是为了"参与"。理解了这次变更,这份理解就成为下一个判断的材料。脑中有概念结构,下一个想法才会冒出来,而那才是人的份额。跳过理解,你还能继续做判断,却提不出主张。
描述这种代价的词是认知债(cognitive debt),由维多利亚大学的 Margaret-Anne Storey 教授提出、Simon Willison 推广,与技术债成对。技术债积在代码里,认知债积在人身上。前者静态分析能看见,后者一直隐形,直到某天以"这是我的项目,却是我最不懂"的形式结账。
好的讲解按什么顺序写

那么该读什么来代替 diff?Litt 提出的问题是:如果派一个团队花一年时间,只为向你讲清这一次代码变更而设计课程,成品会长什么样?
explain-diff 生成的文档就是他的答案。结构分四块,而顺序本身就是教学法——好的数学老师就是这么做的:先给感觉,再上细节。
演讲里用的是真实例子:一个画禅意庭园的游戏,把俯视视角改成等距视角。文档不会一上来就讲改了什么,而是先交代用的游戏引擎和坐标系长什么样,并注明已经熟悉的人可以跳过。
接着是直觉:"这次提交的目标,是只用 2D 绘图技巧让庭园显出立体感。"更像是把写得好的提交信息再往下挖一层。本质先到,代码后到。
代码排第三,而且不按文件列表顺序,而按易于理解的顺序编排,每个文件前先用散文说明将要发生什么。Litt 把这叫做 literate code diff,他会打印出来带到咖啡馆读——过去必须黏在 IDE 前的工作,变成了读教科书。
| 部分 | 内容 | 为什么放这里 |
|---|---|---|
| Background | 系统原本如何运作,分为给初学者的深背景与直接相关的窄背景 | 无从得知读者知道多少,先对齐起跑线 |
| Intuition | 剥掉细节的一句核心、用玩具数据做的具体例子、图示 | 先抓住本质,代码才会被当作佐证来读 |
| Code | 高层走读,按理解顺序而非文件顺序分组排列 | 代码是依据,不是起点 |
| Quiz | 五道中等难度选择题,点击后给出对错与解释 | 唯一能区分"读过"与"读懂"的装置 |
技能是什么,放在哪里
explain-diff 不是程序,而是一个技能(skill)文件。正因为按常规意义没有东西要装,第一次听说的人反而容易困惑。
在 Claude Code 里,技能是一份写着"遇到这种情况请这样做"的 markdown 文档。放到指定位置,需要时就会被自动调用。位置有两处:整机通用放家目录的 ~/.claude/skills/,只在某个项目使用就放该仓库的 .claude/skills/。
文件名必须是 SKILL.md,文件夹名即技能名。也就是说 ~/.claude/skills/explain-diff-html/SKILL.md 这条路径本身就是注册过程。没有配置文件,也不需要重新构建。
文档顶部有一小段 frontmatter。name 是技能名,description 说明何时使用。description 很关键——即使你从不点名调用,只要当前情境与描述吻合,智能体就会自己去读这份文档。explain-diff-html 的描述是:当用户需要对代码变更、diff、分支或 PR 的丰富讲解时使用。
frontmatter 以下全是人话:包含哪些章节、用什么文风、图怎么画、文件存到哪里,没有一行代码。所以后面讲的"按团队改造",其实只是编辑一份文档。
---
name: explain-diff-html
description: Use when the user asks for a rich explanation of a code change, diff, branch, or PR. Produces HTML output.
---安装——两条命令

原件是 Geoffrey Litt 发布的一个公开 gist,里面有两个文件。explain-diff-html.md 生成单页 HTML,explain-diff-notion.md 生成 Notion 页面。装一个或两个都行;两个都装时,会按请求自动挑选。
安装就是建一个文件夹,把文件以 SKILL.md 的名字下载进去。把下面的命令粘贴到终端即可,不需要管理员权限,也不需要包管理器。
这里最常见的失误是文件名。直接存成 explain-diff-html.md 不会被识别。文件夹名是技能名,文件名永远是 SKILL.md——这就是 -o 后面那条路径的由来。
是否装好,打印 frontmatter 就知道。看到 name 那一行就成功了。已经打开的 Claude Code 会话可能还看不到新建的技能,重开一个会话使用更稳妥。
mkdir -p ~/.claude/skills/explain-diff-html
curl -sL https://gist.githubusercontent.com/geoffreylitt/a29df1b5f9865506e8952488eac3d524/raw/explain-diff-html.md -o ~/.claude/skills/explain-diff-html/SKILL.md
# 确认 — 能看到 name 行就说明装好了
head -4 ~/.claude/skills/explain-diff-html/SKILL.mdmkdir -p ~/.claude/skills/explain-diff-notion
curl -sL https://gist.githubusercontent.com/geoffreylitt/a29df1b5f9865506e8952488eac3d524/raw/explain-diff-notion.md -o ~/.claude/skills/explain-diff-notion/SKILL.md跑起来——该说什么
装好之后不必记命令。在代码仓库里打开 Claude Code,用平常的话说"讲讲这个分支相对 main 改了什么"就够了。技能的 description 与情境吻合,智能体会自行遵循那份文档。
讲解对象可以指定三种:整个分支与 main 的差异、某段提交范围,或尚未提交的工作区改动。技能要求智能体不只看 diff,还要广泛阅读周边代码,背景章节的质量就取决于此。
产物是一份自包含的 HTML 文件。CSS 与 JavaScript 都在里面,用浏览器打开测验就能用。它是带目录的一整长页,而不是若干标签页,并有基础响应式样式以便在手机上阅读。
保存位置写死在技能里:放在代码仓库之外的公共位置,文件名必须以当天日期开头,例如 /tmp/2026-08-01-explanation-isometric-view.html。理由有二——按时间排序,且不会混进版本管理。
打开产物只需一条命令:macOS 用 open,Linux 用 xdg-open,Windows 用 start。
讲讲这个分支相对 main 改了什么
# 其他指定方式
讲讲最近 3 个提交
讲讲我还没提交的改动# 找出今天生成的讲解文档
ls -t /tmp/$(date +%F)-explanation-*.html
# 打开(macOS)
open /tmp/2026-08-01-explanation-isometric-view.html把测验当作速度调节器

文档底部那五道题是这个技能的核心。难度指示很具体:中等难度、不许出脑筋急转弯,但必须理解变更实质才答得出来。题目是选择题,选完当场给出对错和解释。
为什么用测验?Litt 引用 Andy Matuschak 的"Books don't work"——人极难自行察觉自己读完却没读懂。Matuschak 与 Michael Nielsen 因此在文章中嵌入间隔重复测验,做出不理解就无法读完的文本。
同一装置被搬到代码评审上。Litt 给自己定的规则只有一句:测验没过,就不把智能体写的代码提交给团队评审。听起来幼稚,却经常拦住他。起点是一次他以为读懂了的 PR,同事问了最基本的问题,他答不上来。
他称之为速度调节器。所有 AI 工具都在往更快的方向施压。只提高正确性的速度、不提高理解的速度,认知债就恰好积在那个落差里。测验把两个速度强行绑回一起。
若要引入团队,建议保留为个人守则。你没法在 CI 里卡"人是否通过测验"。不如从"评审请求里附上讲解文档链接"开始——做文档的过程自然会把测验一起带上。
Notion 版有什么不同
explain-diff-notion.md 产出的不是文件,而是 Notion 页面。内容结构(背景、直觉、代码、测验)完全相同,只是输出不同。
差别在协作。文件在自己电脑上,Notion 页面则是团队一起看的东西。评论可以挂在段落上,讲解文档本身就成了讨论场所——同事可以直接在有异议的那一行对智能体的方案提出反对。Litt 在 Notion 工作是一层原因,但这个变体的目的,是把理解建立在团队而非个人尺度上。
有一个前提:必须连接 Notion MCP。MCP 是让智能体直接与外部服务对话的标准方式;接上 Notion 连接器后,智能体会创建页面并返回 URL。没有它,这个技能什么也产不出来。
测验的表现方式也不同。HTML 版用 JavaScript 判定点击,Notion 没有这种交互,于是改用折叠块。逐个展开选项,每项都会说明为何正确或错误。在你做出选择前答案不外露,这一点是相同的。
演示中,Notion 页面里甚至嵌入了交互式模拟——拖动坐标去体会这次变更改了什么。不过 Litt 附了一句警告:交互很容易变成拐杖,也很容易变成垃圾内容。只在静态图示确实做不到的地方才做交互。
按团队改造,以及另外两种技法
技能文件就是普通 markdown,直接改即可。真正会动的地方有四处。其一,章节构成——把团队每次都要问的东西(如回滚方案、性能影响)加成章节。其二,测验题数与难度。其三,保存路径与文件名规则,若希望积累到公司共享目录就改这里。其四,文风指示:原件要求以 Martin Kleppmann 的清晰度书写,你也可以改指你们团队推崇的某份文档。
也有最好别动的地方。原件明令禁止 ASCII 图示、要求用 HTML 画图,并要求代码块使用 pre 标签;若坚持自定义样式的 div,则必须把 white-space 设为 pre-wrap,并在保存前逐块检查。这是实践中常坏的一点,护栏留着为好。
同一场演讲还有两种技法。其一是微世界:让智能体做出只为帮助理解、永不发布的软件。Litt 为自己写的 Prolog 解释器做了一个能按时间轴逐步回放内部执行的调试器;把个人网站迁移到另一框架时,他让智能体做了一个小游戏,自己一步步点着完成迁移。脚本自动跑完结果一样,但手感留不下来。
其二是共享空间:人与智能体在同一线程里对话,讨论以评论形式留在文档上,把编码智能体请进团队的文档空间。它要解决的问题是:各自与自己的智能体一对一交谈,团队的理解就碎掉了。
三种技法共有一个动作:不止于让智能体写代码,还让它写出使代码可被理解的工具。代码变便宜了,用于理解的一次性工具也变便宜了。于是这份能力可以花在理解得更多、而不是更少上——这正是这场演讲的结论。
