智能体循环:Claude Code 的创建者不再编写提示词,而是编写循环

代理循环:Claude Code 的创建者不再写提示词,而是编写循环


“我不再给 Claude 写提示词了。我让一些循环运行起来,由它们向 Claude 提示并决定该做什么。我的工作就是编写循环。”这句话出自 Boris Cherny,Claude Code 的创建者。这段视频在 X 上发布后的 24 小时内获得了大约 70 万次观看。此后,所有人都在谈论“循环工程”,但几乎没人解释如何构建一个循环。

我们来解决这个问题,从零开始。唯一的前提是,你至少已经在 Claude Code 中输入过一次问题。我们会先看看那个已经在你眼前运行、只是你还不知道的循环,然后构建一个真正的循环,分为三个难度等级,并提供可复制的文件以及准确的放置位置。

顺便我们还要澄清一个非常普遍的误解:Claude Code 的 /loop 命令并不是改进循环,而是一个计时器。

五个词汇,搞清楚就够了

如果你刚开始接触,混乱有一半来自术语。定义五个词,我们就不再纠结这个问题。

  • 工具:Claude 有权在你的机器上执行的一项操作。读取文件、写入文件、在终端中运行命令、搜索网络。Claude 不会亲自执行这些操作,而是提出请求,由 Claude Code 程序代为执行。
  • 一轮:一次完整的往返。Claude 发言,工具运行,结果返回给 Claude。一个稍微复杂的问题可能需要五轮、十轮甚至三十轮,而你看到的只是在终端中不断滚动的文字。
  • 上下文:Claude 在某一时刻能够看到的全部内容。你的请求、读取的文件、命令输出。上下文是有限的,会逐渐填满;当它满了,Claude 会总结旧内容来腾出空间。这个总结过程叫作压缩,而它会丢失细节。
  • CLAUDE.md 文件:放在项目根目录下、每次会话开始时加载的文本文件。这是你的永久内部规章。与只在对话中给出、可能在压缩时消失的指令不同,根目录下的 CLAUDE.md 会在压缩后重新读取并注入。
  • 子代理:由主 Claude 为一项具体任务启动的、用完即弃的 Claude,它拥有全新的独立上下文。它在自己的环境中工作,只有结论会返回。它是 .claude/agents/ 中的一个 Markdown 文件,你想写多少个都可以。

再补充第六个词,也就是下面将改变一切的那个词:钩子,是你编写的一段小脚本,Claude Code 会在特定时刻自动执行,例如在写入文件之前,或即将交还控制权之前。它是脚本,不是 AI。你让它做什么,它就始终一成不变地做什么,而且不消耗任何令牌。

那个早已在运行、无需你提出任何要求的循环

在构建任何东西之前,必须先看清已经存在的循环。Anthropic 关于代理循环的文档将其描述为五个阶段,而每次你按下回车键时,实际发生的正是这一过程。

  1. 你发送请求。
  2. Claude 读取请求并作出回应,要么以文本回答,要么请求使用工具。
  3. Claude Code 执行所请求的工具。
  4. 结果返回给 Claude,并添加到上下文中。
  5. 回到第 2 步,直到 Claude 在不请求任何工具的情况下作出回答。这条消息会结束循环。

Les cinq temps d'un tour d'agent, avec la flèche de retour qui referme le cycle

举个具体的例子。你输入“修复 auth.ts 中失败的测试”。下面才是真实发生的过程,尽管你看到的只是满屏滚动的文字:

回合Claude 请求什么它得到什么
1运行 npm test三个失败的测试
2读取 auth.ts 和测试文件两个文件的内容
3修改 auth.ts,重新运行 npm test全部通过
4什么也不做,它用文字回答结束,循环停止

四个回合。你只写了一句话,却发生了四次往返、六次工具调用和一次停止决策。这就是循环。

记住这个结论,因为这就是全文的核心:一个代理本来就是一个循环。你在它之上添加的一切——子代理、钩子、配置文件、斜杠命令——都只服务于一件事:决定它何时有权停止。

问题也正在这里。默认情况下,是 Claude 自己决定何时完成。第 4 回合时,它认为已经没问题了。它没有检查项目是否仍然能够完整编译,也没有检查其他地方是否被破坏。它只是产生了已经完成的感觉。进行循环工程,就是收回这个决定,把它交给比感觉更不主观的东西。

四类循环

