本节摘要:评测告诉你系统几斤几两,护栏决定它犯错的瞬间谁去拦。本节把拦截机制组织成三道闸——输入过滤、输出校验、人工介入——给出完整的管道代码,并重点讲清第三道闸的设计学问:介入点设在哪、怎么让用户不烦。
评测与护栏的分工,用机场做个不恰当但直观的对照:评测是定期体检(发现问题航班),护栏是登机口安检(拦下每一班有问题的)。护栏的特殊性在于它运行在每一次请求的路径上——既不能漏拦,也不能拦出体验灾难。三道闸就是按"漏拦代价"与"误拦代价"的权衡组织起来的。

class GuardrailPipeline: """三道闸按序执行;任何一闸拦截即短路,避免后续成本与风险。""" def check_input(self, user_msg: str, user_ctx: dict) -> Verdict: # 第一闸:注入模式、敏感信息、明显越权的请求 if hits_injection_patterns(user_msg): # 规则层,快且可解释 return Verdict(block=True, reason="检测到疑似指令注入内容") if contains_pii(user_msg) and not user_ctx.get("pii_allowed"): return Verdict(redact=True) # 打码而非拦截,可用性优先 if requests_forbidden_action(user_msg, user_ctx): return Verdict(block=True, reason="该操作需要走人工渠道") def check_output(self, reply: str, trace) -> Verdict: # 第二闸:格式、事实一致性、敏感词、动作风险分级 if not schema_ok(reply): # 结构校验 return Verdict(retry_with_note="输出不符合要求的格式") if not citation_ok(reply, trace): # 关键主张是否有观察支撑 return Verdict(retry_with_note="存在无出处的关键结论") level = classify_action_risk(trace.pending_calls) if level == "high": # 高风险动作改道第三闸 return Verdict(escalate=True, payload=render_approval(trace)) return Verdict(pass_=True) def check_human(self, approval_req: dict) -> Verdict: # 第三闸:人拍板。请求必须让审批者看得懂、判得快 render_to_console(approval_req) # 动作、依据、备选项 decision = wait_for_human(approval_req["deadline"]) return Verdict(pass_=(decision == "approve"))
三道闸的拦截后果刻意不同。第一闸多用"拦截加解释"——输入有问题,责任在请求侧,请用户重述即可。第二闸优先"自修"——把违约原因作为观察喂回模型(2.1 节的违约处理),给它一次改正机会,改不过来再升级;直接拦截会浪费大量可自愈的轻微违约。第三闸永远是"人拍板"——到达这里的都是规则与模型都无法安全决断的情形。
护栏最大的失败模式不是漏拦,而是被用户绕开——确认弹窗太频繁,用户养成无脑点确认的习惯,护栏形同虚设。介入点的选址因此要在两个维度上收敛:
风险维度写死在配置里:金额超过阈值、删除与批量操作、对外发送、不可逆动作——这些是铁打的介入点,不随模型置信度浮动。
置信度维度动态计算:检索证据不足、判分模型打分低、同类请求的历史失败率高、连续重试之后——这些是浮动的介入触发。两个维度取并集,其余情况放行并记录,供 7.1 节的评测抽样复核。
介入请求本身也要设计:动作是什么、依据是什么、有哪些备选、不批会怎样——审批者在十秒内能拍板,护栏才可持续。
背景:报销助理收到一张八千元的招待费报销,制度上限为两千元。
操作与结果:第一闸放行(请求本身合法);循环中抽取金额与制度比对,第二闸的动作风险分级判为 high(金额超阈值且属不可逆提交),改道第三闸。审批者看到的请求卡片:动作(提交报销单)、金额与制度上限对比、依据(制度文档条款)、备选项(退回补充说明 / 拆分单据 / 特批提交)。审批者选择退回,附一句备注,助理按备注起草了退回说明。
解读:注意整条链路里模型的角色——它完成了抽取、比对、起草,但决定权在制度与审批者手里。护栏不削弱智能体的能力,只是把"越界的决定"从概率性的模型手里收回到确定性的规则与人手里。
变式:介入可以分级而非二元——低风险偏差自动处理并事后抽样复核,中风险异步审批(不阻塞用户,半小时内人工处理),高风险同步阻塞。分级让介入密度与风险精确挂钩。
⚠️ 常见坑:护栏逻辑散落在各处代码里。三道闸应当是独立的管道层,集中配置、集中日志、集中评测(护栏自身的误拦率与漏拦率也要进 7.1 节的评测)——散装的护栏既没法审计,也没法迭代。
三道闸防的是"乱来",下一节正面迎击蓄意攻击:提示注入、越权与数据外泄的攻防。
三道闸上线后最先积压的不是漏报,而是误报——拦了不该拦的。误报的危害是双重的:用户被无端打扰,更糟的是运维团队在申诉面前不断放宽规则,护栏被一点点掏空。治理误报的三板斧:灰度放量——新规则先以"只记录不拦截"的观察模式跑一周,看命中样本里误报占比,低于一成才切换为真拦截;分桶放行——拦截日志按规则条款分桶统计,误报集中的条款单独收紧措辞而不是整体放宽;申诉回路——用户对拦截结果申诉后,人工复核结论回填到规则的测试集,规则迭代从此有了负样本来源。护栏是长期运营的活系统,这三板斧决定了它半年后是越来越准,还是形同虚设。