我是如何不再害怕 Claude Code 并学会爱上 Guard Hooks 的
想象一下:你正悠闲地窝在扶手椅里,品着咖啡,而你最喜欢的 AI 代理(无论是 Claude Code、Cursor 还是 GitHub Copilot CLI)正兴高采烈地汇报重构任务已完成。突然,终端上闪过 rm -rf,或者更好笑的是 sudo rm -rf /。咖啡卡在喉咙里,那些尚未提交的工作成果——数小时的免费劳动——瞬间化为乌有。
面对神经网络"幻觉"时的无助感很熟悉吧?在我实际使用中,这种情况发生过好几次,每次都是惨痛的教训。这就是为什么 destructive_command_guard 项目(简称 dcg)立刻引起了我的注意。它不是什么"革命性平台",只是你终端的一条非常快速且勇敢的看门狗。
这货是什么
简而言之,dcg 是一个用 Rust 编写的高性能钩子。它拦截你(或你的 AI 代理)与命令行之间的通信过程。它的唯一任务是在破坏性命令有机会造成损害之前将其拦截。
该工具支持目前 AI 开发领域几乎所有热门产品:Claude Code、Codex CLI、Gemini CLI、Copilot CLI、Cursor IDE、Grok,甚至还有 Hermes Agent 等小众选择。该工具可在 Linux、macOS 和 Windows(通过 WSL 或原生 PowerShell)上运行。
为什么普通的 grep 救不了你
你可能会想,为什么要搞一个完整的 Rust 项目,写个简单的 Bash 或 Python 脚本不就行了?项目作者 Jeffrey Emanuel 最初也是这么做的:第一版是用 Python 写的。但很快发现,现代任务需要更细致的处理方式。
上下文决定一切
dcg 不仅仅搜索字符串 rm -rf。它会分析上下文。如果代理在文档中写"不要使用 rm -rf /",钩子会理解这是数据,不会阻止文件写入。但一旦涉及实际执行命令——拦截就会启动。
为此,使用了三级验证系统:
- 通过 SIMD 指令进行快速子字符串搜索(快速拒绝)。这只需要微秒级时间。
- 命令规范化(去除多余空格,用相对路径替换绝对路径)。
- 使用正则表达式检查复杂模式。
防范"隐藏"威胁
一个有趣的功能——扫描 Heredocs 和内联脚本。如果代理决定调用 rm -rf,简单的命令行过滤器会放行。dcg 会深入这类结构内部,使用 AST(抽象语法树)解析它们,并找出可疑的函数调用。
它具体拦截什么
开箱即用,即使你没有进行任何配置,dcg 也能防护最可怕的东西:
rm -rf、sudo rm -rf /、dd if=/dev/zero。- 临时文件夹之外的
git push --force。 - 磁盘格式化、分区删除以及其他系统级"惊喜"。
但最棒的是"安全包"(security packs)。仓库中有超过 50 个。你可以在 dcg.toml 中激活针对特定技术的保护:
[packs]
enabled = [
"database.postgresql", # Заблокирует DROP TABLE
"kubernetes.kubectl", # Не даст удалить namespace по ошибке
"cloud.aws", # Спасет от случайного terminate-instances
"containers.docker", # Ограничит docker system prune
]
实际使用效果
假设你的代理决定"发疯"并重置所有更改。你会在终端中看到类似这样的内容:
════════════════════════════════════════════════════════════════
BLOCKED dcg
────────────────────────────────────────────────────────────────
Reason: git reset --hard destroys uncommitted changes
Command: git reset --hard HEAD~5
Tip: Consider using 'git stash' first to save your changes.
════════════════════════════════════════════════════════════════
拦截会附带有用的建议。在大多数情况下,代理收到这样的拒绝后,会意识到错误并建议更安全的路径,例如使用 git stash。
技术内幕与性能
打动我的是性能方案。作者声称亚毫秒级延迟。对于喜欢细节的人来说:
- Rust + SIMD:使用处理器向量指令进行闪电般的关键词搜索。
- 双正则引擎:简单模式由具有线性执行时间的快速引擎处理,而复杂模式(需要 lookahead/lookbehind 的)则由更强大但稍慢的
regex处理。 - 零分配:在热路径中,程序尽量不分配堆内存,这在钩子每次按键或代理命令时被调用的情况下至关重要。
顺便说一句,该项目实现了故障开放(fail-open)理念。如果 dcg 在分配的时间预算内(默认 200ms)来不及分析命令,它会放行。这样做是为了让工具永远不会成为妨碍正常工作的"刹车"。在我看来,这是安全性和便利性之间的合理权衡。
如何集成到工作流程中
最简单的尝试方法是运行 README 中的安装脚本。它会检测你的操作系统,下载正确的二进制文件,并在 AI 代理配置中设置。
对于 Claude Code,需要在 claude_desktop_config.json 中添加一个部分:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "dcg" }]
}
]
}
}
如果你在团队中工作,想确保没有人提交破坏性的 git push --force 或损坏的 CI 管道,可以使用扫描模式:
dcg scan --staged
你可以将它挂到 pre-commit 钩子上,它会检查你试图推送到 Git 的所有文件。
关于缺点的一些话
没有完美的工具。可能会出什么问题?
- 误报:尽管有高级解析,有时
dcg仍会拦截完全合法的命令。为此,可以通过DCG_BYPASS环境变量或DCG_UNLOCK_CODE系统进行"紧急退出"。 - 配置复杂性:如果你需要特定功能,就得深入研究 TOML 配置文件。
- Rust Nightly:如果你想从源码构建项目,需要 Rust 的 nightly 版本,因为用到了 2024 edition 的特性。
谁需要这个
如果你每周使用 AI 代理超过一次,并且信任它们在终端中执行命令——毫不犹豫地安装它吧。这是一份廉价的保险。对于可能不会立即注意到神经网络建议的"缓存清理"命令实际上会清空半个系统的新手来说,这尤其重要。
对于有经验的开发者来说,这更多是一种保护神经的方式。我们都知道在自动驾驶模式下按 Ctrl+C 有多容易,然后疯狂回想上一次备份是什么时候。
dcg 就是那个在后台静静运行、在关键时刻才"出手"的工具。它不会变魔术,只是解析字符串很在行,知道坏命令长什么样。在一个我们越来越多地将代码编写和执行委托给机器的世界里,这样的"数字保险丝"正在成为工作环境的必备属性。
值得一试,至少看看现代 Rust 软件有多快。你有没有信任过你的 AI 删除文件?结果如何?
相关项目