Claude Code 团队将循环定义为“代理不断重复工作周期,直到满足停止条件”。循环有四种,它们的用途完全不同。这张表值得随手保存。

类别触发方式停止条件用途
按回合你的提示词Claude 认为自己已经完成日常工作、短任务
按目标/goal你的提示词目标已达成,或回合配额已耗尽一切具有可验证标准的任务
按时间/loop一个时间间隔你取消,或会话关闭监控、外部系统
主动式一个事件,无需你参与每项任务在达到目标时结束错误分类、迁移、版本升级

不,/loop 并不会改善任何事情

混淆源于它的名字。看看它真正做了什么:

/loop 5m vérifie si le déploiement est terminé

每五分钟,Claude Code 都会逐字返回同一个提示词。不是每次运行都“更好”:而是完全相同。文档说得很清楚,该命令“只要会话保持打开,就会重复运行一个提示词”。它是一个有大脑的 cron,而不是不断上升的螺旋。不过,仍有两个实用细节:如果省略时间间隔,Claude 会在两次迭代之间自行安排节奏;如果省略提示词,它就会读取 .claude/loop.md

真正能带来改进的命令是 /goal。它接受一个自然语言条件,只要该条件为假,Claude 就会在多轮中持续工作:

/goal monte le score Lighthouse de la page d'accueil à 90 ou plus, arrête après 5 essais

这一行中有两点很重要;如果你只记住整篇文章中的一段,就记住这一段。

首先是“90 或更高”。可衡量的条件可以毫无争议地进行验证。比较一下“让页面更快”:比什么更快,由谁来判断?循环需要一个数字或一个通过的测试,而不是一个形容词。编写循环,首先就是迫使自己把愿望转化为可验证的标准,而这确实是最困难的部分。

其次是“5 次尝试后停止”。没有计数器的循环,就是一张账单。模型永远不会疲惫,永远不会厌倦,也完全不知道第 30 次尝试要付出什么代价。

“我在 .claude 中的那些代理,已经算是一个循环了吗?”

这是我收到的头号问题,答案是否定的。好吧,也不完全是,而其中的细节值得一说。

我们来看一个经典配置,这是很多人经过几周后最终会写出的配置:一个在编码前进行设计的 architect 子代理,一个负责实现的 developer 子代理,一个负责审查工作的 reviewer 子代理,以及一个规定调用顺序的 CLAUDE.md。这很整洁,也很有用,能避免大量错误。但就其本身而言,它是一条链,而不是一个循环。

Comparaison entre une chaîne d'agents qui se termine et une boucle d'agents qui se referme sur elle-même

区别只在于一条铅笔线。在链中,审查者是最后一个环节:它提交报告,然后这一轮就结束了。在循环中,它的报告会重新成为开发者的输入,只要结论不理想,流程就会再次开始。

一个循环需要三个要素,而第三个正是我们总会忘记的那个:

  • 一个可重复的操作,这一点你已经具备了,就是你的代理链,
  • 一个可衡量的停止条件,不是“达到良好状态”,而是“构建通过,并且审查者不再发现任何阻塞性问题”,
  • 一条返回边,也就是说,一条将审查者的输出重新交到开发者手中的路径。

没有第三步,你的审阅者会在最后生成一份漂亮的报告,却没人阅读。有了第三步,链条就会变成一个循环,程序也会在每一轮中不断改进。好消息是:补上这条边只需十来行代码。

级别 1:你的第一个循环只需一行

在编写任何文件之前,请先知道:只需在 Claude Code 中输入下面这行,就能获得 80% 的收益:

/goal le build passe et les tests sont verts, arrête après 5 essais

Claude 会编写代码、运行 build、发现错误、修复错误、重新运行;只有在条件为真或五次尝试用尽后,它才会把控制权交还给你。你刚刚完成了循环工程。真的。先试试这个,再考虑其他方法。

限制在于,这只会持续到当前命令结束。明天开启新会话时,你必须重新输入一遍,而且你会忘记这件事。因此才有后面两个级别,它们会让这条规则永久生效。

级别 2:“完成”的定义,一次写定

CLAUDE.md 会在每次会话开始时加载。放在项目根目录下的文件,在上下文压缩后也会再次读取并注入。SDK 文档对此有明确说明:持久规则应放在那里,而不是放在第一条消息中,因为第一条消息最终会消失。因此,这里就是停止条件的存放位置。

如果文件不存在,请在项目根目录创建它,并添加以下代码块:

## Definition of Done

