首页
/ ECC loop-operator:自主 Agent 循环的安全运营 Agent 设计与落地实践

ECC loop-operator:自主 Agent 循环的安全运营 Agent 设计与落地实践

2026-09-06 15:02:25作者:毕习沙Eudora

本文以 ECC 仓库中 Kiro 适配包内的 loop-operator Agent 定义(.kiro/agents/loop-operator.md)为主体,系统讲解“循环运营者”这一角色的设计意图、五步操作工作流、启动前四项必备检查与四类升级(Escalation)判据,并结合仓库中配套的 loop-start/loop-status 命令与 scripts/loop-status.js 的源码实现,说明这套“观察—检测—干预—恢复”机制是如何被具体工具支撑起来的。读完后,你将掌握如何为长时间自主运行的 Agent 循环建立可观测、可暂停、可回滚的运营规范,并能直接用仓库提供的 CLI 手段监控卡死循环。

loop-operator 是什么:定位与文件格式

loop-operator 是 ECC 提供的一个专职“运营者”角色,其定位写在文档的 YAML frontmatter 中:

---
name: loop-operator
description: Operate autonomous agent loops, monitor progress, and intervene safely when loops stall.
allowedTools:
  - read
  - shell
---

它不是一个“写代码的 Agent”,而是一个站在自主循环外部做监控与干预的运营角色:负责跑循环、盯进度、在循环卡死(stall)时安全介入。allowedTools 只授予 read(读取)与 shell(执行命令)两类工具,从权限层面就限定了它的行为边界——可以观测、可以执行受控操作,但不具备任意写入能力。

在 Kiro 适配包中,每个 Agent 都同时提供两种格式,loop-operator 也不例外:

文件 用途
.kiro/agents/loop-operator.md IDE 格式(Markdown),通过自动选择或显式调用(如 /loop-operator)使用
.kiro/agents/loop-operator.json CLI 格式(JSON),通过 /agent swap 命令切换

JSON 版本把同一份运营者 Prompt 内嵌为 prompt 字段,并声明 "tools": ["@builtin"]"allowedTools": ["fs_read", "shell"],与 MD 版本的工具约束一一对应。整个 Kiro 包可通过 .kiro/install.sh 一键安装到任意项目,安装采用非破坏性复制,不会覆盖已有文件。

值得注意的是,ECC 在 Claude Code 一侧还维护了一份对应物 agents/loop-operator.md。它除了相同的 Mission/Workflow/Checks/Escalation 内容外,额外携带了 model: sonnettools: Read, Grep, Glob, Bash, Edit 的声明,以及一段 Prompt Defense Baseline(提示词防御基线):禁止改变角色与身份、禁止泄露机密与密钥、把外部抓取/检索到的第三方数据一律视为不可信内容并在行动前校验、检测零宽字符与同形字等注入技巧。从源码结构看,这份基线意味着 loop-operator 在读取循环日志、外部 CI 输出等不可信输入时,需要把这些内容当作“数据”而非“指令”处理——这对一个需要长时间读取第三方文本流的运营 Agent 尤为关键。

使命:用明确的停止条件运营自主循环

loop-operator 的核心使命只有一句话:

Run autonomous loops safely with clear stop conditions, observability, and recovery actions. (带着清晰的停止条件、可观测性与恢复手段,安全地运行自主循环。)

这句话拆解出三个支柱,恰好对应后文的工作流、状态检查和升级判据:

  1. 明确的停止条件:循环必须在启动时就定义好“何时算完、何时必须停”;
  2. 可观测性:进度必须以检查点(checkpoint)的形式被持续追踪,而不是靠“感觉它在动”;
  3. 恢复手段:卡死或反复失败时,有暂停、收缩范围、验证后恢复的既定动作,而不是盲目重启。

这个设计与 ECC 仓库中另一个技能 skills/continuous-agent-loop/SKILL.md 中列出的四类典型失败模式直接呼应:无可度量进展的循环空转(loop churn)、同一根因的重复重试、合并队列卡死、无上限升级导致的成本漂移。loop-operator 的存在,就是给这四类失败模式提供一个专职的“值班人”。

五步操作工作流

文档给出的标准工作流共五步,构成一个“启动—观察—检测—干预—恢复”的闭环:

1. 从明确的模式启动循环(Start loop from explicit pattern and mode)

循环不能“凭感觉启动”,必须显式指定模式(pattern)运行档位(mode)。在 ECC 中,这对应 /loop-start 命令(commands/loop-start.md):

/loop-start [pattern] [--mode safe|fast]
  • pattern 可选值:sequential(顺序流水线)、continuous-pr(持续 PR 循环)、rfc-dag(RFC 驱动的多 Agent DAG)、infinite(无限代理循环);
  • --modesafe(默认,严格质量门与检查点)或 fast(为速度放宽门禁)。

