LLMOps可观测性【免费下载链接】openllmetryOpen-source observability for your GenAI or LLM application, based on OpenTelemetry项目地址https://gitcode.com/gh_mirrors/op/openllmetry点击查看免费下载本篇技术指南聚焦 openllmetry 仓库中的opentelemetry-instrumentation-litellm包讲解如何对基于 LiteLLM外部项目文中不提供链接的 LLM 应用进行零侵入可观测性插桩包括安装接入、Span 生成原理、Provider 归一化、gen_ai.*属性 Schema、指标与流式处理以及以TRACELOOP_TRACE_CONTENT为核心的隐私配置。读完你将掌握如何用一行代码让 LiteLLM 的同步/异步补全与 Embedding 调用自动产出符合 OpenTelemetry GenAI 语义约定的链路和指标并能按隐私需求精准控制内容的记录与否。一、这个插桩要解决什么问题LiteLLM 是业界常用的统一 LLM 网关上层应用通过litellm.completion()/litellm.embedding()等统一 API 调用由 LiteLLM 路由到 OpenAI、Azure、Bedrock、Vertex AI、Gemini、Mistral 等数十种后端。这意味着只要插桩 LiteLLM 这一个入口就能覆盖它背后的所有 Provider。opentelemetry-instrumentation-litellm正是基于这个特性设计的见 README.md因为 LiteLLM 会把每个 Provider 的回复统一归一化为 OpenAI 风格的ModelResponse——包括通过litellm.CustomLLM注册的自定义 Provider——所以一组包装器wrapper就能在所有后端上产生一致的gen_ai.*Span 和指标。从源码看该插桩采用进程内in-process包装方式直接包装 LiteLLM 库公开的模块级函数completion/acompletion/embedding/aembedding见init.py 的WRAPPED_METHODS定义而非针对每个 Provider 单独插桩。这是一个入口覆盖全部后端的关键。二、安装与最小接入安装pip install opentelemetry-instrumentation-litellm安装前提见 pyproject.tomlPython 版本要求3.10,4运行时依赖opentelemetry-api1.38.0,2、opentelemetry-instrumentation0.59b0、opentelemetry-semantic-conventions-ai0.5.1,0.6.0、opentelemetry-semantic-conventions0.63b1目标库版本插桩声明的依赖范围是litellm 1.0.0见__init__.py中_instruments常量仓库内测试使用litellm1.40.0。该包还注册了opentelemetry_instrumentor入口点litellm opentelemetry.instrumentation.litellm:LiteLLMInstrumentor见 pyproject.toml因此也支持通过 OpenTelemetry 的标准机制自动发现/加载。最小接入代码from opentelemetry.instrumentation.litellm import LiteLLMInstrumentor LiteLLMInstrumentor().instrument()调用.instrument()后所有经过litellm.completion()、litellm.acompletion()、litellm.embedding()、litellm.aembedding()的调用都会被自动追踪无需修改任何业务代码。在需要显式注入 SDK 组件例如测试或自定义导出的场景下可以传入tracer_provider与meter_providerLiteLLMInstrumentor().instrument( tracer_providertracer_provider, meter_providermeter_provider, )仓库的测试夹具见 tests/conftest.py即采用这种显式注入方式并在用例结束后调用instrumentor.uninstrument()完成卸载。三、包装了哪些方法、Span 如何生成WRAPPED_METHODSinit.py定义了一张插桩清单可以用表格概括被包装方法Span 名称gen_ai.operation.name是否异步litellm.completionlitellm.chatchat否litellm.acompletionlitellm.chatchat是litellm.embeddinglitellm.embeddingsembeddings否litellm.aembeddinglitellm.embeddingsembeddings是Span 以SpanKind.CLIENT创建并在创建时即写入两个基础属性gen_ai.provider.name解析结果见下一节与gen_ai.operation.namechat/embeddings。包装器的处理流程_wrap_factory/_awrap_factory见init.py可概括为检查抑制上下文若被抑制则直接放行详见嵌套抑制一节启动 Span记录请求侧属性与输入消息或事件模式下的输入事件记录调用耗时执行真实调用若发生异常记录error.type、record_exception、置 Span 状态为 ERROR并累加异常计数指标然后重新抛出正常返回时解析 Provider、序列化响应model_dump()只执行一次同时用于属性、事件与指标避免重复序列化开销、记录响应属性与指标、Span 置 OK 并结束流式请求走独立的流式累积通道详见流式场景一节。四、Provider 解析与归一化LiteLLM 使用的 Provider 前缀如azure、bedrock、vertex_ai与 OTel GenAI 语义约定中gen_ai.provider.name的标准取值并不完全一致。因此插桩实现了归一化逻辑init.py解析优先级如下从响应对象response._hidden_params.custom_llm_provider读取流式场景下则从每个 chunk 中解析从调用参数kwargs[custom_llm_provider]读取从模型名前缀读取model形如provider/model时取斜杠前部分全部失败时回退到兜底值litellmgen_ai.provider.name是anyOf [enum, string]非标准值也合法。归一化别名表源码_PROVIDER_ALIASES将 LiteLLM 前缀映射到 OTel 规范值例如LiteLLM 前缀规范化目标azureOTel 标准值Azure OpenAIazure_aiOTel 标准值Azure AI InferencebedrockOTel 标准值AWS Bedrockvertex_aiOTel 标准值GCP Vertex AIgeminiOTel 标准值GCP GeminimistralOTel 标准值Mistral AI未知前缀按原样透传不做强转。仓库的 test_provider_resolution.py 对该逻辑做了参数化断言如azure/gpt-4o归一化为 Azure OpenAI 标准值、openai/gpt-4o保持openai、someprovider/some-model原样透传、裸模型名gpt-3.5-turbo回退为litellm。归一化的意义让 LiteLLM 的链路和指标与其他直接插桩的 Provider 在gen_ai.provider.name维度上保持同一套取值体系便于跨 Provider 聚合对比。五、Span 属性与消息 Schema请求侧属性插桩从调用参数中提取以下属性_set_request_attributesinit.py属性名来源参数gen_ai.request.modelmodelllm.is_streamingstream布尔值gen_ai.request.temperaturetemperaturegen_ai.request.top_ptop_pgen_ai.request.max_tokensmax_tokensgen_ai.tool.definitionstoolsJSON 序列化后的工具定义列表其中gen_ai.tool.definitions会把 OpenAI 风格的工具定义type/function.name/function.description/function.parameters转成符合 OTel source-system 格式的字典后 JSON 序列化写入_build_tool_def/_set_tool_definitions。输入/输出消息parts 结构项目已全面采用基于 parts 的gen_ai.input.messages/gen_ai.output.messagesJSON Schema原先扁平的gen_ai.prompt.*/gen_ai.completion.*属性已被淘汰与仓库内 OpenAI 插桩产出的消息形态保持一致见init.py 的注释说明。输入消息gen_ai.input.messages示例[ { role: user, parts: [{type: text, content: What is the capital of France?}] } ]消息内容的规范化规则_map_content_parts/_map_content_block字符串内容转为{type: text, content: ...}单元素列表image_url块HTTP(S) 链接转uri类型部分data:base64 链接解析为blob类型部分带modality: image与mime_typeassistant 消息若携带tool_calls转为{type: tool_call, name, id, arguments}部分其中arguments会尽力从 JSON 字符串解析为字典role: tool的 tool 结果消息转为{type: tool_call_response, id: tool_call_id, response: content}部分与其调用的 tool call 通过 id 关联。输出消息gen_ai.output.messages在每条消息上额外携带finish_reason保证为非空字符串。Finish Reason 归一化LiteLLM 已将各 Provider 的 finish reason 归一为 OpenAI 取值插桩只需将其中与 OTel GenAI 词汇不一致的映射即可LITELLM_FINISH_REASON_MAPinit.py原始值映射后tool_callstool_callfunction_calltool_call其他如stop原样透传空/None顶层属性gen_ai.response.finish_reasons为去重后的元组保序且不受内容开关控制详见下一节。响应侧属性_set_response_attributesinit.py从响应写入gen_ai.response.id、gen_ai.response.model、gen_ai.usage.input_tokensprompt_tokens、gen_ai.usage.output_tokenscompletion_tokens、项目自定义属性gen_ai.usage.total_tokens以及当响应含prompt_tokens_details.cached_tokens时gen_ai.usage.cache_read.input_tokens。仓库的 test_completion.py 对这些属性做了端到端断言使用mock_response离线验证无需 API Key例如输出消息finish_reason stop、顶层gen_ai.response.finish_reasons (stop,)、gen_ai.usage.input_tokens 0等。六、隐私与内容开关核心配置这是原 README 的重点章节完整继承如下默认情况下该插桩会把 prompts、completions 和 embeddings 记录到 Span 属性中让你能清晰看到 LLM 应用的工作方式便于调试和评估输出质量。但如果其中包含高度敏感的用户数据你可能希望出于隐私原因关闭这一记录也可能只是想减小 trace 的体积。关闭方法将环境变量TRACELOOP_TRACE_CONTENT设为false。TRACELOOP_TRACE_CONTENTfalse源码层的判定逻辑should_send_prompts()见 utils.py的实现要点def should_send_prompts(): return ( os.getenv(TRACELOOP_TRACE_CONTENT) or true ).lower() true or context_api.get_value(override_enable_content_tracing)环境变量取值大小写不敏感False、false均生效仓库测试即用False未设置环境变量时默认值为true即默认记录内容还支持通过 OTel Context 中的override_enable_content_tracing键在代码层面覆盖实现更细粒度的动态控制。关闭后仍保留的属性关闭内容记录不等于放弃所有属性。根据 test_completion.py 的验证TRACELOOP_TRACE_CONTENTfalse时被移除gen_ai.input.messages、gen_ai.output.messages所有承载内容的消息属性仍然保留gen_ai.request.model、gen_ai.usage.input_tokens、gen_ai.response.finish_reasons顶层 finish reasons 不受内容开关限制等非内容属性。也就是说关闭内容后你依然能拿到模型、Token 用量、完成原因等关键的可观测数据只是不再记录 prompt/completion 的正文——这对成本监控与质量评估场景仍然够用同时兼顾了隐私与 trace 体积。事件模式下的内容移除在事件模式use_legacy_attributesFalse见第八节下内容开关同样生效事件体中的content字段会被删除assistant 的tool_calls中的function.arguments也会被移除见 event_emitter.py。七、指标Metrics插桩默认同时开启指标可用TRACELOOP_METRICS_ENABLEDfalse关闭见 utils.py。在_build_metricsinit.py中创建以下 4 个指标指标名类型单位说明gen_ai.client.token.usageHistogramtoken输入/输出 Token 用量gen_ai.client.operation.durationHistogramsGenAI 操作耗时gen_ai.client.generation.choicesCounterchoicechat 补全返回的 choices 数量llm.openai.chat_completions.exceptionsCountertimechat 补全调用异常次数Token 指标通过gen_ai.usage.token_type属性区分input/output两个维度耗时指标与 Token 指标、choices 计数都携带gen_ai.provider.name与gen_ai.request.model标签。此外还可通过LiteLLMInstrumentor构造参数get_common_metrics_attributes注入一组公共指标属性见 config.py。异常指标额外带error.type标签异常类名。测试 test_completion.py 验证了gen_ai.client.token.usage与gen_ai.client.operation.duration在调用后确实产出。八、流式场景span 生命周期与累积流式调用streamTrue返回的是 LiteLLM 的CustomStreamWrapper。插桩对其做了专门处理init.py_LiteLLMStream/_LiteLLMAsyncStream基于wrapt.ObjectProxy实现保留原流对象的接口与isinstance判定测试 test_streaming.py 验证包装后的流仍是litellm.CustomStreamWrapper调用方依赖的辅助方法不受影响每个 chunk 的id、model、usage、各 choice 的delta.content、role、finish_reason、tool_calls按 index 累积拼接 arguments被汇总进累积结构_accumulate_chunk流耗尽StopIteration/StopAsyncIteration、异常、close()/aclose()、__del__等所有退出路径都会确保 span 恰好结束一次_finish/_finish_error有done标志防重复。设计动机在源码注释中写得很清楚如果用裸生成器包装span 生命周期会绑定到流被完整消费一旦消费者提前break、超时或抛异常span 就会永远挂起。测试 test_streaming_span_ends_on_early_break 与 test_streaming_span_ends_on_consumer_error 正是这两类回归场景的验证。流式结束时累积结果会经_build_accumulated_response组装为完整响应id、model、choices、usage再走与普通调用相同的_finalize通道产出属性、事件与指标llm.is_streaming属性被置为True。九、嵌套抑制与自定义 Provider自定义 Providerlitellm.CustomLLMREADME 明确提到插桩同样覆盖通过litellm.CustomLLM注册的自定义 Provider。仓库测试 test_custom_provider.py 注册了一个假的CustomLLM处理器证明通过custom_provider_map路由的调用同样生成litellm.chatspangen_ai.provider.name解析为注册的 Provider 名myprov响应中的 Token 用量total_tokens7被正确记录。防重复 span 的抑制机制包装器在发起真实调用前会在 OTel Context 中挂上SUPPRESS_LANGUAGE_MODEL_INSTRUMENTATION_KEY源码定义于 semconv_ai/init.py并在调用结束后 detach。这带来两个关键效果测试 test_nesting.py 验证litellm 内部嵌套例如acompletion内部对仅支持同步的 Provider 委派completion或自定义 Router Provider 内部再次调用litellm.completion嵌套调用不会再开新 span只有最外层产生一个 span底层 Provider SDK 插桩LiteLLM 路由到 OpenAI/Azure 时会调用它们自身的 SDK若同时启用了opentelemetry-instrumentation-openai该插桩同样会识别这个抑制键而跳过——测试 test_both_openai_and_litellm_instrumented 验证了同时插桩两者不会重复计数只产出litellm.chat一个 span。此外_is_suppressed还同时检查 OpenTelemetry 标准的_SUPPRESS_INSTRUMENTATION_KEY支持标准的抑制机制。十、事件模式use_legacy_attributesFalse插桩支持两种输出模式由LiteLLMInstrumentor的构造参数控制LiteLLMInstrumentor(use_legacy_attributesFalse, exception_logger..., get_common_metrics_attributes...)构造参数默认值作用use_legacy_attributesTrueFalse时切换为事件模式通过 OTel Logger 以 LogRecord 形式发出gen_ai.*事件替代消息属性exception_loggerNone插桩内部出错时的回调dont_throw装饰器保证追踪失败不干扰业务调用见 utils.pyget_common_metrics_attributeslambda: {}为指标注入公共属性的回调事件模式下的事件命名见 event_emitter.py输入消息gen_ai.user.message/gen_ai.assistant.message/gen_ai.system.message/gen_ai.tool.message按角色命名角色与事件名一致时从 body 中省略role字段输出选择gen_ai.choice携带index、message、finish_reason、tool_calls所有事件属性固定带gen_ai.provider.name: litellm。注意事件模式仅在use_legacy_attributesFalse且提供了logger_provider时生效should_emit_events检查两者见 utils.py。测试 test_events.py 验证了事件路径下tool_calls与映射后的finish_reason能正确保留。十一、测试与验证方式仓库测试全部离线运行利用 LiteLLM 内置的mock_response参数模拟响应无需 API Key、无需网络但仍然走完整的 Provider 解析与ModelResponse归一化路径与真实调用代码路径一致见 test_completion.py 的说明。主要测试文件tests/test_completion.py同步/异步补全、tool_calls 输入序列化、工具定义捕获、finish reason 映射与去重、内容开关、指标产出tests/test_custom_provider.pyCustomLLM自定义 Provider 追踪与抑制验证tests/test_provider_resolution.pyProvider 别名归一化参数化测试tests/test_streaming.py同步/异步流式累积、提前 break / 消费者异常下的 span 收敛tests/test_embeddings.pyEmbedding 输入字符串与列表两种形态的 parts Schematests/test_nesting.py嵌套抑制与双插桩去重tests/test_events.py事件模式输出。在本地复现测试可进入包目录执行uv run pytest tests/项目配置见 project.json 的 test target。小结接入清单把以上内容收敛为一份可直接落地的接入清单安装pip install opentelemetry-instrumentation-litellm初始化应用启动时调用LiteLLMInstrumentor().instrument()可选传入tracer_provider/meter_provider/logger_provider业务代码零改动completion/acompletion/embedding/aembedding自动产生litellm.chat/litellm.embeddings的gen_ai.*Span 与 4 项指标隐私配置需要关闭内容记录时设置TRACELOOP_TRACE_CONTENTfalse非内容属性模型、Token 用量、finish reasons仍会保留进阶用use_legacy_attributesFalse切换事件模式用get_common_metrics_attributes扩展指标维度流式与嵌套场景无需额外处理。相关源码与文档入口README.md、插桩核心实现、配置类、工具函数。赞分享LLMOps可观测性【免费下载链接】openllmetryOpen-source observability for your GenAI or LLM application, based on OpenTelemetry项目地址https://gitcode.com/gh_mirrors/op/openllmetry点击查看免费下载相关推荐OpenLLMetry 接入指南用 OpenTelemetry 插桩 Anthropic SDK 实现 LLM 全链路可观测OpenLLMetry 接入指南用 OpenTelemetry 插桩 Anthropic SDK 实现 LLM 全链路可观测 导读 本指南讲解 openllmLLMOps可观测性OpenClaw 接入 LiteLLM 网关实战统一模型路由、用量审计与图像生成配置指南OpenClaw 接入 LiteLLM 网关实战统一模型路由、用量审计与图像生成配置指南 LiteLLM 是一个开源的 LLM 网关通过统一 API 接入AI 应用AI Agent交互助手后端即时通讯网关GPUStack 与 LiteLLM 集成指南将本地 GPU 集群聚合为统一 AI API 网关GPUStack 与 LiteLLM 集成指南将本地 GPU 集群聚合为统一 AI API 网关 GPUStack 提供了一套在自有 GPU 集群上高效部署与后端人工智能模型推理服务集群管理可观测性创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?