| name | gateguard |
| description | 事实强制门控,阻止 Edit/Write/Bash(包括 MultiEdit)并要求具体调查(导入器、数据模式、用户指令)后才允许操作。经测量输出质量提升 +2.25 分(相比无门控智能体)。 |
| origin | community |
GateGuard — 事实强制预操作门控
一个 PreToolUse 钩子,强制 Claude 在编辑前进行调查。它不使用自我评估("你确定吗?"),而是要求具体事实。调查行为本身创造了自我评估永远无法产生的认知。
何时激活
- 在文件编辑影响多个模块的任何代码库上工作
- 数据文件具有特定模式或日期格式的项目
- AI 生成代码必须匹配现有模式的团队
- Claude 倾向于猜测而非调查的任何工作流
核心概念
LLM 自我评估不起作用。问"你违反了什么策略吗?"答案总是"没有"。这已被实验验证。
但问"列出每个导入此模块的文件"会强制 LLM 运行 Grep 和 Read。调查本身创建了改变输出的上下文。
三阶段门控:
1. 拒绝 — 阻止第一次 Edit/Write/Bash 尝试
2. 强制 — 告诉模型确切要收集哪些事实
3. 允许 — 在事实呈现后允许重试
没有竞品同时做到这三点。大多数止步于拒绝。
证据
两次独立 A/B 测试,相同智能体,相同任务:
| 任务 | 门控 | 无门控 | 差距 |
|---|
| 分析模块 | 8.0/10 | 6.5/10 | +1.5 |
| Webhook 验证器 | 10.0/10 | 7.0/10 | +3.0 |
| 平均 | 9.0 | 6.75 | +2.25 |
两个智能体都产生了能运行并通过测试的代码。差异在于设计深度。
门控类型
Edit / MultiEdit 门控(每个文件首次编辑)
MultiEdit 被相同处理——批次中的每个文件单独门控。
在编辑 {file_path} 之前,请提供以下事实:
1. 列出所有导入/引用此文件的文件(使用 Grep)
2. 列出受此更改影响的公共函数/类
3. 如果此文件读/写数据文件,显示字段名称、结构和日期格式
(使用脱敏或合成值,而非原始生产数据)
4. 原样引用用户当前的指令
Write 门控(首次创建新文件)
在创建 {file_path} 之前,请提供以下事实:
1. 命名将调用此新文件的文件名和行号
2. 确认没有现有文件提供相同功能(使用 Glob)
3. 如果此文件读/写数据文件,显示字段名称、结构和日期格式
(使用脱敏或合成值,而非原始生产数据)
4. 原样引用用户当前的指令
破坏性 Bash 门控(每次破坏性命令)
触发条件:rm -rf、git reset --hard、git push --force、drop table 等。
1. 列出此命令将修改或删除的所有文件/数据
2. 写一个一行回滚步骤
3. 原样引用用户当前的指令
常规 Bash 门控(每个会话一次)
1. 当前用户请求一句话描述
2. 这个特定命令验证或产生什么
快速开始
选项 A:使用 ECC 钩子(零安装)
此插件包含 scripts/hooks/gateguard-fact-force.js 钩子。通过 hooks.json 启用它。
如果 GateGuard 阻止了设置或修复工作,使用 ECC_GATEGUARD=off 启动会话。对于钩子级别的控制,继续使用 ECC_DISABLED_HOOKS 配合 GateGuard 钩子 ID。
选项 B:带配置的完整包
pip install gateguard-ai
gateguard init
这会添加 .gateguard.yml 用于项目级配置(自定义消息、忽略路径、门控开关)。
反模式
- 不要用自我评估替代。 "你确定吗?"总是得到"是"。这已被实验验证。
- 不要跳过数据模式检查。 两个 A/B 测试智能体都假设 ISO-8601 日期,而真实数据使用
%Y/%m/%d %H:%M。检查数据结构(使用脱敏值)可防止整类 bug。
- 不要门控每个 Bash 命令。 常规 bash 每会话门控一次。破坏性 bash 每次都门控。这种平衡在避免减速的同时捕获真实风险。
最佳实践
- 让门控自然触发。不要试图预先回答门控问题——调查本身才是提高质量的关键。
- 为你的领域自定义门控消息。如果你的项目有特定约定,将它们添加到门控提示中。
- 使用
.gateguard.yml 忽略 .venv/、node_modules/、.git/ 等路径。
相关技能
safety-guard — 运行时安全检查(互补,不重叠)
code-reviewer — 编辑后审查(GateGuard 是编辑前调查)