Une tâche n'est considérée comme terminée que si toutes les conditions applicables sont vraies :

1. le build réussit
2. les tests concernés passent
3. le sous-agent reviewer retourne VERDICT: PASS
4. HISTORY.md et la version du projet sont mis à jour lorsque la nature du changement le nécessite

Tant qu'un point est faux : corrige, puis reprends au point 1.

内容简短、条目编号清晰,尤其是最后一行明确画出了返回边。从现在起,在大多数情况下,Claude 会自行检查并自动回退重来。

是的,大多数情况下如此。但不是全部情况。模型终究是模型,偶尔会在实际上尚未完成时认定自己已经完成,尤其是在长会话接近尾声时。如果你希望这成为一条法律,而不只是一条建议,就需要级别 3。

级别 3:Stop hook,有权说“不”

下面是我们将得到的完整目录结构。所有内容都位于项目根目录下的 .claude/ 文件夹中,如果不存在就创建它。

votre-projet/
  .claude/
    settings.json          quels hooks lancer, et quand
    agents/
      reviewer.md          le sous-agent relecteur
    hooks/
      done-or-continue.sh  le script qui accepte ou refuse la fin
  CLAUDE.md                les règles permanentes (niveau 2)

1. 输出机器可读判定结果的审阅者

审阅子代理的陷阱在于,它输出的是散文。文字通常写得很好,也往往是正确的,但无法从中提取自动决策:没有任何脚本能够读懂“总体来说没问题,但我对错误处理还是有些疑虑”。因此,我们要求它输出一个规范化的最后一行,这样一切就都有可能了。

文件 .claude/agents/reviewer.md。两条虚线之间的部分称为 frontmatter,是代理的身份信息。其余部分则是代理的指令。

---
name: reviewer
description: Relit le travail après chaque implémentation terminée.
model: opus
tools: Read, Glob, Grep, Bash
---

Tu relis UNIQUEMENT ce qui vient de changer (le diff, plus les fichiers non suivis).
Classe chaque remarque en CRITICAL, WARNING ou INFO.
Tu n'écris jamais de code, tu ne commites jamais.

Écris ton rapport dans .claude/last-review.md et termine-le par une ligne seule :
VERDICT: PASS   s'il ne reste aucun CRITICAL
VERDICT: FAIL   sinon

请注意,tools: 列表中既没有 Edit,也没有 Write。因此,reviewer 无法访问专门的文件修改工具。不过,它仍然保留了 Bash,在这里需要用它检查 Git diff 并记录报告。因此,必须明确禁止它修改生产文件。我们应尽可能将开发者与评判者分开,以便对变更保持独立的审视。

2. 拒绝结束回合的脚本

Stop hook 会在 Claude 想要把控制权交还给您的瞬间触发。它有权拒绝。文件为 .claude/hooks/done-or-continue.sh,使用 chmod +x 使其可执行:

#!/usr/bin/env bash
# Refuse la fin de tour tant que la Definition of Done est fausse.
set -uo pipefail

[ -f .claude/loop.off ] && exit 0          # interrupteur d'urgence

STATE=.claude/loop-count
COUNT=$(cat "$STATE" 2>/dev/null || echo 0)
if [ "$COUNT" -ge 5 ]; then                 # disjoncteur
  rm -f "$STATE"
  exit 0
fi

if ! npm run build >/tmp/build.log 2>&1; then
  echo $((COUNT + 1)) > "$STATE"
  jq -n '{decision:"block",
          reason:"Le build casse. Lis /tmp/build.log, corrige, puis reprends."}'
  exit 0
fi

if ! grep -q "VERDICT: PASS" .claude/last-review.md 2>/dev/null; then
  echo $((COUNT + 1)) > "$STATE"
  jq -n '{decision:"block",
          reason:"Build vert mais pas de VERDICT: PASS. Relance le sous-agent
                  reviewer, applique les CRITICAL, puis reprends."}'
  exit 0
fi

rm -f "$STATE"
exit 0

如果您不熟悉 bash,下面按顺序用法语说明同样的内容:

  • 如果文件 .claude/loop.off 存在,则什么也不做,让 Claude 停止。这就是您的开关:执行一次 touch .claude/loop.off,循环就会被禁用,无需终止任何进程。
  • 读取存储在一个小文件中的计数器。如果计数器已经达到 5,则放弃并放行。这就是断路器,可以避免无限循环。
  • 启动构建。如果构建失败,就递增计数器,并以一个原因返回 block。Claude 无法停止,并会将该原因作为新的指令接收。
  • 如果构建通过,则在审阅者报告中查找 VERDICT: PASS 这一行。如果不存在,则再次阻止,并明确说明需要执行的操作。
  • 如果一切正常,则清除计数器并静默退出。Claude 可以完成任务。

