2026年7月10日 2 分钟阅读

Demo_CLI 实战教程:给 AI Agent 装上智能撤销,毁灭性操作一步还原

tinyash 0 条评论

Claude Code 和 Cursor 在运行危险命令前会弹出确认框问你要不要继续,但它们不会提前快照。当 Agent 执行了 rm -rf 删错目录、DROP TABLE 丢了数据库、或者 git reset --hard 毁掉了未提交的工作,确认对话框上的 “Allow” 按钮就是你最后的心理防线——点下去,就没有回头路了。

Demo_CLI 的思路截然相反:恢复是默认行为,拦截是最后手段。在每个破坏性命令执行之前,它自动快照目标文件、目录或本地数据库,生成一份防篡改的收据(Receipt)。如果 Agent 搞砸了,一条 demo_cli undo 命令就能回到快照时刻。只有当操作确实无法恢复(如 terraform destroy、远程资源删除)时,它才升级为硬拦截。

安装与初始化

Demo_CLI 是一个 Python CLI 工具,通过 pipx 全局安装:

pipx install git+https://github.com/WePwn/demo_cli.git@beta
demo_cli --version

安装完成后,进入你的项目目录,执行初始化:

cd /path/to/your/project
demo_cli init            # 生成 .demo_cli.toml 配置文件(默认 shadow 模式)
demo_cli doctor          # 验证安装:Python 版本、PATH、钩子注册状态

demo_cli doctor 是非常实用的诊断命令,它会检查 demo_cli 是否在 Claude Code 能够找到的 PATH 中。如果安装在虚拟环境内,需要保持该环境激活——否则 Claude Code 会静默跳过钩子,不做任何安全检查。

工作模式:从 Shadow 到 Enforce

Demo_CLI 有两种模式,建议按阶段切换:

Shadow 模式(默认):观察、快照、记录,但绝不拦截。这是推荐的上手方式。钩子会在 stderr 上输出捕获到的快照信息,让你看到价值而不影响 Agent 工作流。运行一周后查看收据日志,再决定是否启用强模式。

Enforce 模式:钩子主动拦截工具调用,根据操作类型做出不同响应:

判定结果钩子响应触发条件
ESCALATEdeny(拦截)不可恢复的破坏(基础设施销毁、强制推送等)
CONTEXT_MISMATCHask(暂停)声明的环境与解析到的环境不匹配
REVERSIBLE / DRY_RUNallow(放行)已快照且可恢复
ALLOWallow(放行)非修改性操作,无需处理

切换模式只需修改配置文件或指定参数:

demo_cli check "rm -rf dist" --mode enforce

shadow 模式下运行一段时间积累信任后,再切换到 enforce

与 Claude Code 集成

Demo_CLI 利用了 Claude Code 的 PreToolUse 钩子机制。每个工具调用之前,Claude Code 会运行一个外部命令,接收完整的工具输入 JSON,并返回权限决策。

注册钩子:

demo_cli install-hook    # 写入 .claude/settings.json

钩子注册后,每次 Claude Code 执行 BashEditWriteMultiEditNotebookEdit 命令前,Demo_CLI 都会自动触发:

Claude Code 即将执行: Bash(rm -rf dist/)
                             ↓
             demo_cli hook(自动触发)
                             ↓
        分类 → 解析目标 → 快照 → 决策
                             ↓
        allow(放行,附带恢复点)
        deny  (拦截,原因返回给 Agent)
        ask   (暂停,等待人工决定)

这里有一个容易被忽略的关键点:PreToolUse 钩子返回 deny 时,即使会话使用了 --dangerously-skip-permissions 模式(跳过交互式确认),钩子仍然生效。也就是说,在完全自主运行的场景下,恢复保障层依然在工作。

与 Cursor 集成

Cursor 也支持钩子机制,Demo_CLI 为其提供了独立的适配命令:

demo_cli install-hook --cursor                # 项目级(.cursor/hooks.json)
demo_cli install-hook --cursor --scope global # 全局级(~/.cursor/hooks.json)

