DeepSeek Harness Hub
← 返回列表

dancingteeth/agent-looper

DeepSeek Harnessspec-screened在 GitHub 查看 ↗
⚠ 装前注意

Agent Looper @dancingteeth/agent-looper

基本兼容但装前注意:未发布到 npm registry,仅可从源码安装 · 最近上游提交 2026/9/15 · 已提供中文文档

使用 shell 验证作为真相的“修复直到通过”智能体循环,可插拔的多运行时工作器(Cursor/Cline/OpenCode/Codex/DSH/Pi),以及每次迭代使用全新上下文。

综合分
31.2
GitHub 分
31.2
用户评分
★ Stars
2
周下载量
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add dancingteeth/agent-looper
未发布到 npm registry,仅可从源码安装,改用 GitHub 源安装
数据截至 2026/9/18(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
安装兼容性检查⚠ 装前注意

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

npm 包@dancingteeth/agent-looper(未发布到 npm,仅可源码安装)
Node 引擎要求 >=22 · 基线 Node 22.19 满足
dsh CLI 依赖未声明 dsh 版本约束
入口文件main/exports/bin 已声明

未发布到 npm registry,仅可从源码安装

验证方式:npm registry 存在性 + package.json 静态校验 · 最后验证 2026/9/19 04:05:41

用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

tags:
- documentation
- agents

Agent Looper (@dancingteeth/agent-looper)

如果你已经在 Cursor 中进行循环: 你启动 Composer,它说完成了,CI 仍然是红的,你粘贴日志,你打开一个新聊天。你就是那个验证步骤。

这个包就是那个循环,但不需要你夹在中间。每一轮都是全新的 Cursor worker。一个你已经信任的 verify.sh。当它退出码为 0 时停止。

落地页: looper.dancingteeth.net(静态站点位于 site/)。

pnpm add -D @dancingteeth/agent-looper @cursor/sdk
export CURSOR_API_KEY=…   # 或者 doppler run -- …

pnpm exec agent-loop-init
或者:pnpm exec agent-loop-prompt --out .cursor/loops/my-task
编辑 GOAL.md
把你反复运行的检查放进 verify.sh

pnpm exec agent-loop run .cursor/loops/my-task --runtime cursor

其他 worker、judge 和标志见下文。第一次跑绿并不需要它们。

循环是如何构成的:README.intro.md。技术深入解析:ARCHITECTURE.md(包括 §1.1 —— 该 harness 是一个小型控制流图;Ralph 循环位于 worker 节点内部)。npm 发布:docs/releasing.md。已发布内容:CHANGELOG.md(当前 0.6.1)。将此包作为库依赖嵌入另一个 ADE:docs/embed-api.md。报告漏洞:SECURITY.md。

支持可插拔的 agent SDK worker(runtime)和 judge(reviewRuntime)。目前已发布:Cursor、Cline(Pass / Credits)、OpenCode(Go + BYOK)、Pi、Codex、DSH(PATH dsh)、Muse(PATH muse)、Claude(PATH claude、--safe-mode)。默认值和成本说明:docs/runtime-map.md。dsh web 的 DSH 配套工具(skills + scaffold,不是第二个 harness):docs/dsh-plugin.md。Muse Code:docs/muse-runtime.md。Claude Code:docs/claude-runtime.md。要在冻结的循环上衡量廉价 worker 的说法:docs/runtime-cost-bench.md。主 judge 默认使用 Cursor(reviewRuntime 未设置),但可以通过 reviewRuntime + reviewModel 使用任何 worker runtime。

功能一览

| 层 | 作用 | 是否阻止完成? |
| --- | --- | --- |
| Worker | 每次迭代都是全新的 agent SDK 会话(runtime);朝 GOAL.md 实现 | —(执行工作) |
| Verifier | Shell verify / finalVerify(退出码 0)。可选的 verifyMode: skill 先运行一个 verify agent(VERIFY_RESULT: PASS/FAIL),然后运行 shell。 | 是 —— 硬性门禁 |
| Review | 成功后进行 LLM 质量审查 → review.md(主 judge 通过 reviewRuntime,默认 cursor)。可选的 reviewGate 仅对门禁发现重新打开修复循环。 | 仅在 reviewGate: true 时 |
| Human | HITL 检查点(hitlProvider)、reviewGateHitl / hitlCheck / hitlOnFailure、完成通知(Telegram / webhook / notifyCommand / PR 评论) | 关闭 / 告警 |

审查栈(除非另有说明,否则为可选启用):

1. 影响严重性 — 仅 severity: error + 已识别的 impact 标签会触发门禁(data-loss、security-boundary、false-closure、cross-dispatch、verify-bypass)。表面性问题保持为建议性。
2. 先复现后报告 — reviewReproduce:丢弃在变更文件集中没有可引用路径的 error+impact 阻断项。
3. 全新复现 agent — reviewReproduceAgent:第二个评审会话对剩余门禁阻断项进行 KEEP/DROP 判定(与主评审使用相同的 reviewRuntime)。
4. 次级评审 — reviewSecondaryRuntime(任意 worker/judge 运行时):将门禁阻断项与主评审取并集;当主评审为 PASS/ADVISORY 且零门禁时跳过。

工厂规模: agent-loop-batch(顺序执行 + 元循环 probe→fix)、agent-loop-meta-review(对 N 个 bundle 的只读跨循环报告)。

运维: 停滞检测、failure-domains.ndjson、Telegram 完成报告、通过环境变量 / 你的密钥管理器提供密钥(CURSOR_API_KEY、CLINE_API_KEY、OPENCODE_API_KEY、OPENROUTER_API_KEY、AI_GATEWAY_API_KEY、AGENT_LOOP_TELEGRAM_、AGENT_LOOP_CURSOR_TIMEOUT_MS)。

验证清单编写:docs/verification-as-skill.md。冻结一个四部分终点线(结果、记分板、权限、预算)以及可选的黄金产物 — templates/GOAL.template.md。指标循环:若比基线更差则回退 — templates/GOAL.metric.template.md。视觉 / 品味循环(首页、模型图、以截图为主角):templates/GOAL.visual.template.md。

安装

需要 Node.js 22+。从 npm 安装(可在云 agent 和任意消费方仓库中使用)。

CLI 遥测(可选启用,默认关闭): 设置 AGENT_LOOPER_TELEMETRY=1 以向 PostHog EU 发送匿名使用事件(looper_init、looper_run_started、looper_run_finished)。需要 POSTHOG_PROJECT_API_KEY 或 AGENT_LOOPER_POSTHOG_KEY。仅发送包版本、运行时、操作系统平台、Node 主版本、验证通过/失败、时长和审查门禁标志 — 绝不发送仓库路径、提示词或密钥。位于 looper.dancingteeth.net 的营销网站不使用分析像素。

仅 Cursor(最低要求)
pnpm add -D @dancingteeth/agent-looper @cursor/sdk

可选 worker
pnpm add -D @cline/sdk                                    # Cline Pass / Credits
pnpm add -D @opencode-ai/sdk opencode-ai                  # OpenCode Go / BYOK
pnpm add -D @earendil-works/pi-coding-agent               # Pi BYOK
pnpm add -D @openai/codex-sdk                             # Codex (ChatGPT / OpenAI)
pnpm add -D @muse-code/sdk                                # Muse Code (PATH muse)
通过 pnpm exec(或 npx)使用 CLI,这样你就不需要全局安装:

pnpm exec agent-loop-init
pnpm exec agent-loop-setup --out .cursor/loops/my-task   # Ink TUI;--plain / --answers 供 agent 使用
pnpm exec agent-loop-prompt --out .cursor/loops/my-task  # 想法 → GOAL/verify 草稿 → 冻结 → 监视
pnpm exec agent-check cursor
pnpm exec agent-loop run .cursor/loops/my-task --runtime cursor --review-gate

快速开始

pnpm add -D @dancingteeth/agent-looper @cursor/sdk
export CURSOR_API_KEY=…   # 或用你的密钥管理器(Doppler 等)包装

pnpm exec agent-loop-init
人类:pnpm exec agent-loop-setup --out .cursor/loops/my-task
将仓库默认值(runtime、models、review、notify)写入
.cursor/agent-loop.repo.json。之后稀疏的 loop.json 文件会继承它们;
显式的 loop.json 键优先。Agent 跳过 TUI —— 使用 --answers 或
复制模板并仅设置 verify。
编辑 .cursor/loops/my-task/GOAL.md + verify.sh

pnpm exec agent-check cursor
pnpm exec agent-loop run .cursor/loops/my-task --runtime cursor --review-gate

其他 worker(在安装匹配的可选 peer 之后):

ClinePass / Credits
export CLINE_API_KEY=…
pnpm exec agent-loop run .cursor/loops/my-task --runtime cline-pass
pnpm exec agent-loop run .cursor/loops/my-task --runtime cline

OpenCode(需要来自 opencode-ai 的 opencode 在 PATH 上)
export OPENCODE_API_KEY=…   # 和/或用于 BYOK 的 OPENROUTER_API_KEY / AI_GATEWAY_API_KEY
pnpm exec agent-check opencode
pnpm exec agent-loop run .cursor/loops/my-task --runtime opencode

Pi BYOK
export OPENROUTER_API_KEY=…
pnpm exec agent-check pi
pnpm exec agent-loop run .cursor/loops/my-task --runtime pi
pnpm exec agent-loop run .cursor/loops/my-task --runtime pi --review-runtime pi --review-gate

Codex(需要通过 SDK 来自 @openai/codex 的 codex CLI)
export CODEX_API_KEY=…   # 或 OPENAI_API_KEY / ChatGPT 登录
pnpm exec agent-check codex
pnpm exec agent-loop run .cursor/loops/my-task --runtime codex

DeepSeek Harness(需要 dsh 在 PATH 上;Node ≥ 22.15)
export DEEPSEEK_API_KEY=…   # 或 DSH credentials-local
pnpm exec agent-check dsh
pnpm exec agent-loop run .cursor/loops/my-task --runtime dsh
runtime:docs/dsh-runtime.md —— dsh web 伴侣:docs/dsh-plugin.md

Muse Code(需要 muse CLI + @muse-code/sdk)
export META_API_KEY=…   # 可选;muse 登录即可
pnpm exec agent-check muse
pnpm exec agent-loop run .cursor/loops/my-task --runtime muse

Claude Code(需要 claude 2.1.169+ 在 PATH 上;claude login)
保持 ANTHROPIC_API_KEY 未设置,以便 -p 使用订阅配额
pnpm exec agent-check claude
pnpm exec agent-loop run .cursor/loops/my-task --runtime claude
典型:便宜的 worker + Claude 评判者 —— docs/claude-runtime.md

以另一个检出目录为目标:

pnpm exec agent-loop run /path/to/repo/.cursor/loops/fix-foo --repo-root /path/to/repo

消费者脚本示例:

{
"scripts": {
"agent:loop": "doppler run -- agent-loop run",
"agent:check": "doppler run -- agent-check cursor",
"agent:init": "agent-loop-init"
}
}

维护此仓库本身的 Harness 维护者:使用 pnpm build 构建本地 dist/,并通过 pnpm agent:loop 运行(参见 docs/dogfood.md)。发布 / 可信发布: docs/releasing.md。

仓库配置

.cursor/agent-loop.repo.json:

| 字段 | 用途 |
| --- | --- |
| taskwarriorProject | 当 hitlProvider 为 taskwarrior 时用于 HITL 的 Taskwarrior 项目 — TW HITL 必需 |
| hitlProvider | taskwarrior(默认)、file、github、linear 或 command — 参见 docs/hitl-providers.md |
| hitlFileDir | file provider 的目录(默认 .cursor/hitl) |
| hitlCommand | command provider 的 Shell |
| hitlLinearTeam | 当 hitlProvider 为 linear 时的 Linear 团队 key 或 id |
| syncCommand | 成功后执行的 Shell(或 null) |
| notifyCommand | 每次 CLI 退出时可选执行的 Shell(LOOP_ 环境变量) |
| notifyWebhook | 可选的 JSON POST(url 或 AGENT_LOOP_NOTIFY_WEBHOOK_URL) |
| notifyPrComment | CLI 退出后在打开的 PR 上评论(gh pr comment) |
| defaultBranch | 循环后 diff 基线(main) |
| agentsFile / reviewsFile | Prompt + review overlay 路径 |
| loopRiskProfile | 用于 postQualityReview: "auto" 的可选关键词合并(参见 REVIEWS.md ## Loop risk inference) |
| skillsGlob | System prompt 技能提示 |
| clientName | Cline 客户端标签 |
| telegramNotify | 可选的 chat id + onSuccess / onFailure |

loop.json 中的每循环覆盖项:taskwarriorProject、taskwarriorUuid、hitlCheck、hitlOnFailure、requireNotify,以及可选的 hitlProvider / hitlFileDir / hitlCommand / hitlLinearTeam。

Taskwarrior: 在 GOAL.md 和 loop.json 的 taskwarriorUuid 中使用 UUID — 数字 ID 会被回收。在成功且启用 syncOnSuccess 时,harness 会将该 UUID 标记为完成。

循环包

.cursor/loops/my-task/
GOAL.md                  # 冻结的规格(四部分完成线 + 可选 golden)
RESEARCH.md              # 可选 — 冻结的棕地地图(在 worker prompt 中建立索引)
loop.json                # verify、runtime、可选 taskwarriorUuid
verify.sh                # 可度量的 shell 检查(exit 0 = 通过;75 / 127 = 环境)
setup.sh                 # 可选 — 在第一个 worker 之前的 harness 引导
VERIFY.skill.md          # 代理可读的验证流程(可选;verifyMode: skill 时必需)
log.ndjson               # 仅追加的迭代日志(运行时)
assistant.stream         # 用于 watch 的实时 token/thinking 尾部(运行时)
run-report.md            # 报告卡 + 迭代时间线(当 exportRunReport 时)
transcript.ndjson        # 工具时间线(当 exportTranscript 时)
setup.log                # 可选 — 引导证据(运行时)
verify-logs/             # 可选 — 侧车验证 stdout/stderr(verifyLogMode)
failure-domains.ndjson   # 可选 — 停滞 / 最大迭代次数 / 门禁耗尽
failure-context.md       # 可选 — 由元循环探针写入,用于修复循环

验证(verify / verifyMode)

| 字段 | 默认值 | 用途 |
| --- | --- | --- |
| verify | (必填) | 每次迭代执行的 Shell 命令(通常为 bash …/verify.sh)。退出码 0 = 通过。退出码 75(EX_TEMPFAIL)、退出码 127(命令未找到),或出现 VERIFY_CLASS=env 行时,会作为环境限制挂起(status: waiting,HITL)——worker 不会继续迭代。其他非零退出码属于产品失败,会继续循环。 |
| verifyMode | command | command = 仅 Shell。skill = 验证 agent 读取 verifySkill,输出 VERIFY_RESULT: PASS/FAIL,然后在 PASS 时运行 Shell verify。Skill 验证使用与 worker 相同的迭代 agent(推理阶梯 / escalateModel 适用)。 |
| verifySkill | — | VERIFY.skill.md 的路径(当 verifyMode 为 skill 时必填)。 |
| finalVerify | — | 内层 verify 通过后执行的更严格外层检查。 |
| verifyLogMode | inline | 验证 stdout/stderr 如何传递给下一个 worker。inline 会粘贴捕获内容。sidecar 为可选:写入 /verify-logs/,并在提示中放入约 600 字符的预览 + 路径。当验证输出较短时,保持未设置 / inline。 |

默认保持 inline。仅当验证输出很大(完整的 vitest / Playwright / 编译器输出墙),否则会在后续每个提示中重复时,才使用 "verifyLogMode": "sidecar"。Sidecar 不会改变验证器;在写入磁盘之前,捕获内容仍会被限制(约 64KB)。

旧版 loop.json 字段 syncPostgres 映射到 syncOnSuccess。

loop.json — 循环控制

| 字段 | 默认值 | 用途 |
| --- | --- | --- |
| runtime | cursor | Worker:cursor \| cline-pass \| cline \| opencode \| pi \| codex \| dsh \| muse \| claude。当设置了 costPreset 时取消设置,以便检测可以绑定。参见 docs/runtime-map.md。同任务成本方法:docs/runtime-cost-bench.md。 |
| costPreset | — | 命名的 worker+judge 组合:minmax(效率 — 最便宜的有能力的 worker + 包含的最强 judge;只要安装了 Cursor 就用 Grok)、balanced(升级层级 worker,相同 judge)、cursor(Composer + Grok)。当 runtime/model 未设置时,在解析时进行检测绑定;显式键优先。不是 Auto。 |
| model / escalateModel | (默认值) | Worker 模型;在验证器出现相同停滞时升级,或在 worker 挂起/超时后立即升级(OpenCode/Pi/Codex/DSH/Muse/Claude:达到阈值后;Cline:达到推理上限后 — worker 故障会跳过上限)。 |
| maxIterations | 8 | 限制实现迭代次数。 |
| setup | — | Harness 引导 shell,在第一个 worker 之前运行一次。未设置时,如果 GOAL.md 旁边的 setup.sh 文件存在,则使用它。失败会将 status: waiting(无 worker)挂起,并在 setup 修改了冻结的 spec 文件时恢复它们。模板:templates/setup.example.sh。 |
| maxCostUsd | — | 预算金额的美元上限:当运行时报告超过 $0(PAYG)时使用账单发票金额,否则使用 API 标价,这样 $0 订阅配额仍会停止。当两者不同时,watch/report 会同时显示标价和账单金额(--max-cost)。省略 = 无上限。 |
| stagnationThreshold | 3 | 在 N 次相同的 verifier 失败后停止(0 = 禁用)。 |
| mode | forward | reverse = 洁净室重建(templates/GOAL.reverse.template.md) |
| pauseAfterIteration | false | 每次迭代后等待 Enter(仅 TTY) |
| injectFailureContext | false | 将 failure-context.md 读入 prompt(meta-loop 修复轮次) |
| syncOnSuccess | true | 成功后运行 repo profile 的 syncCommand |
| notifyTelegram | true | 当 Telegram 环境变量 + profile 已配置时发送完成报告 |
| telegramAttachReview | true | 将 review.md 作为第二条 Telegram 消息附加 |
| hitlOnFailure | false | 当循环未完成结束时打开 HITL 检查点 |
| requireNotify | false | 如果 Telegram 预检失败则中止(也可用 --require-notify) |
| completionSignal | true | 当 CLI 退出时在 stdout 上发出 AGENT_LOOP_DONE(本地 Cursor 唤醒;Cloud Agents 尚无法附加 watcher) |
| notifyCommand | — | 为此循环覆盖 repo profile 的 notifyCommand |
| exportPack | true | 将精选产物复制到 .cursor/loop-exports//(便于提交) |
| notifyPrComment | — | 为此循环覆盖 profile 的 notifyPrComment |
| preview | — | 用于 localhost 预览的可选 shell;agent-loop-prompt 会进行信任门控,并在成功 grind 后运行它(agent-loop run 不会执行它) |
| reasoningEffort | — | 当运行时支持时,为 low \| medium \| high \| xhigh \| none(Cline、Pi、Muse)。省略或 none = 无额外思考。Cursor / OpenCode / Codex / DSH / Claude 会忽略它。 |
| escalateReasoningEffort | — | 推理阶梯上限(与 reasoningEffort 相同的运行时)。适用于 worker 和 skill-verify。 |
| reasoningEscalationStep | 1 | 每次迭代提升的层级数(1 或 2) |
| escalateModelReasoningEffort | — | 升级模型上的推理层级 |
| escalateAfterStagnation | 2 | 切换模型前的相同失败计数(在推理上限之后)。Worker 超时 / 无工具停滞会立即切换,不会等待此计数。 |
| skills | — | 显式的 …/SKILL.md 路径(与 GOAL 引用合并)。默认 prompt 是一个索引(名称、描述、路径)——worker 在需要时读取该文件。 |
| skillDisclosure | index | index = 渐进式披露(0.4.0 默认;0.3.0 始终内联)。inline = 粘贴完整的 SKILL.md 正文。在任何必须保留旧版提示内运行手册的循环上固定该字段。 |
| plugins | — | Agent Plugins 包目录 — 发现 skills//SKILL.md(docs/agent-plugins.md) |
| research | — | 指向冻结的棕地地图的可选路径。若未设置,当 GOAL.md 旁的 RESEARCH.md 存在时,harness 会对其建立索引。提示获得路径 + 一行说明(worker Read 它);正文不会被内联。模板:templates/RESEARCH.example.md。 |

loop.json — 审查与质量

| 字段 | 默认值 | 用途 |
| --- | --- | --- |
| postQualityReview | auto | 运行循环后审查(true / false / auto,按推断的风险) |
| reviewRisk | auto | 为 postQualityReview: "auto" 覆盖推断的风险(high / medium / low) |
| loopRiskProfile | — | 用于风险推断的每循环关键词合并(high / medium / low 数组) |
| reviewGate | false | 当为 true 时,门控阻塞项会重新进入修复循环(最多 maxReviewCycles 次) |
| reviewRuntime | cursor | 主评审运行时(与 runtime 相同的枚举)。未设置 → cursor。 |
| reviewModel | (已解析) | reviewRuntime 的评审模型。Cursor 默认值:当 worker 为 cursor 时为 grok-4.6,否则为 composer-2.5。OpenCode 评审(reviewRuntime: "opencode")默认为 opencode-go/deepseek-v4-pro(worker 保持 Flash)。DSH 评审(reviewRuntime: "dsh")默认为 deepseek-official/deepseek-v4-pro。Codex 评审(reviewRuntime: "codex")默认为 gpt-5.6-sol(worker 保持 Luna)。Muse 评审(reviewRuntime: "muse")默认为 muse-spark-1.3(worker 保持 contributor)。Claude 评审(reviewRuntime: "claude")默认为 opus(worker 保持 Sonnet)。Pi / Cline 评审使用该运行时的 worker 默认值。在 cursor 上绝不使用 Composer Fast。 |
| maxReviewCycles | 2 | 当 reviewGate 开启时,由审查触发的修复轮数 |
| reviewGateHitl | false | 门控耗尽时,打开 HITL 检查点(hitlProvider),而不仅仅是硬失败 |
| unparseableReviewRetries | 2 | 当裁决无法解析时的重试次数 |
| reviewBlockerRecheck | true | 在 BLOCKERS 修复轮中,进行更轻量的范围受限复查 |
| reviewReproduce | false | 对错误+影响阻塞项(已更改文件集)的路径过滤 |
| reviewReproduceAgent | false | 对门控阻塞项启动全新的 KEEP/DROP 会话(需要 reviewReproduce;使用主 reviewRuntime) |
| reviewSecondaryRuntime | (未设置) | 第二残余评审(cursor \| cline-pass \| cline \| opencode \| pi \| codex \| dsh \| muse \| claude);未设置 = 关闭 |
| reviewSecondaryModel | (默认) | 第二审查的模型(按该运行时默认) |
| trustConfig | false | 将此循环的 shell 命令标记为已预先审查(与 --trust-config 门控配合使用)。仅在严格模式(--require-trust-config)下生效;默认情况下,不受信任的命令会发出警告但仍会运行。 |
| exportRunReport | true | 循环结束时写入 run-report.md(报告卡 + 时间线) |
| exportTranscript | true | 在 transcript.ndjson 中记录工具事件,并在 log.ndjson 中记录每次迭代的工具计数 |

阻断器语法:从 templates/REVIEWS.md 发布 REVIEWS.md。库:reviewVerdictAllowsCompletion 接收完整的 ParsedReview 用于影响严重性门控。

loop.json — 保留字段(实验性)

这些字段在 loop.json 中可以通过验证,但它们的流水线钩子尚未执行。
当它们被配置时,测试框架会在每次运行(CLI、批处理和直接库调用)时记录一条 loop extension preflight 注释——不要依赖它们来门控任何内容:

| 字段 | 状态 |
| --- | --- |
| smokeScripts | 保留——验证后钩子未实现 |
| siblingRepos | 部分接入——记录在 log.ndjson 中;跨仓库验证未实现 |
| verifyPreflight | 保留——未实现 |

postQualityReview: "auto" 与循环风险

当 postQualityReview 为 "auto"(默认值)时,测试框架会根据 GOAL.md + verify 命令中的关键词推断高 / 中 / 低风险等级。当等级不是 low 时运行审查。
reviewGate: true 始终运行审查,无论等级如何。

合并顺序(每一层添加关键词;首个匹配胜出,高 → 中 → 低):

1. 测试框架默认值(loopRiskProfile.ts 中的 DEFAULT_LOOP_RISK_KEYWORDS)
2. REVIEWS.md → ## Loop risk inference → ### HIGH / MEDIUM / LOW
3. .cursor/agent-loop.repo.json → loopRiskProfile
4. loop.json → loopRiskProfile(按循环合并)

完全覆盖推断:在 loop.json 中设置 "reviewRisk": "high" | "medium" | "low"。

不运行循环即可预览:

agent-loop-review-preview .cursor/loops/my-task

仓库覆盖示例(agent-loop.repo.json;完整示例:templates/agent-loop.repo.json.example):

{
"loopRiskProfile": {
"high": ["stripe-webhook", "crm-admin"],
"medium": ["checkout"],
"low": ["copy-only"]
}
}

按循环覆盖示例(loop.json):

{
"postQualityReview": "auto",
"reviewRisk": "auto",
"loopRiskProfile": { "high": ["payment-refund"] }
}

CLI 覆盖:--mode reverse、--pause-after-iteration、--review-gate、--no-telegram、--review-runtime 、--review-model 、--review-secondary-runtime 、--review-secondary-model 。

审查门控流程

当 reviewGate: true 且验证通过时:

primary review (reviewRuntime + reviewModel; default cursor)
→ optional reviewReproduce path filter
→ optional reviewReproduceAgent KEEP/DROP
→ optional reviewSecondaryRuntime merge
→ gating blockers remain? → fix iteration (up to maxReviewCycles)
→ else PASS / ADVISORY → complete
无法解析的判定重试(unparseableReviewRetries)。门控耗尽可升级到 HITL(reviewGateHitl)。门控条目(severity: error + 可识别的 impact 标签)即使同一个 review.md 后面出现 ### Verdict — PASS 标题,也会保持门控开启。标题与正文 token 不一致且没有门控条目时,视为无法解析。

Ralph 循环对齐

实现 Ralph 循环 模式:

- 单体式 — 一个仓库、一个进程、每个循环一个任务
- 全新上下文 每次迭代;进度保存在 文件和 git 中
- Shell 反向压力(verify / finalVerify)作为确定性的完成信号
- 验证即技能 — verify.sh + VERIFY.skill.md;可选 verifyMode: skill
- 观察循环 — log.ndjson、run-report.md、transcript.ndjson、停滞、可选 --pause-after-iteration
- 完成哨兵 — CLI 退出时 stdout 输出 AGENT_LOOP_DONE {…}(用于附加的本地 Shell notify_on_output 或日志 grep;不要将任务放到后台 — 见下文)
- 失败域 — 在停滞、达到最大迭代次数或 review-gate 耗尽时生成 failure-domains.ndjson
- 元循环 — 探测 → failure-context.md → 修复 → 重新探测

正向 = 增量修复直到通过。反向 = 洁净室提示词引导;通过 verify 和 GOAL.md 强制范围。

元循环(探测 → 修复 → 重新探测)

在 loop-batch.json 中:

{
"metaLoop": {
"probe": "system-smoke",
"fix": "fix-from-smoke",
"maxCycles": 3
},
"hitlCheck": "Manual QA after meta-loop",
"taskwarriorProject": "my-project"
}

循环:探测 → 失败时将 failure-context.md 写入修复包 → 使用 injectFailureContext 修复 → 重新探测。当探测通过或 maxCycles 耗尽时停止。参见 templates/loop-batch.meta.example.json。

带逐项评分标准的顺序批处理

每个 loops[] 条目要么是同级循环名称/路径(字符串),要么是 { "path": "...", "rubric": "..." }。当设置了 rubric 时,批处理运行器会将一个易变的 Batch rubric 部分注入该循环的 worker 提示词;shell verify 仍然是退出闸门。参见 templates/loop-batch.example.json。

跨循环元审查

对 N 个循环包进行只读聚合(不会重新运行 worker,也不会翻转每个循环的 complete 标志):

agent-loop-meta-review .cursor/loops --out-dir /tmp/meta-out
agent-loop-meta-review .cursor/loops --review-runtime opencode --review-model openrouter/anthropic/claude-sonnet-4
agent-loop-meta-review .cursor/loops/a .cursor/loops/b --hitl --project my-project

收集最新的 review.md、log.ndjson、failure-domains.ndjson,以及与 defaultBranch 的 diff 统计。当循环内文件缺失时(云端克隆后很常见 — 这些路径被 gitignore),回退到 .cursor/loop-exports//。提示词简报:docs/meta-review-prompt.md。

CLI

| 命令 | 描述 |
| --- | --- |
| agent-loop run  | 单个循环 |
| agent-loop watch  | 实时进度:Ink 监视视图(TTY)或结构化阶段行;--snapshot / --pulse 打印一帧后退出。Ink 中按 s 刷新 pid/日志/流健康状态;助手 token 和 Cursor 思考/工具输出在面板中尾部跟随。 |
| agent-loop-batch  | loop-batch.json 顺序执行或元循环 |
| agent-check cursor\|cline\|opencode\|pi\|codex\|dsh\|muse\|claude | SDK + API key 冒烟测试(dsh:PATH CLI + Node ≥ 22.15;muse:PATH muse + @muse-code/sdk;claude:PATH CLI 2.1.169+ + --safe-mode,不消耗配额) |
| agent-loop-init | 脚手架模板 + check-running-loops 技能(.cursor/skills 和 .agents/skills) |
| agent-loop-setup | Ink TUI / --plain / --answers 向导:仓库 defaults 位于 .cursor/agent-loop.repo.json,以及用于 --out 的 loop.json |
| agent-loop-prompt | Ink TUI:输入一个想法 → judge 搭建 GOAL/verify → 冻结 lint + 确认 → agent-loop run 监视;成功后可选 preview。当设置了 DOPPLER_PROJECT / DOPPLER_CONFIG 时,失败的运行会打印 Doppler 包装的恢复命令。 |
| agent-loop-doctor | 验证安装 / dist/ 完整性;模型定价漂移对比 CLINE_PASS_LOOP_MODELS |
| agent-loop-meta-review | 跨循环元审查(只读) |
| agent-loop-review-run | 针对单个 bundle 的循环后质量审查 |
| agent-loop-review-preview | 预览审查风险 / 提示词 |
| agent-loop-export-run | 从 log.ndjson(+ 可选的 transcript.ndjson)重新生成 run-report.md |

架构

GOAL.md + loop.json
→ fresh worker agent
→ verify (command or skill + command)
→ optional review gate
→ log.ndjson
→ run-report.md (+ transcript.ndjson when enabled)
→ .cursor/loop-exports// (curated pack; commit-friendly)
→ repeat

成功后(当 postQualityReview 运行时):质量审查 → 使用仓库 REVIEWS.md 覆盖层生成 review.md。当 reviewGate: true 时,只有门控阻塞项会重新进入修复循环;只要这些条目仍然存在,引用的 ### Verdict — PASS 就无法关闭门控。完成需要 PASS 或 ADVISORY 且没有门控阻塞项。然后:可选的关联任务完成(例如 Taskwarrior done)→ hitlCheck(通过 hitlProvider)→ syncCommand。

Stderr 打印 token 总数和估算的 USD(ClinePass 可能包含缓存输入计数)。

| 层级 | 角色 | 是否阻塞循环? |
| --- | --- | --- |
| Shell verify / finalVerify(+ 可选技能预检) | 确定性裁判 | 是 |
| postQualityReview(无门控) | 咨询性 LLM | 否 |
| reviewGate: true | 对门控阻塞项 / 无法解析的裁决进行门控 | 是 |

威胁模型

对于你控制的受信任检出:

- verify / finalVerify / syncCommand 通过 shell: true 运行——恶意配置 = 任意 shell。
- 验证器的 stdout/stderr 会被注入到下一个 worker 提示词中(仅为软性护栏)。
- 启动时,CLI 会打印已配置的 shell 命令,并标记明显的窃取模式(curl、wget、| sh、反引号、$())。
信任门控(可选启用的严格模式):

- 默认是宽松模式:打印警告 + 提示(审查后使用 --trust-config)后继续运行。除非你在下方启用严格模式,否则不会阻止任何操作——在运行非你编写的循环包之前,请先启用严格模式。
- --require-trust-config 或 AGENT_LOOP_REQUIRE_TRUST_CONFIG=1:除非你传入 --trust-config、在 loop.json 中设置 trustConfig: true,或设置 AGENT_LOOP_TRUST_CONFIG=1,否则中止。
- 自用测试 / CI:在已知安全的循环包上设置 trustConfig: true,或在 Doppler 中导出 AGENT_LOOP_TRUST_CONFIG=1。

仅在你信任的仓库和循环包上运行。请先审查 loop.json 和 .cursor/agent-loop.repo.json。

环境变量

| 变量 | 作用 |
| --- | --- |
| CURSOR_API_KEY | Cursor SDK 认证(worker 和/或默认 judge) |
| CLINE_API_KEY | Cline SDK 认证(可选的对等运行时 / 次级 judge) |
| OPENCODE_API_KEY | OpenCode Go 认证(可选的对等运行时;https://opencode.ai/go) |
| OPENROUTER_API_KEY | 用于 OpenCode / Pi worker 和 judge 的 OpenRouter BYOK(包括 :free slug) |
| AI_GATEWAY_API_KEY | 用于 OpenCode 的 Vercel AI Gateway BYOK(vercel/… 模型;harness auth.set) |
| CODEX_API_KEY / OPENAI_API_KEY | Codex SDK 认证(可选;否则使用 ChatGPT CLI 登录) |
| META_API_KEY | Muse Code Model API(可选;否则使用 muse CLI 登录) |
| AGENT_LOOP_VERBOSE | 1 / true — 额外的 stderr 流详细信息 |
| AGENT_LOOP_CURSOR_TIMEOUT_MS | Cursor 运行超时时间(毫秒,默认 2700000 = 45 分钟)。必须是正数;在 Agent.create 之前进行校验,因此错误的值会在不消耗付费运行的情况下失败。超时时,harness 会取消远程运行。 |
| AGENT_LOOP_MUSE_TIMEOUT_MS | Muse 运行超时时间(毫秒,默认 2700000 = 45 分钟)。超时时,harness 会立即关闭 muse serve。 |
| AGENT_LOOP_TRUST_CONFIG | 1 — 将 shell 配置视为已审查/受信任 |
| AGENT_LOOP_REQUIRE_TRUST_CONFIG | 1 — 除非设置了信任(CLI / 环境变量 / loop.json),否则中止 |
| AGENT_LOOP_TELEGRAM_BOT_TOKEN | Telegram bot token(回退:TELEGRAM_BOT_TOKEN) |
| AGENT_LOOP_TELEGRAM_CHAT_ID | Telegram chat id(或仓库配置文件中的 telegramNotify.chatId) |
| AGENT_LOOP_NO_COMPLETION_SIGNAL | 1 — 在 CLI 退出时跳过 AGENT_LOOP_DONE stdout 行 |
| AGENT_LOOP_NOTIFY_WEBHOOK_URL | 当启用 notifyWebhook 但没有内联 url 时使用的 JSON webhook URL |
| AGENT_LOOP_PR_NUMBER | 用于 notifyPrComment 的 PR 编号(回退:GH_PR_NUMBER,然后是 gh pr view) |

Telegram 完成报告

在完成时(成功或失败),可选的简短报告:

- 状态、仓库、bundle/batch、迭代次数、原因
- Token/成本行
- 存在时的审查结论
- 失败时的最后验证器片段

可选的第二条消息:将 review.md 作为文档附加。通过 "telegramAttachReview": false 或配置文件中的 "attachReview": false 选择退出。

设置:

1. 在环境变量中设置 Bot token:AGENT_LOOP_TELEGRAM_BOT_TOKEN(或 TELEGRAM_BOT_TOKEN)
2. 聊天 id:仓库配置中的 AGENT_LOOP_TELEGRAM_CHAT_ID 或 telegramNotify.chatId
3. 用你运行循环时已有的方式注入密钥(doppler run、direnv、CI secrets……)

退出选项: "notifyTelegram": false 或 --no-telegram。通知发送失败不会阻塞退出码,但如果已配置 Telegram 且 failure 报告未送达,harness 会通过 hitlProvider 打开一个 HITL 检查点(notify_failed)。使用 --require-notify / requireNotify: true,在 getMe 预检失败时于循环开始前中止。

从 Cursor 聊天运行

Cursor 的 agent Shell 不是终端。block_until_ms: 0(或 IDE 的 background 按钮)是一个子进程,IDE 会在 约 5 分钟 时回收它(status: aborted、exit_code: unknown,通常是 pnpm 255),而此时 worker 仍在回合中途。这不是 harness 的问题:TTFB 停滞为 3 分钟且无事件;OpenCode 无工具停滞为 8 分钟只有文本没有工具;整体超时为 45 分钟。

如果你是此聊天中的 agent,由你启动循环。不要打印一条命令然后让人类去运行它。 走开不是你的兜底方案。

| 意图 | 做法 |
| --- | --- |
| 此聊天(默认) | Shell attached:block_until_ms ≥ 45m(2700000)。对 ^AGENT_LOOP_DONE  启用 notify_on_output。 |
| 人类要求走开 | 他们的终端(pnpm agent:loop …)。Telegram / HITL / webhook 唤醒他们。 |

绝不要对 agent-loop 或 agent-loop-batch 使用 block_until_ms: 0。中止后重新附加;不要将其视为 harness 失败。

AGENT_LOOP_DONE 是用于 attached watcher 或日志 grep 的 stdout 哨兵。退出选项:--no-completion-signal、"completionSignal": false 或 AGENT_LOOP_NO_COMPLETION_SIGNAL=1。

示例 payload:

AGENT_LOOP_DONE {"v":1,"kind":"loop","bundle":".cursor/loops/my-task","complete":true,"exitCode":0,"reason":"Verifier passed (exit 0).","iterations":2,"runReport":".cursor/loops/my-task/run-report.md"}

人类日志保留在 stderr;哨兵通过 fs.writeSync(1, …) 写入,因此管道 stdout 在 process.exit 之前不会丢失。侧通道(notifyWebhook / notifyCommand / PR comment)在哨兵 之后 运行,并有时间上限,因此挂起的 hook 无法延迟唤醒。

Cloud Agents

Cloud Agent Shell 目前不暴露 notify_on_output,因此即使 harness 仍会发出 AGENT_LOOP_DONE,此聊天也无法附加 regex watcher。在 Cursor 添加该功能(或等效的唤醒机制)之前,将云端完成视为:

- notifyWebhook — 向 Slack/Discord/n8n 发送 JSON POST(Doppler 中的 AGENT_LOOP_NOTIFY_WEBHOOK_URL)
- notifyPrComment: true — 对分支 PR 执行 gh pr comment(当云端 agent 已打开 PR 时设置)
- Telegram(notifyTelegram + env;--require-notify 以失败关闭)
- HITL(hitlOnFailure、Linear / file / github,使用具备 issue 能力的 token)
- Export packs — 提交或附加 .cursor/loop-exports//,以便 meta-review 和人类无需依赖被 gitignore 的运行中途文件即可阅读 review
不要在 Cloud Agents 上承诺从 AGENT_LOOP_DONE 进行聊天内唤醒。

导出包(cloud / PR 审计)

循环内的 review.md / log.ndjson / run-report.md 保持 gitignored(运行中噪声大)。当 exportPack: true(默认)时,每个完成的循环还会将一份精选快照写入:

.cursor/loop-exports//
SUMMARY.md
meta.json
run-report.md      # when present
review.md          # latest review when present
log-tail.ndjson    # last ~40 log lines
failure-domains.ndjson

提交该目录(或在 PR 上附加它),这样 cloud clones 和 meta-review 就不是黑盒。Cloud agent 提示:循环结束后,在循环分支上执行 git add .cursor/loop-exports && git commit && git push。批量完成 webhooks/PR 评论会列出每个现有的子导出包(逗号分隔 / 项目符号列表)。当循环目录位于仓库之外(vitest tmpdirs)时,会跳过这些包,这样 .cursor/loop-exports 就不会填满 ..__var__folders__… 这样的 slug。

notifyWebhook + PR 评论

仓库配置:

{
"notifyWebhook": { "onSuccess": true, "onFailure": true },
"notifyPrComment": true
}

将 URL 放入 Doppler 作为 AGENT_LOOP_NOTIFY_WEBHOOK_URL(或设置 notifyWebhook.url)。Payload 为 JSON(v、kind、bundle、complete、exitCode、reason、exportPack、…)。POST 请求在约 8 秒后中止;stderr 日志会从 URL 中隐去 query/hash。

notifyPrComment 会为当前分支的 PR(或 AGENT_LOOP_PR_NUMBER)运行 gh pr comment。使用与 GitHub HITL 相同的 gh 认证——可与能够评论的用户/PAT 一起工作;GitHub App tokens 通常可以在 PR 上评论,即使它们无法 issue create。

notifyCommand(shell 回退)

可选的 shell,带有 LOOP_* 环境变量(LOOP_EXPORT_PACK、LOOP_RUN_REPORT、…),当你需要超出 JSON webhook 的自定义逻辑时使用。非阻塞;约 15 秒超时;受 shell-trust 门控。选择退出:--no-notify-command。

许可证

MIT

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群