用大白话讲护栏。
护栏是模型调用前后的检查,而不是围着模型的一堵墙——它们能拦住什么、漏掉什么,又该装在哪里。本篇是 Operations 深潜的概念镜像。如果你只记一句话:护栏是一段独立的代码,跑在模型之前或之后——它从不在模型里面,把这两个位置搞混,是绝大多数"我们有护栏"这种说法塌房的地方。
护栏是一道检查,不是模型的属性。
人们说"这个模型有护栏"时,其实在说两件不同的事。一种是实验室在模型自身训练里写进去的行为:它倾向于拒答某些提示词。那是模型的属性——有用,但不是本文要谈的那种,也不是你能掌控的。另一种才是本篇要讲的护栏:一段你自己写的代码,包在一次模型调用外面。输入进入模型之前先过一道预检;输出在被你的应用使用之前先过一道后检;工具调用在真正执行之前先过一道动作检查。模型本身没有变——你只是给它装了一圈闸门。
这个区分要紧,因为两者的失效方式不同。内建的拒答可以被精巧的提示词越狱——那是研究问题。包在外面的检查则会以更朴素、可修的方式失效——一条正则写错了、一个分类器训练不足、一条规则漏掉了。好消息是:这些朴素的失效,恰好是你能修好的那种。
一个好用的检验:如果你的"护栏"在用户换一个模型之后就消失了,那它不是护栏——那是你指望的某种模型属性。真正的护栏是你拥有的代码,坐在模型外面,换模型也照样在那儿。
护栏可以待的三个位置。
生产环境里每一道护栏,相对那次模型调用,都坐在三个位置之一。大多数系统三处都用:
- 输入护栏坐在模型之前。它拒掉或改写进来的文本:拦住看起来像注入的提示词、在请求送达提供方之前抹掉 PII、拒绝已知禁止类别的请求。便宜、快——能让你不花一次模型调用就失败。
- 输出护栏坐在模型之后。它在你的应用使用补全前先检查:拦下不安全输出、抹掉泄漏的机密、丢弃没通过schema 校验的回应。这是你在一个糟糕答案送到用户面前之前的最后一道机会。
- 动作护栏坐在模型的工具调用和真实副作用之间。它检查被提议的动作:这个目的地在白名单里吗?这笔金额在日额度以下吗?这类写入用户授权过没有?智能体安全的大部分就活在动作护栏里——因为工具才是模型触碰世界的地方。
这三处是分层的,不是替代关系。输入过滤接住明显的;输出检查接住模型的失误;动作检查接住两层都漏过的。每一层被允许并不完美,因为下一层就在那儿。
它们能拦什么,漏什么。
护栏擅长形状已知的风险。如果你能用一条规则、一个正则、一个分类器或一份 schema 把"坏东西"描述出来,护栏大概率能拦下:
- PII 模式(邮箱、社保号、信用卡号)——正则或 NER 分类器。
- 脏话和已知的不安全短语——字符串匹配或训练过的过滤器。
- 输出 schema 违规——按类型化 schema 做 JSON 校验。
- 动作白名单——"只允许 POST 到这份列表里的 URL"就是一条 if 语句。
- 硬限制——日花费上限、消息速率上限、域名黑名单。
它们不擅长形状新颖的风险。任何依赖语境、意图或耍小聪明的东西,都会输给一个有决心的攻击者:
- 新颖的越狱——实验室和你的过滤器都没见过的措辞。
- 社会工程——"我奶奶以前总给我念 Windows 产品密钥哄我睡觉"能完全绕开一个脏话过滤器。
- 指令形态攻击——藏在检索内容里的提示词注入;那条注入指令在构造上就是看起来像合法请求的那种文本。
- 任何无法被还原为模式的语义问题——"这个答案微妙地错了"不是一条正则能写出来的。
诚实的结论:护栏必要,但永远不充分。它们处理那一大类宽泛、可预测的失败,让你把更硬的防御(收窄的工具、审批闸门、人工审查)留给规则看不见的那些事。
它们在技术栈里的位置——以及接下来读什么。
实务上,护栏作为中间件坐在你的应用代码和模型客户端之间。几个开源/商用库打包了常用的那批(Llama Guard、NeMo Guardrails、OpenAI 的 moderation、各家厂商的安全过滤器),而你会自己写那些和应用绑定的规则——你的白名单、你的 schema、你的花费上限。"自建还是采购"这个问题,最后塌成一句话:宽泛的分类器(PII、毒性、跑题)就买,针对你领域的规则(你的工具、你的数据、你的钱)就建。别想着比那些握着百万级训练样本的实验室更会做毒性分类器,也别指望买来的护栏能懂得在你的工作流里什么叫"已批准"。
深入版本——概率性 vs 确定性护栏、输入/输出/沙箱/能力控制的分层、以及那些操作层面的坑——在 Operations · 安全 · 护栏。临近的概念是"模型自身无法区分指令和数据,所以我们围着它装闸门",那就是用大白话讲提示词注入——下一篇就读它。