Opik × LiteLLM 集成指南:为多模型 LLM 应用接入端到端可观测性
2026/9/13 16:47:53 网站建设 项目流程

Opik × LiteLLM 集成指南:为多模型 LLM 应用接入端到端可观测性

【免费下载链接】comet-llmDebug, evaluate, and monitor your LLM applications, RAG systems, and agentic workflows with comprehensive tracing, automated evaluations, and production-ready dashboards.项目地址: https://gitcode.com/GitHub_Trending/co/comet-llm

本篇指南以 Opik 的 LiteLLM 官方集成模板为骨架,讲解如何在一个基于 LiteLLM 网关的多模型 LLM 应用中接入 Opik 的追踪(Tracing)、日志与评估能力。读完本文你将掌握:通过OpikLogger回调实现零侵入的 LLM 调用自动日志、在@track装饰器函数内传递current_span_data建立完整 Span 层级、以及如何借助track_completion装饰器对litellm.completion/litellm.acompletion(含流式)做细粒度追踪——无论你调用的是 OpenAI、Anthropic、Groq 还是任意 LiteLLM 支持的上百个 Provider。

背景:为什么需要为 LiteLLM 应用加一层可观测性

LiteLLM 的价值在于把几十家 LLM Provider 的统一成一套 OpenAI 兼容的 API 接口,让应用层可以用litellm.completion(model="groq/llama3-8b-8192")这样的写法无缝切换模型。但统一网关也带来了新问题:调用到底发给了哪个 Provider?prompt、输出、token 用量和成本是多少?在多步骤 Agent 流程里,哪一次子调用拖慢了整体响应?这些问题单靠 LiteLLM 自身无法回答,需要一套独立的追踪层来记录每一次调用的输入、输出、元数据与成本——这正是 Opik 所承担的角色。

在 Opik 仓库中,LiteLLM 集成分为两条互补的路径(集成源码目录):

  • 回调式集成(本文主体):通过litellm.callbacks注册OpikLogger,LiteLLM 每次完成调用后自动把请求与响应发给 Opik;
  • 装饰器式集成track_completion):通过 opik_tracker.py 暴露的track_completion包装litellm.completion/litellm.acompletion,在 Opik 一侧主动拦截并记录调用,适合需要精确控制 Span 结构的场景。

账号与环境准备

选择 Opik 部署形态

Opik 平台有两种运行方式,集成代码完全一致,只需配置不同的端点与密钥:

  1. Comet 托管版(Cloud):在 Comet 平台注册账号并获取 API Key,开箱即用;
  2. 自托管版(Self-hosted):参考 自托管安装说明,通过 Docker Compose 一键拉起完整的 Opik 后端(含 ClickHouse 存储),同时 docker-compose 编排文件 与 Helm Chart 提供了两种生产部署路径。

安装依赖

LiteLLM 集成需要同时安装opiklitellm两个 Python 包:

pip install opik litellm

集成所需的 Python SDK 源码位于 sdks/python/src/opik/integrations/litellm/,opik 包会将其作为官方库内集成随包发布。如果你要参与集成开发,仓库在 sdks/python/tests/library_integration/litellm/ 与 sdks/python/tests/e2e_library_integration/litellm/ 提供了配套的单元与端到端测试。

配置 Opik 客户端

针对你的部署形态,用任一方式配置 Opik Python SDK:

  • CLI 配置:终端执行opik configure,按提示选择 Cloud 或自托管并填入 API Key 与 Base URL;
  • 代码配置:调用opik.configure(),可在运行时动态传入参数;
  • 环境变量:设置OPIK_API_KEYOPIK_URL_OVERRIDE等环境变量(详见 SDK 配置文档 SDK 配置指南)。

配置 LiteLLM 的 Provider API Key

在调用具体 Provider 之前,需要先配置对应的 API Key。以 Groq 为例,可将密钥写入环境变量:

export GROQ_API_KEY="YOUR_API_KEY"

对于不同 Provider,环境变量名各不相同(如OPENAI_API_KEYANTHROPIC_API_KEY)。更稳妥的方式是在代码中安全地读取密钥,并同时设定 Opik 的项目名,保证日志落到统一项目下:

import os import getpass if "GROQ_API_KEY" not in os.environ: os.environ["GROQ_API_KEY"] = getpass.getpass("Enter your Groq API key: ") # 为本次集成演示设置项目名,所有 trace 会归入该项目 os.environ["OPIK_PROJECT_NAME"] = "groq-integration-demo"

方式一:通过 OpikLogger 回调自动记录 LLM 调用

这是最省事的接入方式:创建OpikLogger实例并注册进litellm.callbacks,此后所有通过 LiteLLM 发出的调用都会被自动记录,业务代码零改动:

from litellm.integrations.opik.opik import OpikLogger import litellm import os opik_logger = OpikLogger() litellm.callbacks = [opik_logger] # 设置项目名,便于在 Opik UI 中按项目聚合 os.environ["OPIK_PROJECT_NAME"] = "groq-integration-demo" response = litellm.completion( model="groq/llama3-8b-8192", # 替换为实际模型名,如 "openai/gpt-4o" messages=[ {"role": "user", "content": "Why is tracking and evaluation of LLMs important?"} ] )

执行后,在 Opik 的 Trace 列表中即可看到一条完整的调用记录:chat.completion级别的 trace 与对应 span,携带输入 messages、输出 choices、token usage 与created_from: "litellm"元数据。

这一行为有仓库端到端测试作为依据:test_opik_logging.py 中的test_litellm_opik_logging__happyflowlitellm.callbacks = ["opik"]触发一次真实调用后,断言 Opik 侧恰好生成 1 条 trace 与 1 条 span,且:

  • trace 名称为chat.completion,span 名称以模型名(如gpt-5-nano)开头;
  • 两者元数据均包含{"created_from": "litellm"}
  • 输入严格等于原始messages数组,span 类型为llm,tags 中包含 Provider 名(测试中为openai)。

回调集成的工作原理

OpikLogger回调本身定义在 LiteLLM 一侧,但 Opik 与之对应的底层能力由 litellm_completion_decorator.py 的LiteLLMCompletionTrackDecorator实现,可以从源码确认其记录行为:

  • 输入过滤:记录输入时仅保留messagesfunctionsfunction_calltoolstool_choiceresponse_formatstop等业务参数(见源码中KWARGS_KEYS_TO_LOG_AS_INPUTS);
  • 敏感信息脱敏api_keyaws_secret_access_keyazure_ad_tokenvertex_credentials等 21 项密钥类参数会被显式排除,绝不落盘(见SENSITIVE_PARAMS_TO_EXCLUDE);
  • Provider 识别:通过litellm.get_llm_provider(model_name)解析模型前缀(如groq/openai/),再经LITELLM_PROVIDER_MAPPING映射为 Opik 统一的LLMProvider枚举,写入 span 的provider字段;
  • 成本计算:调用litellm.completion_cost()计算单次调用的费用,并随 span 记录total_cost,供 Opik 侧做成本聚合;
  • usage 归一化:把 LiteLLM 返回的 usage 数据转换为 Opik 统一的OpikUsage结构(见 opik_usage.py 与 litellm_provider_mapping.py)。

方式二:在 @track 函数内记录调用并维护 Span 层级

当 LiteLLM 调用发生在 Opik@track装饰的函数内部时,若不额外处理,LiteLLM 侧回调产生的 trace 与外层函数不在同一调用树中。解决办法是在litellm.completionmetadata中显式传入opik_context.get_current_span_data(),把当前 Span 作为元数据带给 LiteLLM,使内层调用挂载到外层函数对应的 Span 之下:

