为什么执行边界比 AI Guardrails 更重要
Source: Dev.to
请提供您想要翻译的文章正文内容,我将把它翻译成简体中文并保持原有的格式、Markdown 语法以及技术术语不变。谢谢!
概率提示 与 确定性运行时安全
在过去的一年里,我们看到直接嵌入模型的 AI 防护措施快速提升——更好的拒绝、更安全的补全,以及日益激进的对齐调优。然而仍有一种根本性的违和感。
当 AI 代理被允许读取文件、发起网络请求或生成进程时,我们不再只面对纯对话系统;我们面对的是 代码执行。此时问题不再是 “模型会负责任地行为吗?” 而是 “责任到底归属在哪里?”
模型层面的防护基于概率。它们依赖于:
- 模式识别
- 学习到的安全启发式
- 输入与“安全”输出之间的统计相关性
这在文本生成或摘要等任务上表现尚可,但概率系统有一个不可避免的特性:它们永远无法在单次执行中保证正确性。“大多数情况下” 在以下情形下根本不够:
- 错误的文件路径导致数据删除,
- 误解的 URL 触发 SSRF,
- 微妙的提示变化绕过拒绝机制。
你可以改进提示、进行更多微调,或堆叠系统消息,但仍然是在让一个概率系统自行监管。当代理能够 行动——而不仅仅是回应——安全模型必须改变。
执行边界
执行具有语言所不具备的特性:
- 有状态,
- 有副作用,
- 往往是不可逆的。
一旦生成进程或删除文件,就没有 “用更好的提示重试” 的余地。这时 执行边界 的概念变得至关重要。执行边界是指:
- 意图转化为行动的点,
- 语言转化为效果的点,
- 概率必须让位于确定性的点。
执行边界由代码强制,而非由意图决定。它们回答的是二元问题,例如:
- 这个文件路径是否被允许?
- 这个网络地址是私有还是公共?
- 在当前策略下,这个进程是否被许可?
这些检查是 显式的、可重复的,且没有歧义。这并不是对 AI 模型的不信任,而是把保证放在实际上能够实现保证的地方。
Source: …
实际中的确定性执行边界
下面是一个简化的概念示例,展示运行时可以强制执行的确定性策略。该策略并不“思考”——它仅仅执行规则。
{
"policy": "enforce",
"rules": [
{
"id": "fs_write_limit",
"type": "filesystem",
"action": "allow",
"pattern": "/app/data/temp/*"
},
{
"id": "block_sensitive_paths",
"type": "filesystem",
"action": "deny",
"pattern": ["/etc/*", "/usr/bin/*"]
}
]
}
模型无法仅通过提示在
/app/data/temp/file.txt
上可靠地 允许 访问,同时在
/etc/passwd
上 阻止 访问,保证 100 % 的成功率。运行时执行边界可以做到这一点。
Fail‑fast vs. retry
一个常见的论点是,代理能够检测并自行修正错误。但在实际中,这种想法很快就会失效:
- 代理可能没有意识到自己越界了,
- 解释违规的上下文可能会丢失,
- 重试可能会放大损害,而不是防止损害。
Fail‑fast 系统的行为则不同:
- 不安全的操作会被立即拒绝,
- 不会产生部分副作用,
- 系统状态保持一致。
这并不是 AI 专属的概念。我们不会让数据库“尽力”去强制约束,也不会让操作系统“可能”遵守权限。代理运行时也不应成为例外。
当出现问题时,你需要明确的答案:
- 试图做了什么?
- 为什么被阻止?
- 哪条规则触发了决定?
概率性的拒绝难以审计;它们往往只能说明被拒绝了什么,却无法说明系统层面的原因。确定性的执行边界会产生以下产物:
- 跟踪记录,
- 决策日志,
- 规则评估。
这些产物对调试、合规和事件响应都至关重要。如果代理在真实环境中运行,其行为必须事后可解释,而不仅仅是在运行时“出于良好意图”。
可审计性与合规性
随着 AI 代理获得更大的自主性,单次错误的代价随之上升。在这种规模下,安全不能完全存在于模型内部;它必须位于执行边界:
- 通过确定性代码强制执行,
- 通过审计日志进行观察,
- 设计为快速失败而非迟迟恢复。
这是一种系统工程的立场,而非哲学层面的观点。系统在我们忽视其边界时往往会迅速惩罚我们。
FailCore
这段思路促使我构建了 FailCore。该项目仍在演进中,但其核心目标很简单:使不安全的操作无论如何生成都不可能被执行。