litellm请求钩子3步上手:请求预处理与响应后处理怎么做
【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm
litellm 是一个用 OpenAI 格式统一调用 100 多家 LLM 的 AI 网关,它的请求钩子机制让你能在调用被转发之前做拦截,在响应返回之后做加工:敏感信息扫描、违禁词过滤、审计留痕,只需继承一个类改三个方法。
一条 prompt 里的 API Key,你敢直接发给模型吗
想象这样一个场景:你的团队把客服机器人接上了 litellm,用户随口在 prompt 里贴了一串 Stripe 测试密钥,这条内容原封不动转发给了云端模型,密钥就此进入外部日志。
类似的麻烦还有:竞品相关术语不允许出现在回复里、某些内容需要合规审核、每条调用都要留下审计轨迹。如果靠在每个业务调用处手动写 if 判断,十几条调用链下来很快就乱掉。请求钩子的价值就在于:把这类逻辑集中到网关层,所有请求统一经过同一道检查。
三个钩子位置:pre_call、success、streaming
litellm 的钩子机制围绕请求生命周期设了三个挂载点,都定义在 litellm/integrations/custom_logger.py 的CustomLogger基类上:
async_pre_call_hook:请求发给模型之前触发,拿到本次调用的用户身份和请求参数,此时拦截可以返回 400,请求根本不会出网关;async_post_call_success_hook:非流式响应返回后触发,拿到完整的模型响应对象;async_post_call_streaming_hook:流式场景下逐块触发,处理每个 chunk。
触发点在代理的请求分发处,litellm/proxy/proxy_server.py 中可以看到await proxy_logging_obj.pre_call_hook(...)的调用,即所有 /chat/completions 请求都会先过这一层。以仓库内置的违禁词钩子为例,核心逻辑只有几行:
class _ENTERPRISE_BannedKeywords(CustomLogger): def test_violation(self, test_str: str): for word in self.banned_keywords_list: if word in test_str.lower(): raise HTTPException(status_code=400, detail={"error": f"Keyword banned. Keyword={word}"})它在 pre 阶段扫请求文本,在 success 和 streaming 阶段扫响应文本,命中即抛 400,详见 enterprise/enterprise_hooks/banned_keywords.py。
三步配置你自己的请求钩子
- 克隆仓库,浏览 litellm/proxy/example_config_yaml/ 下的示例配置。这里存放了大量
litellm_settings的真实写法,照着抄不会错。 - 实现钩子类:继承
CustomLogger,按需覆盖async_pre_call_hook等方法。为什么要用基类而不是写独立函数——只有注册进回调管理器的类,才会被代理在请求链路上自动调用。 - 在
proxy_config.yaml的litellm_settings里注册你的钩子(回调项支持类路径或模块.类名两种写法),然后以litellm --config proxy_config.yaml启动。 - 用一条会触发拦截规则的测试请求验证:预期收到 400 而不是模型响应,说明钩子已经生效。
三个高频场景怎么用
违禁词双向过滤
面向 C 端的产品需要保证输入输出都干净。用banned_keywords_list配置词表后,请求和响应会被同时检查——pre 阶段拦输入,success/streaming 阶段拦输出,命中关键词直接 400 并返回具体是哪个词。词表既可以是列表,也可以是文件路径,按行读取。
敏感信息扫描
用户可能在对话里带上云厂商密钥、JWT、私有仓库 token。enterprise/litellm_enterprise/enterprise_callbacks/secret_detection.py 内置了数十种检测器(AWSKeyDetector、StripeDetector、JwtTokenDetector等),在调用前把命中的内容替换或屏蔽,密钥不再随 prompt 流向模型。
审计追踪与可观测性
合规要求"每次调用可追溯"时,把钩子和日志回调一起注册即可:每条请求的输入、输出、耗时、token 用量和成本都会落到日志。上图的 Langfuse 集成面板就是这类效果——完整的请求轨迹,包含输入输出与成本估算,排查问题不用翻后端日志。
常见坑:流式钩子漏配、词表未设置、目录混用
流式响应为什么过滤没生效?非流式响应走async_post_call_success_hook,流式响应走的是async_post_call_streaming_hook,两个钩子参数和触发时机完全不同。如果你的接口开了stream: true,只写了 success 钩子就会整条漏过。
启动报错banned_keywords_list ... None set怎么办?违禁词钩子要求词表非空,必须是列表或文件路径,没配置时初始化直接抛异常。先配置词表再启用该钩子。
enterprise 目录下的钩子能直接用吗?enterprise/enterprise_hooks/ 和 enterprise/litellm_enterprise/enterprise_callbacks/ 属于企业版实现,需要企业版权限。开源场景下,自己继承CustomLogger写同等逻辑即可,基类是开源的。
litellm 的请求钩子把"调用前拦截、调用后加工"变成了标准能力,安全、合规、审计需求都不必再侵入业务代码。克隆仓库git clone https://gitcode.com/GitHub_Trending/li/litellm开始使用,配置写法参考 litellm/proxy/example_config_yaml/ 目录内的示例文件。
【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考