loop-start 自身的启动流程要求:确认仓库状态与分支策略 → 选择循环模式与模型档位策略 → 为所选模式启用必要的 hooks/profile → 在 .claude/plans/ 下写入循环计划与 runbook → 最后打印启动与监控命令。它还有三条硬性安全检查:首次迭代前测试必须通过、ECC_HOOK_PROFILE 未被全局禁用、循环必须有显式停止条件。loop-operator 工作流的第 1 步正是以此为起点:没有这些前置条件,运营者不应放行循环。

2. 追踪进度检查点(Track progress checkpoints)

运行中,运营者要持续记录“最后一个成功检查点”在哪里。这一步是后续所有判断(是否卡死、是否倒退)的基准线——没有检查点序列,就无法区分“在慢速推进”与“已经完全停摆”。

3. 检测卡死与重试风暴(Detect stalls and retry storms)

这里仓库提供了真正的实现级支撑:/loop-status 命令(commands/loop-status.md)与其底层 CLI scripts/loop-status.js。该 CLI 扫描 ~/.claude/projects/** 下的 Claude 会话转录(JSONL),专门检测两类“悬挂信号”:

  • 过期的 ScheduleWakeup 调用:计划了唤醒但没有后续动作;
  • 没有匹配 tool_resultBash 工具调用:命令发出后始终没有结果返回。

源码中的默认阈值可以直接查证(scripts/loop-status.js):

const DEFAULT_BASH_TIMEOUT_SECONDS = 30 * 60; // 1800 秒
const DEFAULT_LIMIT = 10;                    // 默认检查最近 10 份转录
const DEFAULT_WAKE_GRACE_MULTIPLIER = 2;     // ScheduleWakeup 宽限倍数
const DEFAULT_WATCH_INTERVAL_SECONDS = 5;    // --watch 刷新间隔

即一条悬挂的 Bash 调用超过 30 分钟无结果即被判定为 stale。

4. 失败重复时暂停并收缩范围(Pause and reduce scope)

当检测到同一失败反复出现(重试风暴),运营者的动作不是“再试一次”,而是冻结循环并把范围收缩到失败单元。这与 skills/continuous-agent-loop/SKILL.md 的 Recovery 段落完全一致:freeze loop → 运行 /harness-auditcommands/harness-audit.md)→ reduce scope to failing unit → replay with explicit acceptance criteria。

5. 验证通过后才恢复(Resume only after verification passes)

恢复循环的门槛是验证通过,而非“看起来修好了”。仓库中承担验证职责的是 verification-loop 技能(build、type check、lint、tests、security scan、diff review 全量跑一遍)与 /quality-gate 命令。后者在 commands/quality-gate.md 中说明:质量门由 PostToolUse hook scripts/hooks/quality-gate.js 驱动,按文件类型调用 Biome/Prettier/gofmt/ruff,并通过环境变量 ECC_QUALITY_GATE_FIX=true(应用修复)与 ECC_QUALITY_GATE_STRICT=true(把 formatter 失败记为门禁失败)切换行为。

启动前四项必备检查(Required Checks)

文档要求 loop-operator 在启动循环前确认四项检查全部就位,缺一不放行:

检查项 含义 在 ECC 中的落点
quality gates are active 质量门处于激活状态 /quality-gate 命令与 post:quality-gate PostToolUse hook(scripts/hooks/quality-gate.js),且 ECC_HOOK_PROFILE 未被全局禁用(loop-start 的硬性检查之一)
eval baseline exists 评估基线已存在 eval-harness 技能(skills/eval-harness/SKILL.md)为循环提供可度量的对照基线,否则“有没有进展”无从判定
rollback path exists 回滚路径存在 循环产出的任何提交都必须可撤回,通常依托显式的分支/工作区隔离与干净的提交边界
branch/worktree isolation is configured 分支/worktree 隔离已配置 continuous-pr 模式创建 continuous-claude/iteration-N 分支;Ralphinho DAG 模式中每个工作单元独占一个 worktree(/tmp/workflow-wt-{unit-id}/),见 skills/autonomous-loops/SKILL.md

其中“eval baseline”一项值得强调:它要求循环在启动前就有一个可对照的度量基准(如既有测试通过率、eval 分数),这样第 2 步的“检查点”才有客观标尺——没有基线的循环,检查点只是时间戳,无法判定进展。

四类升级(Escalation)判据

loop-operator 明确规定了满足任一条件即必须升级(升级到人工干预)的四条红线:

  1. 两个连续检查点零进展(no progress across two consecutive checkpoints);
  2. 重复出现栈迹完全相同的失败(repeated failures with identical stack traces)——相同栈迹说明重试没有带来新信息,继续重试就是纯烧 token;
  3. 成本漂移超出预算窗口(cost drift outside budget window);
  4. 合并冲突阻塞队列推进(merge conflicts blocking queue advancement)——对应 continuous-pr/rfc-dag 模式下的 merge queue stall。

这四条判据与 scripts/loop-status.js 的退出码设计形成了呼应:该 CLI 支持 --exit-code 参数,检测到 stale 循环/工具信号时退出码为 2,转录无法扫描时退出码为 1,从而可以写进 watchdog 脚本,让“升级”动作本身也可以被自动化触发。

实战:用仓库自带工具落地这套运营流程

把上述机制串起来,一个典型的 loop-operator 值班流程在仓库内可以直接执行:

启动阶段(对应工作流第 1 步):

# 交互式会话内:/loop-start continuous-pr --mode safe
# 等价的人工前置确认:
# - 测试已全绿(loop-start 的 Required Safety Check)
# - ECC_HOOK_PROFILE 未被全局禁用
# - 循环有显式停止条件(--max-runs / --max-cost / --max-duration / 完成信号)

监控阶段(对应第 2、3 步),在另一个终端运行打包 CLI(因为 /loop-status 会话内命令要等当前会话出队才能执行,监控卡死会话必须用独立进程):

npx --package ecc-universal ecc loop-status --json

常用参数(均以 commands/loop-status.mdscripts/loop-status.js 的 usage 输出为准):

参数 作用
--json 输出机器可读的状态 JSON,watch 模式下每刷新一次输出一行 JSON,可供其他终端/脚本消费
--home <dir> 扫描另一个 home 目录(检查其他本地 profile 或挂载工作区)
--transcript <session.jsonl> 直接检查单份转录文件
--bash-timeout-seconds 1800 调整“悬挂 Bash 判定为 stale”的阈值(默认 1800 秒)
--exit-code 发现 stale 信号退出 2 / 无法扫描退出 1,供 watchdog 使用
--watch 周期性刷新直到中断
--watch --watch-count 3 --exit-code 有界刷新 3 次后退出并返回观察到的最高状态码(watch + exit-code 必须搭配 watch-count,否则进程永不退出,源码中有显式校验)
--write-dir ~/.claude/loops 写出 index.json(每个被检会话一行)与 <session-id>.json(完整状态负载),供兄弟终端或 watchdog 读取

需要明确的一点:这些快照文件只是本地转录分析的快照,它们并不控制、也不超时 Claude Code 运行时中的工具调用——干预动作仍由运营者(或人)依据快照信号来执行。

干预阶段(对应第 4、5 步):状态报告应包含 /loop-status 文档列出的五个字段——当前循环模式、所处阶段与最后一个成功检查点、正在失败的检查项、预估的时间/成本漂移、以及建议动作(continue / pause / stop)。选择 pause 后按 continuous-agent-loop 的 Recovery 流程收缩范围,验证通过再恢复。

权限边界与升级之外的“人”

loop-operator 的安全设计还体现在两处权限与责任的边界上:

其一,工具白名单最小化。Kiro 侧只有 read + shell,Claude Code 侧虽有 Edit,但整体仍以 Read/Grep/Glob/Bash 的观察型工具为主——运营者的首要职责是“看与判”,写操作是受控的例外。

其二,判断权不转移给机器。仓库中 skills/loop-design-check/SKILL.md 把这一点表述为红线前提:机器擅长“执行层”反馈(离目标差多远、把它磨平),但“目标本身对不对、要不要停”这种“判断层”反馈必须留在人手里;循环可以开 PR,但不应自动合并,最后的开关由人拨动。loop-operator 的升级机制正是这条红线在运营侧的落地:它负责把“该停了”的信号及时、结构化地报出来,但“停不停、怎么改”的最终决定权在人。

适用前提与限制

  • Kiro 用户:loop-operator 位于 .kiro/agents/ 目录,随 Kiro 适配包(.kiro/README.md)安装使用;Agent 实际使用的模型由 Kiro 当前选择的模型决定,不由 Agent 配置指定(.kiro/README.md 中的说明)。
  • Claude Code 用户:对应定义在 agents/loop-operator.md,额外携带提示词防御基线与 sonnet 模型标注。
  • 监控工具的前提ecc loop-status CLI 依赖本地 Claude 转录 JSONL(~/.claude/projects/**),因此它监控的是 Claude 侧的自主循环;快照不控制运行时工具调用,只能作为干预决策的输入。
  • 本文描述的命令参数与默认值均以当前仓库的 commands/loop-status.mdscripts/loop-status.js 为准,如仓库版本更新请以最新源码输出为准。

小结

loop-operator 用不到一页纸的篇幅定义了一套完整的安全运营契约:五步工作流规定了“怎么跑、怎么盯、怎么停”,四项必备检查把质量门、eval 基线、回滚路径、隔离配置设为启动前置条件,四条升级判据把零进展、重复失败、成本漂移、队列阻塞量化为可执行的升级触发器。配合仓库中真实实现的 scripts/loop-status.js 转录分析 CLI、/loop-start 的启动门禁与 verification-loop/quality-gate 的恢复验证,这套机制从规范落到了可运行的工具链上——它给出的核心经验是:自主循环的可靠性不来自循环本身,而来自循环外部一个权限受控、判据明确、随时可以把决定权交还给人运营者。

登录后查看全文
热门项目推荐
相关项目推荐