[Feature]: return a guardrail’s structured output from /guardrails/apply_guardrail

在 LiteLLM 中独立调用 /guardrails/apply_guardrail 时,接口默认只返回 response_text ,所以 guardrail 产生的结构化结论无法传回调用方。修复方向已合并:改用 SDK 的 litellm.guardrails.apply() ,或在 REST

快速结论:在 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 等依赖,无需作为排查项。

解决步骤

  1. 将 LiteLLM 升级到包含上述三个 PR 的源码(在正式发布包包含之前,SDK 和网关都使用同一份源码)。
  2. 修改自定义 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。

  3. 调用侧优先改用 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}]}。

  4. 如必须用 REST,继续调用同一 /guardrails/apply_guardrail 接口,并在请求体中加入 response_format: "native";不传该选项则保持原有的 response_text 响应。
  5. 对未上报结构化结论的 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 实际未上报结构化结论,需回头确认上报辅助函数是否被调用。

参考来源

BerriAI/litellm #49217

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 31619

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注