☰
openllmetry 的 traceloop-sdk 使用指南:基于 OpenTelemetry 的 LLM 应用可观测性接入
2026/10/15 11:19:36 网站建设 项目流程
  • LLMOps
  • 可观测性

【免费下载链接】openllmetry

Open-source observability for your GenAI or LLM application, based on OpenTelemetry

项目地址:https://gitcode.com/gh_mirrors/op/openllmetry
点击查看免费下载

导读

traceloop-sdk是 openllmetry 仓库中面向 Python 的 LLM 可观测性 SDK,它以 OpenTelemetry 为底座,以非侵入式的方式自动埋点 LLM 应用:一行Traceloop.init()即可自动插桩 OpenAI、Anthropic、LangChain、LlamaIndex 等主流框架,并配合@workflow、@task等装饰器刻画业务实体与调用链。读完本文,你将掌握 SDK 的初始化参数、自动插桩选择机制、装饰器体系、关联属性(association properties)以及自定义导出/处理器等完整接入方案。

一、SDK 定位:非侵入式 LLM 可观测性

根据 packages/traceloop-sdk/README.md 的说明,该 SDK 的核心主张是:

  • 非侵入式:无需修改 LLM 调用代码,通过 OpenTelemetry 插桩机制自动捕获调用;
  • 基于 OpenTelemetry:trace 数据完全符合 OTel 语义约定(SDK 直接依赖opentelemetry-api、opentelemetry-sdk,并配套使用本仓库的 opentelemetry-semantic-conventions-ai 包定义 GenAI 语义属性);
  • 导出灵活:既可以把 trace 导出到 Traceloop 云端平台,也可以接入你现有的任何 OpenTelemetry Collector / 可观测性后端。

从 pyproject.toml 可以看到,SDK 还内置了日志(opentelemetry-instrumentation-logging)、HTTP 客户端(requests/urllib3)、数据库(sqlalchemy、redis)等通用插桩依赖,以及 40+ 个 GenAI 专项插桩包,构成完整的可观测性覆盖。

二、快速开始:最小可用示例

README 给出了最精简的接入形态——只需两步:调用Traceloop.init()初始化,然后用@workflow装饰业务函数:

Traceloop.init(app_name="joke_generation_service") @workflow(name="joke_creation") def create_joke(): completion = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[{"role": "user", "content": "Tell me a joke about opentelemetry"}], ) return completion.choices[0].message.content

这段代码揭示了两层机制:

  1. Traceloop.init()是总开关,负责创建 TracerProvider、注册 span processor、自动初始化各框架插桩(详见下文第三、四节);
  2. @workflow装饰器把create_joke标记为一个"工作流"实体,它内部对 OpenAI 的调用会自动产生 LLM span,并成为工作流 span 的子 span,从而在 trace 中还原完整的业务调用链(装饰器实现位于 decorators/base.py)。

更完整的可运行示例可参考仓库中的 packages/sample-app/sample_app/anthropic_joke_example.py,其中演示了带api_key/api_endpoint参数的Traceloop.init()调用。

三、Traceloop.init() 初始化参数详解

Traceloop.init()是 SDK 的入口,定义于 traceloop/sdk/init.py。关键参数如下:

参数默认值作用说明
app_namesys.argv[0]应用名,会作为 OTel 资源的service.name写入所有 trace/指标
api_endpointhttps://api.traceloop.comOTLP 导出端点;可被环境变量TRACELOOP_BASE_URL覆盖
api_keyNoneTraceloop 平台 API Key;可被TRACELOOP_API_KEY覆盖
enabledTrue总开关,为False时完全禁用插桩(输出黄色提示并直接返回)
headers{}自定义导出请求头;可被TRACELOOP_HEADERS覆盖(支持Key1: Value1,Key2: Value2格式字符串)
disable_batchFalse为True时使用SimpleSpanProcessor(同步导出),否则使用BatchSpanProcessor
telemetry_enabledTrueSDK 自身遥测开关
exporterNone自定义SpanExporter,替换默认 OTLP exporter
metrics_exporterNone自定义指标MetricExporter
logging_exporterNone自定义日志LogExporter
processorNone自定义SpanProcessor或处理器列表,可覆盖默认导出流程
propagatorNone自定义TextMapPropagator,会通过set_global_textmap全局生效
samplerNone自定义Sampler,用于 trace 采样
traceloop_sync_enabledFalse为True时启用 Traceloop 平台配置/提示词同步(Fetcher)
should_enrich_metricsTrue是否让各 LLM 插桩上报 token 用量等增强指标
resource_attributes{}附加 OTel 资源属性,service.name会自动并入
instruments全部显式指定启用的插桩集合(见第四节)
block_instrumentsNone显式禁用的插桩集合
span_postprocess_callbackNonespan 结束前回调,可用于脱敏/修改属性
use_attributesTrueTrue时 prompt/completion 以 span 属性(gen_ai.input.messages/gen_ai.output.messages)上报;False时改为 OTel log events
trace_contentNone控制是否捕获 prompt/completion 内容,等价于设置环境变量TRACELOOP_TRACE_CONTENT

