跳到主要内容

18 篇博文 含有标签「guardrails」

查看所有标签

护栏税:当安全分类器让你的延迟和账单翻倍时

· 阅读需 11 分钟
Tian Pan
Software Engineer

在安全评审中,有人问道:“如何防止用户通过越狱来泄露系统提示词(system prompt)?”于是你添加了一个输入分类器。接着又有人问:“如果模型生成了有害内容怎么办?”于是你又增加了一个输出分类器。然后法务部门要求对个人可识别信息(PII)进行脱敏,RAG 团队想要进行可靠性(groundedness)检查。现在,原本只需要一次模型调用的用户消息,变成了需要四次。你的 p95 延迟翻了一倍,推理费用上涨了 40%,而那个原本感觉是秒开的演示 Demo,现在在屏幕显示内容之前有了明显的停顿。

这就是“护栏税”(guardrail tax),而且几乎没有人为此做预算。出于本能去“添加护栏”感觉是免费的,因为每一个单独的检查都很便宜,而且显然是有益的。但护栏的组合并不是免费的——它们堆叠在关键路径(critical path)上,每一个都是增加延迟、消耗 Token 的串行环节,并且成为了一个新的依赖项,可能宕机、触发限流,或者干脆判错。

诚实的讨论应该从承认这一点开始:护栏不是一个功能开关(feature flag)。它是强行加在第一个推理系统之上的第二个推理系统,它有自己的失效模式和自己的账单。以下是如何思考护栏的实际成本,以及如何在不支付高昂代价的情况下获得保护的方法。

真正的后端是电子表格 —— 而你的智能体刚刚获得了写入权限

· 阅读需 11 分钟
Tian Pan
Software Engineer

问一个工程师他们公司的业务逻辑在哪里,他们会指向一个 Git 仓库。问财务团队、运营团队或销售团队,诚实的回答是一个名为 pricing_model_v7_FINAL_final.xlsx 的文件。定价公式、人员编制计划、佣金计算、月末对账宏 —— 大多数公司的运营核心都运行在 Excel 和 Google Sheets 上。它没有类型,没有测试,没有代码审查,也没有部署流水线。它是像餐巾纸草图一样被维护着的生产基础设施。

三十年来,这套系统基本行得通,因为读取和写入这些文件的只有人类 —— 动作缓慢、谨慎,并且具备“这个数字看起来不对”的直觉。那个时代刚刚结束了。适用于 Google Sheets 和 Excel 的 MCP 服务器现在将完整的“增删改查(CRUD)”权限作为一等公民 Agent 工具开放,而且每个 Agent 平台都提供电子表格连接器,因为那里才是客户数据真正存放的地方。我们将有史以来构建的最快的写入者连接到了有史以来部署的最脆弱的生产系统上,而大多数团队只花了一个下午就完成了这项工作,甚至没有进行过一次设计评审。

护栏也是模型:那个没人放进仪表盘的隐藏依赖

· 阅读需 13 分钟
Tian Pan
Software Engineer

这是一个正在演变成一种典型的故障复盘(postmortem)模式。主模型整晚运行良好。延迟平稳,Token 吞吐量正常,服务商状态页显示正常。然而,整整 40 分钟内,每一个用户请求都失败了——因为位于模型前端的安全分类器(safety classifier)超时了,中间件将该超时封装为一个通用异常,而异常处理程序返回了拒绝响应。你的模型并没有宕机。是你的“门禁”宕机了,而这扇门被一名从未将其视为决策选项的工程师配置成了“故障即关闭”(fail closed)。

令人不安的事实是,大多数团队在生产环境中运行着第二个机器学习系统,却不愿承认。内容审核分类器、越狱检测器、PII 清洗器、主题过滤器——每一个都是模型,拥有各自的延迟分布、错误率、在漂移中悄然腐烂的训练数据假设,以及各自的故障模式。但因为它被称为“护栏”,它就被当作配置文件来对待:设置一次,从不监控,在仪表盘上缺席,也不在值班手册中。你绝不会在没有 SLO 的情况下发布主模型。但大多数团队发布护栏时,甚至连健康检查都没有。