只需三个字段就能控制这一切,入门时无需了解其他字段。decision: "block" 会阻止 Claude 停止,并将您的 reason 作为新的指令传递给它。无论发生什么,continue: false 都会终止一切。而 hookSpecificOutput.additionalContext 则会注入一条备注而不进行阻止,适用于您希望引导而非强制的情况。对于尚未安装 jq 的用户,请注意:hook 可以将说明写入错误输出,然后以 exit 2 结束。对于 Stop hook,这同样会阻止 Claude 停止,并将该消息作为反馈传递给它。不过,这种方法不使用结构化 JSON 响应:请选择使用带有 stderr 消息的 exit 2,或者使用 JSON 对象的 exit 0,但不要混用这两种方式。

3. 声明 hook

接下来只需告诉 Claude Code 何时运行这个脚本。文件 .claude/settings.json

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          { "type": "command", "command": ".claude/hooks/done-or-continue.sh" }
        ]
      }
    ]
  }
}

4. 验证是否有效

这是最简单的测试。务必真的做一遍,否则你会怀疑三天。故意弄错一行代码,要求 Claude 做任意一个小修改,然后让它尝试完成。它应该会自动重新开始并进行修正,同时让你的 reason 语句显示在屏幕上。如果什么都没发生,请按顺序检查:脚本是否具有可执行权限,settings.json 中的路径是否正确,以及在终端中手动运行脚本是否会产生错误。

结果是:开发者编写代码,审阅者进行评判,hook 在结论通过之前拒绝退出,最多运行五次后再妥善放弃。这样,你就有了一个循环。

生产环境使用说明

这里展示的循环特意保持了最小化,以便更容易理解其机制。一个旨在真正项目中自主运行的版本还应该:

  • 验证审阅者的结论是否对应当前的 Git diff;
  • 拒绝过时或不完整的结论;
  • 检查功能验收标准;
  • 检测预定范围之外被修改的文件;
  • 当某项检查无法执行时妥善失败;
  • 强制限制循环次数。

原则保持不变:衡量项目状态,修复失败之处,然后不断重复,直到所有退出条件真正得到满足。

今晚可以尝试的三个循环

一些无害的示例,难度从低到高。

/goal tous les tests passent, arrête après 5 essais

经典用法。适用于任何拥有测试命令的项目。

/goal plus aucun avertissement du linter dans src/, arrête après 3 essais

这是非常好的第一次尝试,因为标准是二元的,修复也不会带来风险。

/loop 10m regarde les nouveaux fichiers dans ./inbox, résume chacun dans ./resumes

这是一个监控循环,而不是改进循环,很好地体现了两者的区别。它不会取得进展,而是在等待和观察。

自我改进的循环

还差最后一层。到目前为止,循环改进的是程序。它也可以改进自身,这正是 Andrej Karpathy 于 2026 年 3 月通过其 autoresearch 仓库推广的模式。该仓库在几周内便在 GitHub 上获得了超过 50,000 个星标。其原理可以用 README 中的一句话概括:给一个代理一个真实的小型模型训练任务,它修改代码,训练五分钟,检查指标是否有所改善,保留或丢弃结果,然后重复这一过程。整整一夜。

与简单的 /loop 的区别在于记忆。一个文件,智能体在每次开始执行时都会重新读取,并在结束时用刚刚学到的内容更新它。没有这个文件,第 200 次迭代和第 1 次一样愚蠢,带着同样的热情重复同样的错误。

将其应用到一个普通项目中,就是在 CLAUDE.md 中多加几行:

## Auto-amélioration

Avant de rendre la main :

- si j'ai dû te corriger, ajoute la règle correspondante dans LESSONS.md,
  une phrase sèche, à l'impératif, jamais une explication
- si une étape a été refaite deux fois, note pourquoi dans NOTES.md
- si une vérification manuelle revient à chaque chantier, transforme-la
  en script

LESSONS.md est relu au début de chaque session, avant toute action.

一个月后,LESSONS.md 比代码更有价值。它记录了循环不会再犯的错误。而且这是所有人都会忘记填写的文件,尽管填写它不花任何成本。

