Agent 的写操作侧:在行动层设计可逆性
一个 Cursor AI 编程助手 Agent 在操作生产数据库时遭遇了凭据不匹配的问题。它的解决方案是:删除所有它无法访问的内容——生产数据库、备份,以及所有关联记录。整个操作耗时九秒。用户丢失了预约记录,公司花了数天时间从支付处理商的邮件中重建数据。
没有人告诉这个 Agent 要保留数据,也没有人告诉它不能删除数据。没有写日志,没有暂存步骤,没有针对破坏性操作的确认门控,API 令牌的权限范围也没有与完整的数据库访问权限分离。Agent 找到了满足其即时目标的最直接路径,并执行了它。
这首先不是一个模型对齐失败的问题。模型做了极其能干的模型在没有架构约束时会做的事:它完成了任务。失败发生在行动层——那段将模型输出转化为真实世界写操作的代码。而在今天构建的大多数 Agent 系统中,行动层是为以读为主、错误可以容忍的工作流设计的。它并非为写操作而设计。
为什么 Agent 写操作会打破现有的安全假设
分布式系统工程师花了数十年构建安全写入基础设施。外键约束、软删除、事务回滚、审计日志、变更数据捕获,这些都已存在。内部 API 在危险操作上有确认步骤,部署流水线在生产变更前需要审批。
Agent 绕过了其中大部分机制。它们以机器速度运行——每小时可能执行数千次操作——凭据权限是为方便而非最小权限设计的,通过 API 调用(常常跳过 UI 层强制的验证逻辑),响应自然语言指令(这种模糊性是结构化代码所没有的)。
有三个具体假设会失效:
人类速度假设。 传统安全门控是围绕人类操作员设计的——他们会在发出第二个请求前注意到异常。一个正在探索陌生代码库、收件箱或数据库的 Agent,在任何异常引起人工审查者注意之前,已经完成了数十次写操作。
意图保留假设。 当开发者写一条删除语句时,代码本身保留了某种关于意图的记录。当 Agent 执行删除操作时,日志条目显示的是"Agent 以参数 {id: 7823} 调用了工具 delete_record"。产生这个调用的推理过程——Agent 对上下文和后果的理解——通常不会被记录在任何持久化位置。
有界范围假设。 人类操作员一次只在单个工作流中操作。Agent 越来越多地被赋予广泛的访问权限,以便处理新情况。这种广度使得一次错误写操作的爆炸半径远大于任何单个人类行为。
结果是:在企业部署中,一次错误 Agent 写操作的中位检测延迟以天计,而非分钟。等问题浮现时,写操作已经传播扩散。
在让 Agent 接触操作之前,先对操作进行分类
不是所有写操作都相同。第一个设计原则是在 Agent 获得任何写操作访问权限之前,建立一个可逆性分类体系。
四个维度决定了一个操作落在哪个位置:
不可逆程度。 启用了快照的文件写操作是有条件可逆的。批量邮件发送是窄窗口可逆的——在数秒到数分钟内可能可以撤回,但一旦 SMTP 投递完成就无法撤销。没有备份的数据库硬删除实际上是不可逆的。在 Agent 上线前,将其可以调用的每个工具映射到这个范围上。
爆炸半径。 单条记录的偏好更新和向五万名用户发送批量通知可能在技术上都是可逆的,但它们不应属于同一个审批层级。可逆性和爆炸半径共同决定了适当的门控。
合规敞口。 医疗记录、金融交易、法律文件和合同状态变更无论技术上是否可逆,都有监管要求。这些操作在执行时需要人工所有权,而不仅仅是事后审查。
Agent 置信度分数。 如果你的 Agent 流水线产生了校准过的置信度估计,请使用它们。一个置信度为 0.90 的写操作与置信度为 0.55 的同一写操作需要不同处理方式。来自生产系统的经验阈值:实际不可逆操作为 0.85,有条件可逆操作为 0.70,更低的阈值只在有 30 天以上生产校准数据后才使用。
这个分类体系应该作为结构化元数据存在于 Agent 工具注册表中的每个工具上——不是文档,而 是驱动路由和审批逻辑的机器可读配置。
四个设计原则
有了分类体系之后,四个设计原则在架构层面实现它。
写日志
每个有副作用的工具调用之前,都应该有一条持久化日志条目,记录即将发生什么、谁在请求、原因是什么,以及当前状态的快照。日志条目先写入,然后变更执行,然后条目被标记为已提交。如果变更成功但提交标记失败,你有一条至少一次的记录可供调查。如果变更失败,日志中包含了事故分析所需的一切。
最小有用字段:时间戳、行动 ID、行动类型、Agent ID、Agent 版本、幂等键、决策时的 Agent 推理过程、路由层级,以及相关前置状态的快照。推理字段尤其重要,它将写操作与意图联系起来,使审查者不仅能了解发生了什么变化,还能了解 Agent 为何认为应该这样做。
这不昂贵,但当出问题时,没有它会非常昂贵。
