快速结论:在 LiteLLM 中独立调用 /guardrails/apply_guardrail 时,接口默认只返回 response_text,所以 guardrail 产生的结构化结论无法传回调用方。修复方向已合并:改用 SDK 的 litellm.guardrails.apply(),或在 REST 请求中加 response_format: "native";同时 guardrail 内必须通过标准上报辅助函数登记结论,仅返回 guardrail_outputs 键不会被识别。
适用环境:LiteLLM 代理(自托管,端口示例 4399)、使用自定义 CustomGuardrail 的 guardrails 配置;稳定版代理提交 b8283d8b61。Issue 未提供操作系统、Python、CUDA、显卡或 PyTorch 版本信息。
最快修复方案:把 LiteLLM 更新到包含 PR #49460、#49469、#49470 三个改动的源码;自定义 guardrail 在计算出结论的位置调用 add_standard_logging_guardrail_information_to_request_data(..., guardrail_status="success") 后返回 inputs;调用侧优先用 SDK,REST 则加 response_format: "native"。
注意事项:这些改动只合并到 main,Issue 回复说明“在某个正式包发布包含这三项改动前,SDK 和网关都要用源码”。REST 不带 response_format: "native" 时行为保持不变,仍只返回 response_text;native 请求若 guardrail 未上报任何结构化结论,会返回 HTTP 422,调用方需处理该状态码。
问题场景
用户在 LiteLLM 代理中配置了一个自定义 guardrail(示例为 grounding_demo.GroundingDemoGuardrail,mode: "post_call"),并在 agent loop 结束后通过独立接口 POST /guardrails/apply_guardrail 做落地/依据性检查:请求携带 guardrail_name、text(agent 已生成的回答)和 messages(检索到的来源)。该 guardrail 在 /v1/chat/completions 流程里能把判定附加到模型响应上,但走独立接口时,判定结果被丢弃,调用方拿不到“回答是否有依据”的结论,只能再发一次 /v1/chat/completions 补查。
报错原文
[Feature]: return a guardrail's structured output from /guardrails/apply_guardrail
原因分析
可能原因:在该提交(b8283d8b61)下,/guardrails/apply_guardrail 的响应体只有 {"response_text": "..."},接口没有把 guardrail 产生的结构化输出回传;同时自定义 guardrail 若只是在返回值里追加 guardrail_outputs 键,这个键并不会被注册为“已上报的结论”。Issue 回复明确说明:单独返回额外的 guardrail_outputs 键不会登记 finding。
环境排查
- 确认 LiteLLM 版本或源码提交是否包含 PR #49460(接口修复)、#49469(SDK 辅助方法)、#49470(Bedrock assessment 配置);三项都合并于 main。
- 确认代理配置:
guardrails[].guardrail_name是否为grounding-demo,litellm_params.guardrail是否指向正确的自定义类,mode是否为post_call。 - 确认自定义 guardrail 内是否调用了标准上报辅助函数,而不是仅改返回值。
- 确认 REST 调用是否带
response_format: "native"。 - 确认 SDK 调用时
litellm.api_base、litellm.api_key指向同一个 LiteLLM 网关,避免 SDK 与网关版本不一致。 - Issue 未涉及 CUDA、显卡、PyTorch 等依赖,无需作为排查项。
解决步骤
- 将 LiteLLM 升级到包含上述三个 PR 的源码(在正式发布包包含之前,SDK 和网关都使用同一份源码)。
- 修改自定义 guardrail:在计算
is_grounded后,通过上报辅助函数登记结论,然后返回inputs:self.add_standard_logging_guardrail_information_to_request_data( guardrail_json_response={ "haip_guardrail_check": [{"is_grounded": is_grounded}], }, request_data=request_data, guardrail_status="success", ) return inputs不再依赖在返回值中追加
guardrail_outputs。 - 调用侧优先改用 SDK 辅助方法,在 agent 产出回答后调用已配置的 guardrail:
import asyncio import os import litellm litellm.api_base = os.environ["LITELLM_API_BASE"] litellm.api_key = os.environ["LITELLM_API_KEY"] async def main(): result = await litellm.guardrails.apply( "grounding-demo", response="The tower is 450 metres tall", messages=[{"role": "user", "content": "The tower is 330 metres tall"}], ) print(result) asyncio.run(main())SDK 会在既有清洗逻辑之后直接返回上报的结论,例如
{"haip_guardrail_check": [{"is_grounded": false}]}。 - 如必须用 REST,继续调用同一
/guardrails/apply_guardrail接口,并在请求体中加入response_format: "native";不传该选项则保持原有的response_text响应。 - 对未上报结构化结论的 native 请求,按 HTTP 422 做错误处理,不要当作成功响应解析。
验证方法
用同一组 guardrail_name、text 和 messages 重新调用:SDK 应打印出与 guardrail 上报结构一致的对象(如 {"haip_guardrail_check": [{"is_grounded": false}]});REST 加 response_format: "native" 后应能拿到结构化结论,不再只有 response_text。同时回归检查其他 guardrail 的普通调用:不带 native 参数时响应体应仍为 {"response_text": "..."},不受影响。若请求返回 422,说明该 guardrail 实际未上报结构化结论,需回头确认上报辅助函数是否被调用。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[Bug]: aiohttp per-host pool exhaustion is silent, requests just time out with no diagnostic](https://www.chat-gpts.plus/wp-content/uploads/2026/11/46864-00d31e5d-768x403.jpg)
![[Bug]: OpenRouter streaming chunks report the requested router name instead of the model OpenRouter served](https://www.chat-gpts.plus/wp-content/uploads/2026/11/46095-0cdac0c6-768x403.jpg)