3.1 初始化流程中的关键校验逻辑

从init.py 的实现可以看到几条重要行为:

  • use_attributes与use_legacy_attributes不能同时传入,后者已标记为 Deprecated(未来版本移除),建议统一使用use_attributes;
  • 若既未传exporter也未传processor,且api_endpoint仍是默认的https://api.traceloop.com而缺少api_key,SDK 会报错并提示去平台创建 API Key;
  • 同时传exporter和processor时,exporter会被忽略并给出告警——自定义processor应当自行包裹 exporter,例如SimpleSpanProcessor(my_exporter);
  • trace_content=False只是进程级关闭内容捕获,而每个关联属性(association properties)的允许列表(content allow list)仍可针对特定 span 重新开启内容追踪。

3.2 自定义导出端点

SDK 的init_spans_exporter(位于 tracing/tracing.py)会根据api_endpoint的 URL scheme 自动选择导出协议:

scheme导出器说明
http:///https://OTLP HTTP exporter自动补全/v1/traces路径
grpc://OTLP gRPC exporter(insecure)使用netloc作为端点
grpcs://OTLP gRPC exporter(TLS)安全模式
无 schemegRPC(insecure)为向后兼容保留的默认行为

因此接入本地 OpenTelemetry Collector 或任何兼容 OTLP 的后端,只需:

