亚马逊AWS官方博客
一站式搞懂如何在LiteLLM上配置 Amazon Bedrock Guardrail
摘要:Bedrock Guardrail 是功能丰富的业界领先的大模型安全护栏解决方案,如果您也在尝试给LiteLLM配置上Bedrock Guardrail,本文将会是您或者您的agent最好的参考资料
目录
本文基于 2026-08-26 的真实实测(LiteLLM 1.81.14,模型含 Claude Haiku 4.5 与 GPT-5.6 Sol/Terra/Luna),所有关键结论都有可复现的实验数据支撑。如果你正准备在生产环境给 LLM 加上内容安全检查,这篇文章大概能帮你省下几天的踩坑时间。
一、先把三个主角介绍清楚
如果你已经熟悉这三个组件,可以直接跳到第二节。
1.1 AWS Bedrock
AWS 的托管大模型服务。你不用自己部署模型,通过 API 就能调用 Claude、GPT、Llama 等各家模型。调用方式主要是 Converse(一次性返回完整结果)和 ConverseStream(流式返回,逐字蹦出来,聊天场景标配)。
1.2 Bedrock Guardrail
Bedrock 自带的内容安全组件。你先在控制台配好策略——比如”拦截暴力内容””检测到邮箱就 BLOCK””识别提示词注入攻击”——它会生成一个 Guardrail ID。之后有两种用法(这两种用法的区别是全文最重要的伏笔):
- 用法 A:调模型时在请求里带上 guardrailConfig 字段,Bedrock 内部自动执行检查;
- 用法 B:单独调用一个叫 ApplyGuardrail 的独立 API,想查什么文本就提交什么文本,和模型调用完全无关。
1.3 LiteLLM
一个流行的开源 LLM 网关/代理。它把上百家模型的 API 统一成 OpenAI 格式,你的业务代码只写一种调用方式,换模型只改配置。它也内置了对 Bedrock Guardrail 的集成——这正是故事开始的地方。
二、需求场景:一个看似简单的要求
假设你在做一个带工具调用(tool calling / agent)的 LLM 应用,接了合规要求。安全团队提了两条验收标准:
要求 1:Input 侧只检查用户输入。 用户提交的内容必须全部过 Guardrail,防止恶意输入;但 system prompt、工具返回结果(tool result)、助手历史消息这些”系统自己产生的内容”不许送检——因为固定提示词里可能有触发误报的措辞,而且这些内容根本不是用户可控的。
要求 2:Output 侧完全不检查。 模型输出必须原速流式返回,不做 output 检查,不引入任何缓冲延迟。
看起来很合理对吧?”进来的查一下,出去的别碰”。但用 LiteLLM 的标准配置去实现时,你会发现——两条要求居然凑不齐。
三、一个贯穿全文的比喻:安检员、办事窗口和中介
在看具体配置之前,先建立一个心智模型,后面所有问题都用它来解释。
- 办事窗口 = Bedrock 模型调用
- 文件袋 = 一次请求的全部 messages:里面装着用户亲笔写的申请(user 输入)、公司内部流程说明(system prompt)、上个环节退回的回执(tool result)
- 安检员 = Guardrail
安检员有两种雇佣方式:
方式一:派驻到窗口里面(用法 A,guardrailConfig)。你在申请表上勾”带安检”,安检流程由 AWS 在窗口内部执行:进门查一次(input),出门也查一次(output)。你在外面只能看到结果,管不了里面的流程。
方式二:门外雇私人安检员(用法 B,ApplyGuardrail)。安检和办事彻底分开:你先自己把材料交给门外的安检员查,通过了再去窗口办事——申请表上不勾安检。窗口内部就完全没有安检环节。
中介 = LiteLLM。你不想自己跑窗口,把材料交给中介,中介替你办。
记住这个画面,我们开始踩坑。
四、踩坑实录:LiteLLM 的两种标准玩法为什么都不行
4.1 坑 1:Proxy pre_call 模式——门口安检员不拆包
LiteLLM 的第一种 Guardrail 集成方式,配置长这样:
这对应比喻里的:中介在自己店门口雇了个安检员,材料送去窗口前先查一遍,去窗口时不勾安检。好消息是——出门(output)确实没人查,要求 2 满足了。
坏消息是:这个安检员不拆包。实测抓包看 LiteLLM 实际发给 ApplyGuardrail 的内容:
整个文件袋原样塞给安检员。于是 system prompt 里一句无关紧要的话触发警报:
整单被拒。这就是固定提示词误拦截——要求 1 直接违反。
4.2 坑 2:latest 参数——只查最上面那张纸
LiteLLM 提供了一个补救参数:
听名字像是”只查最新的用户消息”,实测语义却是**”只查最后一条 message,不管它是谁写的”**。
如果最后一条恰好是 user 消息,一切正常。但在标准的 agent 工具循环里,请求经常长这样:
实测:当请求以 tool result 结尾时,LiteLLM 把 tool result 的内容原样送检,又是 HTTP 400。用比喻说:门口安检员只查文件袋最上面那张纸,可惜最上面那张经常是退回的回执,不是用户的申请。 这个参数的语义是”查最上面那张”,不是”翻出用户亲笔写的那张”。
结论:坑 1 + 坑 2 说明 Proxy 模式能满足要求 2,但无法可靠满足要求 1。
4.3 坑 3:模型级 guardrailConfig——出门安检关不掉
LiteLLM 的第二种集成方式,在模型配置里直接写 guardrailConfig:
这对应比喻里的:中介只是帮你在申请表上勾了”带安检”——安检员被派驻进窗口。
这个方式的 input 侧其实做得很漂亮:LiteLLM 会用 Bedrock 的 guardContent 标记把最新用户输入包起来,等于在用户材料上贴了张标签”重点查这份”。实测 trace 证实了精准性:
全部输入 213 个字符,只有贴标签的 58 个字符(最新用户输入)被检查——system prompt 和 tool result 都没被误查。要求 1 满足了。
但出门呢?我们把所有 output 策略都设成 NONE(一项都不检查),trace 里依然出现:
翻译一下:输出的 40 个字符全部被扣下来过了一遍安检门(guarded=40/40),只是门里没开任何检查仪(policy units=0)。 排队过门的时间——也就是流式缓冲延迟——一点没省。出门安检这一步在流水线里是焊死的,没有开关。要求 2 违反。
4.4 坑 4:两种方式一起开?
有人会想:Proxy 管 input,模型级的……算了都开上试试。实测链路变成:
同一份用户输入被查两遍(花双份检查费用),出门照样有人拦。花双份钱买双份麻烦。
4.5 四个坑的全景图
客户要的是”门口安检 + 只查用户亲笔材料”这个组合——它不在中介的标准套餐目录里。
五、正解:把安检彻底搬到门外(自研两步调用)
绕开所有坑的方法,是回到 Bedrock 的用法 B:自己调 ApplyGuardrail,然后调一个不带任何 Guardrail 字段的模型请求。代码就两步:
两条要求同时满足,而且是结构性满足:
- 查什么内容由你的代码字面决定——system prompt 和 tool result 连安检员的面都见不着;
- 出门安检不是”被关掉了”,是根本没装——模型请求里没有 Guardrail 字段,输出路径上结构上就不存在检查环节。
三个新手常见疑问顺便答掉:
Q1:第一步的 guard 和第二步的 stream 之间怎么关联? 答:没有任何数据关联,唯一的联系是那个 if——被拦的请求活不到第二行代码。Bedrock 不会校验”你调模型前查过没有”,这个保证完全来自你的代码结构。生产上要配一条 IAM 约束:只有网关的角色拥有 bedrock:InvokeModel 权限,业务方拿不到,防止有人绕过安检直连窗口。
Q2:为什么第二步不用 guardContent 标记了? 答:那个标签是贴给驻场安检员看的。门外模式下安检发生在另一个 API 里,模型请求里放普通 text 就行。
Q3:一定要”自研网关”这么重吗? 答:不一定。如果你想保留 LiteLLM,可以写一个自定义 hook(继承 CustomGuardrail,在 pre_call 里回溯最后一条 role=user、排除 toolResult、单独调 ApplyGuardrail(INPUT)),大约百来行代码,等于给中介的门口安检员写一份”如何拆包挑材料”的定制委托书。LiteLLM 本身是 FastAPI/asyncio 架构,hook 用 async def 一路写下去即可。
六、为什么出门检查必然带来延迟:水管物理学
有读者可能会问:output 检查慢,就不能”边流边查、完全不加延迟”吗?答案是不能,这是物理定律,谁做都一样。
流式响应不是”结果一股脑给你”。converse_stream() 返回的一瞬间,你拿到的只是一根水管的接头——模型可能一个字还没生成。内容是逐段生成、逐段流过转发代码的:
(底层机制:你的进程在 socket 上阻塞等待,数据到达时被操作系统内核唤醒——和 nginx/redis 用的 epoll 是同一套”等待队列+唤醒”机制的单连接版本。不迭代就没有数据,”水”不会绕过你的代码流向客户端。)
于是一个必然推论:只要想在”放行前”检查内容,就必须扣住一段、查一段、放一段。 AWS 的驻场安检就是这么做的(默认攒块检查,这就是坑 3 里延迟的来源);你自己在网关里查 output 也逃不掉(实测 ApplyGuardrail 每次约 150ms)。
唯一的零延迟玩法是事后异步审计:水照常实时流给客户端,流完之后再把全文异步送检一份,结果只进日志和告警、不做拦截。如果哪天合规团队要求”输出也得有个交代”,这是不违背零延迟要求的唯一选项——也是门外安检模式独有的解耦能力:查不查、何时查、查完怎么处置,三件事各自独立;驻场模式里这三件事是焊死在一起的。
七、意外发现:GPT-5.6 的”VIP 通道闸机没通电”
实测中还发现了一个有趣的特例,值得单独讲。
7.1 实测现象
用一个”EMAIL → BLOCK”的临时 Guardrail 做闭环实验:让模型固定输出 audit@example.com,如果 output 检查在跑,邮箱必然被替换成拦截文案;如果没跑,客户端收到原文。结果:
| 模型 | 带 guardrailConfig 调用,输出含邮箱 | 结论 |
| Claude Haiku 4.5 | 收到 OUTPUT_BLOCKED_BY_GUARDRAIL,stopReason: guardrail_intervened | output 检查正常执行 |
| GPT-5.6 Sol / Terra / Luna | 收到 audit@example.com 原文,end_turn | output 检查没有执行 |
| gpt-oss-120b(开源权重,跑在 Bedrock 自有栈) | 被拦截 | output 检查正常执行 |
而 GPT-5.6 的 input 检查完全正常——发提示词注入攻击文本,返回 guardrail_intervened, inputTokens: 0(模型一个 token 都没跑就被拦了)。
7.2 最关键的一条证据
非流式调用 GPT-5.6 时,trace 里返回是:
对照 Claude:modelOutput 里装着完整的模型回复。也就是说,Guardrail 编排层在跑(连登记表的壳都发了),但模型输出从来没有被递到安检员手上。
7.3 怎么解释?
GPT-5.6 是 Bedrock 新接入的”VIP 通道”——它有专属的 serving 栈(有独立的 bedrock-mantle 端点、不支持 Invoke API 等诸多特殊之处)。合理的推断是:input 检查发生在 Bedrock 统一入口层,对谁都生效;而 output 检查需要在响应路径上把内容拦下来送检,这个钩子是对 Bedrock 自有流水线实现的——GPT-5.6 的新通道出口,安检闸机还没通电。 分界线不是”OpenAI vs Anthropic”,而是模型跑在哪条流水线上(开源 gpt-oss 跑在自有栈上,output 检查就正常)。
7.4 这意味着什么?
“模型级 guardrailConfig + GPT-5.6″这个组合,目前碰巧同时满足两条要求:input 精准(贴标签)、output 没人查(闸机没电)。如果你正好要用 GPT-5.6,这是一条零开发成本的捷径。但务必认清两种”行”的本质区别:
自研/直调方案行,是架构上的必然——出门安检结构上不存在。 GPT-5.6 目前支持,是实现上的偶然——AWS 文档写的是”支持 Guardrails”,没有任何地方承诺”output 不检查”。
如果决定吃这个红利,两件事必须做:
- 放金丝雀:定时任务让模型固定输出可拦截内容(如上面的邮箱),断言客户端收到原文。哪天金丝雀”被拦截”了,说明闸机通电了,第一时间切换方案;
- 把自定义 hook 方案写进二期规划,作为随时可切换的退路。
八、总结速查表
| 方案 | Input 只查真实用户输入 | Output 完全不送检 | 性质 |
| 自研两步调用(ApplyGuardrail + 无 guardrailConfig) | ✅ | ✅ | 架构必然,任何模型稳定,推荐 |
| LiteLLM Proxy pre_call(含 latest 参数) | ❌ 整袋送检 / 只查最后一条 | ✅ | 不可靠 |
| LiteLLM 模型级 guardrailConfig + Claude 等 | ✅(guardContent 精准) | ❌ 出门必查 | 不满足 |
| LiteLLM 模型级 guardrailConfig + GPT-5.6 | ✅ | ✅(暂时) | 实现偶然,需金丝雀盯守 |
| LiteLLM + 自定义 CustomGuardrail hook | ✅ | ✅ | 架构必然,约百行代码 |
三句话带走:
- Bedrock Guardrail 有两种用法:驻场(guardrailConfig,进出必查、流程焊死)和门外(ApplyGuardrail,查什么、何时查全由你定)。需求越精细,越应该用门外模式。
- LiteLLM 的标准配置覆盖不了”input 只查用户输入 + output 完全不查”这个组合——两种集成方式恰好各满足一半。要么写自定义 hook,要么自己做两步调用。
- 凡是依赖”实测发现但文档没承诺”的行为(如 GPT-5.6 目前跳过 output 检查),一定要配金丝雀监控。
➡️ 下一步行动:
相关产品:
- Amazon Bedrock — 用于构建生成式人工智能应用程序和代理的端到端平台
- Amazon IAM — 身份管理和访问权限
相关文章:
- 接入 Amazon Bedrock 新一代推理引擎 Mantle:用 LiteLLM 网关统一调用 GPT-5.6 与 Claude
- OpenAI GPT-5.6 Sol、Terra 和 Luna 现已在 Amazon Bedrock 上正式推出
- 开始在 Amazon Bedrock 上使用 OpenAI GPT-5.5、GPT-5.4 模型和 Codex
- 使用 lm-evaluation-harness 评估 Amazon Bedrock 模型:以 HumanEval 为例
九、附录:本文实测环境与关键数据
- 日期:2026-08-26;LiteLLM 1.81.14;区域 us-west-2
- 模型:us.anthropic.claude-haiku-4-5-20251001-v1:0、us.openai.gpt-5.6-sol/terra/luna、openai.gpt-oss-120b-1:0
- 闭环实验设计:临时 Guardrail 配 EMAIL → BLOCK,system prompt 强制模型输出 audit@example.com,以”客户端是否收到原文”作为 output 是否送检的判据(避免仅凭”请求里没带 guardrailConfig”做推断)
- 关键数据点:
- Proxy 默认模式送检内容 = system + 历史消息 + tool result + 最新 user(导致误拦截 HTTP 400)
- latest 模式在请求以 tool result 结尾时,送检的就是 tool result 本身
- 模型级模式 input coverage guarded=58/total=213(guardContent 精准圈定)
- output 策略全 NONE 时仍有 outputAssessments guarded=40/40, policyUnits=0(安检门在,检查仪没开,延迟照付)
- GPT-5.6 非流式 trace:modelOutput: []、无 outputAssessments;input 侧 guardrail_intervened, inputTokens: 0
- ApplyGuardrail 单次检查延迟实测约 150ms;GPT-5.6 在 Bedrock 上不接受 temperature 参数(复现时需去掉)
*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。
本篇作者
AWS 架构师中心:云端创新的引领者探索 AWS 架构师中心,获取经实战验证的最佳实践与架构指南,助您高效构建安全、可靠的云上应用 |
![]() |

