跳到主要内容

设计不拖垮延迟的 AI 安全层

· 阅读需 10 分钟
Tian Pan
Software Engineer

大多数团队引入护栏的方式,和引入日志一样随意:直接挂上去,以为代价很小,然后继续往下走。但代价并不小。一次内容审核检查要花 10–50ms,再加上 PII 检测,又是 20–80ms;再叠上输出 schema 校验和毒性分类器,在第一个 token 到达用户之前,串行开销就已累积到 200–400ms。加上 500ms 的模型响应,你那个"快速"的 AI 功能现在给人的感觉就是迟钝。

把锅甩给 LLM 是错的。护栏才是瓶颈。解决方案不是去掉安全措施,而是停止把安全检查当成一堆无差别的任务,改用架构思维来对待它。

安全栈的延迟解剖

不同的护栏机制运行在截然不同的时间量级上,理解这一差异是设计不叠加出数百毫秒延迟的护栏栈的第一步。

正则表达式和关键词过滤几乎是免费的——亚毫秒级、确定性执行、CPU 密集。一个设计良好的信用卡号或已知侮辱性词语的模式匹配,无论输入多长,都能在微秒内完成。

轻量级 ML 分类器——例如针对毒性或 PII 检测微调过的 BERT 量级模型——每次检查耗时 10–50ms。对于少数几个类别,串行执行的速度足够快,不会明显影响感知延迟。

基于 LLM 的评估器则完全不同。将一个完整的大模型调用用作输出判断器,最坏情况下需要 7–10 秒;即便是 Meta 的 PromptGuard(86M 参数)或 Prem AI 的 MiniGuard(600M 参数)这类较小的守卫模型,也需要精心部署才能控制在 100ms 以内。把主流前沿模型调用当毒性检测器,是一个延迟陷阱——准确,但慢到足以毁掉用户体验。

大多数团队犯的错误,是把这三个层级等同对待,然后串行堆叠。五个串行检查,每个加 50ms,在调用 LLM 之前就已经付出了 250ms。

风险分级架构

正确的心智模型是安检通道,而不是质检清单。你不会给每个人都做全身搜查——先过金属探测器,只有触发了才升级处理。

同样的逻辑适用于安全检查:

快速通道(微秒级): 正则模式、黑名单、输入长度约束、Unicode 归一化。立即拦截明显的违规。每个请求都经过这一层。

二级分析(10–100ms): 轻量级 ML 分类器——专用于 PII 检测、毒性、提示注入的小型模型。所有通过快速通道的请求都在此处理,但模型足够小,串行执行依然可行。

深度检查(秒级,仅用于模糊案例): 基于 LLM 的评估、多模型共识或人工审核排队。这一层只处理前两层标记为不确定的情况。大多数生产流量永远不会到达这里。

关键设计约束:每一层只向上传递值得进一步审查的流量。如果快速通道过滤器能捕获 95% 的明显违规,你昂贵的 LLM 判断器只需评估剩余的 5%。每个请求的平均成本大幅下降。

一个具体的基准:采用这种级联方式构建的系统,安全评估的 P50 延迟始终低于 70ms,P95 低于 120ms——这些数字在对话界面中对用户来说真正是无感的。

并行化:隐藏无法消除的成本

并非所有检查都可以通过分级来消除。某些类别需要对每个请求进行 ML 级别的评估,某些生产环境还有多个独立要求(PII、内容政策、合规监管),各自都需要独立检查。

串行运行这些检查是默认做法,也是错误做法。如果 PII 检测和毒性评估是相互独立的——事实上它们确实独立——就没有理由等一个完成再开始另一个。

Cloudflare 的 AI 防火墙是一个很好的生产案例:其架构会同时向每个检测模块发出并行、非阻塞的请求。多检查评估的总延迟由最慢的单个检查决定,而不是所有检查的总和。增加新的检测类别不会增加总延迟——只有当新类别比当前瓶颈更慢时才有影响。

实践含义:把每个安全检查当作协程,而不是阻塞调用。同时启动,统一等待结果,结果全部到达后再执行任何阻断逻辑。Python 的 asyncio 模式或任何语言的并行任务执行器都能免费实现这一点。

阻断 vs. 异步:真正重要的设计决策

并非所有安全检查都需要阻断响应。这是护栏设计中最关键的架构决策,大多数团队因为对所有内容都默认阻断而犯错。

输入检查几乎总是需要阻断。如果用户发送了提示注入尝试或针对被封锁类别的请求,你需要在 LLM 处理之前就拒绝它。允许提示通过并在事后捕获输出,成本更高,可靠性也更低。

