文章

LLM Observability 生产实战:用 OpenTelemetry GenAI 语义规范追踪 Agent 调用链

本文系统讲解如何使用 OpenTelemetry GenAI 语义规范为 LLM 与 Agent 应用建立可观测性,从调用链、Token、工具调用、隐私治理到上线检查,帮助团队定位延迟、成本和质量问题。

背景:为什么 LLM 应用不能只看接口日志

传统 Web 服务的问题通常可以从 HTTP 状态码、接口耗时、数据库慢查询和错误堆栈中定位。但 LLM 应用的失败路径更长:一次用户请求可能经过 RAG 检索、Prompt 拼装、模型调用、函数调用、外部工具、重试、二次总结、内容审核和最终响应。

当用户反馈”回答很慢""成本突然升高""Agent 调错工具""RAG 找错材料”时,普通日志往往只能看到入口接口成功返回,却看不到中间每一步到底发生了什么。

这就是 LLM Observability 的价值:不是简单记录一次 chat.completions.create(),而是把模型调用、检索、工具、Token、延迟、异常、成本和质量信号串成一条可分析的执行链。

OpenTelemetry 在 2026 年进一步强化了 GenAI 场景的语义规范。官方文章指出,GenAI 语义规范用于标准化记录模型名称、输入输出 Token 计数,以及在显式开启时记录 Prompt、Completion、工具调用和工具结果等内容。

核心问题:Agent 调用链里到底应该观测什么

一个生产级 Agent 请求至少应该拆成以下几类观测对象。

1. 请求入口

入口层要记录用户请求、租户、会话、业务场景、调用来源、请求 ID 和 Trace ID。这里不一定保存原始用户输入,但必须能把一次 LLM 执行和业务请求关联起来。

关键字段包括:

  • trace_id:贯穿整个调用链。
  • session_id:关联多轮对话。
  • tenant_id:多租户成本和问题定位必需。
  • user_intent:可选,用于后续质量分析。
  • feature_flag / prompt_version:定位 Prompt 改版引入的问题。

2. 检索与上下文构造

RAG 系统常见问题不是模型能力不够,而是检索上下文质量不稳定。因此要记录:

  • query rewrite 前后的查询。
  • 检索源、索引名称、过滤条件。
  • top-k 文档 ID、分数、版本号。
  • rerank 前后的排序变化。
  • 最终进入 Prompt 的 chunk ID。

OpenInference 文档明确提到,其规范目标之一就是提供 LLM 调用及周边应用上下文的可见性,包括向量存储检索和外部工具使用。

3. 模型调用

模型调用是最容易被观测,但也最容易被观测错的部分。只记录模型名称和耗时是不够的,至少应记录:

  • provider / model:模型供应商和具体模型。
  • operation name:chat、embedding、rerank、tool_call、agent_run 等。
  • input_tokens / output_tokens:成本和性能分析核心指标。
  • streaming / non-streaming:影响 TTFT 与用户体验。
  • finish_reason:判断截断、拒答、工具调用或正常停止。
  • temperature / max_tokens:解释输出不稳定的重要上下文。

Datadog 的 OpenTelemetry GenAI 支持文章也说明,GenAI 语义规范为 prompts、model responses、token usage、tool/agent calls 和 provider metadata 建立了统一 schema。

4. 工具调用与外部依赖

Agent 的不确定性很大一部分来自工具调用。每次工具调用都应成为独立 Span,而不是埋在模型输出文本里。

工具 Span 建议包含:

  • tool name。
  • tool type,例如 function、datastore、extension。
  • 参数 schema 版本。
  • 参数摘要或脱敏后的参数。
  • 执行耗时。
  • 返回状态。
  • 错误类型。
  • 是否触发重试或降级。

如果工具结果会影响最终回答,还应记录工具结果 ID 或摘要,便于后续审计。不要默认保存完整敏感结果。

5. 输出质量与后处理

LLM Observability 不应只停留在”是否成功返回”。对于生产应用,还需要补充质量信号:

  • 是否命中引用证据。
  • 是否通过结构化输出校验。
  • 是否通过安全策略。
  • 是否触发人工审核。
  • 用户是否点赞、点踩或继续追问。
  • 是否进入离线评估数据集。

LangSmith 文档也将可观测性覆盖到 individual traces、production-wide performance metrics、dashboard、alert、feedback 和 online evaluations 等环节。

