Loop Engineering

Loop Engineering 是什么?从提示词工程到自主循环

一句话摘要:Loop Engineering(循环工程)不是「把提示词写得更长」,而是设计一套能自己发现工作、分配任务、验证结果、记录状态的系统------让你从「每一轮都亲手打字」变成「设计好循环后走开」。


阅读说明:本文适合谁?

目标读者

本文主要面向 已会使用 Cursor、熟悉 Git 基本操作、了解 CI/测试概念的开发者。你若符合以下情况,阅读体验最佳:

  • 用过 Cursor Chat / Agent,写过提示词;
  • 知道什么是 PR、单元测试、lint;
  • 希望在「概念理解」之外,还能照着搭一个最小循环。

不太适合谁?

若你属于以下情况,建议先补基础再读本文第七节及以后:

  • 零基础 AI 使用者 → 先学提示词工程与 Cursor 基本操作;
  • 未接触过 Git → 先学版本控制(commit、branch);
  • 未接触过 CI → 先了解「自动化测试在提交后自动跑」是什么。

阅读路径建议

你的背景 建议读法
想先懂概念 读「术语速查」→ 第一至六节 → 停
想在 Cursor 里试一手 加上第七节 7.7 入门案例(约 15 分钟可动手)
团队级自动化 再读 7.8 进阶案例(需 GitHub Actions、MCP 等)

版本与时效性声明

文中涉及的 Cursor 产品能力 (如 /loop、Automations、agent -p@cursor/sdk、Hooks、Rules 等)以 2026 年上半年公开文档与社区实践为例。AI 工具迭代很快,具体命令、界面入口、定价与权限可能随版本变化。

请以 Cursor 官方文档 为准 ;本文侧重讲清 Loop Engineering 的设计思想与通用模式,产品细节落地前请自行核对。


术语速查(建议先扫一遍)

后文会反复出现下列词。先建立模糊印象即可,遇到时再回查。