输出安全检查需要更多权衡。某些输出违规必须阻断——你不能把一个泄露 PII 的响应流式传输给用户,然后再想办法从用户屏幕上撤回。但许多输出质量检查根本不需要同步执行。

以分析、日志记录或模型改进管道的输出 schema 验证为例。如果目标是捕获漂移或将输出标记为人工审核,在响应交付后异步运行这些验证也不会有任何问题。用户立即得到答案;你的监控管道在 200ms 后获得数据。这对于非阻断安全要求来说是正确的权衡。

心智模型:对违规后会造成即时用户可见伤害的安全属性进行阻断。其他所有内容作为审计异步运行,而不是作为门控。

流式护栏:在完成之前捕获问题

现代 LLM 应用中的流式输出模式创造了一个大多数护栏设计忽略的新优化机会:你不需要等待完整输出才开始评估。

关于部分检测方法的研究表明,分类器平均只需检查前 18% 的生成 token,就能达到 95% 以上的检测准确率。这意味着对于一个 500 token 的响应,通常可以在 token 90 处做出阻断决策并完全停止生成——节省生成剩余 410 个 token 的计算成本,并显著降低被阻断响应的延迟。

NVIDIA 的 NeMo Guardrails 流式模式将此付诸实践:在生成时按块处理输出,而不是等待完成。安全评估器在最近的 token 上维护一个滑动上下文窗口,随着内容的生成检测违规模式。安全内容立即通过,违规则触发提前终止。

工程含义:如果你已经在向用户流式传输响应,你的护栏系统应该并行流式处理,而不是评估完整缓冲区。这不是小优化——它把失败模式从"慢但正确"改变为"快且正确"。

Token 膨胀陷阱

有一类"护栏"是工程师在不把它当延迟问题思考的情况下就会去用的:在每个系统提示前加入安全政策。

"你绝不能讨论竞争对手产品。你必须始终以专业语气回应。你不得提供医疗建议……"——这些指令确实是护栏,因为它们引导了模型行为,但在每个提示中嵌入冗长的政策文本有直接、可测量的延迟成本。

系统提示中每增加 250 个 token,根据模型和基础设施的不同,首 token 时间大约增加 20–50ms。一份详尽的政策清单很容易达到 500–1000 token,给每个请求增加 100–200ms 的开销——这个开销以模型延迟的形式出现,而不是作为离散的护栏成本,因此很容易被忽视。

解决方案是将分类规则从系统提示中移出,转为外部分类检查。"绝不讨论竞争对手产品"更好的实现方式是对输入运行主题分类器,而不是写一条模型每次都要处理的 50 token 指令。分类器更快、更可靠,也不会随时间增长你的系统提示。

所有权与可观测性

护栏架构也是一个所有权问题。安全检查通常跨越多个关注点——安全、合规、信任与安全、产品——而构建护栏层的团队往往不拥有延迟预算。

结果是:护栏在设计时追求正确性,却缺乏成本意识。合规团队增加一个需要 200ms 的检查;产品团队承受了延迟影响,却对原因毫无感知。

正确的模式是:把护栏层当作有延迟 SLA 的服务来对待,而不是一堆临时拦截器。每个检查记录自身的持续时间,护栏总开销作为一级指标与模型延迟一同追踪。增加新检查的团队有责任证明它们符合预算。

影子测试是最安全的部署模式:以仅观察模式运行新检查,测量其延迟影响,测量其在真实流量上的误报率,待两者都可接受后再提升为阻断。直接在生产环境上线一个新的阻断检查,是让你在凌晨两点发现新合规要求导致 P99 延迟飙升的方式。

不可妥协的检查与其他一切

最后的设计原则是明确哪些检查真正需要在阻断路径上不可妥协。

在大多数应用中,只有少量检查真正需要同步阻断:明显的提示注入、输出中违反隐私法的 PII,以及任何违规后会造成即时法律或声誉损害的内容类别。这些检查需要在快速通道或二级分析层中,并行运行,延迟 SLA 可测量可执行。

其他所有内容——细微差别检测、质量评分、政策对齐验证、用于分析的输出分类——都属于关键路径之外。异步运行,存储结果用于模型评估,用来改进你的提示,但不要用它来门控用户响应。

那些以干净延迟曲线交付 AI 功能的团队已经内化了这种分离。他们运行快速、并行的检查,对真正的违规进行阻断;其他所有内容作为异步审计运行。他们把每一毫秒的护栏开销都当作预算分配决策,而不是实现细节。

问题不是该不该有护栏,而是你栈中的每个护栏是否值得占据阻断路径的位置,还是只是你默默接受的延迟。

Let's stay in touch and Follow me for more thoughts and updates