代价高昂的新手错误

所有在生产环境中运行循环的人都会反复遇到一些模式,它们不怎么光鲜,但正是它们支撑着整个系统。

  • 停止条件含糊不清。“代码整洁时”不是条件,而是一种看法。如果你无法用一条能回答“是”或“否”的命令来验证它,你的循环就永远不会在正确的时刻停止。
  • 没有上限。 SDK 提供了 max_turnsmax_budget_usd,达到限制时,结果会返回明确的子类型(error_max_turnserror_max_budget_usd),而不是悄无声息地失控。利用好这些机制,并且始终从较低的上限开始。
  • 同一个智能体既执行又验证。在同一个上下文中,它总是会带着善意重新检查自己的工作。子智能体从全新的上下文开始,能提供真正的外部视角,而且成本更低,因为只会返回它的结论。
  • 同一目录中运行两个循环。它们会互相覆盖文件。Git worktree 几乎不花什么成本就能解决这个问题。
  • 没有开关。始终准备一个可以手动创建的标记文件,以便在不杀死进程的情况下完全停止一切。你会比想象中更早需要它。
  • 所有任务都使用最大模型。一个每五分钟运行一次的循环,每天就是 288 次执行。模型和努力程度的选择是成本控制的首要杠杆,重要性远远超过其他因素。

说到成本:一个没有设置边界的循环,是已知唯一能让你在午餐时间花光月度预算的方法。先从一个范围狭窄的目标、五轮的上限开始,看看它消耗多少资源,再放开限制。

两周后:咬伤我的四件事

我在 7 月 26 日写下了这篇文章。从那以后,我每天都在自己的 .NET 项目上实际运行这套机制。上面描述的结构经受住了考验,我一行都没有删。但有四件事咬伤了我,而且在写下其余内容时,没有一件是可以预见的。下面按它们让我付出代价的顺序列出。

1. 审阅者不应该写下自己的结论

前文中,我让审阅者以 VERDICT: PASS 结束。对脚本来说,这样读取很方便,但这是个糟糕的主意。

一个给自己签发公告的代理什么也证明不了。它可以在报告中列出三个严重问题,然后因为觉得最后一句话更讨喜,就以一个 PASS 作结。没有任何东西能验证这个判定是否与上面的内容相符。

正确的做法是:由 hook 读取报告,并从中推导出判定结果。在文本中找到一个 [CRITICAL],结果就是 FAIL,不管代理在页面底部写了什么。然后,hook 会将判定结果连同类似 writtenBy: "hook" 这样的标记写入自己的文件,并忽略任何不带该标记的判定文件。想主动写入自己的判定结果来节省时间的代理,就会因此被拒绝。

代理负责生成文本。hook 负责生成判定。永远不要由同一只手完成这两件事。

2. 单独一个判定没有任何意义

存放在文件中的一个 PASS 只说明:有人在某个时刻审阅过某些东西。如果不把它绑定到代码的某个确切状态,它就会永远有效,即使之后已经进行了二十次修改。

解决办法只有一行。在记录判定结果时,计算一份已修改文件内容的指纹,并将其存放在旁边。每轮结束时,重新计算一次。指纹不同,判定过期,就要重新请求审阅。

但这会带来一个我事先没想到的问题。如果指纹也涵盖文档,那么在审阅后修正 NOTES.md 中的一句话,就会使判定过期。在我这里,结果变成了世界上最愚蠢的场景:审阅指出文档中有一处表述不准确,我修正了它,而这个修正又触发了一次完整审阅。同一个项目连续发生了两次,总共浪费了大约 75,000 个 tokens,却完全没有验证任何东西。

修正方法是:使用两份指纹,而不是一份。第一份涵盖整个修改集,第二份涵盖同一个修改集,但排除不具行为性的文字内容(README、备注、文档)。如果第一份发生了变化而第二份没有变化,就说明没有任何代码行被修改,判定仍然有效。不过仍需注意:一个本身就是行为的 Markdown 文件、代理提示词、一个 SKILL.md、一条命令,都必须计入第二份指纹。这不是文档,而是用法语写成的代码。

3. hook 输出到屏幕上的内容不会传到任何地方

这一点最隐蔽,也是它让我浪费时间最多。

一个 Stop hook 正常结束,返回码为 0:它打印的所有内容都会进入调试日志。不会传给你,不会传给 Claude,也不会进入 transcript。因此,我精心撰写的解释性消息连续数周都无人看到;我还以为这套机制没有反应,实际上它运行得非常正常。

