P3 multi-agent-case 问题日志AI工程Synapse

AI自动化时间窗口设计:让守护规则与自动化任务和平共存

当AI安全守卫(CEO Guard)与无人值守的定时任务产生冲突时,时间窗口豁免是优雅的架构解法

当守护规则遇上定时任务:一次架构冲突的复盘

前阵子我在给团队的 AI CEO 加了一套叫 CEO Guard 的守护规则:主对话里禁止直接调用 Bash、Edit、Write 等高风险工具,所有实际操作必须派单给子 Agent 执行。这个规则在人在线的场景下运行得很好 —— 它逼着 CEO 先承接目标、再分派、最后审查交付,避免了”头脑一热直接动手”式的事故。

但两周后定时任务上线,问题来了。我配置了三个 cron 触发的远程 Agent:6 点恢复阻塞任务、8 点抓情报日报、10 点执行情报行动。这些任务本质上需要代码级别的执行能力 —— 读文件、跑脚本、提交 git。但它们都从 CEO 入口进来,被 Guard 无差别拦截,第二天早上起来一看日志,三个任务全部卡在”等待派单”环节,无一成功。

直觉的解法为什么都不行

我先想到的是关掉 Guard —— 简单粗暴。但这等于白建了安全机制,只要有一条绕过通道,人为操作一定会走那条通道。放弃。

第二个想法是给定时任务一个”永久豁免标签”,让它们绕过 Guard。但这意味着任何持有那个标签的上下文都能无限制执行 —— 如果哪天 prompt injection 伪造了这个标签,守护机制直接裸奔。也放弃。

第三个想法是把定时任务完全拆到另一套身份体系,不走 CEO 入口。技术上可行,但维护成本翻倍:两套上下文、两份工具白名单、两处日志。对一个小团队来说这是过度工程。

时间窗口豁免:用维度隔离代替权限裁剪

最后采用的方案是时间窗口豁免。Guard 逻辑本身不变,但它在判断”是否拦截”时多读一层上下文:当前触发时间是否落在预先登记的自动化窗口内。落在窗口内就放行,落在窗口外就维持原有拦截。

具体实现很轻:我在 harness/automation-windows.yaml 里登记了三个窗口,每个窗口写明起止时间(Dubai 时区)、对应的任务 ID、允许的工具子集。PreToolUse hook 在拦截前先做三件事:读当前 UTC 时间、查命中的窗口、核对本次工具调用是否在该窗口声明的子集内。命中就放行并记一条审计日志,未命中就按原规则拦截。

这套设计的关键不在代码量,而在于选对了隔离维度。权限维度的隔离(给某个身份永久豁免)会随身份泄漏而失效;时间维度的隔离天然是有界的 —— 就算某个 prompt 伪造了自动化身份,它也必须在对的时刻出现,而 cron 时刻本身在仓库里是公开的、可审计的。攻击成本被推到了”必须同时控制身份和时间”这一层,比单纯的身份豁免高一个量级。

踩过的两个坑

第一个坑是窗口边界的处理。早期我写的是”8:00 到 8:30”,结果某次日报 Agent 跑到 8:32 才发起最后一次 git push,被拦截。改成”软边界 + 任务 ID 关联”:只要任务在窗口内启动,其整个调用链在后续 60 分钟内都可继续执行,超时才拦截。这避免了长任务被时钟切断。

第二个坑是审计粒度。一开始我只记录”放行/拦截”二值,排查问题时才发现根本不知道是哪条窗口规则命中的。现在每条放行日志都会同时写入:命中的窗口 ID、任务 ID、当前时间与窗口边界的偏移、允许的工具子集。出了问题五分钟就能定位。

可复用的三条原则

**原则一:守护规则不要为自动化让路,让自动化进入守护规则的已知窗口。**安全机制的价值来自不可预测下的一致性,临时关掉等于放弃这个价值。

**原则二:豁免要选最不容易被劫持的维度。**身份、标签、token 都可能被伪造,但”当前时间”是系统级的外部事实,攻击者很难同时伪造身份和让 cron 在错误的时刻触发。

**原则三:豁免机制本身必须可审计。**每一次豁免放行都是潜在的安全缺口候选,要留下足够细的日志让人能在事后看清”为什么这次放行了”。没有审计的豁免等于后门。

如果你在构建 AI 工程团队,欢迎参考我们开源的 Synapse 框架,里面包含了 CEO Guard、时间窗口豁免、以及完整的执行链审计机制,可以直接复用或按自己的业务场景改写。