loop-engineering 实战:为 Opencode 的 CLI 优先工作流定义 loop-triage 技能约束(Constraints Example)
2026/9/24 22:23:32 网站建设 项目流程

loop-engineering 实战:为 Opencode 的 CLI 优先工作流定义 loop-triage 技能约束(Constraints Example)

【免费下载链接】loop-engineeringPractical patterns, starters & CLI tools for loop engineering with AI coding agents. Design systems that prompt and orchestrate agents (inspired by Addy Osmani and Boris Cherny). Includes loop-audit, loop-init, loop-cost.项目地址: https://gitcode.com/gh_mirrors/lo/loop-engineering

导读

本文围绕 loop-engineering 仓库中的 Opencode 约束示例(examples/opencode/constraints-example.md),讲解如何为 CLI 优先的循环工程(loop engineering)工作流定义显式防护栏(guardrails):以一个最小化的skills/loop-triage/SKILL.md为例,展示如何把"入职第一周只读、禁止 force-push"等 3~5 条硬性约束直接写进技能文件,并通过loop-init --tool opencode与脚手架自动配对。读完本文,你将掌握在 Opencode 场景下为自动化 Agent 编排声明式约束的完整套路,理解约束如何被loop-constraints技能在每次循环运行前强制加载,并能结合 docs/safety.md 的安全基线写出真正可落地的规则。

为什么需要"约束示例":CLI 优先循环的失控风险

Opencode 是一个开源 CLI 编码 Agent,支持通过opencode run无头(headless)运行,支持命名 Agent(named agents),并可通过 MCP 连接外部工具。在 loop-engineering 的视角里,循环工程原语以纯文本文件发布:AGENTS.mdSTATE.mdskills/目录下的技能文件(examples/opencode/README.md)。这意味着你的循环(loop)可以跑在 cron、systemd timer 甚至无头服务器上,而不再依赖一个交互式 TUI。

但自动化越彻底,失控成本越高。一个被调度器反复触发、拥有文件编辑与命令执行权限的 Agent,一旦缺乏明确的行为边界,可能做出删除文件、force-push、触碰敏感路径等不可逆操作。这正是"约束示例"存在的意义:为 CLI 优先用户提供一个可以照抄的loop-triage技能,把显式防护栏内置在技能定义里,让每次运行在动手之前就明确知道"什么可以做、什么绝对不可以做"。

仓库中的 issue 描述(scripts/issue-bodies/opencode-constraints-example.md)给出了这个示例的验收标准:

  • 展示一个最小化的skills/loop-triage/SKILL.md片段,包含 3~5 条约束(入职第一周只读、禁止 force-push 等);
  • 展示如何与loop-init --tool opencode配对使用;
  • 链接到 docs/safety.md 与 Cursor 约束示例(examples/cursor/constraints.md)以便对比;
  • 不包含任何密钥或内部 URL。

最小化 loop-triage 技能:把约束写进 SKILL.md

约束示例的核心是下面这个目录结构与技能文件(源自 examples/opencode/constraints-example.md):

skills/ └── loop-triage/ └── SKILL.md
# Loop Triage ## Constraints - Read-only during the first week of onboarding. - Never force-push to any branch. - Only modify files directly related to the assigned issue. - Request confirmation before deleting or renaming files. - Do not expose secrets, tokens, or internal URLs.

这 5 条约束覆盖了自动化循环最容易出问题的五类风险,值得逐条拆解:

约束防护的风险对应安全基线
入职第一周只读(Read-only during the first week)新贡献者/新接入的循环在缺乏上下文时擅自改代码L1 report-only 模式,见 starters/minimal-loop-opencode/AGENTS.md
禁止 force-push 任何分支覆盖他人提交、破坏共享历史推送/合并类约束,见 templates/loop-constraints.md
只修改与分配 issue 直接相关的文件顺手重构无关代码、扩大 diff 面maxFiles类护栏思想,见 docs/safety.md
删除/重命名文件前必须请求确认不可逆操作人工门禁(Human Gates),见 docs/safety.md
不得暴露密钥、令牌、内部 URL凭据泄露进状态文件或日志Secrets in Prompts & Logs,见 docs/safety.md