法律免责声明如何从答案泄露到工具调用参数中

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的法律顾问批准了一个单行的系统提示词指令:在每一个涉及受监管领域的回答中附加 “此信息不构成法律建议,不应以此为依据”。三周后,一个用户提交了一个 Bug,因为他们的日历事件描述字段以该行开头,随后是智能体本应放入会议邀请的合同摘要。智能体并没有发生故障。它完全按照系统提示词的要求执行了操作,结果发现这种行为涵盖了模型输出文本的每一个渠道——包括它调用的下一个工具的 JSON 参数。

该指令是一条内容格式规则,而模型也将其视为一条规则。它没有区分 “面向用户的回答” 和 “工具调用参数”,因为提示词中没有任何内容告诉它这些是不同的表面。免责声明最终出现在日历中、邮件草稿中,以及你的智能体代表用户发布的 Slack 消息中。这些中的每一个都是独立的下游系统,其作者根本不知道会有合规字符串被注入到结构化字段中,且每个系统的清理成本各不相同。

那个在行动已发出后才生效的预算上限

· 阅读需 10 分钟
Tian Pan
Software Engineer

一个超级用户在第三天早上 9 点就耗尽了你的月度 token 预算。熔断机制(kill-switch)准确触发——网关返回 429,模型停止调用,账单停止增长。与此同时,智能体(agent)已经订好了机票,发送了确认邮件,并将支持工单标记为已解决。仪表盘显示“支出已停止”。用户却问:“为什么要为我从未要求的行程扣费?”两者都没错。预算上限阻止了模型思考,但它没能阻止世界的改变。

这是几乎每个智能体预算护栏都会携带的失效模式:上限信号位于 支出 平面,但损害发生在 行动 平面,而这两个平面在连接时并没有共享的事务边界。告诉模型停止并不等同于告诉世界撤销模型刚刚所做的一切。

流式回滚问题:你无法收回已发送的 Token

· 阅读需 11 分钟
Tian Pan
Software Engineer

观察某人第一次使用聊天产品时,你会发现他们在模型完成输出之前就开始阅读了。这种“边出边读”的行为正是流式传输(streaming)存在的全部意义:它将数秒的等待转变为一种对话般的感觉。然而,这也是你的输出防护栏(guardrails)悄然失效的原因。

这是一个令人尴尬的过程。模型生成了第 1 个 Token、第 2 个 Token、直到第 150 个。每一个 Token 在到达时都会立即渲染。到第 200 个 Token 时,模型产生了一个虚假的用药剂量、泄露了一个电子邮件地址,或者生成了一句违反内容政策的话。你的输出侧防护栏正确且立即触发了。但“立即”已经太晚了——用户已经阅读了前 200 个 Token。你无法撤销渲染。防护栏履行了职责,但违规内容仍然传达给了人类。

你的拒绝日志其实是伪装的产品需求清单

· 阅读需 10 分钟
Tian Pan
Software Engineer

每个 AI 产品团队的某个角落都有一个安全仪表板,显示着被拒绝的请求。触发了哪些过滤器,拦截了哪些越狱尝试,抓住了哪些违反政策的行为。运营团队通过它来确保防护栏(guardrails)稳固,而其他人都对其视而不见。

这是一个错误。AI 拒绝的请求是你所能接触到的最集中、最真实的用户调研信号。如果一个用户尝试了三种不同的措辞,想让你的产品去做它不愿做的事情,他是在以极其清晰的方式告诉你,他到底想要什么以及无法得到什么。将这一信号视为安全产物而非产品产物,是在浪费你所能收集到的最宝贵的反馈。

LLM 系统中的软约束与硬约束:为什么失配会导致真正的失败

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数 LLM 系统故障并非源于模型出错。而是源于系统误判了模型能够强制执行的约束。当你在系统提示词中写下“绝不泄露客户数据”并将其等同于“撤销数据库凭据”时,你引入了一个范畴错误。这最终会导致安全事件、可靠性故障或受损的用户体验——而你直到故障在生产环境中发生时才会察觉。

软约束与硬约束之间的区别是架构层面的,而非风格层面的。搞错这一点不会导致风格退化,而是会导致安全漏洞。

