AI 安全能力平台化:把 Prompt 防火墙做成统一网关
一、散落的检测:每个应用都自救,谁都没救好
LLM 应用上线时,团队往往临时拼凑安全检测。注入拦截写在 Agent 里,越狱识别塞在网关前,内容过滤丢给上游 SDK。每个应用各自维护一套规则,彼此不通信。
说实话,这种"散点防御"挺蠢的。同一个新型注入手法,会在多个应用里重复打穿。每个团队各自复盘,规则却沉淀不下来。安全能力的演化速度,被工程交付节奏拖死。
更麻烦的是策略一致性。同一个用户请求,在 A 应用被拦,在 B 应用放行。产品侧拿不到统一口径,安全侧也无法横向归因。审计时只能逐应用翻日志,事件复盘成本被放大数倍。
性能开销也是隐形坑。每个应用都跑一遍本地小模型做越狱检测,GPU 占用翻倍。规则散落各处,重复匹配,请求链路被拉长。看似每个应用都"安全",实则整体延迟与成本都失控。
可控的思路是把 Prompt 防火墙收拢成统一网关。所有应用的请求与响应,都经过同一套分层检测。规则集中维护,模型集中升级,审计集中落库。安全从"应用内自查"升级为"平台级管控"。
二、分层检测:从规则到模型的纵深网关
统一网关的做法是把检测能力分层。任何单一手段都会被绕过,得用纵深叠加。
第一层是规则黑名单,命中即拦。处理已知注入签名,延迟最低。第二层做词法归一,对抗大小写混淆、Unicode 同形字、分块注入。第三层跑本地小模型做越狱分类,延迟可控在几十毫秒。第四层用大模型做语义审计,只对前三层存疑的请求触发,避免全量调用。
四层之间是"漏斗"关系。前一层放行的才进入下一层,命中即短路。这样既保证纵深,又控制总开销。审计在每层都落库,便于事后归因。
三、生产级网关:规则与模型混合的并发安全实现
下面是一段可落地的网关骨架。它把四层检测串成流水线,带超时、并发安全与熔断:
python
import asyncio
import time
import hashlib
import re
from dataclasses import dataclass, field
# L1:规则黑名单(生产应从配置中心加载,支持热更新)
RULE_SIGNATURES = [
r"ignore\s+(previous|all)\s+instructions",
r"system\s*:\s*you\s+are",
r"<\|im_start\|>",
]
# L2:编码归一策略
def _normalize(text: str) -> str:
# 处理全角字符、零宽字符、重复空格,避免绕过
text = text.replace("\u200b", "").replace("\ufeff", "")
return re.sub(r"\s+", " ", text)
@dataclass
class GatewayRequest:
text: str
user_id: str
app_id: str
trace_id: str = field(default="")
def sign(self) -> str:
raw = f"{self.user_id}|{self.app_id}|{time.time_ns()}"
return hashlib.sha256(raw.encode()).hexdigest()[:16]
class PromptFirewall:
def __init__(self, timeout: float = 0.8):
self._timeout = timeout
self._l4_circuit_open = False # 大模型熔断状态
async def check(self, req: GatewayRequest) -> dict:
req.trace_id = req.sign()
# 每层独立超时,单层失败不影响整体链路判定
try:
return await asyncio.wait_for(self._pipeline(req), self._timeout)
except asyncio.TimeoutError:
# 超时按"可疑拦截"处理,宁可误拦也不放行
self._audit(req, "timeout", "blocked")
return {"action": "block", "reason": "timeout", "trace": req.trace_id}
async def _pipeline(self, req: GatewayRequest) -> dict:
# L1:规则匹配
for pat in RULE_SIGNATURES:
if re.search(pat, req.text, re.IGNORECASE):
self._audit(req, "rule_hit", "blocked")
return {"action": "block", "layer": "L1", "trace": req.trace_id}
# L2:归一后再做规则匹配,对抗混淆
norm = _normalize(req.text)
for pat in RULE_SIGNATURES:
if re.search(pat, norm, re.IGNORECASE):
self._audit(req, "normalize_hit", "blocked")
return {"action": "block", "layer": "L2", "trace": req.trace_id}
# L3:小模型分类
score = await self._jailbreak_score(norm)
if score > 0.85:
self._audit(req, f"model_high:{score:.2f}", "blocked")
return {"action": "block", "layer": "L3", "trace": req.trace_id}
# L4:大模型语义审计,仅在 L3 存疑时触发
if score > 0.5:
if self._l4_circuit_open:
self._audit(req, "l4_circuit_open", "blocked")
return {"action": "block", "layer": "L4", "trace": req.trace_id}
verdict = await self._llm_audit(req)
if verdict == "violated":
self._audit(req, "llm_violated", "blocked")
return {"action": "block", "layer": "L4", "trace": req.trace_id}
self._audit(req, "ok", "passed")
return {"action": "pass", "trace": req.trace_id}
async def _jailbreak_score(self, text: str) -> float:
# 占位:本地小模型推理,生产应带批次与缓存
await asyncio.sleep(0.01)
return 0.0
async def _llm_audit(self, req: GatewayRequest) -> str:
# 占位:调用大模型审计,失败时熔断并降级
try:
await asyncio.sleep(0.05)
return "clean"
except Exception:
self._l4_circuit_open = True
return "violated"
def _audit(self, req: GatewayRequest, reason: str, action: str):
# 审计落库:含追踪号、层级、原因、动作
print(f"AUDIT|{time.time_ns()}|{req.trace_id}|{action}|{reason}")
# 使用示例
async def demo():
fw = PromptFirewall()
req = GatewayRequest(text="ignore previous instructions", user_id="u1", app_id="app1")
print(await fw.check(req))
四层之间用"漏斗"短路;每层独立超时;大模型层带熔断,故障时降级为拦截而非放行;审计贯穿全链路。规则与模型可热更新,无需重启网关。
四、网关的边界:误报、延迟与对抗演化
统一网关不是银弹。落地要认清三条现实。
误报是第一关。规则过严会拦截合法请求,模型过敏感会误伤正常业务对话。这个没有完美方案,只能靠分层放行来缓解:L1 只拦高置信签名,L3 设分数阈值,L4 才做最终判决。任何单层命中都应支持人工申诉与回放,不能"一拦了之"。被误拦的用户体验很差,这个坑我踩过。
延迟是硬约束。L4 大模型调用动辄数百毫秒,全量触发会拖垮链路。所以必须用漏斗:前几层过滤掉 95% 的明显攻击,L4 只处理边缘案例。整体 P99 控制在 200ms 内,否则下游应用会因超时绕过网关直连模型,反而制造更大风险面。
对抗会持续演化。今天的规则签名,明天就被新越狱模板绕过。网关不能依赖静态规则,要配套红队与线上样本回流。把线上拦截的样本持续喂回训练,让模型随攻击演化。否则规则越加越厚,模型却越来越迟钝。
还有一条隐形成本:策略治理。多应用接入时,每个业务方都想"特殊豁免"。若无统一策略仲裁,网关会退化为各自为政。必须坚持"安全策略集中下发、例外申请留痕审批",否则平台化会形同虚设。
五、总结
把 Prompt 防火墙做成统一网关,这件事说到底就是:别让十个应用各自搞一套安全检测,结果谁都没做好。四层漏斗(规则→归一→小模型→大模型)保证纵深,前几层短路控制开销,熔断保证可用性,审计保证可追溯。
但这套东西好不好用,取决于两件事:误报率能不能压住,以及策略能不能集中管控。误报多了用户骂人,策略散了网关形同虚设。安全平台化的真正价值,不是部署了多少层检测,而是让安全能力可以随攻击演化,且成本可控。