注意这个技能文件本身并没有完整实现 triage 逻辑——完整的loop-triage技能模板在 templates/SKILL.md.loop-triage,它定义了 High-Priority / Watch / Noise / State Updates 四段输出格式,并要求"brutally concise""When in doubt, put it in Watch or Noise"。约束示例展示的是在既有技能骨架之上叠加显式护栏的写法:约束放在## Constraints小节,与技能指令同处一个文件,Agent 每次加载技能时必然读到。

与 loop-init --tool opencode 配对:脚手架自动落位

约束示例明确与下面这条命令配对:

loop-init --tool opencode

从源码看,tools/loop-init/src/cli.ts 对opencode工具做了专门处理:技能文件被复制到仓库根目录下的skills/<skillName>/SKILL.md(区别于 grok 的.grok/skills/、claude 的.claude/skills/、codex 的.codex/skills/),verifier 被复制到skills/loop-verifier/SKILL.md——这正是 Opencode 在仓库根目录自动发现技能的约定位置(源码见copyTemplateSkillcopyTemplateVerifier,tools/loop-init/src/cli.ts)。

以 daily-triage 模式为例,完整命令是:

npx @cobusgreyling/loop-init . --pattern daily-triage --tool opencode

执行后,脚手架会基于 starters/minimal-loop-opencode 生成:skills/loop-triage/SKILL.md(triage 技能)、AGENTS.md(始终生效的项目规则)、STATE.md.example(状态文件模板)、LOOP.mdopencode.json.example(命名 Agent 定义)。初始化完成后,你就可以用约束示例中的写法,把 3~5 条项目专属约束加进生成的skills/loop-triage/SKILL.md

如果想跳过脚手架手动复制,等价做法是:

mkdir -p skills/loop-triage cp templates/SKILL.md.loop-triage skills/loop-triage/SKILL.md cp starters/minimal-loop-opencode/STATE.md.example STATE.md cp starters/minimal-loop-opencode/AGENTS.md . cp starters/minimal-loop-opencode/opencode.json.example opencode.json

然后按 examples/opencode/daily-triage.md 的描述,用opencode run驱动第一周报告模式:

opencode run \ "Run the loop-triage skill. Read STATE.md first. Append high-priority items under High Priority and Watch List. Update Last run timestamp. Do not edit source code. End with a 5-line summary." \ --title "Daily triage — repo:${PWD##*/}"

约束不只是文档:loop-constraints 技能的强制加载机制

"把约束写进 SKILL.md"是快速入门;而要让它成为每次循环运行前必须执行的硬机制,需要用仓库里的loop-constraints技能。其设计是:

  1. loop-constraints.md放在仓库根目录,标题行之下每一行都是一条绑定规则(binding rule),支持注释;
  2. loop-constraints技能位于skills/loop-constraints/SKILL.md,模板见 templates/SKILL.md.loop-constraints;
  3. 每次循环运行开始时先执行该技能——它读取loop-constraints.md,把全部规则加载进上下文,输出一行确认Constraints loaded from loop-constraints.md: N rules active.
  4. 之后 triage 等动作技能在同一上下文内运行,规则已被烘焙进提示词,无法绕过。

在 Opencode 下,把约束技能排在 triage 之前即可(见 examples/opencode/constraints.md):

opencode run "Run skills/loop-constraints/SKILL.md. Then run skills/loop-triage/SKILL.md. Update STATE.md. No auto-fix in week one."

默认约束集(模板 templates/loop-constraints.md)按主题分组,可以直接作为编写自己约束的起点:

  • Push & Merge:推送前必须告知、未经人工批准不得自动合并到 main、先建 draft PR 再转为 ready;
  • Paths:永不编辑.envauth/payments/secrets/credentials/等敏感路径,基础设施配置改动需人工批准;
  • Code:提出修复前必须跑测试、绝不为让 CI 变绿而禁用测试、不重构无关代码(一次运行一个修复)、单条目最多重试 3 次后升级;
  • Communication:行动前先说明意图、未经批准不关闭 issue 或 PR;
  • Budget:token 消耗达日限额 80% 时切换为只读报告模式、loop-pause-all激活时立即退出。

这套机制与loop-initscaffoldConstraints逻辑对应:初始化时会自动复制loop-constraints.mdskills/loop-constraints/SKILL.md(tools/loop-init/src/cli.ts),无需手工装配。

