OpenShell 实际执行的是什么
运行时遏制工具(例如 Nvidia 的 OpenShell)作用于 agent 栈中的特定位置:位于模型推理之下、工具调用之上。它们拦截 agent 尝试调用工具、发送消息或写入记录的那一刻。在这个边界上,它们可以检查拟执行的操作,将其与一组规则比对,并中止执行。这很有用。但仅凭这一点,并不完整。
拦截层看到的是操作,而不是意图。当 agent 选择工具并组装参数时,遏制系统收到的是一个结构化请求:工具名称、一组参数,可能还有目标目的地。它收不到的是产生该请求的推理过程、agent 追求的目标,或它自认为所依据的授权。分类器可以对该请求进行异常评分,但它无法知道该操作是否在 agent 的职责范围内,因为从未声明过任何职责范围。
检测延迟使问题进一步加剧。即使遏制系统能在毫秒级响应,它也是在 agent 已经确定行动方向之后才响应。模型已经生成了 token、选择了工具并构造了参数。在多步轨迹中,这一个操作可能只是数十个操作之一,而先前步骤的副作用可能已经不可逆。毫秒很重要,但它们不能替代事先知道 agent 被允许做什么。
实际后果是,每一次中止都变成一次主观判断。由分类器判断该操作是否可疑。该分类器是概率性的、依赖上下文的,并且在每一步都运行成本高昂。它不是策略。它是对意图的推断,既会产生假阳性,也会产生假阴性。当它产生假阴性时,操作继续执行。当它产生假阳性时,合法操作被阻止,agent 的轨迹被打断。两种结果都不是由已声明的边界决定的;两者都由模型的猜测决定。
运行之前的契约
契约改变了问题的形态。在生成第一个 token 之前,agent 应当声明其工具面、出站目的地和支出额度。工具面是 agent 可以调用的工具集合,以及它可以使用的参数范围。出站目的地是它可以向其发送数据的端点、域名或队列。支出额度是一次运行可以消耗的某种资源(无论是 token、API 调用还是货币)的最大数量。
这种声明不是提示词指令。它是运行时可以确定性地检查的机器可读产物。当 OpenShell 式的执行机制检查的是已声明的范围,而不是推断的意图时,检查就变成了集合比较:该工具是否在已声明的工具面中,该目的地是否在已声明的出站列表中,该支出是否在已声明的额度内。答案只有是或否。没有分类器,没有延迟,没有主观判断。

契约还可以组合。子 agent 应当从父 agent 继承一个收窄的额度,而不是父 agent 的完整工具面。如果父 agent 可以访问支付 API 和消息 API,那么负责起草消息的子 agent 应当只获得消息工具,且目的地列表限制为父 agent 已批准的接收者。这不是运行时推断;这是 agent 定义的结构性属性。子 agent 无法超出其额度,因为它的额度从未被授予。
正是这一机制将遏制从恢复工具转变为预防工具。运行时不需要猜测 agent 是否打算向外部端点发送数据。该端点要么在已声明的出站列表中,要么不在。运行时不需要估计 agent 的支出是否异常。该支出要么在已声明的额度内,要么不在。契约使执行变得确定。
为什么终止开关是错误的原语
终止开关是恢复机制。契约是预防机制。只交付前者,就是把成本转嫁给事件响应。agent 运行,分类器未能捕获有问题的操作,终止开关终止运行。到那时,损害可能已经造成。
在轨迹中途终止运行会留下部分副作用。数据库中写了一半的记录。发给客户的消息只发了一半。提交了一半的事务使两个系统处于不一致状态。终止开关停止了 agent,但它不会撤销 agent 已经执行的操作。在某些系统中回滚是可能的,但它成本高昂、容易出错,而且往往不完整。事件的成本不是终止开关的成本;而是清理的成本。
遏制应当是范围检查、出站预算和能力上限之后的最后手段。范围检查防止 agent 调用其已声明工具面之外的工具。出站预算防止它发送超过已声明数量的数据。能力上限防止它提升自身权限,或生成拥有更广访问权限的子 agent。这些是确定性的、低成本的,并且可以在每一步执行。终止开关是当所有这些都失败时剩下的手段,它应当被调用得足够少,以使其成本可以接受。
诚实的权衡是,契约需要前期工作。为每个 agent 声明工具面、出站列表和支出额度,比部署运行时监控并指望分类器捕获问题要付出更多努力。契约还会限制 agent 的灵活性。如果 agent 发现对已声明工具面之外的工具存在合法需求,它不能直接使用;

一种实用的分层
一个可行的 agent 安全架构使用四层,每一层都比上一层更便宜、更确定。
第一层是在 agent 定义时的静态范围声明。agent 的工具面、出站目的地和支出额度被写入其定义中。这是一个配置产物,与 agent 的代码一起进行版本控制。它在 agent 运行之前被审查和批准。
第二层是针对已声明范围的逐步验证。在每次工具调用之前,运行时根据契约检查拟执行的操作。这种检查成本低且确定:集合成员测试、目的地比较、支出统计。它不需要模型。它不会引入延迟。它要么通过,要么失败,而失败会在任何副作用发生之前中止该步骤。
第三层是针对漂移的运行时异常检测。这正是基于分类器的工具发挥价值的地方。agent 可能停留在其已声明范围内,但其行为方式表明其目标已经漂移,或其输入已被操纵。异常检测可以标记这些模式以供审查。它是概率性的且成本高昂,因此它与确定性检查并行运行,而不是取代它们。它捕获契约无法表达的内容。
第四层是遏制和回滚,仅在第一至第三层失败时调用。终止开关停止运行。回滚尝试撤销副作用。这一层成本最高、可靠性最低,这就是为什么它应当是最后手段。它的存在是必要的,但它的调用应当很少。
论点并不是运行时遏制毫无用处。而是没有契约的遏制,就是没有定义所遏制对象的遏制。终止开关停止 agent,但它不告诉 agent 它被允许做什么。契约则告诉它。契约是预防;终止开关是恢复。只交付恢复,就是选择为事件付出代价,而不是预防事件。
封面照片:panumas nikhomkhai / Pexels。
