腾讯云 OpenTelemetry-Python 探针基于社区 OpenTelemetry Python 项目二次开发,同时支持对常见 AI Agent 框架和传统 Python 框架的自动埋点,兼容 OpenTelemetry 协议标准,能够和其他使用 OpenTelemetry 方案接入的应用实现链路信息互通。
前提条件
关于 OpenTelemetry-Python 探针支持自动埋点的 AI Agent 组件与框架,请参见 AI Agent 组件和框架支持清单。
关于 OpenTelemetry-Python 探针支持自动埋点的传统(非 AI 相关)组件与框架,请参见 传统组件与框架支持清单。
接入流程
获取接入点与 Token
2. 单击接入应用。
3. 选择您所要接入的地域以及业务系统。
4. 选择您想要的接入类型和上报方式,获取您的接入点和 Token。
说明:
内网上报:使用此上报方式,您的服务需运行在腾讯云 VPC。通过 VPC 直接连通,在避免外网通信的安全风险的同时,可以节省上报流量开销。
外网上报:当您的服务部署在本地或非腾讯云 VPC 内,可以通过此方式上报数据。请注意外网通信存在安全风险,同时也会造成一定上报流量费用。
安装 pip 包
通过
pip 命令安装探针,其中已包含 OpenTelemetry SDK 及 OTLP exporter 相关依赖。pip install tapm-distro-v2tapm-bootstrap -a install
tapm-bootstrap -a install 会扫描当前环境中已安装的框架,自动安装对应的插桩包(例如检测到 OpenAI 会安装 tapm-hook-openai-v2)。修改启动命令
在项目启动命令加上
tapm-instrument 前缀完成探针初始化。假设原来的项目启动命令是 ppython app.py,可以通过如下命令启动 Python 应用。tapm-instrument --traces_exporter otlp \\--metrics_exporter otlp \\--logs_exporter none \\--service_name <service_name> \\--resource_attributes "token=<token>,host.name=<host.name>" \\--exporter_otlp_endpoint <endpoint> \\python app.py
对应的字段说明如下,请根据实际情况进行替换。
<service_name> :应用名,多个使用相同应用名接入的应用进程,会表现为相同应用下的多个实例。应用名最长63个字符,只能包含小写字母、数字及分隔符“ - ”,且必须以小写字母开头,数字或小写字母结尾。<token> :获取接入点与 Token 中拿到业务系统 Token。<host.name>:该实例的主机名,是应用实例的唯一标识,通常情况下可以设置为应用实例的 IP 地址。<endpoint> :获取接入点与 Token 中拿到的接入点。说明:
探针默认使用 OTLP over gRPC 上报(
OTEL_EXPORTER_OTLP_PROTOCOL=grpc),接入点的端口为4317。如需切换到 HTTP,可显式设置环境变量 OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf,并使用 HTTP 端口(通常为4318)。设置 SessionID 和 UserID(可选)
探针内置
GenAIContextSpanProcessor,会在每个 Span 创建时自动从链路上下文的 Baggage 中读取 user_id / session_id / conversation_id ,并注入到 Span 属性中。推荐用法:tapm_user_session 上下文管理器
在业务代码入口用
with 块包裹后续调用即可,块内产生的所有 Span(无论是 HTTP、DB 还是 LLM 调用)都会自动带上对应属性;同时这三个值会被写入 W3C Baggage,随出站 HTTP 请求头 / MCP params._meta 自动传播到下游进程。from tapm.distro import tapm_user_sessionwith tapm_user_session(user_id="user-12345",session_id="sess-67890",conversation_id="conv-abcde", # 可选):resp = openai_client.chat.completions.create(model="gpt-4o-mini",messages=[{"role": "user", "content": "hello"}],)
进阶用法:手动设置到已有 Context
如果需要在自定义中间件、异步任务、消息队列消费者等场景把值绑定到指定的链路上下文,可使用
set_gen_ai_context:from opentelemetry.context import attach, detachfrom tapm.distro import set_gen_ai_contextctx = set_gen_ai_context(user_id="user-12345",session_id="sess-67890",)token = attach(ctx)try:do_business_logic()finally:detach(token)
跨进程传播
通过全局 propagator,下游服务的 Span 会自动继承
user_id / session_id / conversation_id,无需业务代码传递。如果下游服务需要开启独立会话(不继承上游值),在处理入口调用
clear_gen_ai_context ,清除已承继的 user_id / session_id / conversation_id。from opentelemetry.context import attach, detachfrom tapm.distro import clear_gen_ai_context, tapm_user_sessiondef handler(request):token = attach(clear_gen_ai_context())try:with tapm_user_session(user_id="new-user"):return do_work()finally:detach(token)
框架原生字段自动映射
部分 SDK 具备原生的 Session/User 字段,探针会优先从原生字段读取并自动同步到 Span 属性中,无需再手动使用
tapm_user_session:OpenAI / LiteLLM:
chat.completions.create(user="user-123", ...) 的 user 参数。Anthropic:
messages.create(metadata={"user_id": "user-123"}, ...) 的 metadata.user_id 字段。Agno:
Agent.run(user_id="...", session_id="...") 的原生关键字参数。OpenAI Agents:
RunConfig.group_id 自动映射到 gen_ai.session.id。AI 入口标记(可选)
AI 入口代表一条链路中开启 AI 相关逻辑的环节。探针会为每一条 AI 相关调用链的入口 Span 自动加上
gen_ai.is_entry = True 属性,用于标识 AI 入口。在大多数场景下,AI 入口标记无需由业务代码干预。在如下场景,可选择手动接管 AI 入口标记。场景 1:显式指定某个业务 Span 为入口
如果您希望自己的业务 Span(例如
agent.reasoning、workflow.run)作为整条链的入口,而不是让内部第一个 LLM 调用被判为入口,只需在 start_as_current_span 时把 gen_ai.is_entry 放进初始 attributes。from opentelemetry import tracefrom tapm.semconv import GENAI_ENTRY_ATTRIBUTEtracer = trace.get_tracer("my.business")with tracer.start_as_current_span("agent.reasoning",attributes={GENAI_ENTRY_ATTRIBUTE: True},):llm_call_1()llm_call_2()
行为说明:
1. 用户设的值优先:
GENAI_ENTRY_ATTRIBUTE 一旦在初始 attributes 中出现,探针不会覆盖(无论是 True 还是 False)。2. 接管整条链:显式设置了
is_entry=True 的 Span,其后续所有子 Span 会跳过自动打标;本 Span 结束后恢复自动判定,不影响后续独立调用。3. 禁用自动打标:如果希望某个 LLM 调用不被判为入口(例如一段"预热"调用),可在外层套一个
is_entry=False 的业务 Span。with tracer.start_as_current_span("warmup",attributes={GENAI_ENTRY_ATTRIBUTE: False},):llm_client.chat.completions.create(...) # 内部 LLM Span 不再被自动打 entry
场景 2:外部自建 LLM hook 参与自动打标
如果您在项目里自己封装了 GenAI 埋点(例如自研模型客户端),希望它产生的 Span 也纳入
is_entry 自动判定,可通过环境变量登记 instrumentation scope 名单。export TAPM_GENAI_EXTRA_SCOPES="my.company.llm,my.company.retriever"
说明:
其中
my.company.llm 需要与您 trace.get_tracer("my.company.llm") 的 scope 名一致。接入验证
1. 确认探针日志:查看
/tmp/tencent/agent-python.log,正常应能看到 tapm-instrument shim delegating to opentelemetry-instrument 以及各类 instrumentor 加载信息。2. 临时切换到 console exporter:将
--traces_exporter otlp 改为 --traces_exporter console(或设置环境变量 OTEL_TRACES_EXPORTER=console),触发一次业务调用,观察 stdout 中是否有 Span JSON 输出,并检查其中的 user_id / session_id / conversation_id 等属性是否符合预期。3. 确认 TracerProvider 就位。
tapm-instrument python -c "from opentelemetry import trace; print(trace.get_tracer_provider())"
应输出
TracerProvider(...) 而非 ProxyTracerProvider。4. 在 链路追踪 页面确认调用链数据已上报。