Traceloop.init( app_name="my_llm_app", api_endpoint="http://localhost:4318", # 标准 OTLP/HTTP 端口 )

四、自动插桩:Instruments 与插桩选择

SDK 的"非侵入式"核心在于自动加载各框架的插桩器。Instruments枚举定义于 instruments.py,覆盖了当前主流 GenAI 生态:

  • LLM 厂商:OPENAI、ANTHROPIC、COHERE、MISTRAL、OLLAMA、GROQ、TOGETHER、BEDROCK、SAGEMAKER、GOOGLE_GENERATIVEAI、VERTEXAI、WATSONX、WRITER、REPLICATE、ALEPHALPHA、VOYAGEAI、AGNO、OPENAI_AGENTS;
  • 框架/编排:LANGCHAIN、LLAMA_INDEX、LITELLM、HAYSTACK、CREWAI、MCP、TRANSFORMERS;
  • 向量数据库:CHROMA、PINECONE、QDRANT、MILVUS、WEAVIATE、LANCEDB、MARQO;
  • 基础设施:REQUESTS、URLLIB3、REDIS、PYMYSQL。

默认情况下init()会尝试初始化所有已安装库对应的插桩器;也可以精细控制:

from traceloop.sdk.instruments import Instruments # 只启用 OpenAI 插桩 Traceloop.init( app_name="chat_service", instruments={Instruments.OPENAI}, ) # 启用全部,但排除 Anthropic Traceloop.init( app_name="chat_service", block_instruments={Instruments.ANTHROPIC}, )

从 tracing/tracing.py 的init_instrumentations实现可见其选择逻辑:instruments集合先减去block_instruments,再逐个检查对应三方库是否已安装(is_package_installed),已安装才真正执行instrumentor.instrument();若最终没有任何插桩成功,会输出"No valid instruments set"的红色告警。这套逻辑在测试中有对应验证,见 tests/conftest.py 的exporter_with_custom_instrumentationsfixture。

注意:Instruments中CREW = "crewai"是已弃用的别名(源码注释标明会在未来大版本移除),请使用CREWAI。

五、装饰器体系:workflow / task / agent / tool / conversation

除自动插桩外,SDK 提供一套语义化装饰器,用于把函数标注为业务实体并自动生成 span。全部装饰器定义于 decorators/init.py,包括同步与异步版本:

装饰器span 类型(traceloop.span.kind)适用场景
@workflow(name=...)workflow端到端业务工作流(README 示例即用它)
@task(name=...)task工作流中的子任务
@agent(name=...)agentAgent 实体,遵循 OTel GenAI 的gen_ai.agent.name语义
@tool(name=...)tool工具调用,同时写入gen_ai.tool.name属性
@conversation(conversation_id=...)—为上下文中的所有 span 设置会话 ID(gen_ai.conversation.id)

5.1 span 命名与属性

以@workflow(name="joke_creation")为例,生成的 span 名称为joke_creation.workflow(f"{entity_name}.{tlp_span_kind.value}",见 decorators/base.py),并写入:

  • traceloop.span.kind:实体类型;
  • traceloop.entity.name:实体名称;
  • traceloop.entity.version(若传入version参数);
  • traceloop.entity.input/traceloop.entity.output:函数入参与返回值的 JSON 序列化(受内容追踪开关控制)。

实体名缺省时取函数的__qualname__。异步函数、生成器函数同样被支持:entity_method内部通过inspect.iscoroutinefunction/isasyncgenfunction自动分流(decorators/base.py)。

5.2 错误处理

装饰器对异常有完整的语义化处理:函数抛异常时,span 会被置为StatusCode.ERROR,状态描述携带异常消息并调用record_exception记录异常事件,随后异常原样向上抛出。这一点在 tests/test_tasks.py 中有直接的测试验证(同步与异步任务各一例)。

5.3 实体路径与上下文

装饰器在 span 建立时会通过 context 机制把workflow_name、agent_name、entity_path附加到当前上下文,后续创建的 LLM span 会自动继承(default_span_processor_on_start,见 tracing/tracing.py)。entity_path支持链式拼接:task 的路径会带上其父实体,例如workflow_name.task_name(get_chained_entity_path)。源码中的注释特别强调:这些 context token 必须在装饰函数结束时按 LIFO 顺序 detach,否则实体名会泄漏到同 trace 中后续创建的 span 上——这也是实现细节中对并发/异步场景的显式处理。

5.4 会话关联

@conversation(conversation_id="conv-123")可将同一会话中的所有 span 关联起来,支持与@workflow叠加使用(装饰器 docstring 给出了两个示例)。它内部调用set_conversation_id(tracing/tracing.py),写入符合 OTel GenAI 语义约定的gen_ai.conversation.id属性。

六、关联属性与内容追踪控制

6.1 Association Properties

关联属性用于把业务维度(客户、用户、会话)绑定到 trace 上,便于按业务口径检索。两种设置方式等价:

from traceloop.sdk import Traceloop # 方式一:直接传 dict Traceloop.set_association_properties({ "customer_id": "cust-123", "user_id": "user-456", }) # 方式二:使用标准枚举(定义见 associations/associations.py) from traceloop.sdk.associations import AssociationProperty from traceloop.sdk.associations import Associations Associations.set([ (AssociationProperty.CUSTOMER_ID, "cust-123"), (AssociationProperty.SESSION_ID, "session-789"), ])

标准枚举包括customer_id、user_id、session_id三个预定义键(associations/associations.py),也支持任意自定义键。关联属性会被写入每个 span 的traceloop.association.properties.<key>属性(tracing/tracing.py),并同样作用于指标的公共标签(metrics_common_attributes)。

6.2 内容追踪与允许列表

是否捕获 prompt/completion 等敏感内容,由TRACELOOP_TRACE_CONTENT环境变量控制(默认true,见 config/init.py)。此外 SDK 内置ContentAllowList(tracing/content_allow_list.py):当全局内容追踪被关闭时,若当前关联属性命中了允许列表(从 Traceloop 平台同步的associationPropertyAllowList),该 span 的内容追踪会被重新打开(override_enable_content_tracing)。这对于"默认脱敏、白名单用户例外"的合规场景很有价值。

七、环境变量速查表

以下环境变量在init.py 与 config/init.py 中有明确实现:

环境变量默认值作用
TRACELOOP_API_KEY无Traceloop 平台 API Key
TRACELOOP_BASE_URLhttps://api.traceloop.comOTLP 导出端点
TRACELOOP_HEADERS无自定义导出请求头(K: V逗号分隔)
TRACELOOP_TRACING_ENABLEDtrue总开关,置false时跳过 tracing 初始化
TRACELOOP_TRACE_CONTENTtrue是否捕获 prompt/completion 内容
TRACELOOP_METRICS_ENABLEDtrue是否启用指标
TRACELOOP_METRICS_ENDPOINT/TRACELOOP_METRICS_HEADERS继承 tracing 配置指标专用端点与请求头
TRACELOOP_LOGGING_ENABLEDfalse是否启用日志导出(默认关闭)
TRACELOOP_LOGGING_ENDPOINT/TRACELOOP_LOGGING_HEADERS继承 tracing 配置日志专用端点与请求头
TRACELOOP_SUPPRESS_WARNINGSfalse抑制"未初始化"告警
OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT无装饰器 JSON 入参/出参属性的截断长度(见 decorators/base.py)

八、指标与日志

  • 指标:SDK 会为 token 用量(Meters.LLM_TOKEN_USAGE)等指标建立带显式 bucket 的直方图视图,并对 Pinecone 查询耗时/相似度等预置聚合(metrics/metrics.py)。传入metrics_exporter即可把指标导出到自定义后端。
  • 日志:默认关闭(TRACELOOP_LOGGING_ENABLED=false)。启用后通过opentelemetry-instrumentation-logging的LoggingInstrumentor自动接入标准logging,并挂载LoggingHandler到logging.basicConfig(logging/logging.py),实现 Python 日志的 OTel 结构化导出。

九、自定义导出:exporter 与 processor

9.1 传入自定义 exporter

适用于"导入到自有可观测性栈"的典型场景:

from opentelemetry.sdk.trace.export import SimpleSpanProcessor from my_backend import MySpanExporter Traceloop.init( app_name="my_app", exporter=MySpanExporter(), )

9.2 传入自定义 processor 列表

processor参数支持单个或多个SpanProcessor。SDK 会链式包装每个 processor 的on_start,保证默认的实体属性注入(workflow/task 名称等)依然生效。测试 tests/conftest.py 展示了"默认 Traceloop processor + 自定义 processor"的组合用法:

default_processor = Traceloop.get_default_span_processor(disable_batch=True) custom_processor = MyCustomSpanProcessor() Traceloop.init( app_name="my_app", processor=[default_processor, custom_processor], )

Traceloop.get_default_span_processor()是官方提供的辅助方法(init.py),方便用户把 SDK 默认处理器与其他自定义处理器合并使用。

9.3 span 后处理回调

span_postprocess_callback允许在 span 结束前对属性做脱敏/改写。由于 OTel 在Span.end()后会把属性标记为不可变,SDK 在回调执行期间临时解除冻结、回调结束后恢复(tracing/tracing.py)。tests/conftest.py 给出了把gen_ai.input.messages内容替换为"REDACTED"的脱敏示例,是生产环境治理敏感数据的常用手段。

十、Client 高级能力

当使用 Traceloop 平台(api_endpoint指向 traceloop.com 且提供api_key)时,Traceloop.init()会返回一个Client实例(client/client.py),聚合了以下能力(从 SDK 包结构 traceloop/sdk 可以看出):

  • Prompt 管理:prompts/registry.py维护PromptRegistry,支持按 key 加载平台同步的提示词版本(get_prompt_by_key/load),配合set_prompt可在 trace 中记录模板与变量;
  • Datasets / Experiment / Evaluator:数据集管理、离线实验与评估(datasets、experiment、evaluator);
  • Guardrails:@guardrail(*guards, input_mapper=..., on_failure=..., name=...)装饰器为函数附加输出校验,支持"raise"(默认)、"log"、"ignore"或自定义兜底字符串/回调(decorators/init.py);
  • User Feedback:user_feedback子客户端收集用户反馈。

单例模式还支持Traceloop.get()获取共享 client;如需多实例,可直接构造Client(api_key=..., app_name=..., api_endpoint=...)。

十一、适用前提与限制

  • Python 版本:SDK 要求python >= 3.10, < 4(pyproject.toml)。
  • 依赖体量:SDK 默认聚合了全部 40+ 插桩包(见 pyproject.toml 的[project.optional-dependencies]与[tool.uv.sources])。插桩是否实际生效取决于对应三方库是否已安装——未安装的库会被自动跳过,因此不会因缺依赖而崩溃。
  • 内容追踪注意点:use_attributes=False走 OTel log events 路径,需要应用自行配置EventLoggerProvider(opentelemetry._events.set_event_logger_provider),否则 prompt/completion 数据将无处可去(init.py 的 docstring 明确说明)。
  • 装饰器未初始化时的行为:若未调用Traceloop.init(),被装饰函数会降级为直接执行原逻辑(TracerWrapper.verify_initialized()返回False),不产生 trace,也不抛异常,可通过TRACELOOP_SUPPRESS_WARNINGS=true关闭相关告警提示。
  • 早退的生成器:源码注释提示,对异步生成器若消费者未aclose()就提前break,实体名清理可能延迟到事件循环回收时才执行;需要确定性清理时应使用contextlib.aclosing()或排空生成器(decorators/base.py)。

结语

traceloop-sdk把 OpenTelemetry 的插桩能力与 LLM 业务语义(workflow/task/agent/tool、会话、关联属性)封装成极简 API:接入成本低至一行初始化,深度使用时又能精细控制插桩范围、内容脱敏、自定义导出与平台高级能力。若要继续深入,建议直接阅读 packages/traceloop-sdk/traceloop/sdk 下的源码与 packages/traceloop-sdk/tests 中的测试用例,前者是行为的最终权威,后者则提供了大量可直接复用的验证模式。

  • LLMOps
  • 可观测性

【免费下载链接】openllmetry

Open-source observability for your GenAI or LLM application, based on OpenTelemetry

项目地址:https://gitcode.com/gh_mirrors/op/openllmetry
点击查看免费下载

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

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

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

立即咨询