6月8日到6月9日期间，三个很少写同一篇文章的人写了同一篇文章。 Google Cloud 人工智能总监 [Addy Osmani](https://x.com/addyosmani/status/2064127981161959567) 发表了“循环工程”，这是一种提示编码代理的系统分类法，这样您就不必这样做。 [Matt Van Horn](https://x.com/mvanhorn/status/2063865685558903149) 发表了“WTF Is a Loop?”，这是一项横跨 Reddit、X、YouTube 和 Hacker News 的研究，追踪了 2022 年 ReAct 论文中的想法到人们今天运行的编排循环。 Anthropic 的技术人员 [Lance Martin](https://x.com/RLanceMartin/status/2064397389189071163) 发表了“用 Fable 5 设计循环”，这两种模式通过设计循环而不是直接提示来充分利用前沿模型。

这三者都集中在同一个转变上：提示正在让位于为您提示代理的设计循环。这三个组件都与最重要的组件名称相同。奥斯马尼列出了五个组成部分，然后添加了第六个，并给出了他的文章中最有力的一句话：“国家文件是整个事情的支柱。” Van Horn 认为，由于一个结构性原因，当前一代的循环确实是新的：“耐久性变得明确，具有 git 支持的状态和崩溃恢复。”马丁将记忆描述为“跨越会话的外循环”。

目前诊断已达成共识。持久的外部状态是自治代理的承载部分。让我惊讶的是接下来发生的事情。三人都将工作交给了一个文本文件。

## 简单来说什么是循环

Van Horn 的定义是最简洁的：一个循环就是 cron 加上一个决策者的主体。 cron 作业运行固定的脚本。循环运行一个模型，该模型查看当前状态，决定要做什么，执行它，检查它是否有效，并决定是否继续下去。将它们堆叠起来，让一个循环调度其他循环，你就明白了鲍里斯·切尔尼（Boris Cherny）说他的工作是编写循环时的意思。

该循环内的模型会根据设计忘记运行之间的所有内容。上下文窗口结束。会话重新启动。所以系统中的某些东西必须不要忘记。循环读取该内容以决定下一步要做什么，并写入以记录发生的情况。它就是脊柱，奥斯马尼这样称呼它是正确的。

## 底物弃踢

以下是所有三篇文章中脊椎候选者的完整清单：一个 markdown 文件、一个线性板、提交给 git 的状态文件以及跨会话共享的已安装文件系统。奥斯马尼提供了前两个。范·霍恩 (Van Horn) 记录了第三个，这是史蒂夫·叶格 (Steve Yegge) 的煤气镇 (Gas Town) 用来协调二十到三十个克劳德 (Claude) 实例的方法。 Martin 使用第四个功能，即 Claude Managed Agents 的内存功能。

所有这些都解决了持久性问题。这些字节在重新启动后仍然存在。它们都不能解决诚信问题。询问这些底物中的任何一个，循环实际上需要回答的问题：这两个相互矛盾的注释中，哪一个是真实的，谁写的，何时写的，是否曾经被验证过？散文文件并排保存两个注释，并将对帐留给接下来读取该文件的模型。 Git 保留了歧义的每个历史版本，但没有解决它。共享挂载将最后写入胜利添加到顶部。

持久性和完整性是不同的属性。话语完全吸收了第一个，但尚未注意到第二个。

## 我们之前进行过这个实验

应用程序将其状态存储在平面文件中数十年。三种力量结束了那个时代：并发作者损坏了文件，积累的矛盾没有解决机制，回答问题意味着解析一切。数据库获胜是因为它们使完整性成为存储层的属性，而不是每个接触数据的程序所期望的规则。

这些力量中的每一个都在三个柱子内可见。

并发性在循环监督循环的时刻到来，这正是 Van Horn 所说的我们正在进入的阶段。两个循环写入一个状态文件与两个工程师在不交谈的情况下提交同一行是同样的失败。工作树通过代码解决了这个问题。当前工具链中没有任何内容可以解决[共享状态](/posts/when-agents-share-state-everything-breaks)。

马丁的基准测试结果记录了矛盾。在一项持续学习任务中，Sonnet 4.6 留下了一个记忆存储，他将其描述为失败注释和开放猜测的列表，包括诸如“也许 prc 而不是 prc_usd？”之类的条目。猜测不断累积。没有什么标志着一个人已经解决了。下一个会话将继承该堆。

质疑是范霍恩自己的妙语。他认为代理编码的昂贵部分现在是循环管理：停止条件、无进度检测和预算上限。其中每一项都需要将当前运行与之前的运行进行比较。在散文基础上，这意味着在每次更新时重新读取和重新解析不断增长的文件，这是一种随着循环年龄而增加的象征性税。

## 运行集群教会了我什么

我在自己的机器上运行了一群指定代理：一个用于客户智能，一个用于内容，一个用于外展，其他用于运营。在早期的设置中，每个人都在自己的文件中保存笔记。这些文件漂移了。同一个人以三个名字出现。一个文件中更正的事实在另外两个文件中未得到更正，并且没有记录显示哪个版本是最新版本或其中任何版本来自何处。

群体现在共享[一个结构化存储](/posts/from-memory-to-nervous-system)，而这篇文章本身就是一张收据。其背后的研究是由我的客户智能代理完成的，该代理获取所有三个 X 帖子，将每个帖子存储为包含参与编号和出处的打印记录，将竞争结果写入结构化分析中，并通过共享商店向其他两个代理提交后续任务。当我在一小时后提出后续问题时，比较结果被附加到具有自己的来源轨迹的相同分析记录中，而不是分散到新文件中。没有一个代理人重新推导另一个人已经建立的东西。

## 内存成熟度是一个底层属性

这三个帖子中最清晰的数据来自马丁的。他描述了内存使用的五个阶段：代理失败，调查原因，验证发现的内容，将答案提炼成规则，并在下次查阅该规则。完成所有五个任务的代理会将失败转变为经过验证的、可重用的规则。提前停下来的特工会留下一堆猜测。

他的结果都在同一个安装的文件系统上：Sonnet 4.6 在第一阶段停止，记录故障而不进行调查。 Opus 4.7 进入了验证阶段，但在中值运行中仅检查了大约 17% 的声明。 《神鬼寓言 5》完成了这一进程，验证率高达 73%。

相同的文件系统，截然不同的内存质量。差异完全在于模型的规则，因为文件系统不保证任何内容：每个阶段都是模型必须选择执行的行为。结构化存储将这些行为转化为数据操作。失败是存储的观察结果。调查正在调取相关记录。验证是附有出处的更正。蒸馏就是编写一条类型化的规则。咨询是有界查询。当基质承载进展时，任何模型都可以完成它。

## 循环状态层需要什么

从工具不可知论的角度来看，循环的主干应该提供六件事：键入的记录而不是散文 blob、每个字段的出处、计算当前事实而不是累积版本的更正、不能冲突的并发写入、仅返回当前标记所需的内容的检索以及从任何工具而不是某个供应商的堆栈进行访问。

为了公平地对待文本文件：对于一个存储库上的一个循环，[markdown 确实很好](/posts/the-markdown-memory-ceiling)。它是可读的、可区分的并且免费的。强制函数是第二个循环，第一次两个进程关心相同的事实，并且两个进程都不能信任对方所写的内容。

## 文件记得，记录系统知道

范霍恩在结束他的文章时认为，循环是管道，持久的资产是它所调用的技能库。我想，对了一半。技能是程序性记忆，即如何重复工作。在它们的下面是事实记忆，即每项技能调用所依赖的当前真实情况。两者都是复合的，但前提是事实层在一千次无人值守的写入之后可以被信任。

我构建了 [Neotoma](https://github.com/markmhendrickson/neotoma)，因为我自己的群体需要该层：类型化观察、每个字段的出处、解决当前事实的修正，以及我运行的每个代理的共享访问。循环话语只花了一周的时间描述它所填充的位置，但没有命名任何填充它的东西。

奥斯马尼在文章的结尾提出了像那些打算继续担任工程师的人一样构建循环的建议。状态层是可以测试意图的地方。文件记得。记录系统知道。