安装此技能
npx skills@latest add mattpocock/skills --skill=retro 然后在你的编码 agent 里输入 /retro 。
本页目录
它做什么
retro 回顾一场编码会话(session),并就 agent 的**环境(environment)**提出改进建议,好让下一次运行更顺利。它读这场会话自己的记录(默认是当前这场,也可以是你指向的会话日志中的某一场)。它找出 agent 挣扎过的那些时刻,并给你一份候选修法清单,最严重的排在最前面。
它改的是环境,不是代码。拿 agent 交付出去的 bug、它花了二十次工具调用(tool calls)才找到的文件,或者审查者漏掉的那条规则来说。retro 不直接修复其中任何一个。它问的是:仓库里有什么东西让这些得以发生;然后它提议那项能防止它们下次再发生的检查、指针或标准。而且它只是提议。在你挑中一个候选之前,什么都不会改变。
什么时候用它
你通过输入 /retro 来调用它;agent 不会主动去拿它。
在一场比本该有的难度更难的会话结束时用它。比如,agent 找某个东西找了太久、犯了一个工具本可以抓住的错误,或者需要它拿不到的信息。一场顺利的会话没什么可教的,发现来自那些困难的会话。如果你想对这场会话产出的代码要一个判决,改用 code-review。
结论落在哪里
每个候选都属于一个类别,而类别决定修法落在哪里:
| 会话里出了什么问题 | 用什么修 |
|---|---|
| agent 花了很久才找到一个文件或事实 | 从它已经读取的某个文件里加一条导航指针 |
| 它犯了一个工具本可以抓住的错误 | 一项**自动化检查(automated check)**:lint 规则、类型、测试、pre-commit 钩子、CI 任务 |
| 审查者漏掉了一个属于主观判断的错误 | 给审查代理的 CODING_STANDARDS.md 里加一条规则 |
AGENTS.md 或 CLAUDE.md 很大 | 把它的引导内容挪出去,挪进标准或检查 |
| 一次工具调用相对于它返回的东西太贵了 | 精简这个工具,或者替换它 |
| 一个引导文件(steering file)里塞满了不改变任何行为的内容 | 删掉这些空操作(no-ops) |
| agent 需要它够不到的信息 | 放宽它的访问权限:把开发服务器日志 tee 到文件、给某个服务只读权限 |
核心观点是:标准属于审查者,而不属于实现者。负责实现的 agent 承受着最大的上下文压力,因为它在探索、写代码、调试失败。负责审查的 agent 只拿到一个 diff,别的什么都没有。所以一条新规则要去有空间应用它的地方,也就是审查环节。它永远不会进 AGENTS.md,那个文件无论相关与否都会加载进每一场会话的上下文窗口(context window)。
在 retro 写下任何规则之前,它会先给违规分类。**机械性(mechanical)**违规(一个被禁用的 API、一种 import 形状、一条文件位置规则)会得到一项确定性的检查,因为检查可以失败,而标准文件里的一句话不能。只有真正的、任何 linter 都无法强制的按判断行事的决定,才会变成散文。如果仓库完全没有防护栏(没有 pre-commit 钩子,也没有跑 lint、类型检查和测试的 CI 任务),retro 会把这一点作为它自己的发现报告出来。
常见问题
它会自己写 lint 规则,还是等你点头?我能把它接成每场会话后自动运行吗?
它会等。retro 只提议。在你挑中一个候选之前,什么都不会改变,所以它不会手工编辑任何东西,也不会自动安装任何钩子。这是刻意的。有一位用户在被「会拦住好改动的自动钩子烧过」之后,明确提出了这个要求。决定什么值得一项永久检查需要判断力,所以这个技能保持人在回路(human-in-the-loop)并由用户主动调用。有些用户确实会在每次实现运行之后跑它。但一场顺利的会话没什么可教的,所以每场会话后都跑一次,大多只会产出没人需要的规则。没有试运行模式。一个被提议的检查就是一段普通的代码,所以在让它拦住合并之前,先拿仓库试一遍。
这不会让 lint 规则永远堆下去吗?它有没有提过删掉一条?
部分会,而这是它最弱的地方。它能删除散文:引导文件里的空操作,以及 AGENTS.md 或 CLAUDE.md 里本该属于标准或检查的引导内容。当这些文件很大时,它会把这些标出来供删除。它是对照它所读的那一场会话来判断的,所以把每一条都当作删除测试的候选,而不是裁决。它不会审计它上个月提议的那些 lint 规则、钩子或 CI 任务。它只看到一场会话,所以它无法告诉你某条规则现在触发得太频繁,或者它背后的 bug 已经没了。你仍然必须自己修剪检查。一条频繁对好代码触发的规则,就是要删掉它的信号。
它不会为了填满自己的类别,就编造一些泛泛的建议吗?
这是对它最强烈的批评。有一位用户发现:「任务一结束,AI 往往就忘了会话中段的那些挣扎,转而编造泛泛的建议来满足 retro 的各个类别。」每一条候选都必须来自这场会话自己的记录,所以建议是那场会话特有的。这有代价,也有好处。它很少编造无关的东西,但它可能给这场会话恰好涉及的内容过大的权重。丢掉任何你追溯不到具体时刻的候选。也把严重程度排序当作初稿,因为一个安静而昂贵的错误,可能排在一个喧闹而廉价的错误后面。
我的会话很长。现在跑它,还是开一场新的?
默认情况下,它审查当前会话。那是最好的情况,因为那些挣扎还在上下文窗口里。如果这场会话已经移出了高效区(smart zone),就清除(clearing)它,然后让一场全新的 /retro 指向会话日志里的上一场会话。
agent 老是犯同一个错误。我该往 CLAUDE.md 里加一行吗?
通常不该,而 retro 在这件事上比在任何别的事上都更坚持反对。CLAUDE.md 里的一行会加载进每一场会话,削弱文件里其他一切内容的分量,还会随着代码变化而过时。如果这个错误是机械性的,修法就是一项会失败的检查。如果它属于主观判断,就写进审查者所读的编码标准。AGENTS.md 和 CLAUDE.md 是给导航指针用的,除此以外没多少别的用途。同样的原因,retro 不是一个记忆系统(memory system)。它不存储发生过什么。它改变环境,让这个错误无法再次发生。
我的配置提到了 CODING_STANDARDS.md,可我没有这个文件。它是从哪来的?
没有技能自带这个文件。当一场会话第一次为审查者找到一条主观判断规则时,retro 会提议创建它。在你接受之后,code-review 会读取它。你已有的任何其他标准文档,比如 CONTRIBUTING.md,作用方式相同。
它和 improve-codebase-architecture 有什么不同?
输入不同。improve-codebase-architecture 只需要代码,并在代码里寻找结构性改进。retro 需要一段会话历史,改进的是 agent 工作所处的环境,而不是代码。两者你都会用;谁都不取代谁。
它生效的标志
- 每一条候选都指回会话中一个具体的时刻,而不是一条泛泛的最佳实践。
- 重复出现的错误变成会失败的检查,而你的
AGENTS.md随着时间变短,而不是变长。 - 如果某项检查已经存在但没有接上,发现的内容是把它接上,而不是提议新建一个。
- 下一场做同类任务的会话,能更快找到它需要的东西。
它在体系中的位置
retro 是主链的最后一步,你在这里回顾这条链走得怎么样:
grill-with-docs → to-spec → to-tickets → implement → code-review → retro
在一次值得学习的构建之后运行它,就在同一场会话里,或者指向那场会话的日志。一次顺利的构建之后,你可以跳过它。
- code-review 是
retro最常调校的那个审查代理。新的编码标准会放到它的标准维度读取的地方。 - writing-for-agents 为
retro提议的每一个引导文件和技能设定写作风格,而retro会在开始前加载它。
当你不确定这个处境需要哪个技能时,ask-matt 会在整套技能之间为你路由。