360 Secure SkillHub
360 安全技能中心

agent-constraints

核心功能是基于四层约束模型,提供规则定层流程、各层落地要点及新建约束、错误治理、体检等工作流。典型场景包括写改约束文件、Agent反复犯错、CLAUDE.md过长、禁止动特定目录等。输入为用户相关需求或问题,输出为约束分层方案、落地建议、验证方法等,帮助高效治理Agent约束。

snowsonz
snowsonz
热度 21.09
最近更新 2026-09-04 15:43:55
分类:开发依赖:纯提示词应用场景:DevOps / 调试排错 / 工作流 / 自动化脚本

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add agent-constraints
Metadata
name
agent-constraints
license
MIT
description
给 coding agent 设置和治理约束——决定一条规则该落到 hook、AGENTS.md/CLAUDE.md、Skill、path-scoped rule 还是 prompt。当用户要写或改 AGENTS.md、CLAUDE.md、hooks、权限规则、Skill,或者问"agent 老犯某个错该怎么办"、"这条规则该放哪"、"我的 CLAUDE.md 太长了"、"怎么禁止 agent 动某个目录"、"怎么强制它跑完测试再结束"时使用。

Agent 约束的分层设计与治理

前提

上下文文件是行为杠杆,不是性能增强器。实测:无配置文件时目标指令执行率 0%,有文件时 67.7%;但任务成功率变化不显著,推理成本必然上升约 20%。

写下的每一条都会被真的执行——包括在不该执行的任务上。

同时,文件层会系统性失守:需要反复应用的规则,约 65% 的运行至少违反一次,首次失守通常在第 4 次应用附近,改存量代码场景单次命中率仅 45%。

这两件事共同决定了:约束必须分层,每条规则放在能承载它的最低层。

需要用数字说服人时读 EVIDENCE.md。


四层模型

层 机制 性质 详见
1 执行层 执行门:hooks、permissions.deny、CI required check、pre-commit;检查器:linter、formatter、类型系统、测试 执行门确定性;检查器须接入执行门 LAYER1-ENFORCEMENT.md
2 常驻层 AGENTS.md / CLAUDE.md 每会话付费,建议性;单次应用命中 45%–84%,主要看任务类型 LAYER2-INSTRUCTIONS.md
3 按需层 Skill、path-scoped rule 只在相关时进上下文 LAYER3-ONDEMAND.md
4 会话层 prompt、plan mode、SPEC.md、/goal 一次性,最灵活 本文末尾

官方定性:settings 规则"由客户端强制执行,与 Claude 的决定无关";CLAUDE.md"塑造行为但不是硬强制层"。

检查器不是执行门。 linter、formatter、类型系统和测试只有接入 CI required check、pre-commit、PostToolUse 或 Stop hook 后,才构成第 1 层约束。单独存在的配置只能判定结果,不能保证它会被运行。


核心动作:给一条候选规则定层

任何"要不要加这条""该放哪"的问题都走这个流程。默认答案不是"加到 AGENTS.md"。

候选规则
  ↓
① agent 读代码能自己知道吗? ──────────── 能 ──→ 不写。删。
  ↓ 不能
② 能在检查器中表达规则吗? ───────────── 能 ──→ 先在检查器中表达规则,再按执行时机和失败成本选择门禁(第 1 层)
  ↓ 不能
③ 是"必须发生、零例外"的动作或禁令吗? ─── 是 ──→ hook 或 permissions(第 1 层)
  ↓ 否
④ 删掉它,会导致一个你能具体命名的错误吗? 不能 ─→ 不写。这是投机性规则。
  ↓ 能
⑤ 每个任务上都该被执行吗? ───────────── 不是 ─→ 第 3 层
  ↓ 是                                          ├ 只在某类文件上成立 → path-scoped rule
  ↓                                             └ 是多步流程/检查清单 → Skill
⑥ 需要被反复应用吗(每个函数/每个文件/每次提交)?
  ↓                                       是 ──→ 写进第 2 层,**并且**配 hook 兜底
  ↓ 否
写进 AGENTS.md,一行祈使句,HTML 注释里记下触发它的那次失败

第 ⑥ 步不是保守,是算术:反复应用的规则在文件层必然漏,hook 接住的正是那条尾巴。

第 ⑤ 步只认一个判据:「每个任务上都该被执行吗」。 不要用"这是不是项目知识"来替代它——通用的工程纪律如果对本仓库每个实现任务都成立,它就属于第 2 层,哪怕它一点也不"项目特有"。搬别处的结论而不重跑这一步,是最容易犯的错。

判到第 3 层之后再验一道:这条规则的触发词有辨识度吗? Skill 靠模型判断 description 匹配来唤醒,"写代码"这类默认活动唤不醒(见 LAYER3-ONDEMAND.md)。唤不醒就退回第 2 层。

