Opencode 循环工作流约束设计:为 CLI 优先的 AI Agent 配置绑定护栏(loop-constraints 实战指南)
【免费下载链接】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 的自动化循环工作流定义简单而有效的安全护栏(guardrails)。本文将以此文档为骨架,结合仓库中的loop-constraints技能、默认约束模板与安全基线,完整讲解如何在 Opencode 中落地一套"每次运行前必读、运行中绝不违反"的绑定约束体系,帮助你掌控自动循环的边界、降低误操作风险,并让新贡献者与共享仓库的协作变得可预测、可审计。
一、约束的本质:让循环可预测
自动化循环(loop)放大的不仅是产出,也包括错误。约束(constraints)是一组绑定规则(binding rules)——循环在任何场景下都不得违反的边界。examples/opencode/constraints-example.md开篇即点明其定位:为 CLI 优先工作流定义简单护栏,并与loop-init --tool opencode初始化命令配对使用;初始化完成后,可以针对项目定制生成的技能,附加项目专属约束。
它之所以有效,是因为约束在循环运行之前就被注入到 Agent 上下文中,而不是在运行中途才被想起。约束使自动化工作流可预测,并显著降低意外或危险操作的发生概率——这一点对新贡献者和共享仓库尤其重要。
二、最小示例:一个带护栏的 loop-triage 技能
原文档给出的最小示例只有三行目录结构,却代表了 Opencode 中约束的典型载体——技能(skill):
skills/ └── loop-triage/ └── SKILL.mdOpencode 会自动发现仓库根目录skills/下的技能文件,因此约束规则被直接写进技能文件的## Constraints小节:
# 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.这五条规则覆盖了 L1(报告模式)阶段最常见的风险面:读写边界(只读)、Git 操作边界(禁止强推)、修改范围边界(只动与任务相关文件)、破坏性操作边界(删除/重命名需确认)以及信息泄露边界(不暴露密钥与内部 URL)。它们全部使用平实的自然语言书写,因为约束的消费方是 LLM Agent,而不是编译器。
与之配套的loop-triage技能本体(见 starters/minimal-loop-opencode/skills/loop-triage/SKILL.md)定义了技能的执行纪律:输出 High-Priority Items、Watch Items、Noise/Ignore、State Updates 四个区块,并要求"Be brutally concise"(尽量简洁)、triage 阶段绝不提出架构级改造——这些自身就是一种内置约束,约束与技能互相强化。
三、约束技能如何运作:每次运行前的强制注入
仅把规则写在技能里还不够,还需要一个机制保证规则每次运行都被读到。仓库通过loop-constraints技能(skills/loop-constraints/SKILL.md,模板见 templates/SKILL.md.loop-constraints)完成这一职责。
该技能的核心身份是 "Loop Constraints Enforcer"(约束执行者),其强制流程如下:
- 从项目根目录读取
loop-constraints.md; - 将每一条规则加载进工作记忆;
- 检查
loop-pause-all是否激活——若激活则立即退出; - 对后续每一个动作应用这些规则。
技能会在每次运行开始时输出一行确认信息,给出生效规则数量:
Constraints loaded from loop-constraints.md: N rules active.如果loop-constraints.md不存在,技能不会静默放行,而是回退到 docs/safety.md 中的默认安全规则,例如:永不编辑.env、.env.*、auth/、payments/、secrets/、credentials/;永不自动合并到 main;永不禁用测试;连续 3 次修复失败后升级上报。
与其他技能的协作契约
约束技能并非孤立运行,它与循环中的其他技能存在明确的交互契约:
- loop-triage:约束可能覆盖 triage 的优先级(例如"不要 push"意味着不要对 CI 修复采取行动);
- minimal-fix:约束限定可被修改的文件范围;
- loop-verifier:约束定义验证器必须检查的黑名单路径;
- loop-budget:约束可能施加比
loop-budget.md更严格的预算策略。
四、约束文件:loop-constraints.md的结构与默认集
约束规则的持久化载体是项目根目录的loop-constraints.md。examples/opencode/constraints.md明确:技能在每次运行开始时读取该文件,把 header 之下的每一行都视为绑定规则(允许注释)。
仓库提供的默认模板 templates/loop-constraints.md 按主题分节,是开箱即用的起始约束集:
| 分节 | 默认规则 |
|---|---|
| Push & Merge | 不 push 前先告知;未经人工批准不自动合并到 main;先建 draft PR 供审阅后再标记 ready |
| Paths | 永不编辑.env、.env.*、auth/、payments/、secrets/、credentials/;未经批准不编辑基础设施配置 |
| Code | 提出修复前必须运行测试;永不为让 CI 变绿而禁用测试;不做无关重构,一次运行只修一个问题;单项目最多 3 次修复尝试,之后升级 |
| Communication | 行动前先告知;未经批准不关闭 issue 或 PR |
| Budget | token 消耗达到日上限 80% 时切换为只报告模式;loop-pause-all激活时立即退出 |
模板末尾特别注明:"使用平实英语添加你自己的规则。循环逐字读取。"——这意味着约束的语义完全由书写者负责,Agent 不会主动"猜"你隐含的意图。
新增规则的方式
在 Opencode 中追加规则有两种途径:
方式一:通过opencode run追加(让循环自己写入)
# 追加一条规则(循环先运行一次完成读取与持久化,之后每次运行都会强制执行) opencode run \ "Append this rule to loop-constraints.md verbatim: 'Don't push before telling me. Always run tests first.'"方式二:直接编辑文件。任何规则修改都会在下一次循环运行时生效。
五、把约束放在每次循环运行之前
有了约束文件和技能之后,关键操作是把约束注入到每次调度运行的最前面,让它先于 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."这条命令的含义是:先运行约束技能(读取loop-constraints.md并把规则烘焙进上下文),再运行 triage,最后更新状态文件,且第一周不启用自动修复。由于 triage 与约束运行在同一个上下文中,规则已经内嵌到 Agent 的上下文窗口,triage 的任何决策都会被约束实时约束。
六、自动脚手架与手动拷贝
examples/opencode/constraints.md提供了两种落地方式。
方式一:使用 loop-init 自动生成
npx @cobusgreyling/loop-init . --pattern daily-triage --tool opencodeloop-init会将loop-constraints.md和skills/loop-constraints/SKILL.md复制到 opencode 期望的仓库根目录布局中。
方式二:手动拷贝(无需初始化工具)
mkdir -p skills/loop-constraints cp templates/SKILL.md.loop-constraints skills/loop-constraints/SKILL.md cp templates/loop-constraints.md loop-constraints.md同时,examples/opencode/README.md提示当前尚未提供loop-init --tool opencode的正式支持,推荐直接复制 starters/minimal-loop-opencode/ 启动包,或按上述片段在 30 秒内手动完成搭建。
启动包中的权限控制参考
starters/minimal-loop-opencode/opencode.json.example展示了如何在 opencode 层面对 agent 施加第二道约束——权限(permission):
{ "agent": { "loop-triage": { "mode": "primary", "prompt": "Read AGENTS.md, LOOP.md, STATE.md, and skills/loop-triage/SKILL.md. Run report-only triage. Update STATE.md. Do not edit source code unless the human has explicitly enabled L2.", "permission": { "bash": "ask", "edit": "ask" } }, "verifier": { "mode": "subagent", "prompt": "Review the supplied diff or worktree summary against project rules, tests, and docs/safety.md. Do not edit files. Respond with APPROVE or REJECT and concise evidence.", "permission": { "bash": "ask", "edit": "deny" } } } }注意 verifier 的edit权限被设置为deny——验证者只能审查、只能 APPROVE 或 REJECT,不能改代码。这是约束在工具权限层的物化:即使上下文注入失效,权限系统仍会兜底拦截。
starters/minimal-loop-opencode/AGENTS.md则把关键约束固化为 opencode 每次加载的项目级规则:"L1 只读模式起步;triage 前先读STATE.md;每次运行后更新STATE.md;未经人工明确开启 L2 前不修改源码;永不未经批准 push 或 merge;禁止编辑.env、auth/、payments/等路径;每次改代码必须使用独立 git worktree;单项目最多 3 次修复尝试。" 这构成了技能约束 + 项目规则 + 权限配置三层防护。
七、安全基线:约束背后的仓库级护栏
约束不是孤立的灵感,仓库在 docs/safety.md 中给出了系统化的安全基线,可作为书写约束时的权威参考:
- 路径黑名单:
**/.env、**/.env.*、**/secrets/**、**/credentials/**、**/*_key*、**/*_secret*、**/.terraform/**、**/k8s/production/**、**/migrations/**、**/auth/**、**/payments/**、**/billing/**——循环未经人工批准永不自动编辑这些路径,应编码进minimal-fix与实施类技能中; - 自动合并策略:默认不自动合并。即使对琐碎循环开放自动合并,也只允许注释/文档错字、测试文件内的 lint 自动修复、import 排序、白名单
docs/路径下的配置;依赖版本升级、lockfile 变更、任何黑名单路径一律禁止; - 人工门禁(Human Gates):安全、认证授权、支付账单、基础设施/Terraform/K8s 生产环境、依赖升级(供应链风险)、超过 N 个文件(建议 N=10)的改动、同一事项第三次失败、token 预算超限申请——这些场景必须有人工介入;
- Secrets 防护:调度器 prompt 中绝不粘贴 API key;triage 技能应在写入状态前对 CI 日志脱敏;状态文件经常被提交,
STATE.md中不得出现凭证。
docs/safety.md还强调loop-sync每次运行都会将上述规则与gate.yaml交叉校验,报告漂移但绝不自行改写任何一侧——哪边是正确的属于人工判断范畴。
八、与其他工具链的约束写法对比
约束的载体随工具而变化,但核心契约一致:每次循环运行开始前读取并强制执行loop-constraints.md。仓库提供了多套对照实现:
- examples/claude-code/constraints.md:通过
/constraints <rule>命令追加规则,技能安装在.claude/skills/loop-constraints/SKILL.md; - examples/cursor/constraints.md:Cursor 无原生
/constraints命令,采用"技能 + always-on rules + Automation prompt"组合,并可选在.cursor/rules/loop-constraints.mdc中镜像关键规则; - examples/codex/constraints.md:直接在 Automation prompt 中声明"运行约束技能后再 triage";
- examples/grok/constraints.md:与 Claude Code 类似的
/constraints追加方式。
examples/opencode/constraints-example.md建议将本文方案与 Cursor 的编辑器优先工作流示例对照阅读——两者的差别本质上是"CLI 优先"与"编辑器优先"两种循环形态下约束载体的差异。
九、约束的书写纪律
examples/opencode/constraints.md在 Safety 一节给出了最关键的提醒,也是整个约束体系的设计哲学:
Constraints arebinding. If a rule can be misinterpreted, rewrite it — the loop will not second-guess, the human will.
约束是绑定的。如果某条规则可能被误解,就重写它——循环不会二次揣测,最终承担后果的是人类。这意味着约束作者必须假设 Agent 会逐字照办,因此规则要尽量单义、具体、可判定(例如"永不强推分支"优于"推送时小心"),并覆盖读写范围、Git 操作、破坏性操作、信息泄露等风险维度。结合docs/safety.md的路径黑名单与人工门禁清单来编写约束,可以让自动化循环既高效又有清晰的问责边界。
十、参考资料索引
- examples/opencode/constraints-example.md — 本文骨架来源的最小护栏示例
- examples/opencode/constraints.md — Opencode 约束完整指南
- templates/loop-constraints.md — 默认约束集模板
- templates/SKILL.md.loop-constraints — 约束技能模板
- skills/loop-constraints/SKILL.md — 已安装的约束技能实现
- docs/safety.md — 路径黑名单、自动合并策略、人工门禁与 Secrets 防护
- starters/minimal-loop-opencode/ — 可克隆即用的最小 L1 triage 启动包(含
opencode.json.example、AGENTS.md、LOOP.md) - examples/cursor/constraints.md — 编辑器优先工作流的约束对照实现
【免费下载链接】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),仅供参考