from opik import track, opik_context import litellm @track def generate_story(prompt): response = litellm.completion( model="groq/llama3-8b-8192", # 替换为实际模型名 messages=[{"role": "user", "content": prompt}], metadata={ "opik": { "current_span_data": opik_context.get_current_span_data(), }, }, ) return response.choices[0].message.content @track def generate_topic(): prompt = "Generate a topic for a story about Opik." response = litellm.completion( model="openai/gpt-4o", # 可与上方不同模型 messages=[{"role": "user", "content": prompt}], metadata={ "opik": { "current_span_data": opik_context.get_current_span_data(), }, }, ) return response.choices[0].message.content @track def generate_opik_story(): topic = generate_topic() story = generate_story(topic) return story generate_opik_story()

运行后,Opik 中会呈现一棵清晰的调用树:generate_opik_story(Trace)→generate_topic/generate_story(Span)→ 各自的litellm.completionLLM Span,方便你在 Trace 详情页逐层下钻定位延迟与失败节点。

方式三:track_completion 装饰器精确追踪(含流式)

如果不想依赖 LiteLLM 全局回调,可以直接用 Opik 内置的track_completion装饰器包装调用函数。它支持同步与异步、流式与非流式四种组合,并通过 opik_tracker.py 暴露:

import litellm from opik.integrations.litellm import track_completion tracked_completion = track_completion(project_name="my-project")(litellm.completion) response = tracked_completion(model="gpt-3.5-turbo", messages=[{"role": "user", "content": "Hello"}])

track_completion接收两个可选参数:

参数类型说明
project_namestr | None日志写入的 Opik 项目名,缺省时使用 SDK 默认项目
sourceTraceSource | NoneTrace 来源标识(如"sdk""optimization"),用于区分数据产生方

流式调用的聚合原理

流式场景下,LiteLLM 返回的是CustomStreamWrapper,无法一次性拿到完整响应。Opik 通过 stream_patchers.py 对包装器的__next__/__anext__进行打补丁,逐个累积 chunk;流结束后由 completion_chunks_aggregator.py 的aggregate把全部 chunk 拼装为一条完整的ModelResponse

  • 从每个 chunk 的delta中提取增量contentrole并拼接成完整消息;
  • 聚合首尾 chunk 中的usage(token 统计)与finish_reason
  • 若流中途抛异常,通过error_info_collector收集错误信息写入 span,保证失败调用也可追溯。

对应测试位于 test_litellm_streaming.py,覆盖了同步/异步流式 chunk 聚合与错误路径。

三种方式的选型建议

接入方式侵入性适用场景
litellm.callbacks = [OpikLogger()]最低,全局生效快速接入、全量记录所有 Provider 调用,最契合官方模板的默认路径
@track+metadata["opik"]["current_span_data"]多步骤 Agent / 编排链,需要把 LLM 调用挂入业务函数的 Span 层级
track_completion装饰器低~中,按调用点生效需要按函数粒度控制项目归属与来源、或对流式输出有精细追踪诉求

常见问题与排查

  • 回调未生效:确认litellm.callbacks = [opik_logger]在首次litellm.completion之前执行;若使用 e2e 测试中的字符串形式litellm.callbacks = ["opik"],需要确保opik已安装且其 LiteLLM 回调入口可被 LiteLLM 动态加载。
  • API Key 泄露风险:集成内置脱敏机制,但仍应避免在metadata或消息内容中放置密钥;自托管场景建议配合 docker-compose 的配置 限制后端网络访问。
  • 成本字段为空litellm.completion_cost()依赖模型定价表,若 Provider/模型不在 model_prices_and_context_window.json 所对应的定价体系中,total_cost会以None落库,不影响其余日志字段。
  • Provider 识别失败litellm.get_llm_provider对未识别前缀会抛异常,装饰器会静默返回None,span 的provider字段为空,属预期行为。

结语

通过本文的三种接入方式,你已经可以为任何基于 LiteLLM 的应用建立完整的 Opik 可观测链路:从一次最简单的litellm.completion自动日志,到多模型 Agent 编排中的 Span 树,再到流式输出的逐 chunk 聚合与成本核算。更深层的实现细节(敏感参数过滤清单、usage 归一化、流式打补丁)均可在 sdks/python/src/opik/integrations/litellm/ 中直接阅读源码,配套测试为你的接入行为提供了可复现的验证基准。

【免费下载链接】comet-llmDebug, evaluate, and monitor your LLM applications, RAG systems, and agentic workflows with comprehensive tracing, automated evaluations, and production-ready dashboards.项目地址: https://gitcode.com/GitHub_Trending/co/comet-llm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询