为什么约束能提升工作流质量

约束示例原文给出两条核心理由,值得展开:

一是可预测性(predictability)。自动化工作流一旦被调度器驱动,每次运行都是独立会话。约束把"什么是允许的"从隐含假设变成显式声明,Agent 的行为边界不再依赖模型当下的随机判断,而是由一组每次运行前都重新加载的规则决定。同一个 triage 技能,周一和周五的行为保持一致。

二是对新贡献者与共享仓库尤其重要。新贡献者不熟悉项目的敏感路径、推送约定与测试纪律;共享仓库中一次越界操作会影响整个团队。把约束写进技能文件,等于把团队多年积累的安全直觉编码成了新人也能自动遵守的规则。

编写高质量约束:结合 safety.md 的三个要点

约束示例链接的 docs/safety.md 提供了编写约束时的安全基线,这里提炼三个直接影响约束质量的实践:

1. 路径黑名单(Path Denylist)要机械可执行。safety.md 定义了循环未经批准绝不自动编辑的路径集合:**/.env**/.env.***/secrets/****/credentials/****/*_key***/*_secret***/.terraform/****/k8s/production/****/auth/****/payments/****/billing/**等。约束示例中的"Do not expose secrets, tokens, or internal URLs"正是这一基线的自然语言表达;更强的做法是同时用loop-gategate.yaml机械执行(loop-gate check --action <type> --paths <changed files>,退出码 2 升级、0 放行)。

2. 人工门禁(Human Gates)写清楚触发条件。安全、认证授权、支付计费、基础设施变更、依赖升级、单次改动超过 N 个文件(建议 N=10)、同一条目第三次失败、token 预算扩展,都应强制人工介入。约束示例中的"Request confirmation before deleting or renaming files"就是把人工门禁下沉到技能层的典型。

3. 规则必须无歧义。仓库反复强调一条原则:约束是绑定(binding)的,循环不会二次揣测,只有人会。如果一条规则可能被误读,就重写它。例如"不要乱改文件"就比"Only modify files directly related to the assigned issue."更容易被宽泛解释——后者给出了可判定的标准(是否与分配的 issue 直接相关)。

与 Cursor 约束示例的对比:同一套语义,不同的承载位置

约束示例还建议对照 Cursor 版本(examples/cursor/constraints.md)阅读。两者的约束语义完全一致——都是"绑定规则、每次运行前加载"——但承载位置不同:

维度OpencodeCursor
技能目录仓库根skills/<name>/SKILL.md(自动发现).cursor/skills/<name>/SKILL.md
约束文件仓库根loop-constraints.md仓库根loop-constraints.md
附加机制命名 Agent(opencode run --agent ...)+AGENTS.md可选.cursor/rules/loop-constraints.mdc常驻规则 + Automation 提示词
运行方式cron/systemd +opencode run(无 TUI)Cursor Automations / 定时 Agent 对话

这个对比揭示了一个设计要点:Opencode 的约束示例走"纯文件 + CLI"路线——技能、状态、约束都是普通文本文件,即使宿主机更换、会话中断,约束依然随仓库保留并在下次opencode run时重新加载。这正是 CLI 优先工作流的核心诉求。

参考资料与延伸阅读

  • 约束示例本体:examples/opencode/constraints-example.md
  • Opencode 示例总览:examples/opencode/README.md
  • 完整 triage 技能模板:templates/SKILL.md.loop-triage
  • 默认约束集模板:templates/loop-constraints.md
  • 约束强制技能模板:templates/SKILL.md.loop-constraints
  • 安全与防护栏基线:docs/safety.md
  • 对照参考(编辑器优先):examples/cursor/constraints.md
  • Opencode 每日 triage 实操:examples/opencode/daily-triage.md
  • 可直接运行的脚手架:starters/minimal-loop-opencode
  • 脚手架实现:tools/loop-init/src/cli.ts

【免费下载链接】loop-engineeringPractical patterns, starters & CLI tools for loop engineering with AI coding agents. Design systems that prompt and orchestrate agents (inspired by Addy Osmani and Boris Cherny). Includes loop-audit, loop-init, loop-cost.项目地址: https://gitcode.com/gh_mirrors/lo/loop-engineering

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询