桃子桃子快讯
←返回首页
工具

在执行层为 AI 智能体加一道闸:ctrlrun 开源工具

ctrlrun 是一个 Apache-2.0 的 Python 库,在智能体调用工具前校验参数与权限,防止重复、越权与错…

2026.09.25 · 周五约 4 分钟阅读

随着 AI 智能体(agent)逐步接入支付、退款、部署等高风险操作,「模型决定调用某个工具」与「真的发出请求」之间的鸿沟被越来越多开发者意识到。开源工具 ctrlrun 正是填补这一缺口:它是一个 Python 库,部署在智能体进程内部,在每一次外部调用真正发出前,按规则判定「放行」「请求人工审批」或「直接拒绝」,并为每次动作生成可回溯的收据(receipt)。

核心思路:模型可以猜,ctrlrun 不猜

ctrlrun 的设计者认为,模型本身对「应不应该退款 500 欧元」可以非常自信地犯错——例如把金额多写一个零。要拦截这种错误,不能依赖模型的判断,只能在调用真正离开本进程前检查参数本身。库的定位因此十分明确:「可被调用」不等于「被允许这样调用」。

库内置的策略由四种规则构成:

  • Exact means exact:参数变更需要重新审批,避免审批后被替换。
  • Once stays once:通过 effect key 与共享存储,保证同一后果只生效一次。
  • Unknown means wait:结果未知时显式返回 AMBIGUOUS,而不是 FAILED,杜绝盲目重试。
  • Every answer is kept:请求、决策、结果、拒绝全部留痕。

演示覆盖的五类失败

ctrlrun 自带一个本地 demo,策略示例为「500 欧元以内自主退款、10000 欧元以内需人工审批、以上全部拒绝」。在不到一秒、纯本地、无外部服务的情况下,它重现并拦截五类典型事故:

  • 重复执行:远程已提交、响应丢失,智能体重试同一退款 → 因 effect key 已记录为 AMBIGUOUS 而被拒绝。
  • 审批替换:人工批准了 2000 欧元,智能体实际请求 5000 欧元 → 因 action hash 不一致被拒。
  • 并发抢占:两个智能体同时尝试处理同一笔退款 → 后者因 effect 已 ACQUIRED 被拒。
  • 审批重放:单次使用的审批 ID 第二次提交 → 被识别并拦截。
  • 权限越级:客服智能体被授予 2000 欧元额度,却尝试 50000 欧元 → 因超出 delegated grant 被拒;连上游财务智能体想越权下放额度也会被拒绝。

demo 会把所有决策写入 .ctrlrun/demo/receipts.jsonl 与 events.jsonl,便于审计。

三步上手

使用流程被作者刻意压缩到最小:

  1. 安装:pip install ctrlrun。
  2. 写策略文件 ctrlrun.yaml,金额采用最小货币单位(整数),例如 50000 即 500 欧元;金额下限与上限都要显式声明,避免负数绕过;任何未列出的 action 默认拒绝,无默认放行。
  3. 在智能体调用工具前插入 ctrlrun 检查;敏感动作挂审批流程。

部署方式上,单机可直接用文件存储,多主机可切到 Postgres,库本身不依赖任何外部服务。

边界与不做的事

作者明确划出了 ctrlrun 不覆盖的范围,以免造成误解:

  • 不检测提示词注入(prompt injection),它控制的是「后果」而非「原因」。
  • 对不受控的远端无法承诺 exactly-once,只能拒绝「明知会执行两次」的操作,且不做回滚。
  • 收据采用链式结构可发现篡改,但对尾部截断与伪造追加无能为力——这一项由配套的 ctrlrun anchor 负责。
  • 收据未签名,「能发现被改」不等于「能证明作者身份」。
  • 项目 README 中的徽章仅表示「在所跑配置下声明的保证通过」,并不等同于安全、合规或通过审计。

如果智能体只读不写,作者建议直接跳过 ctrlrun;一旦它具备「发送、支付、退款、删除、部署、授权、撤销、审批、提交、购买、取消」等任一能力,就值得把它接进调用链路。整体来看,ctrlrun 是一份面向 AI 智能体执行安全的小而清晰的开源实现,适合作为生产级 agent 系统中的「最后一道闸」组件进行评估。

信源