我准备自己做一个 agent 调度层
前段时间在 AI 随想第十篇 里,我写过一个判断:代码学会了自我进化。证据是 Peter Steinberger,一个小时做出 OpenClaw,三个月 25 万颗星,没有团队,软件自己改自己。这个判断本身我现在也不改,agent 确实能读自己的源代码,能理解架构,能自己提 PR,这些都是真的。
但对照我自己每天的工作流,就会发现中间还缺一层。我现在每天的流程大概是这样的:
- 打开 claude code
- 描述一个任务
- 看它干 20 分钟
- review PR
- merge
- 再开一个终端
- 描述下一个任务
- 重复
你看这个流程,每一步中间站着的都是我。调度是我在做,review 是我在做,哪个任务依赖哪个任务、得排在谁后面,也是我在脑子里算。把 context 从一个终端复制粘贴到另一个终端的是我,瞄一眼 Linear、算哪个 issue 对应哪个终端的还是我。这些活没有一件真的需要人的判断,全是系统该干的事,但现在全压在我身上。
所以只能说,模型是会写代码了,harness 也很好用,但这个环没有真的闭上,调度 agent 的那一层还没有人做出来,现在是我在人肉充当这个调度层。每天排任务、盯进度、把 context 从这搬到那,都是我手动在干。这篇就讲讲我准备怎么把这一层做出来。
模型会写代码,但调度、review、依赖排序每一步中间都站着人——人肉充当了那层缺失的调度器。
先看了一圈市面上有什么
动手之前我花了一周,把号称能解决这个问题的开源项目都扒了一遍,主要看它们各自做到了哪一步。
Composio Agent Orchestrator,5650 颗星,MIT 协议。这是里面最认真的一个:完整的插件架构,7 个类型接口把 runtime、agent、workspace、tracker、SCM、notifier、terminal 全覆盖了;session 生命周期有 16 种状态;CI 挂了还能自动响应。工程上是真下了功夫的。
但翻开引擎盖一看,执行层是 tmux 跑在单机上,轮询架构,状态存在平面文件里,还有一个 setInterval 在循环检查 agent 还活没活着。没有持久化执行,进程在任务中途挂了,session 就没了。也没有 Linear Agent Sessions,没有 webhook 驱动的事件流。
AgentsMesh,1200 颗星,Go 写的。做的是看板到 Pod 的绑定,还有实时拓扑可视化。它的架构直觉我觉得是对的:ticket 内容直接变成 agent 的 prompt,MR 和 ticket 自动关联。问题是 BSL 协议,不能自由用;也没有飞书集成,没有 Temporal,部署模型跟我要的不是一回事。
dmux,1300 颗星,MIT 协议。本地终端多路复用器,按 n 开一个新 pane,输入 prompt,按 m 把输出合回来,简洁到极致。但也就到这了:纯本地工具,没有 API,没有 webhook,没法从一条聊天消息触发,也连不上任何项目管理工具。
这三个每个都做对了一些事。Composio AO 的插件接口设计得好,AgentsMesh 的看板绑定是对的抽象,dmux 证明了交互模型可以做到极简。但没有一个能做到我要的效果。我要的效果说具体一点,就是我发一条指令进去,最后拿到的是 review 过、合并好的代码,中间这一段完全不需要我参与。这三个离这一步都还差一截。
我想要的场景,拆开是五个问题
具体想要的场景是这样的:在飞书发一条消息,「实现 JWT 用户认证,给所有 API 加上限流,写集成测试」,然后去泡杯咖啡。回来的时候,三个 Linear issue 已经建好,三个 PR 开着,都自动 review 过了。通过的已经合了;没通过的那个,agent 读了 reviewer 的意见,改完又提了一版。飞书里有一张汇总卡片告诉我发生了什么。整个产品就是这一件事,说白了就是把我现在人肉干的那部分调度活全部接过去。
但要让这个真的跑起来,得回答五个问题。市面上没有一个工具同时解决了这五个:
1. 状态怎么活过 30 分钟。 agent 干一个复杂任务可能要半个小时,编排器在第 29 分钟崩了怎么办?Composio AO 的答案是:全白干。传统 serverless 会超时,cron job 也维护不了工作流状态。需要的是持久化执行——崩了能恢复,从上一个 checkpoint 接着跑。
2. 等待怎么不烧钱。 agent 提交 PR 之后,可能要等 5 分钟 review。这 5 分钟里轮询是在白烧算力,setTimeout 又靠不住。需要「等一个外部事件」这个操作本身不消耗任何资源。
3. agent 怎么跟密钥隔离。 你给 agent 开了 full-auto 的 bash 权限,环境里又放着 GitHub token、Linear API key、飞书凭证,那这些 agent 全能读到。一条 code review 评论里藏一段提示注入,攻击者就能把你环境里所有的密钥偷走。所以写代码的和调 API 的,必须是两个不同的东西。
4. 怎么防止 agent 自己批准自己的 PR。 GitHub 本来就不允许自批准:agent 创建 PR,CI bot 再用同一个身份去 review,GitHub 直接拒绝。所以得有两个身份,一个写代码,另一个 review。
5. 反馈怎么闭环。 reviewer 在 PR 上留了评论,这条评论得送到写代码的那个 agent 手上,而不是掉进通知收件箱。agent 得读反馈、理解、改代码、再推、再等下一轮 review。这是一个跨 GitHub 和编排器两个系统的有状态对话,可能持续几个小时。
这五个问题单独拎出来的话,每一个都有人解决过。只是我翻了一圈,没有找到把五个串在一起解决的工具,所以决定自己做一个。
核心的选择是 Temporal
Foundry 干的就是把这五个问题串起来。核心的架构选择只有一个:用 Temporal 做骨架。其他所有决策都是从这个选择里推出来的。
Temporal 是一个 workflow 引擎,专门处理长时间运行、有状态、要跟外部系统打交道的流程,OpenAI 生产环境的 codex 就跑在它上面。它最关键的原语是 workflow.condition():工作流暂停在那,不消耗任何资源,直到一个 Signal 到达才恢复。放到我的场景里具体是这样的:agent 提交 PR,工作流暂停;GitHub review 完成,触发 webhook;webhook 翻译成 Temporal Signal,工作流恢复。整个过程没有轮询,不会超时,状态也不会丢。上面第 1 个和第 2 个问题,用这一个原语就都解决了。
Temporal 的 condition 原语让工作流在等 review 时暂停、零资源消耗,直到 GitHub webhook 翻成 Signal 才恢复,不靠轮询。
密钥隔离的做法,是在 Temporal 之上拆三个 worker:
在 Temporal 之上把职责拆成三个 worker:编排 worker 不持密钥、agent worker 只有 AI key、集成 worker 独揽所有集成密钥,写代码的碰不到密钥。
- 编排 worker:轻量,只跑工作流逻辑,不持有任何密钥
- agent worker:CPU 密集,跑
claude -p和codex --quiet子进程,只持有 AI 的 API key - 集成 worker:IO 密集,调 Linear、GitHub、飞书的 API,所有集成密钥都在这
这样 agent worker 永远看不到 GitHub token,编排 worker 永远不碰子进程,每个 worker 的攻击面都压到最小。就算真有一个 agent 被恶意 review 评论注入了,最坏情况也就是它写了一段坏代码——密钥它偷不走,它的环境里根本就没有。
工作流本身分两层,对着任务的层级:父工作流接收指令,让 claude 把指令拆成任务,建 Linear issue,并行 fan out N 个子工作流,最后汇总结果、发飞书卡片;子工作流处理单个任务,写代码 → 开 PR → 等 review → 迭代(最多 5 轮)→ 合并,每个子工作流跑在自己独立的 git worktree 里。大概就是这么两层,父工作流负责往下分派,具体写代码、等 review 这些活全在子工作流里面干。
现在进行到哪了
说实话,Foundry 现在还没有一行可运行的代码。有的是五份调研报告、一份架构蓝图,和一份安全审计。安全审计在初始设计里找出了四个严重漏洞,全部在写第一行实现代码之前就解决掉了。本来第一天就可以直接开写的,我还是先花了一周做调研,这一周我觉得花得值。
AI 随想第八篇里我写过,编排比生成更重要。Foundry 赌的就是再往上一层:agent 之上的编排,或者说编排的编排。
后面会跟着 build 的进度接着写:
- 第二篇:五份调研报告教我的事
- 第三篇:三个 worker、三把钥匙,怎么给 agent 做权限隔离
- 第四篇:从第一条指令到第一个 PR,端到端跑通
- 第五篇往后:多任务并行、Linear Agent Sessions、失败恢复这些

