1. 当 AI Agent 真的敲下 rm -rf,你只剩两秒钟后悔
先说结论:Destructive Command Guard(下称 dcg)是一个用 Rust 写的命令拦截钩子,它挂在 AI Agent 执行 shell 命令之前,把rm -rf、git reset --hard、DROP TABLE这类破坏性操作拦下来,把决定权交还给你。它适合谁?适合每天用 Claude Code、Cursor、Codex 这类工具写代码,又不想某天醒来发现src目录没了的开发者。核心检索词就三个:AI Agent 自动执行命令、破坏性命令拦截、Rust 实现的 PreToolUse 钩子。
我见过太多类似的翻车现场。你让 Agent「清理一下临时文件」,它理解成rm -rf ./tmp还算客气,理解成rm -rf ./src就直接把你三小时没提交的代码送走。你让它「把 Git 状态重置一下」,它给你来一发git reset --hard HEAD~5,未提交的改动全没了。问题不在于模型笨,而在于 AI Agent 对「破坏性」的权重判断和人类不一样——它知道这条命令会删东西,但它不知道你当前工作区里那些未提交的改动值多少钱。
dcg 的思路很朴素:在命令真正落到 shell 之前,加一道门。命令先过一遍规则引擎,命中危险模式就拦,输出拦截原因和替代建议;判断安全就放行,整个判断延迟小于 1 毫秒。它不是防火墙那种「一刀切禁止」,而是「增加摩擦」——让你在危险操作前多一次确认的机会。这篇文章我会带你从零复现一次拦截:装好 dcg、配好 Claude Code 钩子、故意触发一次rm -rf,看它怎么把命令挡下来。同时我会说明怎么用 TaoToken 统一管理调用凭证,让 Claude Code 这类工具的 Key 通道集中在一处,避免到处散落 API Key。
2. TaoToken 前置:把 Claude Code 的 Key 通道收拢到一处
在讲 dcg 配置之前,得先把「谁在调用模型」这件事理清楚。dcg 拦的是命令执行层,但命令是 AI Agent 生成的,Agent 又依赖模型 API。如果你同时用 Claude Code、Cline、Codex 好几个工具,每个工具各配一套 Key,管理起来就是灾难:哪个 Key 快到期了、哪个额度用完了、哪个该轮换了,全靠脑子记。TaoToken 在这里扮演的角色是统一 Key/API 通道——你在一处管理凭证,各个工具通过同一个 Base URL 接入。
具体来说,TaoToken 提供兼容主流模型协议的 API 端点,Claude Code 这类工具只需要改 Base URL 和 Key 就能接上。官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 端点是 https://taotoken.net/api (这个不加 UTM)。注意,这里说的是「统一通道」,不是让你绕过什么——它就是一个正常的 API 聚合入口,帮你把多个模型的调用凭证集中管理。
为什么这件事和 dcg 有关?因为 dcg 的拦截日志里会记录「哪个 Agent 在什么上下文下尝试执行了什么命令」。如果你的 Agent 调用通道是统一的,你就能把「模型调用」和「命令执行」两条链路对上:某次拦截是因为哪个会话、哪个任务触发的。反过来,如果 Key 散落在五六个工具里,出了事你连是哪个工具干的都查不出来。
我自己的做法是:所有需要模型 API 的编码工具,Base URL 统一指向 TaoToken 的 API 端点,Key 用同一个。这样轮换 Key 的时候只改一处,工具侧不用动。Claude Code 的配置在~/.claude/settings.json或者环境变量里,Cline 在插件设置里填 Base URL 和 Key,Codex 走~/.codex/auth.json。下面第三节我会给出可直接复制的配置片段。
需要提醒一点:TaoToken 是凭证通道,不是编辑器替代品,也不是让你跳过任何本地安全措施的捷径。dcg 该装还得装,本地拦截层和 API 通道层是两回事,别混为一谈。
3. 可复制配置:dcg 安装 + Claude Code 钩子 + TaoToken 通道
这一节全是能直接抄的配置。先装 dcg。官方提供了一键安装脚本,会自动检测平台并配置 Claude Code 钩子:
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/main/install.sh?$(date +%s)" | bash -s -- --easy-mode如果你不想用管道执行远程脚本(这个谨慎是对的),可以先把脚本下载下来看一眼再跑:
curl -fsSL -o dcg-install.sh "https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/main/install.sh" less dcg-install.sh bash dcg-install.sh --easy-mode装完之后验证一下二进制在不在:
which dcg dcg --version接下来是 Claude Code 的钩子配置。dcg 的 easy-mode 一般会自动写入,但手动配一遍你才知道它到底改了什么。打开~/.claude/settings.json,加入 PreToolUse 钩子:
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "dcg" } ] } ] } }这段配置的意思是:每当 Claude Code 准备执行 Bash 类工具调用时,先把命令负载通过 stdin 传给dcg,dcg 返回拦截或放行。matcher限定为Bash,不影响文件读写类工具。
然后是 TaoToken 通道的配置。Claude Code 支持通过环境变量指定 API 端点,你可以在 shell 配置里加:
export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="你的_TaoToken_Key"如果你用的是 Codex,配置在~/.codex/auth.json:
{ "base_url": "https://taotoken.net/api", "api_key": "你的_TaoToken_Key", "model": "claude-sonnet-4-5" }Cline 这类 VS Code 插件则在设置面板里填三项:Base URL 填https://taotoken.net/api,API Key 填你的 Key,Model ID 填你要用的模型标识。三件套缺一不可——Base URL、Key、Model ID,少一个都会报连接错误。
dcg 自身的规则包配置在~/.config/dcg/config.toml(路径以实际安装为准)。默认的core.filesystem、core.git、system.disk已经开启,想加数据库和容器防护就补上:
[packs] "db.postgres" = true "db.redis" = true "containers.docker" = true "k8s.kubectl" = true配好之后,dcg 会在每次命令执行前跑四阶段流水线:解析 JSON 负载、规范化命令路径(把/usr/bin/git归一成git)、SIMD 加速的快速子串过滤、最后做模式匹配。整个过程有 200ms 绝对超时,超时就 fail-open 放行——这个设计很关键,它保证 dcg 自己出 bug 时不会卡死你的工作流。
4. 验证请求:故意触发一次 rm -rf 看拦截效果
配置写完不验证等于没配。这一节我们做一次完整的触发实验。先确认 dcg 能独立工作,不依赖 Claude Code。dcg 支持从 stdin 读 JSON 负载,模拟 PreToolUse 的输入格式:
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf ./src"}}' | dcg如果拦截生效,你会看到类似这样的输出:
════════════════════════════════════════════════ BLOCKED dcg ──────────────────────────────────────────────── Reason: rm -rf on non-temporary directory destroys files Command: rm -rf ./src Tip: Use 'rm -rf /tmp/...' for temp files, or confirm the path. ════════════════════════════════════════════════再测一个应该放行的合理操作:
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /tmp/build_cache"}}' | dcg这条应该正常通过,因为/tmp下的临时目录删除是合理操作。如果它也被拦了,说明你的规则配置有问题,检查core.filesystem的临时目录白名单。
接着测 Git 类拦截:
echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard HEAD~5"}}' | dcg预期输出会提示git reset --hard destroys uncommitted changes,并建议你先git stash。
现在做真实场景验证:打开 Claude Code,让它执行一个会触发拦截的任务。你可以直接输入「帮我删除 src 目录下的所有文件」,Claude Code 生成rm -rf ./src后,PreToolUse 钩子会先调用 dcg,命令被拦下,Claude Code 会收到拦截信息并转述给你。这时候你有三个选择:换一个安全的命令、用DCG_BYPASS=1临时绕过、或者用dcg allow-once <code>做一次性豁免。
验证 TaoToken 通道是否通,可以用一个最简单的请求:
curl -s https://taotoken.net/api/v1/messages \ -H "x-api-key: 你的_TaoToken_Key" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{"model":"claude-sonnet-4-5","max_tokens":32,"messages":[{"role":"user","content":"ping"}]}'返回里有正常的content字段就说明通道通了。如果返回 401,往下看第五节。
5. 本篇常见错排查:401、local proxy failed、reading choices、OAuth
配置过程中最容易撞的几类报错,我按实际遇到的频率排一下。
401 Unauthorized。九成是 Key 没配对或者 Base URL 写错了。检查三件事:Key 是不是复制时带了空格、Base URL 是不是https://taotoken.net/api(注意结尾没有多余的/v1,具体路径以文档为准)、请求头字段名对不对。Claude Code 用x-api-key,有些工具用Authorization: Bearer,别搞混。如果 Key 确认没问题还是 401,去控制台重新生成一个 Key 试试,排除 Key 被禁用或过期的可能。
local proxy failed。这个报错通常出现在工具试图走本地代理但代理没起来的时候。检查你的环境变量里有没有残留的HTTP_PROXY、HTTPS_PROXY指向一个已经关掉的本地端口。清掉这些变量再试:
unset HTTP_PROXY HTTPS_PROXY ALL_PROXYError reading choices / reading choices。这是 OpenAI 兼容格式的响应解析错误,一般发生在你用的工具期望 OpenAI 格式但端点返回了别的格式,或者反过来。确认你的工具和端点协议匹配:Claude Code 走 Anthropic 格式,Cline 可以选 OpenAI 兼容模式。如果工具里能选协议,选对了再试。
OAuth 相关报错。有些工具默认走 OAuth 登录流程,你配了 API Key 但它还在尝试 OAuth。去设置里把认证方式从 OAuth 切成 API Key。Codex 的话检查~/.codex/auth.json里是不是同时存在 OAuth token 和 api_key 字段,冲突时删掉 OAuth 部分。
dcg 不拦截。先确认钩子真的注册了:cat ~/.claude/settings.json看 PreToolUse 段在不在。再确认 dcg 二进制在 PATH 里:which dcg。如果都正常但就是不拦,用第四节的 stdin 测试法单独测 dcg,排除是钩子调用的问题还是规则的问题。还有一种情况:命令走了DCG_BYPASS=1或者命中了一次性豁免,检查环境变量和 allowlist。
拦截太频繁误报。dcg 的上下文感知会区分「命令字符串出现在数据里」和「命令真的被执行」。如果你grep "rm -rf" README.md被拦了,那是 bug,去提 issue。但如果你echo "rm -rf /"被拦,那是设计如此——它无法百分百确定你不是在构造一个要执行的字符串。这种情况用dcg allowlist add加白名单。
6. 语义一致 CTA:把凭证通道和拦截层一起用起来
dcg 解决的是「命令执行前」这一层,TaoToken 解决的是「模型调用凭证」这一层,两者配合起来才是完整的 AI Agent 安全实践。你可以在 TaoToken 控制台集中管理所有工具的 Key,轮换时只改一处;同时在本地用 dcg 拦住那些不该执行的命令。两条链路各管各的,互不干扰。
如果你还没配 TaoToken 通道,可以从 API Keys 页面开始:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。接入细节看文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。想先验证模型通不通,用模型对话页面发一条测试消息:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。如果你长期用 Claude Code 做编码或者跑 Agent 任务,Coding Plan 会更划算:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
最后给一个实用技巧:dcg 的scan模式可以扫你仓库里已经存在的危险命令,适合在 CI 里跑一遍:
dcg scan ./ --include "*.sh,*.yml,Dockerfile,Makefile"它会区分 Dockerfile 里RUN rm -rf /var/cache/*(构建层合理)和 workflow 里kubectl delete namespace prod(值得关注)。装 dcg 的成本就是一条安装命令,但它给你的安全边际,在你第一次看到BLOCKED提示的时候就已经回本了。