另外单独问一句:这条规则会引发多少读取? 五问只审规则本身的字数,审不出它的连带成本。"实现前先读 A、B、C"本身两行,引发的可能是每会话几万 token——而且指令会被真的执行,这个成本是实打实的。这类规则要么改成"遇到某类问题时再参考",要么直接删。

只在这一次任务里成立的,根本不要进任何文件——直接写在 prompt 里(第 4 层)。


各层落地要点

第 1 层:确定性执行

三种机制,按"能不能被绕过"排序:

需求 机制
禁止读/改某路径 permissions.deny 的 Read(...) / Edit(...) 规则
禁止某类命令 permissions.deny 的 Bash(...) 规则
编辑后必须跑检查 PostToolUse hook,matcher Write|Edit
按内容动态拦截 PreToolUse hook,退出码 2 阻止
结束前必须验证通过 Stop hook,退出码 2 阻止结束回合
任何进程都不许碰 开启 sandbox(权限规则管不到子进程;不要只用 CI 替代这个客户端隔离)

检查器(linter / 类型检查 / 测试)本身不在这张表里——它要先接进一道门才算数。四道门(PostToolUse / Stop / pre-commit / CI required check)按执行时机和失败成本怎么选,见 LAYER1-ENFORCEMENT.md 的「把检查器接成执行门」。要点:pre-commit 一个 --no-verify 就绕过,红线只能靠 CI required check;而 CI 看不到 agent 在本地干的活,会话内要拦还得配 hook。