OpenTelemetry GenAI 语义规范的工程价值

OpenTelemetry GenAI 语义规范的意义不是”又多一套字段名”,而是让 LLM 应用的观测数据从工具私有格式走向统一格式。

统一字段,降低迁移成本

如果每个框架都自定义 model_namellm_modelprovider_modeltoken_input_count,后续接入数据仓库、告警、成本系统和审计系统时会非常混乱。

GenAI 语义规范把常见字段统一到类似以下结构:

  • gen_ai.request.model
  • gen_ai.response.model
  • gen_ai.provider.name
  • gen_ai.operation.name
  • gen_ai.usage.input_tokens
  • gen_ai.usage.output_tokens
  • gen_ai.response.finish_reasons

MLflow 文档也明确说明,GenAI 语义规范提供描述 AI 和 LLM telemetry 的标准 schema,并支持在 OTLP 导出时映射到 gen_ai.* 字段。

一次埋点,多处消费

比较理想的架构是:应用侧按照 OpenTelemetry 或兼容库产生 trace,经由 OpenTelemetry Collector 做处理,再路由到多个后端。

Application / Agent Runtime
    -> OpenTelemetry SDK or GenAI Instrumentation
    -> OpenTelemetry Collector
    -> Redaction / Sampling / Enrichment / Routing
    -> Observability Backend / Data Lake / Evaluation System

这种架构的好处是:

  • 应用代码不绑定某一个可观测平台。
  • 脱敏、采样、路由可以集中治理。
  • 同一条 trace 可以进入 APM、成本系统、评估系统和审计系统。
  • 平台迁移时不用重写所有埋点。

Datadog 的文章也强调,使用 Collector 可以在数据离开网络之前应用 redaction、sampling、enrichment 和 routing 等处理器。

兼容 OpenLLMetry、OpenInference、MLflow、Phoenix 等生态

当前 LLM Observability 生态并不只有一种标准。OpenLLMetry 基于 OpenTelemetry 提供非侵入式 tracing,并可导出到现有观测栈。OpenInference 则提供用于 AI 应用 tracing 的约定和插件,并被 Phoenix 原生支持。

Phoenix 文档提到,不同 instrumentation 标准会用不同语义约定描述 LLM 操作,因此需要通过 Span Processor 做属性名映射、格式转换并保留数据。

这说明生产落地时不能只问”哪个 UI 好看”,而要先问:

  • 我的数据 schema 是否可迁移?
  • 是否支持 OTLP?
  • 是否能在 Collector 层脱敏?
  • 是否能导出到数据湖或评估系统?
  • 是否能和现有 APM trace 关联?

推荐落地架构

第一层:应用内最小埋点

不要一开始就手写所有 Span。优先使用成熟 instrumentation:

工具适用场景
OpenLLMetry快速给 OpenAI、Anthropic、LangChain、LlamaIndex 等调用加 tracing
OpenInferencePhoenix / Arize 生态,需记录 RAG、工具上下文的项目
MLflow Tracing已有 MLflow 体系,需实验、评估、Prompt 管理结合的团队
LangSmithLangChain / LangGraph 项目,需调试、反馈和在线评估的一体化平台

但自动埋点不能替代业务 Span。核心业务节点仍建议手动补充:

from opentelemetry import trace

tracer = trace.get_tracer("agent-runtime")

with tracer.start_as_current_span("agent.plan") as span:
    span.set_attribute("app.prompt.version", "support-agent-v17")
    span.set_attribute("app.tenant.id", tenant_id)
    span.set_attribute("app.routing.policy", "fast-model-first")
    plan = build_plan(user_message)

第二层:Collector 集中治理

LLM trace 里可能包含敏感信息。不要把所有 Prompt 和工具结果无脑打到 SaaS 平台。

Collector 层至少要做:

  • Redaction:脱敏手机号、邮箱、身份证、地址、密钥、合同号。
  • Sampling:高频成功请求采样,异常请求全量保留。
  • Enrichment:补充环境、版本、业务线、租户等级。
  • Routing:敏感业务 trace 进内网,普通聚合指标进 SaaS。
  • Retention:按数据敏感等级设置不同保留周期。

建议把”是否采集完整 Prompt / Completion”作为显式开关,而不是默认行为。

第三层:指标与告警

不要只做漂亮的 trace UI。生产告警至少覆盖以下指标:

指标说明建议用途
TTFT流式响应首 Token 延迟用户体验告警
Total latency完整请求耗时端到端 SLA
Input tokens输入 Token 数成本与上下文膨胀治理
Output tokens输出 Token 数成本与截断分析
Tool call count单次请求工具调用次数Agent 循环与异常行为识别
Retry count模型或工具重试次数稳定性分析
Retrieval hit rate检索证据命中情况RAG 质量分析
Validation failure rate结构化输出失败比例工程可靠性告警
Safety block rate安全策略拦截率风险监控

第四层:从 trace 回流到评估

Trace 的价值不应只用于排障。高价值生产 trace 应该回流为:

  • golden dataset。
  • prompt regression test。
  • agent tool-use benchmark。
  • reranker 训练或调参样本。
  • 安全规则回归用例。

2026 年关于 Agent traces 与 execution provenance 的综述也指出,仅看最终答案准确率不足以解释输出如何产生、证据如何支持声明、工具调用是否合理,以及错误从哪里发生。

常见误区

误区一:只记录模型请求和响应

这只能解决最浅层问题。真正影响稳定性的通常是检索、工具、重试、Prompt 版本和后处理。

误区二:把完整 Prompt 当普通日志保存

Prompt 可能包含用户隐私、商业数据、访问凭证和内部策略。默认全量保存会放大合规风险。

误区三:只接一个可观测 SaaS,不保留开放 schema

短期方便,长期可能造成数据锁定。建议至少保证 OTLP 导出、标准字段映射和批量导出能力。

误区四:只看平均延迟

LLM 应用更应该看分位数、TTFT、工具调用耗时、重试耗时和不同模型路径下的耗时差异。

误区五:没有把 trace 和 Prompt 版本关联

Prompt 版本、模型版本、工具 schema 版本和检索索引版本缺失时,线上问题很难复现。

上线检查清单

上线前建议逐项检查:

  1. 是否每个请求都有统一 trace_id。
  2. 是否可以从业务请求跳转到 LLM trace。
  3. 是否记录模型、供应商、Token、finish reason。
  4. 是否记录检索文档 ID 和索引版本。
  5. 是否把每次工具调用拆成独立 Span。
  6. 是否记录工具错误、重试和降级。
  7. 是否有 Prompt / Completion 采集开关。
  8. 是否在 Collector 或网关层完成脱敏。
  9. 是否区分成功请求采样和异常请求全量保留。
  10. 是否有成本、延迟、工具循环和结构化输出失败告警。
  11. 是否能把生产 trace 回流到离线评估集。
  12. 是否定义了 trace 数据的访问权限和保留周期。

结论

LLM Observability 的核心不是”看一次模型调用”,而是恢复一次 Agent 决策的完整上下文:用户请求如何进入系统,检索了哪些证据,模型调用了哪个版本,工具执行了什么,Token 和延迟花在哪里,输出为什么被接受或拦截。

OpenTelemetry GenAI 语义规范提供了一条更稳妥的工程路线:用开放字段描述 GenAI 工作负载,用 Collector 统一治理数据,用标准 trace 连接 APM、成本、评估和审计系统。

对于正在把 RAG、Agent、工具调用和多模型路由推向生产的团队,建议尽早把可观测性设计纳入架构,而不是等线上出问题后再补日志。

主要参考资料

常见问题

LLM Observability 和传统 APM 有什么区别?
传统 APM 更关注服务调用、数据库、接口延迟和错误;LLM Observability 还需要追踪模型、Token、Prompt、工具调用、检索证据、重试、成本和输出质量。二者不是替代关系,而是应通过 Trace ID 关联起来。
为什么建议使用 OpenTelemetry GenAI 语义规范?
它提供跨模型、跨框架、跨可观测平台的统一字段,让团队可以用同一套标准描述模型调用、工具调用、Token 用量、延迟和异常,降低厂商绑定。
生产环境是否应该记录完整 Prompt 和模型输出?
不应默认全量记录。应根据合规要求开启内容采集,并在 Collector 或网关层做脱敏、采样、权限控制和保留周期管理。更稳妥的做法是按环境、租户、数据等级进行控制。
是否必须使用 OpenTelemetry?
不是必须,但推荐优先兼容。OpenTelemetry 已是云原生可观测领域的通用基础设施,GenAI 语义规范让 LLM trace 能与现有 APM、日志、指标和 Collector 管道结合,减少重复建设。