几个月前，我写了一篇关于 [my agentic stack](/posts/what-my-agentic-stack-actually-does) 的文章：一个私有 monorepo，其中 AI 代理处理我的电子邮件、付款和部署，并以 [Neotoma](https://neotoma.io) 作为底层的结构化内存。那篇文章以一个承诺结束。我说我是策略层，架构的设计就是为了让这个角色可以被软件取代。这是关于这样做的帖子。

[Ateles](https://github.com/markmhendrickson/ateles) 是我继 Neotoma 之后的第二个产品，它直接构建在它之上。这是一个个人特工群。旧的堆栈是每个会话有一个代理，我在循环中处理每项任务，而 Ateles 是一组按角色定义的代理，通过 Neotoma 进行协调，每天在 launchd 下运行。这是我驾驶每个代理和我指挥一个已经了解其工作的团队之间的区别。

这篇文章解释了我为什么要构建它、它是如何工作的以及它的用途。

## 为什么堆栈停止扩展

触发因素是成交量。在二月底 Neotoma 的[开发者版本](/posts/neotoma-developer-release) 之后，我的注意力分散在三种没有太多共同点的模式上：构建产品、营销产品以及管理与早期用户的关系。我还向 Neotoma 提供了越来越多关于我的生活的背景信息，无论是职业还是个人，记忆力越好，单个特工可以利用它做的事情就越多。这并没有消除约束，而是移动了它。极限不再是特工所知道的。我是唯一一个将他们所知道的转化为行动的人，一次一个疗程。

旧的方法是一套特定于存储库的规则和技能。他们让我避免在程序上重复自己。一项技能定义了电子邮件分类或网站部署的步骤，任何会话都可以针对 Neotoma 中已有的上下文运行它。这种方法一直有效，直到会议变得繁忙为止。

失败是具体的。当一个通用代理同时承担所有规则和每个角色时，它并不能均匀地承担所有规则和角色。在任何特定的转弯处，它都会专注于一种工作，而让其他工作顺其自然。它很好地起草了电子邮件，却忘记了关于我如何签字的现行规则。它修复了错误并跳过回归测试。也没有进行对抗性检查。一名特工计划、执行和审查自己的工作，当它确信错误时，没有任何东西可以发现它。

还有两件事推动了同一个方向。默认情况下，我将产品操作转移到 GitHub 上，使用问题和拉取请求，而不是直接提交到 main。这在一定程度上是由我构建的[问题管道](/posts/agent-to-agent-issue-resolution-with- humans-at-the-edges)推动的，该管道开始将来自用户及其代理的真实报告路由到 Neotoma 并路由到 GitHub。我希望我的开发过程在公众面前清晰可见，这样使用 Neotoma 的人就可以准确地看到正在进行的工作。两者都需要一系列跨设计、产品管理、质量保证和发布的专业代理。一名特工完成所有这一切就失去了意义。

因此，阿特莱斯决定组建一支舰队，并在 Neotoma 本身定义该舰队。

## Neotoma 作为织物，而不仅仅是记忆

阿特莱斯的与众不同之处在于，尼奥托马同时持有两件事。它包含群体所需的操作上下文，与我的旧堆栈读取和写入的事实相同。它本身就拥有蜂群。

代理是 Neotoma 实体。每个都是一个“agent_definition”，带有提示、工具允许列表和一组功能授予。更新代理的行为方式是针对该实体的“ Correct()”调用，具有完整的版本历史记录和作者归属。没有提交，没有重新部署。磁盘上的 SKILL.md 文件是这些实体生成的镜像，而不是源。

他们的关系也是 Neotoma 实体。群有一个层次结构，表示为树，因此协调器知道它调度哪些代理，任务知道哪个代理拥有它。而工作本身就是 Neotoma 实体：任务、计划、工作流程定义、参与记录。代理拿起一个任务，执行它，并将结果写回作为归因于其身份的观察。

结果是一张包含所有内容的世界图。群体作用的事实、作用于它们的群体的定义以及它所做的事情的记录都存在于同一个仅附加存储中。这给了整个事情三个我关心的属性。它是透明的，因为每个动作都是你可以回读的归因观察。它是可审计的，因为您可以在任何窗口上重播任何代理的操作。而且它是可逆的，因为没有任何东西可以覆盖原地的真相。如果代理做出了错误的呼叫，我可以跟踪导致该事件的事件、恢复状态并纠正导致该事件的规则一次。

身份是使归因变得真实而非理想的部分。每个代理都有一个 [AAuth](/posts/know-which-of-your-agents-wrote-what) 密钥对并对每个工具调用进行签名。该工具会在执行之前验证签名，并记录谁声称与谁在 GitHub 上实际执行过操作。代码编写代理不再仅仅充当我的角色。它的行为就像它自己一样，日志也是这么说的。

## 代理，按角色

蜂群是分层组织的。 T1 是主机：拥有通道并生成代理的进程，目前 OpenClaw 用于与我交谈的代理，launchd 用于后台代理。它是基础设施，而不是具有角色的代理。代理本身在其之上分三层运行。 T2 座席始终在线，并拥有自己的角色：Ateles 本身就是我与之交谈的座席，也是唯一给我寻呼的座席。 T3 守护进程是事件驱动的后台进程，没有角色，每个进程都订阅 Neotoma 事件或外部 Webhook。 T4 代理是无状态的，根据任务生成，具有通过查询 Neotoma 获得的稳定身份和内存。

今天运行的一些角色：

**产品。** 协调器守护进程从 Neotoma 读取工作流定义并按顺序分派门：设计、产品管理、QA、发布。代码工作交给问题工作人员，该工作人员跨存储库打开拉取请求。每个拉取请求都会从单独的审核代理处获得基线审核，领域专家会在他们拥有的路径上展开。将这些分开的要点是单一代理人从未有过的对抗性检查。编写代码的人并不是清除代码的人。

**金融。** 定期支付守护进程运行由日历事件和任务到期日期触发的 Wise 和比特币转账，每个接收者和金额从支付配置文件实体而不是代码加载。添加新的定期付款是一个新实体，而不是提交。财务顾问角色和税务申报角色是为了预算和对账而定义的。

**法律与合规性。** 法律角色涵盖风险评估和条款审查。合规角色涵盖隐私和数据治理。当群体可以对人们的数据采取行动时，这些就更重要了，就像我的那样。

**策略。** 这是我在上一篇文章中描述的我的角色，也是我最刻意交出的角色。这种交接是我在[人类倒置](/posts/series/the- human-inversion)中提出的一个论点的具体版本：当代理吸收执行中间时，人类的影响力转移到末端，更清晰的标准进入，更密集的判断出来。自主权是按计划校准的，而不是全局的。执行策略实体声明，对于给定的计划，代理可以自行执行哪些操作，必须清除哪些质量障碍，以及在继续之前必须在哪里停止并与我核实。升级链从代理代理到领域专家，再到宪法管理员，再到我，每个决议都作为一个实体写回，因此下一个实例会继承该判断。

这些背后是摄取和支持守护进程，用于保持图表的供给：电子邮件分类、音频导入、日历准备、健康和健身、问题分类。每个都是一个小进程，将入站信号转换为 Neotoma 实体，群的其余部分可以对其采取行动。

## 任务主干

将舰队联系在一起的是任务管理，而它是故意无聊的。任务是一个实体。它有一个所有者、一个状态、一个优先级以及它为谁执行的记录。计划小组任务并做出自己的决定和后续步骤。工作流定义声明了一项工作所经历的阶段和关卡。

由于所有这些都与其他所有内容都位于同一存储中，因此集群无需单独的编排数据库即可进行协调。守护进程通过 Neotoma 的事件流订阅任务事件。当任务出现时，它会按域路由到正确的代理，在门后面，权衡代理的信心与错误操作可能造成的损害程度。低爆炸半径和高置信度本身就可以发挥作用。高爆炸半径在等着我。

这是我构建其余体验的支柱。

## 这是怎么回事

我想要的界面很简单。我通过最近的任何交通工具向群体提供输入，群体吸收它并采取行动。终端中的提示。一封电子邮件。一条电报消息。散步时录制的音频备忘录，这就是这篇文章的笔记的开始。所有这些都应该落在同一个图表中，并且群体应该积极主动地完成它所暗示的工作，而无需我通过它握住任何代理的手。

有两个特性使这成为可能。群体必须​​自我进化。当它承担新的环境和新的工作类型时，它应该提供所需的功能并培养所需的技能，适应我的更正，而不是等待我手动重新配置它。在真正需要判断的时刻，我的意见仍然需要，永远不应该被给予两次。我纠正了一种做事方式一次，它就变成了一个实体，并且纠正成立。

更近的路线图即将达到。 Ateles 是为我自己使用而构建的，因此其中相当一部分仍然假设只有一个操作员，即我。我正在[推动它走向可安装和多操作员](https://github.com/markmhendrickson/ateles/blob/main/docs/multi_tenant.md)：其他人可以分叉、指向自己的 Neotoma、提供自己的上下文实体并运行的群体。由于代理在策略上与操作员无关，并且代码中没有包含特定于操作员的内容，因此分叉情况主要是上下文问题，而不是重写问题。真正的新工作是在一个租户内支持多个人，这就是为什么租户边界是现在设计的，而不是以后改造的。

Neotoma 制造了具有记忆能力的智能体，而 Ateles 正是记忆使之成为可能：一群可以在没有我参与的情况下对其采取行动的群体。两人一同升起。更好的记忆力并不是我已经解决的问题。它是整个虫群所立足的基础，而 Neotoma 能够容纳和解决的每一点收获都是虫群能够做的事情的收获。记忆力不断提高，群体也随之不断提高。