最常踩的三个坑(详见 LAYER1-ENFORCEMENT.md):

  1. 文件路径规则只认 Edit(...) 和 Read(...)。写 Write(docs/**) 会被接受但永不生效。
  2. Bash(command:rm *) 这种参数形式会被忽略并告警,要写 Bash(rm *)。
  3. Read/Edit 的 deny 规则挡不住任意子进程(比如一个自己打开文件的 Python 脚本),要 OS 级隔离得开 sandbox。

第 2 层:常驻指令

只放无法自动化、又无法从代码推断、且全局恒真的内容。

准入之后的写法:祈使句 + 精确命令、可验证的完成标准、显式 Never、最多一处强调、零冲突。

绝不要写:目录结构、技术栈概览、架构说明、README 复述——实证判定无收益且制造双事实源。

模板在 templates/,完整写作规范、修剪流程和反模式清单在 LAYER2-INSTRUCTIONS.md。

第 3 层:按需加载

内容形态 机制
只在某类文件上成立的规则 .claude/rules/*.md + paths: frontmatter(Copilot 用 applyTo)
多步骤流程、检查清单 Skill
大段参考资料、API 规格 Skill 的附属文件(不进 SKILL.md 主体)

判据:如果一段内容在多数任务里都用不到,它就不该每次进上下文。 CLAUDE.md 里长成流程的那一节,应当搬到 Skill。

写法见 LAYER3-ONDEMAND.md。

第 4 层:会话层

不需要持久化的东西留在这里,别污染前三层:

  • 一次性的复杂任务 → 写 SPEC.md,然后开新会话执行(干净上下文 + 书面规格)
  • 不确定方案时 → plan mode,先探索再动手
  • 长任务的持续目标 → /goal,独立评估器每回合复查
  • 同一问题纠正两次仍未解决 → /clear 重开,带着学到的东西重写 prompt,比在污染的上下文里继续纠正更有效

工作流

A. 新建一套约束

  1. 先看仓库有没有像样的 README 和 docs。几乎没有 → 上下文文件价值显著更高(这是唯一被证实有正收益的场景);文档齐全 → 严格执行定层流程。
  2. 先建第 1 层:把已有的 linter、formatter、测试命令接上 hook。这些是免费的确定性。
  3. 复制 templates/AGENTS.md,先删后填——删掉所有还没遇到过对应失败的条目。宁可从三行开始。
  4. 不要跑 /init 然后直接提交。自动生成的内容大多复述既有文档,实测降低成功率。

B. agent 犯了错

触发条件是第二次犯同一个错,不是"想到一条好规则"。走定层流程。多数情况下正确出口是第 1 层,不是加一行文字。

C. 治理体检

用户说"CLAUDE.md 太长了""agent 不听指令"时用这个。

  1. 读所有相关文件。两类都要读,缺一不可:

    • 第 2/3 层:AGENTS.md、CLAUDE.md、.claude/rules/、.claude/skills/
    • 第 1 层现状:.gitignore、.pre-commit-config.yaml、CI 配置、linter/formatter 配置、.claude/settings*.json 及已有 hooks

    不读第 1 层就无法执行"已被覆盖 → 删"这条判定——那是产出最高的一条。

  2. 逐条重新定层——多数积累下来的条目本该在别的层。判定表见 LAYER2-INSTRUCTIONS.md。

  3. 检查缺什么:安全与性能边界只有约 15% 的项目写,却最不可能从代码推断。

  4. 检查冲突:父子目录文件之间、CLAUDE.md 与 rules 之间。矛盾时模型可能任意挑一条。

  5. 输出建议清单(删除/迁移/补充,各自附理由),让用户确认后再改。

D. 委派子 agent 编写并验证约束

编写约束是一件与当前编码任务无关、且需要独立验证的工作。放在主线程里做会污染上下文,也容易草草了事。

什么时候委派:确认了要新增/修改第 1 层或第 3 层的产物(hook、权限规则、Skill、path rule),且当前主任务尚未完成。第 2 层的一行文字改动不值得开子 agent,直接改。

交给子 agent 的任务描述必须自包含,它看不到你的对话:

  • 要解决的具体失败:agent 做了什么、造成什么后果
  • 已经做过的定层判断和理由(不要让它重新决策)
  • 目标产物与落点(哪个文件、项目级还是用户级)
  • 明确要求它验证,并把验证证据带回来

验证要求(这一段必须写进任务描述,否则会得到"写好了"而没被验证过):

产物 怎么验证 陷阱
权限规则 跑 claude doctor 看 resolved settings;启动时的无效设置告警 静默失效的规则不会报错,只会告警(见 LAYER1-ENFORCEMENT.md 的三个坑)
hook 实际触发一次匹配的工具调用,确认它 fire 了 退出码语义搞反是最常见错误:PostToolUse 阻止不了已执行的调用
Skill 一律新开会话验证——新装、改 description、改正文都是 正文走异步缓存,比磁盘落后一拍:改完立刻重调用拿到的是上一版,中间那次还会回 "instructions unchanged"。在旧会话里改一版调一次,验的不是你刚写的东西
path-scoped rule 读一个匹配的文件,确认规则进了上下文 没有 paths 的规则是无条件加载的,等于第 2 层

要求它带回来的是证据,不是结论:跑了什么命令、输出是什么。「已验证通过」这四个字没有信息量。

边界:子 agent 只负责写和验证约束产物,不要让它顺手改业务代码。主线程收到结果后自己决定是否采纳。

E. 定期复盘(触发入口)

约束的触发条件是「第二次犯同一个错」,这是跨会话的信号,所以不做实时判断,只做记录 + 定期复盘。记录机制的装法见 hooks/README.md。

建议节奏:每周,或每积累 15–20 个会话一次。不要每个会话都做——噪声大于信号。

  1. 收集。两个信号源都看:
    • ~/.claude/constraint-review.log(SessionEnd hook 的记录)——哪些会话值得回看
    • ~/.claude/projects/<project>/memory/ 下 type: feedback 的文件——auto memory 已经消化过的纠正
  2. 找重复。只关心出现两次以上的纠正或失败。出现一次的不动——那是投机性规则的来源。
  3. 每个重复项走定层流程。多数出口是第 1 层,不是加一行文字。
  4. 确认要做的,走工作流 D 委派子 agent 编写并验证。
  5. 输出:这一轮发现了什么重复模式、各自定到哪一层、做了什么、还有什么建议但没做。

复盘时要一并检查的:第 2 层文件是否又长了?有没有已被 CI 覆盖、可以删的条目?(这类文件会像配置代码一样通过频繁小幅增补持续膨胀,熵增是默认的。)


尺寸与跨工具

单文件目标 100 行以内。Claude Code 建议 CLAUDE.md 控制在 200 行内;Codex 合并上限默认 32 KiB,达到上限后停止继续加入文件;Copilot 建议不超过两页。

写短的理由是成本和"少拉杠杆",不是"短则遵从度高"——两项研究都没测到长度与遵从度的关系,数据趋势甚至相反。不要为压行数删掉真正有用的约束。

以 AGENTS.md 为单一事实源,CLAUDE.md 用 @AGENTS.md 导入并承载 Claude 专属内容。绝不维护两份。

验证加载:/context 看 Memory files;Codex 用 codex --ask-for-approval never "Summarize current instructions"。


验证一条约束是否有效

任务类型对合规率的影响达 39 个百分点、模型 12.8 个、代码库 11.0 个——都远大于文件怎么写。别人的结论不可移植,包括本 Skill 的。

有规则与无规则各跑至少三次代表性任务,记录是否达成、步数、token、是否触发了担心的那个错误。没有可观测差异就删掉——成本确定,收益不确定。

但要诚实告知用户:原研究用每条件 50 次运行才对 15 个百分点的差异达到足够功效。跑三次看不出 10 个百分点的差别,小规模验证只能筛掉完全无效的规则。

第 1 层的约束不需要这样验证——它是确定性的,写对了就一定生效。这也是它优先于第 2 层的另一个理由。