内容分类器集成:输出侧三分类器加策略路由器 本节摘要:输出侧分类器回答的问题与输入侧规则不同。输入不是唯一攻击面——一个过了每道输入检查的模型仍可产出泄漏 PII、复读训练分布里的冒犯语、或被一个巧妙问题诱导回显系统提示的输出。本节在输出侧接三个独立分类器到一个策略路由器:毒性(基于规则的冒犯词与骚扰检测)、PII(邮箱/电话/SSN 形/信用卡形/IP 的正则)、指令泄漏(系统提示回显的启发式,用三字母组重叠比较输出与已知系统提示)。路由器收分类器 verdict,取最高严重度,施以 block(丢输出返策略拒绝)/redact(按分类器编辑器替换)/warn(记日志加软提示)/log(记轨迹原样发)。
本节摘要:输出侧分类器回答的问题与输入侧规则不同。输入不是唯一攻击面——一个过了每道输入检查的模型仍可产出泄漏 PII、复读训练分布里的冒犯语、或被一个巧妙问题诱导回显系统提示的输出。本节在输出侧接三个独立分类器到一个策略路由器:毒性(基于规则的冒犯词与骚扰检测)、PII(邮箱/电话/SSN 形/信用卡形/IP 的正则)、指令泄漏(系统提示回显的启发式,用三字母组重叠比较输出与已知系统提示)。路由器收分类器 verdict,取最高严重度,施以 block(丢输出返策略拒绝)/redact(按分类器编辑器替换)/warn(记日志加软提示)/log(记轨迹原样发)。读完本节,你能说清为什么跳过输出分类给攻击者一发绕过(任何输入管道未覆盖的新攻击族直达用户),以及为何 block 胜出、redact+warn 变 redact。
对应原课程:Phase 19 · Lesson 85 ·
content-classifier-integration(原英文phases/19-capstone-projects/85-content-classifier-integration/docs/en.md)。本节属第 20 章「毕业项目」的安全赛道。
阅读完本节,你应当能够:
name/score/severity/findings 的 ClassifierVerdict 加独立 redact。输入不是唯一攻击面。一个过了每道输入检查的模型,仍可产出泄漏 PII、复读训练分布冒犯语、或被巧妙问题诱导回显系统提示的输出。输出侧分类器看模型的实际响应而非用户提示,问不同的问题:不管这提示怎么到这儿的,我们要发给用户的东西可不可接受。
团队常跳过输出分类,因输入分类感觉够用、且输出分类器引入额外延迟。两个论点都站不住:跳过输出分类给攻击者一发绕过——任何输入管道未覆盖的新攻击族直达用户;延迟是真的但可解决:分类器可与 token 流式并行跑,门缓冲最末块,在 flush 前应用分类器 verdict。
每分类器是返回 ClassifierVerdict 的可调用对象,含 name、score in [0,1]、severity(none/low/medium/high)、findings(描述标记了什么的字符串列表)。路由器接 verdict 列表,应用规则表:
| 严重度 | 动作 |
|---|---|
| high | block(丢输出,返策略拒绝) |
| medium | redact(对输出施每分类器编辑器) |
| low | warn(记日志并加软提示) |
| none | log(把 verdict 记进轨迹,原样发) |
路由器取跨分类器的最高严重度,施对应动作。Block 胜出;redact + warn 变 redact;log + warn 变 warn。路由器发 Action 对象,含 verb、output、severity、verdicts、metadata。下游 87 节安全门把 metadata 记进轨迹,要么发编辑后输出、要么发带警告的原输出、要么用策略拒绝替换输出。
每分类器有自己的编辑器:PII 把 name@example.com 替成 [redacted-email]、信用卡形数字替成 [redacted-card];指令泄漏移除看似系统提示头的行;毒性把匹配冒犯语替成 [redacted-language]。Redaction 独立,使一个毒性+PII 输出流过两个编辑器。
system_prompt 参数,用三字母组重叠比较输出;高重叠即泄漏信号。SEVERITY_RANK = {"none": 0, "low": 1, "medium": 2, "high": 3} ACTION_BY_SEVERITY = {"high": "block", "medium": "redact", "low": "warn", "none": "log"} def router_decide(text, verdicts, classifiers): top = max(verdicts, key=lambda v: SEVERITY_RANK[v.severity]) verb = ACTION_BY_SEVERITY[top.severity] out = text if verb == "redact": # 流过所有触发的分类器编辑器 for v, c in zip(verdicts, classifiers): if v.severity in ("medium", "high"): out = c.redact(out) elif verb == "block": out = POLICY_REFUSAL return Action(verb=verb, output=out, severity=top.severity, verdicts=verdicts)
code/classifiers.py 定义三个分类器(各有 classify(text) -> ClassifierVerdict 与 redact(text) -> str);code/main.py 定义 Router(decide(text, verdicts) -> Action 与 run(text) -> Action 快捷方式);demo 把三分类器接一个路由器后,跑一小组各触发每种严重度的精心输出。
业界对比:OpenAI Moderation API、Azure AI Content Safety、Perspective API、Llama Guard、NeMo Guardrails 的 output 模块都是「多输出分类器 + 路由策略」组合。它们的共识与本节一致:输出侧问的是「要发的东西可不可接受」(与提示怎么来的无关)、取最高严重度、block 胜出、redaction 独立、跳过输出分类等于给攻击者一发绕过。差别在分类器是神经的(Moderation/Llama Guard)还是规则的(本节),管道形状不变——神经分类器只让每分类器延迟上升,路由与编辑逻辑照搬。
outputs/classifier_report.json:三分类器在精心输出上的 verdict 与动作,87 节安全门消费的工件。Router + Action 结构:verb/output/severity/verdicts/metadata,作为任何「多分类器→单动作」的模板。运行 python3 main.py:demo 打印每测试输出的动作 verb、写 outputs/classifier_report.json、确认 block/redact/warn/log 各至少在一条固定样例上触发。延迟人为零(全规则分类器);真神经分类器只让每分类器延迟上升,管道同样适用。
<script>、eval( 等),定其严重度策略并集成。name/score in [0,1]/severity(none/low/medium/high)/findings + 独立 redact。下一节,我们将进入「Constitutional 规则引擎」——用声明式规则表达分类器形状之外的约束(「不讨论竞争对手定价」),按可审计的规则表执行。