术语 一句话解释
Agent 能读文件、跑命令、多步推理的 AI 助手(如 Cursor Agent)
Prompt Engineering 优化「单次/多轮对话怎么说」
Loop Engineering 设计「自动重复执行直到达标」的整套系统
Harness 单个 Agent 的运行环境:工具、权限、上下文窗口
Loop / 循环 行动 → 观察反馈 → 推理 → 再行动,直到终止
Automation 按时间或事件自动触发 Agent 任务(如每日 9:00、PR 打开时)
/loop Cursor 会话内定期间隔重复执行 prompt(本地、轻量)
/goal 跨多轮执行直到可验证条件满足(部分产品支持)
Worktree Git 的并行工作目录,多 Agent 改代码时互不踩脚
Skill 外置项目知识文件(SKILL.md),避免每轮重新解释项目
MCP 让 Agent 连接 GitHub、Linear、Slack 等外部工具的协议
Sub-agent 主 Agent 派出的子任务代理(探索 / 实现 / 审查分工)
State / 状态文件 写在磁盘上的进度记录(如 state.md),跨会话不丢
Hook Agent 执行工具前的拦截脚本(如禁止 git push --force
Rules 限制 Agent 能改哪些文件、遵循哪些规范(.cursor/rules
SDK 用代码(TypeScript/Python)程序化驱动 Agent
CLI agent -p 命令行无头模式,适合 CI / 脚本
Intent Debt(意图债) 没写清的意图被模型用「自信的错误」填补
Comprehension Debt(理解债) 代码长得比你的理解快,越跑越不懂

两个图的区别(避免混淆):

  • 能力层级图 (第七节 7.1):按「从轻到重」排列 Cursor 的四档用法(/loop → Automations → CLI → SDK)。
  • 能力模块图 (第四节、7.2):六大积木平级协作,不分第几层。

配图说明:左为传统提示词工程(人每轮驱动);右为循环工程(人设计系统,系统驱动 Agent)。


一、先从一个日常场景说起

假设你要用 AI 助手修一个登录页的 Bug。传统做法大概是这样:

  1. 打开 Chat,描述问题;
  2. AI 给了一段代码,你复制粘贴;
  3. 运行测试,失败了;
  4. 把错误日志贴回去;
  5. 再改一轮......

你可能来来回回聊了 十几轮。每一轮都是你主动发起,AI 被动回答。你既是「项目经理」,又是「测试员」,还是「复制粘贴工」。

2025 年底到 2026 年初,行业里开始流行一个新说法:Loop Engineering(循环工程)

Google Chrome 团队工程师 Addy Osmani 在博客中把它概括为一句话:

Loop engineering is replacing yourself as the person who prompts the agent. You design the system that does it instead.

循环工程,是用「设计系统」取代「亲自给 Agent 打字」。

Anthropic Claude Code 负责人 Boris Cherny 说得更直白:

"I don't prompt Claude anymore. I have loops running that prompt Claude. My job is to write loops."

我不再亲自给 Claude 写提示词了。我有一堆循环在替我写。我的工作,是写循环。

听起来有点「玄」,但拆开看,其实逻辑很朴素:以前你优化的是「一句话怎么说」;现在你优化的是「一整台自动运转的机器怎么搭」。


二、什么是 Loop Engineering?

2.1 用最通俗的话定义

Loop Engineering = 为 AI Agent 设计「行动 → 观察 → 推理 → 再行动」的闭环,直到目标达成或明确停止。

这里的「Loop(循环)」不是 for 循环那种代码语法,而是一种工作范式

  • 你给 Agent 一个可验证的目标(例如:所有 auth 测试通过、lint 无报错);
  • Agent 动手(读文件、写代码、跑命令);
  • 环境反馈结果(测试红/绿、编译错误、CI 状态);
  • Agent 根据反馈决定下一步
  • 重复,直到终止条件满足。

这和传统「你问一句、它答一句」有本质区别:循环里,是 Agent 在驱动下一轮,不是你。

2.2 和 Agent、Harness 的关系

(术语见文首 术语速查

行业里还有几个相近概念,容易混:

概念 通俗理解 关系
Prompt Engineering 写好单次/多轮对话的提示词 循环的「原材料」
Agent Harness Engineering 给单个 Agent 搭运行环境(工具、权限、上下文) 循环的「单兵装备」
Loop Engineering 让多个环节按节奏自动串联、发现工作、验收、记状态 坐在 Harness 上面一层的「流水线设计」

Addy Osmani 的比喻很形象:Harness 是工厂车间 ,Loop 是整条产线的调度系统------带定时器、能派小工、能自己喂下一批任务。

2.3 核心循环:Act → Observe → Reason → Repeat

几乎所有现代 AI 编程 Agent(Claude Code、Cursor Agent、OpenAI Codex、Devin 等)底层都是这个模型:
#mermaid-svg-I6pk6lJ9l5jFzGjq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-I6pk6lJ9l5jFzGjq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-I6pk6lJ9l5jFzGjq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-I6pk6lJ9l5jFzGjq .error-icon{fill:#552222;}#mermaid-svg-I6pk6lJ9l5jFzGjq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-I6pk6lJ9l5jFzGjq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-I6pk6lJ9l5jFzGjq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-I6pk6lJ9l5jFzGjq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-I6pk6lJ9l5jFzGjq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-I6pk6lJ9l5jFzGjq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-I6pk6lJ9l5jFzGjq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-I6pk6lJ9l5jFzGjq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-I6pk6lJ9l5jFzGjq .marker.cross{stroke:#333333;}#mermaid-svg-I6pk6lJ9l5jFzGjq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-I6pk6lJ9l5jFzGjq p{margin:0;}#mermaid-svg-I6pk6lJ9l5jFzGjq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-I6pk6lJ9l5jFzGjq .cluster-label text{fill:#333;}#mermaid-svg-I6pk6lJ9l5jFzGjq .cluster-label span{color:#333;}#mermaid-svg-I6pk6lJ9l5jFzGjq .cluster-label span p{background-color:transparent;}#mermaid-svg-I6pk6lJ9l5jFzGjq .label text,#mermaid-svg-I6pk6lJ9l5jFzGjq span{fill:#333;color:#333;}#mermaid-svg-I6pk6lJ9l5jFzGjq .node rect,#mermaid-svg-I6pk6lJ9l5jFzGjq .node circle,#mermaid-svg-I6pk6lJ9l5jFzGjq .node ellipse,#mermaid-svg-I6pk6lJ9l5jFzGjq .node polygon,#mermaid-svg-I6pk6lJ9l5jFzGjq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-I6pk6lJ9l5jFzGjq .rough-node .label text,#mermaid-svg-I6pk6lJ9l5jFzGjq .node .label text,#mermaid-svg-I6pk6lJ9l5jFzGjq .image-shape .label,#mermaid-svg-I6pk6lJ9l5jFzGjq .icon-shape .label{text-anchor:middle;}#mermaid-svg-I6pk6lJ9l5jFzGjq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-I6pk6lJ9l5jFzGjq .rough-node .label,#mermaid-svg-I6pk6lJ9l5jFzGjq .node .label,#mermaid-svg-I6pk6lJ9l5jFzGjq .image-shape .label,#mermaid-svg-I6pk6lJ9l5jFzGjq .icon-shape .label{text-align:center;}#mermaid-svg-I6pk6lJ9l5jFzGjq .node.clickable{cursor:pointer;}#mermaid-svg-I6pk6lJ9l5jFzGjq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-I6pk6lJ9l5jFzGjq .arrowheadPath{fill:#333333;}#mermaid-svg-I6pk6lJ9l5jFzGjq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-I6pk6lJ9l5jFzGjq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-I6pk6lJ9l5jFzGjq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-I6pk6lJ9l5jFzGjq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-I6pk6lJ9l5jFzGjq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-I6pk6lJ9l5jFzGjq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-I6pk6lJ9l5jFzGjq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-I6pk6lJ9l5jFzGjq .cluster text{fill:#333;}#mermaid-svg-I6pk6lJ9l5jFzGjq .cluster span{color:#333;}#mermaid-svg-I6pk6lJ9l5jFzGjq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-I6pk6lJ9l5jFzGjq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-I6pk6lJ9l5jFzGjq rect.text{fill:none;stroke-width:0;}#mermaid-svg-I6pk6lJ9l5jFzGjq .icon-shape,#mermaid-svg-I6pk6lJ9l5jFzGjq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-I6pk6lJ9l5jFzGjq .icon-shape p,#mermaid-svg-I6pk6lJ9l5jFzGjq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-I6pk6lJ9l5jFzGjq .icon-shape .label rect,#mermaid-svg-I6pk6lJ9l5jFzGjq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-I6pk6lJ9l5jFzGjq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-I6pk6lJ9l5jFzGjq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-I6pk6lJ9l5jFzGjq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否

定义目标 Goal
Agent 行动 Act
环境反馈 Observe
推理下一步 Reason
终止条件?
完成 / 上报人工

关键洞见: 一个 Agent 强不强,往往不只看模型智商,更看循环设计------工具有没有、上下文会不会爆、错了能不能收、什么时候该停。


三、传统提示词工程:我们过去两年在做什么?

3.1 提示词工程的核心动作

2023--2025 年,大家学的「提示词工程」大致包括:

  • 角色设定:「你是一个资深 Go 工程师......」
  • 任务拆解:「先分析,再列步骤,最后写代码」
  • Few-shot 示例:贴一两个理想输出样例
  • 输出格式约束:「只输出 JSON」「用 markdown 表格」
  • 上下文投喂@file、贴日志、贴接口文档

本质是:在单次或有限多轮对话里,尽量把模型一次引导对。

3.2 提示词工程的天然天花板

这套方法能走很远,但有四条硬限制:

① 人类带宽是瓶颈

每一轮都要你:看输出 → 判断对错 → 组织下一句话。Agent 再快,也被你的键盘和注意力卡住。

② 会话是无状态的

关掉窗口,模型「失忆」。下次又得重新解释项目结构、命名规范、那次线上事故的教训......Osmani 称之为 Intent Debt(意图债):缺什么意图,模型就用自信的错误补上。

③ 自评不可靠

让同一个模型写完代码再自己说「好了」,它往往过于宽容------出题人和阅卷人不能是同一个人,这在循环设计里是铁律。

④ 一次性任务 vs recurring 任务

提示词擅长「帮我写这个函数」;不擅长「每天早上扫一遍 CI 失败并开修复 PR」------后者需要调度、记忆、隔离、验收,已经超出「一段话」的范畴。

3.3 用一张图看清差异

#mermaid-svg-ipyrEeEGO1DINd6m{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ipyrEeEGO1DINd6m .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ipyrEeEGO1DINd6m .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ipyrEeEGO1DINd6m .error-icon{fill:#552222;}#mermaid-svg-ipyrEeEGO1DINd6m .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ipyrEeEGO1DINd6m .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ipyrEeEGO1DINd6m .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ipyrEeEGO1DINd6m .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ipyrEeEGO1DINd6m .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ipyrEeEGO1DINd6m .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ipyrEeEGO1DINd6m .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ipyrEeEGO1DINd6m .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ipyrEeEGO1DINd6m .marker.cross{stroke:#333333;}#mermaid-svg-ipyrEeEGO1DINd6m svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ipyrEeEGO1DINd6m p{margin:0;}#mermaid-svg-ipyrEeEGO1DINd6m .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ipyrEeEGO1DINd6m .cluster-label text{fill:#333;}#mermaid-svg-ipyrEeEGO1DINd6m .cluster-label span{color:#333;}#mermaid-svg-ipyrEeEGO1DINd6m .cluster-label span p{background-color:transparent;}#mermaid-svg-ipyrEeEGO1DINd6m .label text,#mermaid-svg-ipyrEeEGO1DINd6m span{fill:#333;color:#333;}#mermaid-svg-ipyrEeEGO1DINd6m .node rect,#mermaid-svg-ipyrEeEGO1DINd6m .node circle,#mermaid-svg-ipyrEeEGO1DINd6m .node ellipse,#mermaid-svg-ipyrEeEGO1DINd6m .node polygon,#mermaid-svg-ipyrEeEGO1DINd6m .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ipyrEeEGO1DINd6m .rough-node .label text,#mermaid-svg-ipyrEeEGO1DINd6m .node .label text,#mermaid-svg-ipyrEeEGO1DINd6m .image-shape .label,#mermaid-svg-ipyrEeEGO1DINd6m .icon-shape .label{text-anchor:middle;}#mermaid-svg-ipyrEeEGO1DINd6m .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ipyrEeEGO1DINd6m .rough-node .label,#mermaid-svg-ipyrEeEGO1DINd6m .node .label,#mermaid-svg-ipyrEeEGO1DINd6m .image-shape .label,#mermaid-svg-ipyrEeEGO1DINd6m .icon-shape .label{text-align:center;}#mermaid-svg-ipyrEeEGO1DINd6m .node.clickable{cursor:pointer;}#mermaid-svg-ipyrEeEGO1DINd6m .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ipyrEeEGO1DINd6m .arrowheadPath{fill:#333333;}#mermaid-svg-ipyrEeEGO1DINd6m .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ipyrEeEGO1DINd6m .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ipyrEeEGO1DINd6m .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ipyrEeEGO1DINd6m .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ipyrEeEGO1DINd6m .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ipyrEeEGO1DINd6m .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ipyrEeEGO1DINd6m .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ipyrEeEGO1DINd6m .cluster text{fill:#333;}#mermaid-svg-ipyrEeEGO1DINd6m .cluster span{color:#333;}#mermaid-svg-ipyrEeEGO1DINd6m div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ipyrEeEGO1DINd6m .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ipyrEeEGO1DINd6m rect.text{fill:none;stroke-width:0;}#mermaid-svg-ipyrEeEGO1DINd6m .icon-shape,#mermaid-svg-ipyrEeEGO1DINd6m .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ipyrEeEGO1DINd6m .icon-shape p,#mermaid-svg-ipyrEeEGO1DINd6m .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ipyrEeEGO1DINd6m .icon-shape .label rect,#mermaid-svg-ipyrEeEGO1DINd6m .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ipyrEeEGO1DINd6m .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ipyrEeEGO1DINd6m .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ipyrEeEGO1DINd6m :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Loop Engineering
自动 prompt
工具/代码/测试
记录状态
需人工时
人类:设计循环一次
循环系统
AI Agent
环境反馈
State / Memory
传统提示词工程
第1轮 prompt
回答
第2轮 prompt
回答
第N轮...
人类
AI


四、Loop Engineering 的六大积木

(各模块含义见文首 术语速查

Addy Osmani 归纳出现代循环几乎必备的 5 块积木 + 1 个状态层。各家产品名字不同,能力形状高度同构。

下图是 能力模块图 (六大积木如何协作),不是 第七节里的「四层能力层级图」------模块之间是平级分工,不存在「第 1 层 / 第 2 层」的上下关系。

4.1 Automations ------ 循环的「心跳」

作用: 让循环真的循环起来,而不是你记得时再跑一回。

  • 定时发现:每天扫 issue、CI 失败、昨日提交;
  • 自动分拣:没问题的运行自动归档,有问题的进 Triage 收件箱;
  • 可调用 Skill :调度里写 $triage-skill,而不是把 2000 字提示词塞进 cron。

典型落地:

产品 实现方式
OpenAI Codex Automations 标签页:选项目、prompt、cadence、环境
Claude Code /loop/goal、cron、hooks、GitHub Actions
Cursor /loop 技能、CLI agent -p、SDK 编排、CI 集成

其中 /goal 特别值得单独说:你给一句可验证的完成条件 (如「test/auth 全绿且 lint clean」),系统跨多轮自动推进;且常用另一个小模型判断是否完成------避免「做题人自己批改」。

4.2 Worktrees ------ 并行不打架

两个 Agent 同时改同一文件,等于两个工程师无沟通改同一行------必乱。

Git worktree :同一仓库、共享历史、独立工作目录和分支 。Agent A 在 feature/login-fix 目录改,Agent B 在 feature/api-refactor 目录改,互不影响。

Codex 可在线程级内置 worktree;Claude Code 用 git worktree--worktreeisolation: worktree;开源项目如 loop-cursor 也用 worktree 做隔离沙箱。

4.3 Skills ------ 把项目知识外置

Skill 通常是一个带 SKILL.md 的文件夹:写清构建步骤、目录约定、禁止事项、评审清单。Agent 每次运行主动读取,而不是靠你口头重复。

Osmani 的洞见:没有 Skill,循环每一圈都在从零猜你的项目;有 Skill,意图可以复利积累。

Skill 是「写作格式」;Plugin 是「分发格式」------给队友一键安装同一套 Skill + 连接器。

4.4 Plugins & Connectors ------ 接入真实世界

只能读写本地文件的循环很小。通过 MCP(Model Context Protocol) 等连接器,Agent 可以:

  • 读 Linear / Jira issue;
  • 查数据库、打 staging API;
  • CI 绿了在 Slack 通知;
  • 自动开 PR、关联 ticket。

差别在于:普通 Agent 说「建议这样修」;完整循环能在你的环境里把事办完

4.5 Sub-agents ------ 出题与阅卷分离

循环里最有价值的结构之一:写代码的 Agent审查的 Agent 分开。

常见三角分工:
#mermaid-svg-UfcjpVdwiIhU9HL9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-UfcjpVdwiIhU9HL9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-UfcjpVdwiIhU9HL9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-UfcjpVdwiIhU9HL9 .error-icon{fill:#552222;}#mermaid-svg-UfcjpVdwiIhU9HL9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UfcjpVdwiIhU9HL9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-UfcjpVdwiIhU9HL9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UfcjpVdwiIhU9HL9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UfcjpVdwiIhU9HL9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-UfcjpVdwiIhU9HL9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UfcjpVdwiIhU9HL9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UfcjpVdwiIhU9HL9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UfcjpVdwiIhU9HL9 .marker.cross{stroke:#333333;}#mermaid-svg-UfcjpVdwiIhU9HL9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UfcjpVdwiIhU9HL9 p{margin:0;}#mermaid-svg-UfcjpVdwiIhU9HL9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-UfcjpVdwiIhU9HL9 .cluster-label text{fill:#333;}#mermaid-svg-UfcjpVdwiIhU9HL9 .cluster-label span{color:#333;}#mermaid-svg-UfcjpVdwiIhU9HL9 .cluster-label span p{background-color:transparent;}#mermaid-svg-UfcjpVdwiIhU9HL9 .label text,#mermaid-svg-UfcjpVdwiIhU9HL9 span{fill:#333;color:#333;}#mermaid-svg-UfcjpVdwiIhU9HL9 .node rect,#mermaid-svg-UfcjpVdwiIhU9HL9 .node circle,#mermaid-svg-UfcjpVdwiIhU9HL9 .node ellipse,#mermaid-svg-UfcjpVdwiIhU9HL9 .node polygon,#mermaid-svg-UfcjpVdwiIhU9HL9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-UfcjpVdwiIhU9HL9 .rough-node .label text,#mermaid-svg-UfcjpVdwiIhU9HL9 .node .label text,#mermaid-svg-UfcjpVdwiIhU9HL9 .image-shape .label,#mermaid-svg-UfcjpVdwiIhU9HL9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-UfcjpVdwiIhU9HL9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-UfcjpVdwiIhU9HL9 .rough-node .label,#mermaid-svg-UfcjpVdwiIhU9HL9 .node .label,#mermaid-svg-UfcjpVdwiIhU9HL9 .image-shape .label,#mermaid-svg-UfcjpVdwiIhU9HL9 .icon-shape .label{text-align:center;}#mermaid-svg-UfcjpVdwiIhU9HL9 .node.clickable{cursor:pointer;}#mermaid-svg-UfcjpVdwiIhU9HL9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-UfcjpVdwiIhU9HL9 .arrowheadPath{fill:#333333;}#mermaid-svg-UfcjpVdwiIhU9HL9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-UfcjpVdwiIhU9HL9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-UfcjpVdwiIhU9HL9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UfcjpVdwiIhU9HL9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-UfcjpVdwiIhU9HL9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UfcjpVdwiIhU9HL9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-UfcjpVdwiIhU9HL9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-UfcjpVdwiIhU9HL9 .cluster text{fill:#333;}#mermaid-svg-UfcjpVdwiIhU9HL9 .cluster span{color:#333;}#mermaid-svg-UfcjpVdwiIhU9HL9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-UfcjpVdwiIhU9HL9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-UfcjpVdwiIhU9HL9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-UfcjpVdwiIhU9HL9 .icon-shape,#mermaid-svg-UfcjpVdwiIhU9HL9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UfcjpVdwiIhU9HL9 .icon-shape p,#mermaid-svg-UfcjpVdwiIhU9HL9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-UfcjpVdwiIhU9HL9 .icon-shape .label rect,#mermaid-svg-UfcjpVdwiIhU9HL9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UfcjpVdwiIhU9HL9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-UfcjpVdwiIhU9HL9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-UfcjpVdwiIhU9HL9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 不通过
通过
Explorer 探索/读代码
Implementer 实现
Verifier 验证/审查
完成

  • Explorer:只读、快速、摸清上下文;
  • Implementer:改代码;
  • Verifier:对照 spec / 测试 / Skill 做对抗式审查。

为什么要分开? 循环在你离开时仍在跑------没有可信的 Verifier,你就不敢走开。Sub-agent 会多耗 token,应花在「值得买第二意见」的环节。

4.6 State / Memory ------ 跨运行的脊柱

模型跨会话失忆 ;仓库和磁盘不忘

状态可以是:

  • progress.mdAGENTS.md
  • state.json
  • Linear 看板;
  • Triage inbox。

记录:试过什么、过了什么、还剩什么。明天早上的 Automation 从同一份状态接着干,而不是重新猜。


五、相比提示词工程:到底变了什么?

5.1 杠杆点迁移

维度 提示词工程 Loop Engineering
优化对象 单轮措辞与上下文 系统架构与终止条件
人的角色 操作员(每轮在场) 设计师(设计好后监督)
时间尺度 分钟级对话 小时/天级持续运行
失败模式 答非所问 跑飞、花光 token、静默犯错
核心技能 表达、拆解、示例 验证、隔离、状态、治理
知识载体 聊天历史 Skill + 状态文件 + 连接器

Cherny 的重点:不是变简单了,而是变难了------难在你要对系统负责,而不是对一句话负责。

5.2 六项实质性提升

① 从「单次正确」到「过程收敛」

提示词追求一次给好答案;循环追求带反馈地逼近目标------测试失败会驱动下一轮,而不是等你粘贴日志。

② 从「人肉调度」到「自动发现」

Automation 把「还有什么活」这件事交给系统。你处理的是收件箱里筛过的值得看项,不是满仓库乱逛。

③ 从「会话记忆」到「仓库记忆」

状态落盘 + Skill 外置,解决 Intent Debt,循环越跑越贴项目,而不是越跑越偏。

④ 从「自评」到「对抗式验证」

/goal、独立 Verifier sub-agent、CI 硬门禁------把「完成」从主观声明变成可检查条件

⑤ 从「单线程」到「受控并行」

Worktree + 多 sub-agent,在隔离前提下提高吞吐;提示词工程很难安全并行。

⑥ 从「个人技巧」到「团队基础设施」

Plugin、hooks、CI 里的 agent -p,把个人 prompt 沉淀为可版本化、可复用的循环资产

5.3 并没有抛弃提示词

重要澄清:Loop 不是不用提示词,而是把提示词放进循环的各个环节。

  • Automation 里有一段「发现 issue」的 prompt;
  • Sub-agent 各有 instruction;
  • /goal 的完成条件本质是一段可执行规格

变化在于:这些 prompt 被模块化、调度化、可验证化,不再依赖你当场即兴发挥。


六、一个完整的 Loop 长什么样?

下面是一个 Addy Osmani 风格的「晨间维护循环」,便于建立直觉:
你 PR / Issue 连接器 Sub-agent 审查 Sub-agent 实现 Worktree 隔离 state.md / Linear Triage Skill Automation 每日定时 你 PR / Issue 连接器 Sub-agent 审查 Sub-agent 实现 Worktree 隔离 state.md / Linear Triage Skill Automation 每日定时 #mermaid-svg-f8kyWOOINPjDNozu{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-f8kyWOOINPjDNozu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-f8kyWOOINPjDNozu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-f8kyWOOINPjDNozu .error-icon{fill:#552222;}#mermaid-svg-f8kyWOOINPjDNozu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-f8kyWOOINPjDNozu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-f8kyWOOINPjDNozu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-f8kyWOOINPjDNozu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-f8kyWOOINPjDNozu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-f8kyWOOINPjDNozu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-f8kyWOOINPjDNozu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-f8kyWOOINPjDNozu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-f8kyWOOINPjDNozu .marker.cross{stroke:#333333;}#mermaid-svg-f8kyWOOINPjDNozu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-f8kyWOOINPjDNozu p{margin:0;}#mermaid-svg-f8kyWOOINPjDNozu .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-f8kyWOOINPjDNozu text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-f8kyWOOINPjDNozu .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-f8kyWOOINPjDNozu .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-f8kyWOOINPjDNozu .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-f8kyWOOINPjDNozu .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-f8kyWOOINPjDNozu #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-f8kyWOOINPjDNozu .sequenceNumber{fill:white;}#mermaid-svg-f8kyWOOINPjDNozu #sequencenumber{fill:#333;}#mermaid-svg-f8kyWOOINPjDNozu #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-f8kyWOOINPjDNozu .messageText{fill:#333;stroke:none;}#mermaid-svg-f8kyWOOINPjDNozu .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-f8kyWOOINPjDNozu .labelText,#mermaid-svg-f8kyWOOINPjDNozu .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-f8kyWOOINPjDNozu .loopText,#mermaid-svg-f8kyWOOINPjDNozu .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-f8kyWOOINPjDNozu .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-f8kyWOOINPjDNozu .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-f8kyWOOINPjDNozu .noteText,#mermaid-svg-f8kyWOOINPjDNozu .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-f8kyWOOINPjDNozu .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-f8kyWOOINPjDNozu .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-f8kyWOOINPjDNozu .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-f8kyWOOINPjDNozu .actorPopupMenu{position:absolute;}#mermaid-svg-f8kyWOOINPjDNozu .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-f8kyWOOINPjDNozu .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-f8kyWOOINPjDNozu .actor-man circle,#mermaid-svg-f8kyWOOINPjDNozu line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-f8kyWOOINPjDNozu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} loop 每个值得修的项 明日从同一状态继续 触发 $triage-skill 写入 CI失败/issue/提交摘要 新建隔离 worktree 起草修复 提交草案 不通过则打回 通过则开 PR、更新 ticket 仅 Triage 处理不了的进收件箱

你只做了一次的事: 设计这条流水线、写好 Skill、定好验收标准。

你没有做的事: 每天早上亲手 prompt 每一轮修复。


七、在 Cursor 里怎么实践 Loop Engineering?

本节前提: 你已会用 Cursor Agent,并读过文首 术语速查。产品命令以官方文档为准(见文首版本声明)。

Cursor 是目前把「Loop 六大积木」落地得较完整的产品之一------从 IDE 里的 /loop,到云端 Automations ,再到 CLI / SDK / Hooks ,可以按能力层级由轻到重逐步叠加。

建议阅读顺序:

  1. 7.1 弄清四层能力层级(选型用)
  2. 7.2 弄清六大积木在 Cursor 的落点(模块图)
  3. 7.3--7.6 各层能力说明(可按需跳读)
  4. 7.7 入门案例 ← 动手最小闭环(建议所有人先做这个
  5. 7.8 进阶案例 ← 团队级 CI 自动化(需更多前置知识)

7.1 四层能力层级:从轻到重

注意: 下图标题是「能力层级 」------描述 Cursor 里四种用法由轻到重的进阶路径。不要 与第四节的「六大积木模块图」混为一谈:模块图讲分工协作,层级图讲选型深浅。

把 Cursor 的 Loop 能力按「工程化程度」分成四层,便于选型:
#mermaid-svg-IVX1yJgwxE39mdp4{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-IVX1yJgwxE39mdp4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IVX1yJgwxE39mdp4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IVX1yJgwxE39mdp4 .error-icon{fill:#552222;}#mermaid-svg-IVX1yJgwxE39mdp4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IVX1yJgwxE39mdp4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IVX1yJgwxE39mdp4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IVX1yJgwxE39mdp4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IVX1yJgwxE39mdp4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IVX1yJgwxE39mdp4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IVX1yJgwxE39mdp4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IVX1yJgwxE39mdp4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IVX1yJgwxE39mdp4 .marker.cross{stroke:#333333;}#mermaid-svg-IVX1yJgwxE39mdp4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IVX1yJgwxE39mdp4 p{margin:0;}#mermaid-svg-IVX1yJgwxE39mdp4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-IVX1yJgwxE39mdp4 .cluster-label text{fill:#333;}#mermaid-svg-IVX1yJgwxE39mdp4 .cluster-label span{color:#333;}#mermaid-svg-IVX1yJgwxE39mdp4 .cluster-label span p{background-color:transparent;}#mermaid-svg-IVX1yJgwxE39mdp4 .label text,#mermaid-svg-IVX1yJgwxE39mdp4 span{fill:#333;color:#333;}#mermaid-svg-IVX1yJgwxE39mdp4 .node rect,#mermaid-svg-IVX1yJgwxE39mdp4 .node circle,#mermaid-svg-IVX1yJgwxE39mdp4 .node ellipse,#mermaid-svg-IVX1yJgwxE39mdp4 .node polygon,#mermaid-svg-IVX1yJgwxE39mdp4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-IVX1yJgwxE39mdp4 .rough-node .label text,#mermaid-svg-IVX1yJgwxE39mdp4 .node .label text,#mermaid-svg-IVX1yJgwxE39mdp4 .image-shape .label,#mermaid-svg-IVX1yJgwxE39mdp4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-IVX1yJgwxE39mdp4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-IVX1yJgwxE39mdp4 .rough-node .label,#mermaid-svg-IVX1yJgwxE39mdp4 .node .label,#mermaid-svg-IVX1yJgwxE39mdp4 .image-shape .label,#mermaid-svg-IVX1yJgwxE39mdp4 .icon-shape .label{text-align:center;}#mermaid-svg-IVX1yJgwxE39mdp4 .node.clickable{cursor:pointer;}#mermaid-svg-IVX1yJgwxE39mdp4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-IVX1yJgwxE39mdp4 .arrowheadPath{fill:#333333;}#mermaid-svg-IVX1yJgwxE39mdp4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-IVX1yJgwxE39mdp4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-IVX1yJgwxE39mdp4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IVX1yJgwxE39mdp4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-IVX1yJgwxE39mdp4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IVX1yJgwxE39mdp4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-IVX1yJgwxE39mdp4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-IVX1yJgwxE39mdp4 .cluster text{fill:#333;}#mermaid-svg-IVX1yJgwxE39mdp4 .cluster span{color:#333;}#mermaid-svg-IVX1yJgwxE39mdp4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-IVX1yJgwxE39mdp4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-IVX1yJgwxE39mdp4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-IVX1yJgwxE39mdp4 .icon-shape,#mermaid-svg-IVX1yJgwxE39mdp4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IVX1yJgwxE39mdp4 .icon-shape p,#mermaid-svg-IVX1yJgwxE39mdp4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-IVX1yJgwxE39mdp4 .icon-shape .label rect,#mermaid-svg-IVX1yJgwxE39mdp4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IVX1yJgwxE39mdp4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-IVX1yJgwxE39mdp4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-IVX1yJgwxE39mdp4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 第 4 层:SDK + Hooks(最重、最可控)
@cursor/sdk 程序化编排
hooks.json 安全门禁
.cursor/rules 分阶段约束
第 3 层:CLI + CI(可版本化)
agent -p 无头单次
GitHub Actions / git hook
agent resume 续跑
第 2 层:云端 Automations(产品化)
定时 / Git / Slack / Linear 触发
Cloud Agent 在远端仓库执行
结果进 Triage / PR 评论
第 1 层:会话内循环(最轻)
/loop 定期间隔
动态唤醒:事件 / 心跳
多轮 Agent + 可验证目标

层级 典型入口 适合场景 你需要写多少「系统」
第 1 层 Chat /loop 30m ... 本地开发时盯部署、盯测试 几乎只有一句 prompt + 可选 state 文件
第 2 层 Automations 编辑器 每日巡检、PR 触发审查、Slack 通知 prompt + 触发器 + 可选 MCP
第 3 层 agent -p + CI 每次 PR 自动 review、夜间 lint shell 脚本 + workflow 文件
第 4 层 SDK + Hooks + Rules 多阶段自主开发、强门禁、状态机 TypeScript/Python 编排代码

实践建议: 不要一上来就 SDK。个人用户从 第 1 层 /loop + 状态文件 + 验收脚本(见 7.7)开始;团队再考虑第 2、3 层。


7.2 能力模块图:六大积木在 Cursor 的落点

下图是 能力模块图(积木如何分工),不是 7.1 的层级图。
#mermaid-svg-EKL2ov9cBQQ3NOYl{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-EKL2ov9cBQQ3NOYl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-EKL2ov9cBQQ3NOYl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-EKL2ov9cBQQ3NOYl .error-icon{fill:#552222;}#mermaid-svg-EKL2ov9cBQQ3NOYl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EKL2ov9cBQQ3NOYl .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-EKL2ov9cBQQ3NOYl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EKL2ov9cBQQ3NOYl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EKL2ov9cBQQ3NOYl .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-EKL2ov9cBQQ3NOYl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EKL2ov9cBQQ3NOYl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EKL2ov9cBQQ3NOYl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EKL2ov9cBQQ3NOYl .marker.cross{stroke:#333333;}#mermaid-svg-EKL2ov9cBQQ3NOYl svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EKL2ov9cBQQ3NOYl p{margin:0;}#mermaid-svg-EKL2ov9cBQQ3NOYl .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-EKL2ov9cBQQ3NOYl .cluster-label text{fill:#333;}#mermaid-svg-EKL2ov9cBQQ3NOYl .cluster-label span{color:#333;}#mermaid-svg-EKL2ov9cBQQ3NOYl .cluster-label span p{background-color:transparent;}#mermaid-svg-EKL2ov9cBQQ3NOYl .label text,#mermaid-svg-EKL2ov9cBQQ3NOYl span{fill:#333;color:#333;}#mermaid-svg-EKL2ov9cBQQ3NOYl .node rect,#mermaid-svg-EKL2ov9cBQQ3NOYl .node circle,#mermaid-svg-EKL2ov9cBQQ3NOYl .node ellipse,#mermaid-svg-EKL2ov9cBQQ3NOYl .node polygon,#mermaid-svg-EKL2ov9cBQQ3NOYl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-EKL2ov9cBQQ3NOYl .rough-node .label text,#mermaid-svg-EKL2ov9cBQQ3NOYl .node .label text,#mermaid-svg-EKL2ov9cBQQ3NOYl .image-shape .label,#mermaid-svg-EKL2ov9cBQQ3NOYl .icon-shape .label{text-anchor:middle;}#mermaid-svg-EKL2ov9cBQQ3NOYl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-EKL2ov9cBQQ3NOYl .rough-node .label,#mermaid-svg-EKL2ov9cBQQ3NOYl .node .label,#mermaid-svg-EKL2ov9cBQQ3NOYl .image-shape .label,#mermaid-svg-EKL2ov9cBQQ3NOYl .icon-shape .label{text-align:center;}#mermaid-svg-EKL2ov9cBQQ3NOYl .node.clickable{cursor:pointer;}#mermaid-svg-EKL2ov9cBQQ3NOYl .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-EKL2ov9cBQQ3NOYl .arrowheadPath{fill:#333333;}#mermaid-svg-EKL2ov9cBQQ3NOYl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-EKL2ov9cBQQ3NOYl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-EKL2ov9cBQQ3NOYl .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EKL2ov9cBQQ3NOYl .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-EKL2ov9cBQQ3NOYl .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EKL2ov9cBQQ3NOYl .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-EKL2ov9cBQQ3NOYl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-EKL2ov9cBQQ3NOYl .cluster text{fill:#333;}#mermaid-svg-EKL2ov9cBQQ3NOYl .cluster span{color:#333;}#mermaid-svg-EKL2ov9cBQQ3NOYl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-EKL2ov9cBQQ3NOYl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-EKL2ov9cBQQ3NOYl rect.text{fill:none;stroke-width:0;}#mermaid-svg-EKL2ov9cBQQ3NOYl .icon-shape,#mermaid-svg-EKL2ov9cBQQ3NOYl .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EKL2ov9cBQQ3NOYl .icon-shape p,#mermaid-svg-EKL2ov9cBQQ3NOYl .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-EKL2ov9cBQQ3NOYl .icon-shape .label rect,#mermaid-svg-EKL2ov9cBQQ3NOYl .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EKL2ov9cBQQ3NOYl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-EKL2ov9cBQQ3NOYl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-EKL2ov9cBQQ3NOYl :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ③ State 状态

docs/*.md · AGENTS.md
① Automation 心跳

/loop · Automations · CI
② Skill 知识

.cursor/skills/
④ Worktree 隔离

git worktree
⑤ Sub-agent

Task 子代理
⑥ Connector

MCP · prComment

循环积木 Cursor 中的具体做法 配置位置 / 命令 注意事项
Automations /loop、Cursor Automations、cron/Git/Slack 触发 Chat、cursor.com Automations、.github/workflows Automations 需 Cloud Agent;本地用 /loop 或 CLI
Worktrees git worktree 隔离并行 Agent 终端 / SDK cwd 指向 worktree 目录 合并前仍需人工或 CI 做 conflict 检查
Skills 项目知识与流程外置 .cursor/skills/<name>/SKILL.md、用户级 ~/.cursor/skills/ Automations prompt 里可 $skill-name 引用
Connectors MCP 接 GitHub、Linear、Slack 等 Cursor Settings → MCP、.cursor/mcp.json Automations 里 MCP 需先在 Dashboard 连好
Sub-agents Task 子代理分工 Agent 模式:explore / generalPurpose / shell 实现与审查应拆成不同 subagent_type
State 跨运行记忆 AGENTS.md.cursor/loop-state.jsondocs/triage.md 必须落盘;模型跨会话失忆

另外三个 Cursor 特有、但 Loop 设计里极常用的「加固件」:

加固件 作用 位置
Rules 按 glob 限制 Agent 能改哪些文件、用什么规范 .cursor/rules/*.mdc
Hooks 在工具执行前拦截危险命令、在 subagent 结束后注入 follow-up .cursor/hooks.json + .cursor/hooks/*
AGENTS.md 给 Cloud/CLI Agent 的仓库级说明书 仓库根目录

7.3 第 1 层详解:会话内 /loop 与动态唤醒

你在 Cursor Chat / Agent 里可以直接说:

text 复制代码
/loop 5m 检查 staging 部署状态,若 health check 失败则总结最近日志并建议修复步骤

固定间隔模式: 每 5 分钟唤醒 Agent 执行同一段 prompt(Windows 上底层是 PowerShell while + Start-Sleep,macOS/Linux 是 bash sleep 循环)。

动态模式: 不设固定间隔,由 Agent 在每次执行后决定------

  • 下一条日志出现 ERROR 时立刻再跑;
  • 或先 sleep 10m 作为兜底心跳,避免空转。

和「手动多轮 prompt」的差别:

手动 prompt /loop
谁决定下一轮 时间表或 Agent
你能否离开 不能 可以(本地机器需保持运行)
状态 在聊天里 应写入文件,供下轮读取

局限: /loop 绑定当前 IDE 会话与本地环境,适合开发者在场时的轻量循环,不适合「关电脑仍要跑」------那种场景用第 2、3 层。


7.4 第 2 层详解:Cursor Automations(云端心跳)

Automations 是 Cursor 产品化的「定时 / 事件触发 Cloud Agent」------最接近 Addy Osmani 说的「晨间 Automation 扫 CI」。

常见触发器:

触发类型 例子
cron 每个工作日 9:00
git PR 打开、push、CI checks 完成
slackTrigger 某频道新消息
linear Issue 创建、状态变更
webhook 自定义 HTTP 入站

可挂载的动作工具:prCommentslackmcprequestReviewers 等。

创建方式: 在 Agents 窗口描述「何时触发、做什么、产出什么」,由 Agent 帮你生成草稿并打开 Automations 编辑器确认。核心字段:触发器、工具、Instructions(prompt)、仓库范围。

/loop 的对比:

/loop Automations
运行环境 本地 IDE 会话 Cloud Agent(远端 clone 仓库)
关电脑后 停止 继续(云端)
与 PR/Slack 集成 需自己写 MCP/脚本 内置 trigger + action
适合 个人开发盯进度 团队级 recurring 任务

7.5 第 3 层详解:CLI agent 与 CI 集成

安装 Cursor CLI 后,自动化入口是 agent (不是 cursor):

bash 复制代码
# 交互式
agent "Explain the auth module"

# 无头模式:脚本 / CI 用
agent -p "Review this PR diff for security issues. Output markdown only."

# 续跑上一次 Agent(跨 job 延续上下文)
agent resume <agent-id> -p "Also update the changelog"

GitHub Actions 典型片段:

yaml 复制代码
name: Cursor Agent PR Review
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    timeout-minutes: 15          # 硬超时,防 runaway
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install Cursor CLI
        run: curl https://cursor.com/install -fsS | bash

      - name: Run agent review
        env:
          CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }}
        run: |
          agent -p "$(cat .cursor/prompts/pr-security-review.md)" \
            > review.md
          # PR 评论由确定性 CI 步骤 posting,不让 Agent 直接 push

      - name: Post review comment
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const body = fs.readFileSync('review.md', 'utf8');
            github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.payload.pull_request.number,
              body
            });

Loop 设计要点:

  • 提示词写进仓库 (如 .cursor/prompts/),可 code review、可版本化;
  • git 操作由 CI 步骤完成,Agent 只产出文本或改 working tree;
  • 必须设 timeout-minutes 和 API 消费上限。

7.6 第 4 层详解:SDK、Hooks、Rules

SDK:把「循环逻辑」写成代码

@cursor/sdk(TypeScript)或 cursor-sdk(Python)适合:多轮、要带分支判断、要解析工具输出的循环。

三种调用形态:

模式 API 何时用
一次性 Agent.prompt(...) CI 单步、跑完即退出
多轮 Agent.create + agent.send + run.wait() 实现→测试→再改的闭环
跨进程续跑 Agent.resume(agentId) 昨晚没跑完,今早 cron 接着干

多轮修复循环(TypeScript 示意):

typescript 复制代码
import { Agent } from "@cursor/sdk";

const MAX_ROUNDS = 5;
const GOAL = `
修复 test/auth 下全部失败用例。
终止条件:npm test -- test/auth 退出码为 0,且 npm run lint 无 error。
使用项目 Skill:$backend-conventions
`;

await using agent = await Agent.create({
  apiKey: process.env.CURSOR_API_KEY!,
  model: { id: "composer-2.5" },
  local: { cwd: process.cwd(), settingSources: [] },
});

for (let round = 1; round <= MAX_ROUNDS; round++) {
  const run = await agent.send(
    round === 1 ? GOAL : `第 ${round} 轮:根据上一轮测试输出继续修复,直到满足终止条件。`
  );
  await run.wait();

  // 确定性验证:由脚本而非模型宣布完成
  const { execSync } = await import("child_process");
  try {
    execSync("npm test -- test/auth", { stdio: "pipe" });
    execSync("npm run lint", { stdio: "pipe" });
    console.log(`Done in round ${round}`);
    break;
  } catch {
    if (round === MAX_ROUNDS) process.exit(2);
  }
}

注意 SDK 的两个失败层次:CursorAgentError(没跑起来)vs result.status === "error"(跑了一半挂了)------退出码应区分。

Hooks:循环的「安全带」

.cursor/hooks.json 在 Agent 生命周期里插入确定性逻辑,常见用途:

事件 用途
beforeShellExecution 拦截 rm -rfgit push --force
subagentStop 审查 sub-agent 结束后自动注入 followup_message 继续循环
stop Agent 声称完成时,触发额外验证 prompt

示例:禁止对 main 强制推送

json 复制代码
{
  "version": 1,
  "hooks": {
    "beforeShellExecution": [
      {
        "command": ".cursor/hooks/block-force-push.sh",
        "matcher": "git push.*--force",
        "failClosed": true
      }
    ]
  }
}
Rules:分阶段缩小 Agent 权力

多阶段循环里,可为「只读探索」「只改 tests」「只改 src」各写一条 rule,用 globs 限制文件范围------相当于给每个阶段一道围墙。


7.7 入门案例:只用 /loop + state.md + 验收脚本

难度:⭐ 入门 | 前置: 会用 Cursor Agent、会在终端跑测试 | 不涉及: GitHub Actions、MCP、worktree、Automations

在跳进 CI 大案例之前,先用 15 分钟 跑通 Loop 的三件核心小事:

  1. 心跳 ------ /loop 定时唤醒 Agent;
  2. 记忆 ------ state.md 记录进度(不赌聊天窗口);
  3. 验收 ------ verify.sh脚本退出码判定完成(不让模型自说「好了」)。
场景

你本地有个 Python 小项目,tests/test_math.py 里有一个故意写错的断言。你希望 Agent 每 10 分钟 尝试修一次,直到测试全绿------你不必每轮亲手粘贴日志。

步骤 1:准备两个文件

docs/loop-state.md

markdown 复制代码
# Loop 状态

## 目标
修复 tests/test_math.py,使 pytest 全部通过。

## 当前轮次
0

## 上次结果
(尚未运行)

## 是否完成
否

scripts/verify.sh

bash 复制代码
#!/usr/bin/env bash
# 验收脚本:退出码 0 = 成功,非 0 = 继续循环
set -e
python -m pytest tests/ -q
echo "VERIFY_OK"

赋予执行权限:chmod +x scripts/verify.sh(Windows 可在 Git Bash 中运行)。

步骤 2:在 Cursor 里启动 /loop

在 Agent 对话中输入(可按项目改写):

text 复制代码
/loop 10m 请执行以下循环任务:

1. 读取 docs/loop-state.md 了解当前轮次与上次结果
2. 阅读 tests/test_math.py 及相关源码,尝试修复失败测试
3. 运行 bash scripts/verify.sh:
   - 若退出码为 0:将 state 中「是否完成」改为「是」,写入通过时间,然后停止后续修改
   - 若失败:将轮次 +1,把 pytest 输出摘要写入「上次结果」,留待下轮继续
4. 每轮结束必须更新 docs/loop-state.md,不要把进度只写在聊天里

终止条件:scripts/verify.sh 退出码为 0。最多尝试 6 轮,超过则标记「需人工介入」。
步骤 3:观察循环如何运转

渲染错误: Mermaid 渲染失败: Parse error on line 18: ... end Note over Loop: 10 分钟后再次唤醒,直到完 ----------------------^ Expecting 'ACTOR', got 'loop'

本案例与六大积木的对应关系
积木 本案例是否用到 怎么用的
Automation ✅(最简形态) /loop 10m 作心跳
State docs/loop-state.md
Skill 入门先省略;熟练后可把 prompt 抽成 Skill
Worktree 单人本地改文件,暂不并行
Sub-agent 单 Agent 即可
Connector/MCP 不需要接 GitHub

你已练到的 Loop 核心: 自动重复 + 外置状态 + 确定性验收------这三样比「堆更多 prompt」更重要。

从入门到进阶的桥

跑通后,可按此顺序加码:

text 复制代码
入门(7.7)/loop + state + verify
    → 把 prompt 抽成 .cursor/skills/fix-test/SKILL.md
    → 用 agent -p 在终端手动触发同一套逻辑(第 3 层)
    → 接入 GitHub Actions 定时跑(7.8 前置)
    → 上 Automations + MCP 读 CI 日志(7.8 完整案例)

7.8 进阶案例:「CI 失败自动 Triage + 修复草稿」

难度:⭐⭐⭐ 进阶 | 前置: 熟悉 Node.js/npm、GitHub Actions、PR 流程、Git 分支;建议 先完成 7.7 入门案例 | 涉及: Automations、MCP、worktree、sub-agent

下面用一个虚构但可落地 的 Node.js monorepo 案例,把六大积木逐步拼起来。假设痛点:main 上 CI 经常红,开发者每天早上手动看 Actions 日志,复制粘贴给 Chat 修------典型提示词工程地狱

Cursor 实践流程图(进阶案例专用)

下图是 Cursor 实践流程图 ,描述 7.8 案例的步骤串联;不是 7.1 的四层能力层级图。
#mermaid-svg-0YrWRoyMnQdzEoSS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0YrWRoyMnQdzEoSS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0YrWRoyMnQdzEoSS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0YrWRoyMnQdzEoSS .error-icon{fill:#552222;}#mermaid-svg-0YrWRoyMnQdzEoSS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0YrWRoyMnQdzEoSS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0YrWRoyMnQdzEoSS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0YrWRoyMnQdzEoSS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0YrWRoyMnQdzEoSS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0YrWRoyMnQdzEoSS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0YrWRoyMnQdzEoSS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0YrWRoyMnQdzEoSS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0YrWRoyMnQdzEoSS .marker.cross{stroke:#333333;}#mermaid-svg-0YrWRoyMnQdzEoSS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0YrWRoyMnQdzEoSS p{margin:0;}#mermaid-svg-0YrWRoyMnQdzEoSS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0YrWRoyMnQdzEoSS .cluster-label text{fill:#333;}#mermaid-svg-0YrWRoyMnQdzEoSS .cluster-label span{color:#333;}#mermaid-svg-0YrWRoyMnQdzEoSS .cluster-label span p{background-color:transparent;}#mermaid-svg-0YrWRoyMnQdzEoSS .label text,#mermaid-svg-0YrWRoyMnQdzEoSS span{fill:#333;color:#333;}#mermaid-svg-0YrWRoyMnQdzEoSS .node rect,#mermaid-svg-0YrWRoyMnQdzEoSS .node circle,#mermaid-svg-0YrWRoyMnQdzEoSS .node ellipse,#mermaid-svg-0YrWRoyMnQdzEoSS .node polygon,#mermaid-svg-0YrWRoyMnQdzEoSS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0YrWRoyMnQdzEoSS .rough-node .label text,#mermaid-svg-0YrWRoyMnQdzEoSS .node .label text,#mermaid-svg-0YrWRoyMnQdzEoSS .image-shape .label,#mermaid-svg-0YrWRoyMnQdzEoSS .icon-shape .label{text-anchor:middle;}#mermaid-svg-0YrWRoyMnQdzEoSS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0YrWRoyMnQdzEoSS .rough-node .label,#mermaid-svg-0YrWRoyMnQdzEoSS .node .label,#mermaid-svg-0YrWRoyMnQdzEoSS .image-shape .label,#mermaid-svg-0YrWRoyMnQdzEoSS .icon-shape .label{text-align:center;}#mermaid-svg-0YrWRoyMnQdzEoSS .node.clickable{cursor:pointer;}#mermaid-svg-0YrWRoyMnQdzEoSS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0YrWRoyMnQdzEoSS .arrowheadPath{fill:#333333;}#mermaid-svg-0YrWRoyMnQdzEoSS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0YrWRoyMnQdzEoSS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0YrWRoyMnQdzEoSS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0YrWRoyMnQdzEoSS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0YrWRoyMnQdzEoSS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0YrWRoyMnQdzEoSS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0YrWRoyMnQdzEoSS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0YrWRoyMnQdzEoSS .cluster text{fill:#333;}#mermaid-svg-0YrWRoyMnQdzEoSS .cluster span{color:#333;}#mermaid-svg-0YrWRoyMnQdzEoSS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0YrWRoyMnQdzEoSS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0YrWRoyMnQdzEoSS rect.text{fill:none;stroke-width:0;}#mermaid-svg-0YrWRoyMnQdzEoSS .icon-shape,#mermaid-svg-0YrWRoyMnQdzEoSS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0YrWRoyMnQdzEoSS .icon-shape p,#mermaid-svg-0YrWRoyMnQdzEoSS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0YrWRoyMnQdzEoSS .icon-shape .label rect,#mermaid-svg-0YrWRoyMnQdzEoSS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0YrWRoyMnQdzEoSS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0YrWRoyMnQdzEoSS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0YrWRoyMnQdzEoSS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ① Automations 触发

定时 / CI 完成
② Skill 读 CI

$ci-triage
③ 写 State

ci-triage-state.md
④ Worktree 隔离

独立分支目录
⑤ Sub-agent

实现 + 审查
⑥ MCP 开 PR

通知人工
#mermaid-svg-Rq3WaxPqVUWH6KJo{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Rq3WaxPqVUWH6KJo .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Rq3WaxPqVUWH6KJo .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Rq3WaxPqVUWH6KJo .error-icon{fill:#552222;}#mermaid-svg-Rq3WaxPqVUWH6KJo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Rq3WaxPqVUWH6KJo .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Rq3WaxPqVUWH6KJo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Rq3WaxPqVUWH6KJo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Rq3WaxPqVUWH6KJo .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Rq3WaxPqVUWH6KJo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Rq3WaxPqVUWH6KJo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Rq3WaxPqVUWH6KJo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Rq3WaxPqVUWH6KJo .marker.cross{stroke:#333333;}#mermaid-svg-Rq3WaxPqVUWH6KJo svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Rq3WaxPqVUWH6KJo p{margin:0;}#mermaid-svg-Rq3WaxPqVUWH6KJo .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Rq3WaxPqVUWH6KJo .cluster-label text{fill:#333;}#mermaid-svg-Rq3WaxPqVUWH6KJo .cluster-label span{color:#333;}#mermaid-svg-Rq3WaxPqVUWH6KJo .cluster-label span p{background-color:transparent;}#mermaid-svg-Rq3WaxPqVUWH6KJo .label text,#mermaid-svg-Rq3WaxPqVUWH6KJo span{fill:#333;color:#333;}#mermaid-svg-Rq3WaxPqVUWH6KJo .node rect,#mermaid-svg-Rq3WaxPqVUWH6KJo .node circle,#mermaid-svg-Rq3WaxPqVUWH6KJo .node ellipse,#mermaid-svg-Rq3WaxPqVUWH6KJo .node polygon,#mermaid-svg-Rq3WaxPqVUWH6KJo .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Rq3WaxPqVUWH6KJo .rough-node .label text,#mermaid-svg-Rq3WaxPqVUWH6KJo .node .label text,#mermaid-svg-Rq3WaxPqVUWH6KJo .image-shape .label,#mermaid-svg-Rq3WaxPqVUWH6KJo .icon-shape .label{text-anchor:middle;}#mermaid-svg-Rq3WaxPqVUWH6KJo .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Rq3WaxPqVUWH6KJo .rough-node .label,#mermaid-svg-Rq3WaxPqVUWH6KJo .node .label,#mermaid-svg-Rq3WaxPqVUWH6KJo .image-shape .label,#mermaid-svg-Rq3WaxPqVUWH6KJo .icon-shape .label{text-align:center;}#mermaid-svg-Rq3WaxPqVUWH6KJo .node.clickable{cursor:pointer;}#mermaid-svg-Rq3WaxPqVUWH6KJo .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Rq3WaxPqVUWH6KJo .arrowheadPath{fill:#333333;}#mermaid-svg-Rq3WaxPqVUWH6KJo .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Rq3WaxPqVUWH6KJo .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Rq3WaxPqVUWH6KJo .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Rq3WaxPqVUWH6KJo .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Rq3WaxPqVUWH6KJo .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Rq3WaxPqVUWH6KJo .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Rq3WaxPqVUWH6KJo .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Rq3WaxPqVUWH6KJo .cluster text{fill:#333;}#mermaid-svg-Rq3WaxPqVUWH6KJo .cluster span{color:#333;}#mermaid-svg-Rq3WaxPqVUWH6KJo div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Rq3WaxPqVUWH6KJo .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Rq3WaxPqVUWH6KJo rect.text{fill:none;stroke-width:0;}#mermaid-svg-Rq3WaxPqVUWH6KJo .icon-shape,#mermaid-svg-Rq3WaxPqVUWH6KJo .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Rq3WaxPqVUWH6KJo .icon-shape p,#mermaid-svg-Rq3WaxPqVUWH6KJo .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Rq3WaxPqVUWH6KJo .icon-shape .label rect,#mermaid-svg-Rq3WaxPqVUWH6KJo .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Rq3WaxPqVUWH6KJo .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Rq3WaxPqVUWH6KJo .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Rq3WaxPqVUWH6KJo :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 第 4 层 · 代码编排
SDK + Hooks + Rules
第 3 层 · CI 脚本化
agent -p + GitHub Actions
第 2 层 · 云端产品化
Cursor Automations
第 1 层 · 本地轻量
/loop 会话循环

上图回顾:7.8 案例主要使用第 2 层 Automations,并组合第 3 层 CLI 做本地预演;横切使用 Skill、State、Worktree、Sub-agent、MCP。

案例目标
项目 内容
业务目标 CI 红了的提交,自动归类原因并生成修复草稿 PR
可验证终止条件 npm testnpm run lint 在隔离 worktree 内通过
人工介入点 仅「需产品决策」或「3 轮仍未绿」的项进 Triage 收件箱
运行频率 每个工作日 9:00 + PR 上 CI checks 完成时
概念 ↔ 步骤对照总览

#mermaid-svg-DeEAyKHK2ly8TE5W{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DeEAyKHK2ly8TE5W .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DeEAyKHK2ly8TE5W .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DeEAyKHK2ly8TE5W .error-icon{fill:#552222;}#mermaid-svg-DeEAyKHK2ly8TE5W .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DeEAyKHK2ly8TE5W .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DeEAyKHK2ly8TE5W .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DeEAyKHK2ly8TE5W .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DeEAyKHK2ly8TE5W .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DeEAyKHK2ly8TE5W .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DeEAyKHK2ly8TE5W .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DeEAyKHK2ly8TE5W .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DeEAyKHK2ly8TE5W .marker.cross{stroke:#333333;}#mermaid-svg-DeEAyKHK2ly8TE5W svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DeEAyKHK2ly8TE5W p{margin:0;}#mermaid-svg-DeEAyKHK2ly8TE5W .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-DeEAyKHK2ly8TE5W .cluster-label text{fill:#333;}#mermaid-svg-DeEAyKHK2ly8TE5W .cluster-label span{color:#333;}#mermaid-svg-DeEAyKHK2ly8TE5W .cluster-label span p{background-color:transparent;}#mermaid-svg-DeEAyKHK2ly8TE5W .label text,#mermaid-svg-DeEAyKHK2ly8TE5W span{fill:#333;color:#333;}#mermaid-svg-DeEAyKHK2ly8TE5W .node rect,#mermaid-svg-DeEAyKHK2ly8TE5W .node circle,#mermaid-svg-DeEAyKHK2ly8TE5W .node ellipse,#mermaid-svg-DeEAyKHK2ly8TE5W .node polygon,#mermaid-svg-DeEAyKHK2ly8TE5W .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DeEAyKHK2ly8TE5W .rough-node .label text,#mermaid-svg-DeEAyKHK2ly8TE5W .node .label text,#mermaid-svg-DeEAyKHK2ly8TE5W .image-shape .label,#mermaid-svg-DeEAyKHK2ly8TE5W .icon-shape .label{text-anchor:middle;}#mermaid-svg-DeEAyKHK2ly8TE5W .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DeEAyKHK2ly8TE5W .rough-node .label,#mermaid-svg-DeEAyKHK2ly8TE5W .node .label,#mermaid-svg-DeEAyKHK2ly8TE5W .image-shape .label,#mermaid-svg-DeEAyKHK2ly8TE5W .icon-shape .label{text-align:center;}#mermaid-svg-DeEAyKHK2ly8TE5W .node.clickable{cursor:pointer;}#mermaid-svg-DeEAyKHK2ly8TE5W .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DeEAyKHK2ly8TE5W .arrowheadPath{fill:#333333;}#mermaid-svg-DeEAyKHK2ly8TE5W .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DeEAyKHK2ly8TE5W .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DeEAyKHK2ly8TE5W .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DeEAyKHK2ly8TE5W .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DeEAyKHK2ly8TE5W .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DeEAyKHK2ly8TE5W .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DeEAyKHK2ly8TE5W .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DeEAyKHK2ly8TE5W .cluster text{fill:#333;}#mermaid-svg-DeEAyKHK2ly8TE5W .cluster span{color:#333;}#mermaid-svg-DeEAyKHK2ly8TE5W div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DeEAyKHK2ly8TE5W .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DeEAyKHK2ly8TE5W rect.text{fill:none;stroke-width:0;}#mermaid-svg-DeEAyKHK2ly8TE5W .icon-shape,#mermaid-svg-DeEAyKHK2ly8TE5W .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DeEAyKHK2ly8TE5W .icon-shape p,#mermaid-svg-DeEAyKHK2ly8TE5W .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DeEAyKHK2ly8TE5W .icon-shape .label rect,#mermaid-svg-DeEAyKHK2ly8TE5W .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DeEAyKHK2ly8TE5W .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DeEAyKHK2ly8TE5W .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DeEAyKHK2ly8TE5W :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 步骤 6
MCP 开 PR + 评论
步骤 5
Sub-agent 实现+审查
步骤 4
Worktree 隔离
步骤 3
State 写入 triage.md
步骤 2
Triage Skill 读 CI
步骤 1
Automation 触发

步骤 在做什么 对应积木 Cursor 落点
1 到点 / CI 完成时启动 Automations Automations cron + git.ciCompleted
2 拉 CI 日志、归类 Skill + Connector $ci-triage Skill + GitHub MCP
3 记录发现与状态 State docs/ci-triage-state.md
4 每项修复独立分支目录 Worktree git worktree add
5 起草修复 + 对抗审查 Sub-agents Task generalPurpose + bugbot
6 开 PR、留审查意见 Connector prComment / gh MCP
横切 防删库、限轮次 Hooks + Rules beforeShellExecution、分阶段 rules

步骤 0:仓库准备(一次性)

建议目录结构:

text 复制代码
your-repo/
├── AGENTS.md                      # 仓库级说明(Cloud Agent 会读)
├── docs/
│   └── ci-triage-state.md         # 循环状态(人工也可读)
├── .cursor/
│   ├── prompts/
│   │   └── ci-fix-goal.md         # 可验证目标原文
│   ├── skills/
│   │   └── ci-triage/
│   │       └── SKILL.md           # 如何读 CI、如何写 state
│   ├── rules/
│   │   └── ci-fix-scope.mdc       # 修复阶段只能改 src/** 和 test/**
│   └── hooks/
│       ├── hooks.json
│       └── block-dangerous.sh
└── scripts/
    └── verify-ci-fix.sh           # 确定性验收脚本

AGENTS.md(摘录):

markdown 复制代码
# Agent 须知

- 包管理:npm;测试:`npm test`;lint:`npm run lint`
- CI 配置:`.github/workflows/ci.yml`
- 循环状态:读/写 `docs/ci-triage-state.md`,不要只在聊天里记进度
- 终止条件以 `scripts/verify-ci-fix.sh` 退出码为准,不要自行宣布完成

docs/ci-triage-state.md(初始):

markdown 复制代码
# CI Triage State

## Open
(暂无)

## In Progress
(暂无)

## Done
(暂无)

## Needs Human
(暂无)

步骤 1:Automation 触发(积木:Automations)

在 Cursor Automations 中配置两条(或合并为一条带多触发器):

字段
名称 CI Failure Triage
触发 1 cron 0 9 * * 1-5(工作日 9:00)
触发 2 git → ciCompleted(checks 完成)
工具 mcp(GitHub)、prComment
Instructions 见下方

Instructions 核心文案:

markdown 复制代码
调用 $ci-triage skill:
1. 读取 docs/ci-triage-state.md
2. 用 GitHub MCP 查 main 最近 24h 内失败的 CI run
3. 将新失败写入 state 的 Open 区;已存在则跳过
4. 对 Open 中每一项:
   - 若标记为 needs-product-decision,移到 Needs Human,不要自动修
   - 否则在独立 worktree 中执行 $ci-fix-goal(见 .cursor/prompts/ci-fix-goal.md)
5. 更新 state;3 轮仍未通过 verify 的项移入 Needs Human

此处 Automation = 循环心跳;你不再每天早上亲手打开 Actions。


步骤 2:Triage Skill(积木:Skills + Connectors)

.cursor/skills/ci-triage/SKILL.md

markdown 复制代码
---
name: ci-triage
description: 读取 GitHub Actions 失败记录,归类并更新 docs/ci-triage-state.md
---

# CI Triage

## 输入
- 仓库:当前 Automation 绑定的 repo
- 状态文件:docs/ci-triage-state.md

## 流程
1. 用 GitHub MCP 列出 main 分支最近失败的 workflow runs
2. 每条失败提取:commit sha、失败 job 名、关键日志片段(最多 80 行)
3. 归类:test / lint / build / flaky / unknown
4. 写入 state 的 Open,格式:
   - `- [sha=abc1234] [type=test] job=unit-tests --- 摘要一句`

## 禁止
- 不要修改源代码(本 skill 只读写 state 与调查报告)

Connector: 在 Cursor Dashboard 连接 GitHub MCP,Automations 的 mcp action 指向该 server。


步骤 3:可验证目标 prompt(积木:State + 终止条件)

.cursor/prompts/ci-fix-goal.md

markdown 复制代码
# Goal:修复单项 CI 失败

## 上下文
- 从 docs/ci-triage-state.md 的 Open 区取当前项
- 阅读失败日志与相关源码

## 终止条件(必须全部满足)
1. `scripts/verify-ci-fix.sh` 退出码为 0
2. 未改动与本失败无关的文件
3. 在 state 中记录尝试轮次与结果

## 流程
1. 将该项移到 In Progress
2. 在独立 git worktree 分支 `auto/ci-fix-<sha>` 中修改
3. 运行 verify 脚本;失败则读输出再改,最多 3 轮
4. 通过后移到 Done,并准备 PR 描述;失败则移 Needs Human

## 分工
- 先用 explore sub-agent 只读定位根因
- 再用 generalPurpose sub-agent 实现
- 最后用只读 bugbot sub-agent 审查 diff,不通过则打回实现

scripts/verify-ci-fix.sh

bash 复制代码
#!/usr/bin/env bash
set -euo pipefail
npm test
npm run lint
echo "VERIFY_OK"

关键: 「完成」由 脚本退出码 判定,不是 Agent 口头说「好了」------这就是 Loop 相比纯 prompt 的核心升级。


步骤 4:Worktree 隔离(积木:Worktrees)

Automation Instructions 中约定(或由 SDK 脚本执行):

bash 复制代码
git fetch origin main
git worktree add ../wt-ci-fix-<sha> -b auto/ci-fix-<sha> origin/main
cd ../wt-ci-fix-<sha>
# 后续 Agent 的 cwd 指向此目录

修完后:

bash 复制代码
git push -u origin auto/ci-fix-<sha>
git worktree remove ../wt-ci-fix-<sha>

并行处理多个 Open 项时,每个 sha 一个 worktree,避免文件碰撞。


步骤 5:Sub-agent 分工(积木:Sub-agents)

在 Instructions 或 ci-fix-goal.md 中写明(Agent 模式会自动 spawn Task):

角色 subagent_type 职责
侦察兵 explore 只读搜索失败测试相关代码
修理工 generalPurpose 在 worktree 内改代码、跑 verify
审查员 bugbot(readonly) 对照 skill 与 diff 做对抗审查

制造 / 检验分离 让你敢在 Automation 运行时走开------审查员不同意就不能进 Done。

可选:用 HooksubagentStop 对审查员注入 follow-up:

json 复制代码
{
  "subagentStop": [
    {
      "command": ".cursor/hooks/after-review.sh",
      "matcher": "bugbot"
    }
  ]
}

步骤 6:开 PR 与通知(积木:Connectors)

通过后 Automation 的 prComment 或 GitHub MCP:

  • 创建 PR:auto/ci-fix-<sha>main
  • PR 正文引用 state 中的摘要与 verify 日志
  • Slack MCP(可选):仅 Needs Human 项 @ 频道

你在 Triage 收件箱只看到: 要产品决策的、或 3 轮没修好的------其余已是草稿 PR。


案例运行时间线(对照「手动 prompt」)

传统提示词路径(约 45--90 分钟/次,你在场):

text 复制代码
09:00 你打开 GitHub Actions
09:10 复制失败日志到 Chat
09:15--10:00 多轮粘贴、改代码、再测
10:00 手动开 PR

Loop 路径(设计一次,后续每日 5--10 分钟 review):

text 复制代码
09:00 Automation 触发 → Skill 更新 state
09:05--09:40 并行 worktree + sub-agent 循环(你不在)
09:45 你收到 2 个草稿 PR + 1 条 Needs Human
09:50 你读 PR diff,合并或评论

GitHub 审查 sub-agent 实现 sub-agent worktree ci-triage-state.md ci-triage Skill Automation 你(设计一次) GitHub 审查 sub-agent 实现 sub-agent worktree ci-triage-state.md ci-triage Skill Automation 你(设计一次) #mermaid-svg-akdKWq60rZuOqyxU{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-akdKWq60rZuOqyxU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-akdKWq60rZuOqyxU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-akdKWq60rZuOqyxU .error-icon{fill:#552222;}#mermaid-svg-akdKWq60rZuOqyxU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-akdKWq60rZuOqyxU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-akdKWq60rZuOqyxU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-akdKWq60rZuOqyxU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-akdKWq60rZuOqyxU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-akdKWq60rZuOqyxU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-akdKWq60rZuOqyxU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-akdKWq60rZuOqyxU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-akdKWq60rZuOqyxU .marker.cross{stroke:#333333;}#mermaid-svg-akdKWq60rZuOqyxU svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-akdKWq60rZuOqyxU p{margin:0;}#mermaid-svg-akdKWq60rZuOqyxU .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-akdKWq60rZuOqyxU text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-akdKWq60rZuOqyxU .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-akdKWq60rZuOqyxU .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-akdKWq60rZuOqyxU .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-akdKWq60rZuOqyxU .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-akdKWq60rZuOqyxU #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-akdKWq60rZuOqyxU .sequenceNumber{fill:white;}#mermaid-svg-akdKWq60rZuOqyxU #sequencenumber{fill:#333;}#mermaid-svg-akdKWq60rZuOqyxU #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-akdKWq60rZuOqyxU .messageText{fill:#333;stroke:none;}#mermaid-svg-akdKWq60rZuOqyxU .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-akdKWq60rZuOqyxU .labelText,#mermaid-svg-akdKWq60rZuOqyxU .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-akdKWq60rZuOqyxU .loopText,#mermaid-svg-akdKWq60rZuOqyxU .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-akdKWq60rZuOqyxU .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-akdKWq60rZuOqyxU .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-akdKWq60rZuOqyxU .noteText,#mermaid-svg-akdKWq60rZuOqyxU .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-akdKWq60rZuOqyxU .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-akdKWq60rZuOqyxU .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-akdKWq60rZuOqyxU .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-akdKWq60rZuOqyxU .actorPopupMenu{position:absolute;}#mermaid-svg-akdKWq60rZuOqyxU .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-akdKWq60rZuOqyxU .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-akdKWq60rZuOqyxU .actor-man circle,#mermaid-svg-akdKWq60rZuOqyxU line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-akdKWq60rZuOqyxU :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} loop 每个可自动修项 配置触发器 + Instructions 每日 9:00 / CI 完成 写入 Open 列表 git worktree add ci-fix-goal verify 脚本(最多 3 轮) 提交审查 不通过则打回 通过则开 PR 标 Done / Needs Human 草稿 PR + 收件箱


案例的简化版:只用 CLI 先跑通

在上马 Automations 前,可用 CLI 在本地验证循环逻辑:

bash 复制代码
export CURSOR_API_KEY="cursor_..."

# 1. Triage(只更新 state,不改代码)
agent -p "执行 \$ci-triage skill,只更新 docs/ci-triage-state.md"

# 2. 单项修复(在 worktree 中)
git worktree add ../wt-test -b auto/ci-fix-test origin/main
cd ../wt-test
agent -p "$(cat ../your-repo/.cursor/prompts/ci-fix-goal.md)"

# 3. 确定性验收
bash ../your-repo/scripts/verify-ci-fix.sh && echo OK || echo FAIL

本地跑通后,把同一份 prompt 搬进 Automation Instructions,即完成从第 3 层到第 2 层的升级。


7.9 四层能力怎么选?

你的情况 推荐起点
第一次接触 Loop 7.7 入门案例/loop + state + verify)
个人 side project,想边写代码边盯测试 /loop 10m 跑测试并摘要
团队要每日 CI 巡检 Cursor Automations + Skill(7.8)
已有 GitHub Actions,不想换平台 agent -p 嵌进 workflow
要多阶段、多分支、强门禁 SDK + Hooks + Rules(可参考 loop-cursor

迁移路径(推荐):

text 复制代码
手动 prompt 修 Bug
    → 7.7:/loop + state.md + verify.sh
    → 把 prompt 存成 .cursor/skills/*.md
    → CLI agent -p 本地验证
    → 7.8:Automations + MCP + worktree + sub-agent
    → 按需加 SDK 状态机

7.10 Cursor 实践中的成本与安全

风险 Cursor 中的缓解
Cloud Automation 跑飞 编辑器里设模型与消费限制;Instructions 写清最大轮次
CLI 在 CI 花太多 token timeout-minutes;prompt 限定 diff 范围;用 agent -p 而非无限 resume
自主改坏 main 只在 worktree / PR 分支操作;禁止 hook 保护 main push
MCP 权限过大 用只读 token;Skill 里写清允许的工具
看不懂 Agent 改了什么 强制 PR + 人工 merge;state 文件留审计轨迹

本节小结: Cursor 里做 Loop Engineering,建议 7.7 入门 → 7.8 进阶 循序渐进。核心链条是:触发器(/loop 或 Automation)→ 知识(Skill)→ 记忆(state 文件)→ 验收(verify 脚本)→ 再按需加隔离、分工、集成


八、设计一个好循环:实战清单

8.1 五条设计原则

  1. 目标可验证 ------ 尽量用测试、lint、类型检查、结构化 diff 约束,少用「感觉对了」。
  2. 终止必存在 ------ 最大轮次、token/美元预算、超时时间;防止跑飞账单。
  3. 制造与检验分离 ------ 实现 Agent ≠ 宣布完成 Agent。
  4. 状态写外面 ------ 进度、决策、失败原因落盘,别赌上下文窗口。
  5. 默认人在环路 ------ 高风险操作(删库、force push、发版)设硬门禁或人工批准。

8.2 安全与成本:循环特有的风险

风险 说明 缓解
Runaway loop 永远「差一点」完成 max turns、budget cap、job timeout
静默错误 无人看守时改坏代码 Verifier + CI 硬门禁
Comprehension debt 代码量产但你不懂 定期自己读 diff、限制自动合并
Cognitive surrender 懒得想,全盘接受 循环是放大器:懂的人更快,不懂的人更危险

Osmani 的警告很实在:循环不会让质量自动变好;如果你不 review,产品质量会螺旋下降。

8.3 何时用 Loop,何时用手动 Prompt?

适合 Loop 适合手动 Prompt
重复性巡检、CI 跟进、依赖升级 一次性探索、架构脑暴
规格清晰、测试齐全的任务 需求模糊、需要大量对齐
你熟悉模块的批量改动 新领域学习、读陌生代码
团队要沉淀为基础设施 快速试错、五分钟小问

最佳实践是混合: 探索阶段手写 prompt;成熟模式封装成 Skill + Automation。


九、案例 walkthrough:修 Bug 的两种路径

路径 A:提示词工程

复制代码
你:登录 500 错误,cookie 没设上,这是 handler 代码 [粘贴]
AI:建议改 SetCookie 的 SameSite......
你:[运行测试] 还是失败,日志如下 [粘贴]
AI:再加 Domain 属性......
你:[合并] [手动开 PR]

轮次: 约 8--15 轮;你的时间: 全程在线。

路径 B:Loop Engineering

复制代码
你(一次性):设计 /goal
  「修复 issue #1289:test/auth 全绿,golangci-lint 无新增问题;
   用 $backend-skill;实现与审查分不同 sub-agent。」

系统:
  → 读 issue + 相关文件
  → worktree 隔离实现
  → 跑测试,失败则自动读日志再改
  → 审查 agent 对照 skill 检查
  → 开 PR,更新 Linear
  → 仅「需产品决策」的项 @ 你

轮次: 系统内部可能 20+ 轮;你的时间: 开头设计 + 结尾 review。


十、常见误区

误区 1:「Loop = 全自动 AGI,我可以不管了」

错。你是系统负责人,不是旁观者。循环放大的是你的判断力,也会放大你的懈怠。

误区 2:「提示词工程过时了」

错。循环内部全是 prompt;表达力仍重要,只是主战场变了。

误区 3:「循环越复杂越好」

错。从 7.7 入门案例/loop + state + verify)开始,比一上来搭 CI 全自动流水线更靠谱。

误区 4:「同一套循环,人人效果一样」

错。Osmani 强调:两人搭相同循环,一人因更懂业务而加速,一人因逃避理解而欠债------循环分辨不了这两种人。


十一、学习路线建议

若你想系统掌握 Loop Engineering,可按四周节奏:

第 1 周:提示词基础仍要扎实

会写清晰任务、约束、反例;会用 @文件、贴验证命令。

第 2 周:外置知识

为一个真实项目写第一份 SKILL.md(构建、测试、目录、禁忌)。

第 3 周:单循环

选一件小事(如「每 10 分钟跑测试直到绿」),用 7.7 入门案例/loop + agent -p 跑通,带明确停止条件

第 4 周:制造/检验分离

加审查 sub-agent 或 /goal 式完成判定;引入 worktree 试并行。
#mermaid-svg-koAefvxmihWj062N{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-koAefvxmihWj062N .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-koAefvxmihWj062N .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-koAefvxmihWj062N .error-icon{fill:#552222;}#mermaid-svg-koAefvxmihWj062N .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-koAefvxmihWj062N .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-koAefvxmihWj062N .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-koAefvxmihWj062N .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-koAefvxmihWj062N .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-koAefvxmihWj062N .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-koAefvxmihWj062N .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-koAefvxmihWj062N .marker{fill:#333333;stroke:#333333;}#mermaid-svg-koAefvxmihWj062N .marker.cross{stroke:#333333;}#mermaid-svg-koAefvxmihWj062N svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-koAefvxmihWj062N p{margin:0;}#mermaid-svg-koAefvxmihWj062N .mermaid-main-font{font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-koAefvxmihWj062N .exclude-range{fill:#eeeeee;}#mermaid-svg-koAefvxmihWj062N .section{stroke:none;opacity:0.2;}#mermaid-svg-koAefvxmihWj062N .section0{fill:rgba(102, 102, 255, 0.49);}#mermaid-svg-koAefvxmihWj062N .section2{fill:#fff400;}#mermaid-svg-koAefvxmihWj062N .section1,#mermaid-svg-koAefvxmihWj062N .section3{fill:white;opacity:0.2;}#mermaid-svg-koAefvxmihWj062N .sectionTitle0{fill:#333;}#mermaid-svg-koAefvxmihWj062N .sectionTitle1{fill:#333;}#mermaid-svg-koAefvxmihWj062N .sectionTitle2{fill:#333;}#mermaid-svg-koAefvxmihWj062N .sectionTitle3{fill:#333;}#mermaid-svg-koAefvxmihWj062N .sectionTitle{text-anchor:start;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-koAefvxmihWj062N .grid .tick{stroke:lightgrey;opacity:0.8;shape-rendering:crispEdges;}#mermaid-svg-koAefvxmihWj062N .grid .tick text{font-family:"trebuchet ms",verdana,arial,sans-serif;fill:#333;}#mermaid-svg-koAefvxmihWj062N .grid path{stroke-width:0;}#mermaid-svg-koAefvxmihWj062N .today{fill:none;stroke:red;stroke-width:2px;}#mermaid-svg-koAefvxmihWj062N .task{stroke-width:2;}#mermaid-svg-koAefvxmihWj062N .taskText{text-anchor:middle;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-koAefvxmihWj062N .taskTextOutsideRight{fill:black;text-anchor:start;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-koAefvxmihWj062N .taskTextOutsideLeft{fill:black;text-anchor:end;}#mermaid-svg-koAefvxmihWj062N .task.clickable{cursor:pointer;}#mermaid-svg-koAefvxmihWj062N .taskText.clickable{cursor:pointer;fill:#003163!important;font-weight:bold;}#mermaid-svg-koAefvxmihWj062N .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163!important;font-weight:bold;}#mermaid-svg-koAefvxmihWj062N .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163!important;font-weight:bold;}#mermaid-svg-koAefvxmihWj062N .taskText0,#mermaid-svg-koAefvxmihWj062N .taskText1,#mermaid-svg-koAefvxmihWj062N .taskText2,#mermaid-svg-koAefvxmihWj062N .taskText3{fill:white;}#mermaid-svg-koAefvxmihWj062N .task0,#mermaid-svg-koAefvxmihWj062N .task1,#mermaid-svg-koAefvxmihWj062N .task2,#mermaid-svg-koAefvxmihWj062N .task3{fill:#8a90dd;stroke:#534fbc;}#mermaid-svg-koAefvxmihWj062N .taskTextOutside0,#mermaid-svg-koAefvxmihWj062N .taskTextOutside2{fill:black;}#mermaid-svg-koAefvxmihWj062N .taskTextOutside1,#mermaid-svg-koAefvxmihWj062N .taskTextOutside3{fill:black;}#mermaid-svg-koAefvxmihWj062N .active0,#mermaid-svg-koAefvxmihWj062N .active1,#mermaid-svg-koAefvxmihWj062N .active2,#mermaid-svg-koAefvxmihWj062N .active3{fill:#bfc7ff;stroke:#534fbc;}#mermaid-svg-koAefvxmihWj062N .activeText0,#mermaid-svg-koAefvxmihWj062N .activeText1,#mermaid-svg-koAefvxmihWj062N .activeText2,#mermaid-svg-koAefvxmihWj062N .activeText3{fill:black!important;}#mermaid-svg-koAefvxmihWj062N .done0,#mermaid-svg-koAefvxmihWj062N .done1,#mermaid-svg-koAefvxmihWj062N .done2,#mermaid-svg-koAefvxmihWj062N .done3{stroke:grey;fill:lightgrey;stroke-width:2;}#mermaid-svg-koAefvxmihWj062N .doneText0,#mermaid-svg-koAefvxmihWj062N .doneText1,#mermaid-svg-koAefvxmihWj062N .doneText2,#mermaid-svg-koAefvxmihWj062N .doneText3{fill:black!important;}#mermaid-svg-koAefvxmihWj062N .doneText0.taskTextOutsideLeft,#mermaid-svg-koAefvxmihWj062N .doneText0.taskTextOutsideRight,#mermaid-svg-koAefvxmihWj062N .doneText1.taskTextOutsideLeft,#mermaid-svg-koAefvxmihWj062N .doneText1.taskTextOutsideRight,#mermaid-svg-koAefvxmihWj062N .doneText2.taskTextOutsideLeft,#mermaid-svg-koAefvxmihWj062N .doneText2.taskTextOutsideRight,#mermaid-svg-koAefvxmihWj062N .doneText3.taskTextOutsideLeft,#mermaid-svg-koAefvxmihWj062N .doneText3.taskTextOutsideRight{fill:black!important;}#mermaid-svg-koAefvxmihWj062N .crit0,#mermaid-svg-koAefvxmihWj062N .crit1,#mermaid-svg-koAefvxmihWj062N .crit2,#mermaid-svg-koAefvxmihWj062N .crit3{stroke:#ff8888;fill:red;stroke-width:2;}#mermaid-svg-koAefvxmihWj062N .activeCrit0,#mermaid-svg-koAefvxmihWj062N .activeCrit1,#mermaid-svg-koAefvxmihWj062N .activeCrit2,#mermaid-svg-koAefvxmihWj062N .activeCrit3{stroke:#ff8888;fill:#bfc7ff;stroke-width:2;}#mermaid-svg-koAefvxmihWj062N .doneCrit0,#mermaid-svg-koAefvxmihWj062N .doneCrit1,#mermaid-svg-koAefvxmihWj062N .doneCrit2,#mermaid-svg-koAefvxmihWj062N .doneCrit3{stroke:#ff8888;fill:lightgrey;stroke-width:2;cursor:pointer;shape-rendering:crispEdges;}#mermaid-svg-koAefvxmihWj062N .milestone{transform:rotate(45deg) scale(0.8,0.8);}#mermaid-svg-koAefvxmihWj062N .milestoneText{font-style:italic;}#mermaid-svg-koAefvxmihWj062N .doneCritText0,#mermaid-svg-koAefvxmihWj062N .doneCritText1,#mermaid-svg-koAefvxmihWj062N .doneCritText2,#mermaid-svg-koAefvxmihWj062N .doneCritText3{fill:black!important;}#mermaid-svg-koAefvxmihWj062N .doneCritText0.taskTextOutsideLeft,#mermaid-svg-koAefvxmihWj062N .doneCritText0.taskTextOutsideRight,#mermaid-svg-koAefvxmihWj062N .doneCritText1.taskTextOutsideLeft,#mermaid-svg-koAefvxmihWj062N .doneCritText1.taskTextOutsideRight,#mermaid-svg-koAefvxmihWj062N .doneCritText2.taskTextOutsideLeft,#mermaid-svg-koAefvxmihWj062N .doneCritText2.taskTextOutsideRight,#mermaid-svg-koAefvxmihWj062N .doneCritText3.taskTextOutsideLeft,#mermaid-svg-koAefvxmihWj062N .doneCritText3.taskTextOutsideRight{fill:black!important;}#mermaid-svg-koAefvxmihWj062N .vert{stroke:navy;}#mermaid-svg-koAefvxmihWj062N .vertText{font-size:15px;text-anchor:middle;fill:navy!important;}#mermaid-svg-koAefvxmihWj062N .activeCritText0,#mermaid-svg-koAefvxmihWj062N .activeCritText1,#mermaid-svg-koAefvxmihWj062N .activeCritText2,#mermaid-svg-koAefvxmihWj062N .activeCritText3{fill:black!important;}#mermaid-svg-koAefvxmihWj062N .titleText{text-anchor:middle;font-size:18px;fill:#333;font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-koAefvxmihWj062N :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 2026-01-01 2026-01-03 2026-01-05 2026-01-07 2026-01-09 2026-01-11 2026-01-13 2026-01-15 2026-01-17 2026-01-19 2026-01-21 2026-01-23 2026-01-25 2026-01-27 2026-01-29 提示词与项目上下文 编写 Skill 与状态文件 第一个 Automation/CLI 循环 Sub-agent 与验证门禁 基础 沉淀 自动化 进阶 Loop Engineering 学习路径


十二、总结:三个核心 Takeaway

  1. Loop Engineering 是范式升级,不是措辞升级。 你从「对话者」变成「循环设计师」------设计目标、反馈、记忆、验收与治理。

  2. 六大积木(Automation、Worktree、Skill、Connector、Sub-agent、State)是通用语言。 Codex、Claude Code、Cursor 名字不同,形状相近;学会抽象后换工具成本更低。

  3. 杠杆点上移,责任也上移。 循环可以 24 小时帮你干活,也可以 24 小时帮你埋雷。Build the loop ------ but stay the engineer.


附录

术语表

完整术语见文首 术语速查。此处仅补充正文后段出现的概念:

术语 解释
Plugin 打包分发 Skill + 连接器的安装单元
AGENTS.md 仓库根目录给 Cloud/CLI Agent 的说明书
Triage 自动分拣:值得处理的留下,其余归档
Runaway loop 循环无法终止、持续消耗 token 的失控状态

参考资料

  • Addy Osmani, Loop Engineering(2026)
  • Boris Cherny(Anthropic Claude Code)关于「写 loops 而非 prompts」的公开表述
  • Peter Steinberger 关于「design loops that prompt your agents」的论述
  • Cursor 文档:Agent CLI、@cursor/sdk、MCP、Skills
  • 开源实践:loop-cursor --- Goal-Driven Autonomous Dev Loop
  • Cursor 文档:Agent CLISDKHooksMCP