拒绝延迟税:为什么分层护栏会侵蚀你的 p95 延迟预算

· 阅读需 11 分钟
Tian Pan
Software Engineer

我最近交流的一个团队为他们的 AI 助手构建了一个所谓的“深度防御”(defense in depth)流水线。一个输入分类器检查提示词注入;一个越狱过滤器扫描对抗性模式;模型生成回复;一个输出审核环节扫描结果;一个拒绝检测器检查模型是否回避了问题,如果是,则通过重新表述步骤,用更委婉的框架再次提问。评估套件显示该提示词在 1.4 秒内生成了答案,但真实用户的等待时间中值是 3.8 秒,p95 则超过了 9 秒。

每一个安全层都是一次往返。每一次往返都包含网络跳数、排队时间、模型加载和解码。当你将它们串行地堆叠在生成调用前后时,你为产品设定的延迟预算就会灰飞烟灭——而几乎没人在设计评审时考虑到这一点。更糟糕的是:流水线中最慢、最昂贵的路径往往是那些触发了安全边缘提示词的路径,而这恰恰是你的安全机制存在所要处理的长尾场景。你正在默默地用普通用户的账单来补贴这些长尾流量。

护栏系统的自研与外购:内容审查 API 已成为安全关键路径上的核心依赖

· 阅读需 11 分钟
Tian Pan
Software Engineer

你为了加快上线速度而购买的托管审核 API,现在已经成了你安全关键路径上的一个同步外部依赖。这句话并非观点——而是被如实重绘后的架构图。在供应商服务降级的日子里,你面临两个选择,且两者都很糟糕:故障开启(fail open),此时护栏在最需要的时候恰恰失效了;或者故障关闭(fail closed),护栏的故障直接导致了功能的停摆。大多数团队是在事故发生时才发现自己选了哪一个,而不是在此之前。

团队选择供应商的原因并非因为懒惰。在内部构建内容分类器、提示词注入检测器和 PII 脱敏工具,看起来像是背离实际产品开发的六个月漫长弯路,而供应商通常提供免费额度和五分钟即可完成的集成。这种集成确实很快。但随之而来的架构后果是,第三方现在介入了每一次面向用户的生成请求路径,其可用性、延迟和行为特征是你无法控制且未曾建模的。

这篇文章的主旨是将这一决定视为架构决策,而非采购决策。

AI 工程师的三种品味:为什么 Prompt、Eval 和 Guardrail 往往无法共存于一个大脑中

· 阅读需 13 分钟
Tian Pan
Software Engineer

我今年雇佣的三位最优秀的 AI 工程师,如果让他们互相面试,可能都会被刷掉。那个能写出在模型升级后依然稳健的提示词(prompt)的人,这辈子没写过一个有用的评估(eval)用例。那个能设计出捕捉到关键故障的评估集的人,写的提示词其他工程师根本不想去维护或扩展。那个能设计出既能“故障闭合”(fail closed)又不阻塞正常路径的护栏(guardrail)的人,对另外两个人的看法我在这里不便多说。

职级体系将他们三人都称为“AI 工程师”。定级委员会在对比他们的晋升材料时,仿佛他们做的是同样的工作。其实不然。

验证器陷阱:事后防御如何从内部腐蚀你的提示词

· 阅读需 10 分钟
Tian Pan
Software Engineer

第一次验证器捕捉到糟糕的 LLM 输出时,感觉像是一场胜利。第二次,你会调整提示词以降低失败的可能性。到第二十次时,团队中没人能解释为什么提示词中存在那三个段落 —— 它们是早已被遗忘的事故留下的瘢痕组织,而模型在阅读警告上花费的 Token 比推理实际任务还要多。

这就是验证器陷阱。你添加的每一个事后防护(post-hoc guard)—— JSON 模式检查、正则表达式、内容分类器、第二个作为裁判的 LLM —— 都会对上游提示词施加反馈压力。提示词会增加防御性指令来安抚验证器,验证器反过来又会捕捉到一类新的失败,接着你又会添加更多指令。每一次迭代在局部看来都是合理且明智的。但总体而言,系统变得越来越慢、越来越贵,而且在原本设计的任务上的表现也明显变差了。