# 五个构件与状态中枢 > Loop engineering 最实用的贡献之一,是把一堆零散 agent 能力压缩成一个清晰骨架: > **调度、worktree、skills、connectors、sub-agents,再加上状态 / memory。** ## 先看全景 源仓库把 loop 的构件总结成“五个 building blocks + memory”。这个提法好用,因为它避免你一上来就陷入某个工具的专有功能,而是先回到能力层: - **调度 / 自动化** - **隔离执行环境** - **项目知识与规则** - **外部系统连接** - **角色分工** - **状态中枢** 把它们串起来,大概就是这样一条链: `schedule -> triage -> read/write state -> isolated worktree -> implementer -> verifier -> connector actions -> human gate` 这条链不一定每次都完整出现,但多数能长期运行的 loop 都绕不开这些问题。 ## 一、调度 / 自动化:决定 loop 什么时候活过来 这是所有 loop 的起点。 没有调度,就没有“持续运行”,只有“我想起来时手动叫 agent 做点事”。 调度层负责解决: - 每 5 分钟、每小时、每天还是事件触发 - 首次启动后要不要立刻跑 - 是否能跨重启继续存在 - 夜间要不要降频或暂停 - 待办清空后是否自动停机 一个成熟团队不会一上来追求高频,而是先问: **这个问题的发现延迟,值不值得我为它付出这条 loop 的 token 和噪音成本?** 比如: - Daily Triage 适合天级或小时级 - PR Babysitter 适合 5-15 分钟 - CI Sweeper 适合更密,但成本也更高 所以调度不是“越快越高级”,而是“和问题时效性匹配”。 ## 二、Worktree:让自动化改动别直接污染主工作区 如果 loop 只做报告,worktree 不是刚需;一旦 loop 开始尝试修复、改依赖、生成提交,worktree 基本就该成为标配。 它的价值很朴素: - 每次自动尝试都有隔离空间 - verifier 可以在独立环境里验证 - 失败后直接丢弃,不污染主分支 - 并行尝试时彼此不打架 这一步的重要性往往被低估。很多“自动修复很危险”的体验,本质上不是 agent 太蠢,而是执行环境没有隔离。 更直接地说: - **没有隔离,自动化错误会直接变成本地混乱** - **有隔离,自动化错误大多只是一次可丢弃的实验** ## 三、Skills:让 loop 不是每次都重新解释项目 Loop 不是一次性会话,所以它必须有长期稳定的任务描述和项目规则载体。 这就是 skills 的位置。 一个好用的 loop skill 一般会明确: - 本轮先读哪些文件 - 输出写到哪里 - triage 后怎样分类 - 哪些情况下禁止改代码 - build / test / verifier 怎么执行 和普通 prompt 相比,skill 的价值在于: - 可复用 - 可版本化 - 可被多个 loop 共用 - 可被不同工具迁移 如果你准备把一条 loop 长期跑下去,skill 应该写得**平淡、具体、可验证**,而不是写成“像一个资深工程师一样聪明地判断一切”。 ## 四、Connectors / MCP:让 loop 接触真实世界 只会读本地仓库的 loop 很快会遇到天花板。 真实工程里,loop 往往还要接触: - GitHub 的 issue、PR、Actions - Linear / Jira 的任务状态 - Slack / 飞书的通知出口 - 依赖和安全扫描结果 - CI 平台和日志系统 这就是 connectors 或 MCP 的位置。 它们让 loop 不只是一段“仓库内自动化”,而是能把判断写回外部系统,形成真正闭环。 但这层同时也是风险放大的开始。因为只要接了外部系统,loop 就可能: - 创建或修改工单 - 评论 PR - 开分支、提 PR - 触发 Actions - 修改远程状态 所以这层最重要的原则不是“能接多少”,而是: **最小权限、先读后写、先建议后执行。** ## 五、Sub-agents:把 maker / checker 分开 这是 loop 从“自动写东西”升级到“有基本工程纪律”的关键一步。 最常见的分工就是: - **Implementer / Maker**:负责生成改动、提建议、做修复 - **Verifier / Checker**:负责跑测试、检查约束、决定是否通过 为什么必须拆开? 因为同一个 agent 同一个上下文里,最容易出现的就是“自我合理化”:它写了改动,于是更倾向于相信改动已经够好了。 maker / checker 分离至少能带来三层好处: - 降低自评偏差 - 让验证逻辑更稳定 - 便于后续替换不同模型或不同权限 这也是为什么很多 loop 设计都强调: **实现者不能自己宣布完成,完成必须由 verifier 或人类 gate 决定。** ## 六、状态 / Memory:loop 的脊柱 前面五个构件都重要,但状态层是脊柱。 为什么? 因为 loop 的本质是跨时间运行。只要跨时间,就一定要解决“上次发生了什么、这次从哪继续”的问题。 ### 状态层至少要回答这些问题 - 上次运行是什么时间 - 找到了哪些待办 - 哪些已经处理,哪些还在观察 - 哪些项重试了几次 - 哪些项必须升级给人 - 哪些 loop 被暂停了,为什么暂停 ### 常见状态载体 - `STATE.md` - `LOOP.md` - `loop-budget.md` - `loop-run-log.md` - issue board / Linear / GitHub Projects 重点不在文件名,而在**每轮都要读、每轮都要写、团队能独立审查**。 如果 loop 只把信息留在聊天记录里,它就不是工程系统,只是对话副产品。 ## 一个建议的状态分层 为了让状态不至于越写越乱,可以按职责拆成三层: ### 一、运行规则层 写在 `LOOP.md` 之类的文件里,放: - loop 目标 - cadence - denylist - human gate - verifier 规则 这是“这条 loop 应该怎样运行”。 ### 二、当前世界状态层 写在 `STATE.md`,放: - 高优先级事项 - watch list - 最近动作 - 最后运行时间 - 升级记录 这是“这条 loop 当前看见了什么”。 ### 三、预算与审计层 写在 `loop-budget.md`、`loop-run-log.md`,放: - token 预算 - 每日上限 - 运行次数 - 失败和暂停原因 这是“这条 loop 花了什么代价、发生过什么事故”。 ## 一个最低配 loop 的组合方式 如果你第一次搭 loop,不需要把所有构件都堆满。最低配版本可以是: 1. 每天一次调度 2. 一个 triage skill 3. 一个 `STATE.md` 4. 只读 GitHub / 仓库 5. 只输出报告,不改代码 这已经足够形成 L1 报告型 loop。 等它稳定后,再逐步加: - worktree - verifier - 写权限 connector - 小范围自动修复 - budget / run log / kill switch ## 设计顺序建议 如果按重要性排序,我会建议这样搭: 1. **先定义状态** 2. **再写 triage skill** 3. **再决定 cadence** 4. **再引入 verifier** 5. **最后才引入自动写回和外部写权限** 原因很简单: - 没有状态,loop 无法连续 - 没有 triage,loop 无法稳定输出 - cadence 太早定,容易空转 - verifier 太晚加,容易越权 - 写权限放太早,最容易出事故 ## 一个实用判断 如果你发现某条 loop 主要时间都花在: - 解释上下文 - 找上次结果 - 追踪自己做过什么 - 人工帮它判断这次能不能继续 那通常说明它的状态层没有设计好,而不是模型不够强。 ## 延伸阅读 - [Loop Engineering 是什么](./01-what-is-loop-engineering.md) - [模式库与上线分级](./03-patterns-and-rollout-levels.md) - [跨工具迁移:Claude Code、Codex、Cursor 怎么落地](./04-cross-tool-mapping.md) 下一篇:[03 模式库与上线分级](./03-patterns-and-rollout-levels.md)