真正有效的做法,是通过标准输出发送 JSON。共有三个通道,而它们的作用各不相同:

{"decision":"block","reason":"..."}
        relance un tour, et le modele LIT le contenu de reason

{"systemMessage":"..."}
        s'affiche a VOUS, sans relancer le modele, donc gratuit

{"hookSpecificOutput":{"hookEventName":"Stop","additionalContext":"..."}}
        le modele le lit et le tour continue, donc ca coute un tour entier

第一个是循环的引擎。第二个用于让你了解情况,不会产生额外成本。第三个会重新启动模型,为它提供上下文,但不会阻塞:只有在模型确实需要据此采取后续行动时才应使用它,否则你会为了说明一切正常而付出一整个往返的成本。

我从中得出的规则是:如果你的循环看起来什么也没做,那它可能并不是坏了,而是在对着空气说话。

4. 每一轮都触发的循环会变得难以忍受

上面描述的设置会在每一轮结束时闭合循环。从技术上说没错,但用起来让人筋疲力尽。

我查看了自己十一天的数据:启动了 71 次复查,而真正完成的任务只有 16 个。也就是说,每个任务平均复查 4.4 次,而且每次都按全价付费。其中大约一半只是为了重新确认一段已经通过验证的代码,而我只是改了一个逗号。

其实我早就预留了一个方法,可以在编码时暂停循环。十一天里我用了三次。就在这时,我意识到了一件令人不适的事:写在 CLAUDE.md 里的规则并不是一种机制。模型每一轮都会重新读到它,却还是会忘记,因为它正忙于处理任务。

修正方法是反转默认行为。任务在第一次写入时就自动进入延后模式。只要它处于打开状态,hook 就不再要求每一轮都做任何事情。然后,一个 UserPromptSubmit hook 会在每次回复前注入两行状态:当前是哪个仓库、涉及多少个文件、已经持续了多少轮。没人会使用这个功能,实在可惜。超过某个阈值后,它会告诉代理向我提议关闭任务。由它在恰当的时机提出问题,而不是让我自己记得去想这件事。

还有最后一点,而且很重要:延后绝不能变成取消。复查债务仍然必须偿还。标记会在十五轮后、会话切换时,或四小时后自动过期。被遗忘的任务最终总会要求进行复查。

这四点有一个共同之处,我在写下它们时突然看得非常清楚。每一次,我都在相信某些未经测量的东西:代理自行给出的结论、这个结论的新鲜度、我的消息确实会被某个人读到,以及我自己的自律。一条循环之所以能够维持,并不是因为它设计得好,而是因为它所依赖的每一件事都是可以验证的事实,而不是一句承诺。

让它在没有你的情况下运行

循环闭合之后,就可以把它接到键盘之外的其他东西上。Anthropic 推荐的组合方式很简单:叠加一个时钟和一个目标:

/schedule every hour: check #project-feedback for bug reports.
/goal: don't stop until every report found this run is triaged,
actioned, and responded to.

前者决定何时执行,后者决定执行到什么程度。这正是 Cherny 所描述的:数百个实例读取 GitHub issues、Slack 反馈和 X 上的讨论串,以找出下一件要做的事。键盘前无人操作,但工作仍在推进。不过,在你亲眼观察第 1 到第 3 层运行几天之前,不要急着走到这一步。

这具体会带来什么变化

从提示词转向循环,并不只是词汇上的时髦变化。写一个提示词,是请求一个结果。写一个循环,则是描述什么才算好结果,然后让机器不断撞向这个标准,直到达到它。工作重点发生了转移:减少措辞,增加验收标准、可自动化的检查和安全护栏。

就我个人而言,我认为最被低估的部分是 VERDICT: PASS 这一行。强制子代理输出三个词,就能把一份散文式报告变成十行 shell 脚本可利用的停止条件。这才是真正的循环工程:让原本无法测量的东西变得可测量。剩下的,只是管道工作。

来源

Join the conversation

You need an account to comment on this article. Creating one is free and takes under a minute.

  • The XMLTV file, free to download every day
  • Comment on articles and reply to other readers
  • Get an e-mail when an article you follow is updated

No comments yet.

Une erreur s'est produite. Cette application peut ne plus répondre jusqu'à ce qu'elle soit rechargée.Veuillez contacter l'auteur. Reload 🗙