与 Claude Code 不同,Cursor 的钩子配置必须设置 failClosed: true——Cursor 默认是”失败开放”(钩子崩溃时放行命令),而 failClosed: true 将其反转:守护程序如果无法运行就阻止执行。

要注意的是,当前 Cursor 适配器仅拦截 Shell 命令(通过 beforeShellExecution 钩子),文件编辑操作的拦截在本次 Beta 中仅限 Claude Code。

日常操作命令

一旦 Demo_CLI 开始工作,你会积累一系列恢复点(Recovery Points)。管理和使用它们非常直观:

demo_cli status          # 查看当前模式、钩子状态、收据完整性
demo_cli log             # 列出所有恢复点:ID、时间、类型、大小、操作
demo_cli diff        # 查看某个恢复点之后发生了哪些变化
demo_cli undo        # 恢复到该操作之前的状态
demo_cli verify          # 验证收据哈希链是否完整(防篡改检查)

手动测试某个命令的判定结果也很方便:

demo_cli check "rm -rf dist/"                    # 检查 rm -rf 的判定
demo_cli check "DELETE FROM users WHERE plan='free'" --db app.db
demo_cli check "terraform destroy" --actual-env production --json

check 命令返回三种退出码:0 允许、1 上下文不匹配、2 需要升级拦截。

配置文件详解

demo_cli init 生成的 .demo_cli.toml 结构清晰:

mode = "shadow"

[workspace]
dir = ".demo_cli"          # 收据和恢复点存储目录(已加入 gitignore)

[approval]
key_env = "DEMO_CLI_APPROVER_KEY"

[[target]]
match = "production"
env = "production"
recovery = "snapshot"

[[target]] 段用于声明环境匹配规则。如果 Agent 的目标是生产环境(通过 match: "production" 子串匹配),Demo_CLI 会使用该段定义的行为。环境优先级:显式 --actual-env 标志 > [[target]] 匹配 > 命令文本启发式判断。

什么能恢复,什么不能

Demo_CLI 的设计哲学是”诚实的恢复”——它只保证自己真正能恢复的操作。

快照目标:SQLite 文件、PostgreSQL(通过 pg_dump/pg_restore)、单个文件、目录(上限 256MB)。

诚实升级为拦截terraform destroykubectl deletegit push --force、远程文件系统变更、对象存储删除、外部副作用(邮件、支付、Webhook)、凭据轮换——以及非本地连接字符串的数据库操作。Demo_CLI 不会虚报那些它无法提供的恢复能力。

全环境硬拦截Remove-Item -Recurse -Force(PowerShell,包括 ri 别名和 -r/-fo 缩写)、rmdir /sdel /s|/f。这些命令递归删除整个目录树且不经过回收站,快照层无法捕获目标,因此即使在开发/暂存环境也会被拒绝。唯一合法的绕过方式是人工结构审批令牌(DEMO_CLI_APPROVER_KEY),Agent 无法伪造。

在 Python 代码中作为库使用

Demo_CLI 也提供了 Python API,可以集成到自己的工具链中:

from demo_cli import Guard

result = Guard(mode="enforce").evaluate("DELETE FROM users", explicit_db="app.db")
print(result.decision.decision)   # REVERSIBLE
print(result.permission)          # allow

为何不直接用 Git 或 Claude Code Checkpoints?

这是 README 里直接回答的问题,也是 Demo_CLI 的价值核心:Git 和 Claude Code 的后悔药无法恢复仓库之外的 rm -rf、丢失的数据库、或未跟踪文件的覆盖——它们在 Shell 命令执行之前不做快照。Demo_CLI 填补的正是这个精确的空白:在工具调用的前一刻捕获状态,而不是在事后找备份。

总结

Demo_CLI 带来的并不是又一个”拦截一切”的安全钩子,而是一种更务实的思路:大多数时候 Agent 的破坏是可逆的,给它们一个”撤销”比一个”拒绝”更有生产力。从 shadow 模式开始,零风险体验它的价值,再逐步切换到 enforce 模式——让你的 AI Agent 在不牺牲安全的前提下保持高效。

相关链接

发表评论

你的邮箱地址不会被公开,带 * 的为必填项。