想象你是一家快递公司的调度员:一个包裹从用户手上出发,要经历揽收、分拣、干线运输、派送等多个环节。从前每个环节各记各的账——有人记纸质单、有人发微信、有人打电话,一旦包裹延误,你根本说不清它卡在哪个转运中心。OpenTelemetry(简称 OTel)就是把各环节统一成一套“扫码系统”:给每个包裹贴一张全球通用的物流单号,每个中转站都拿同一款扫码枪记录“到达、处理、发出”,并且把汇总数据自动发回总部大屏。放在 AI 应用里,这个“包裹”就是一次 LLM 请求,而“中转站”是网关、Prompt 处理、向量检索、模型推理、结果校验等模块。OTel 负责把这条请求变成一条完整可追踪的链路,同时用指标衡量吞吐、延迟、token 用量与成本,用日志记录异常细节。

岗位关联

对 AI 从业者而言,掌握 OTel 等于拥有 LLM 应用的“监控操作系统”;它是大模型运维、AgentOps、成本治理与可靠性工程岗位的核心基建能力。

目录
  1. 可视化演示
  2. 1. OTel 是什么
  3. 2. 数据模型三支柱
  4. 3. SDK 接入流程
  5. 4. 上下文传播
  6. 5. 采样策略
  7. 6. 导出与配置
  8. 7. LLM 专属扩展
  9. 8. 运维协作生态
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

动态演示OpenTelemetry的核心机制,通过源头/管道/节点/终端四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

OpenTelemetry:Open OpenTelemetry三信 SDK Instrumenta 核心机制可视化 OpenTelemetry整体架构与关键组件

1. OTel 是什么

快递公司如果只有一堆分散的纸质单据,调度员永远没法一眼看清全局。OTel 的野心,就是给整个行业定一套“统一包裹单 + 统一扫码枪 + 统一数据仓库”的规范。无论是自研服务、开源中间件还是云厂商组件,只要遵循这个规范,数据就能汇入同一个控制中心。

放在 AI 工程里,一次 LLM 请求会穿过 API 网关、Prompt 模板、向量检索、模型推理、限流与缓存等多个环节。没有统一规范时,各个服务分别写日志,问题发生时只能靠人工逐个翻。OTel 通过 SDK 和协议,把这些环节产生的追踪数据、指标数据、日志数据全部标准化,让“用户问了一句什么”变成一条可回放的完整链路。

OTel 的核心是三个信号:Trace(链路)、Metric(指标)、Log(日志)。它既是一个标准,也是一套开源实现,涵盖多语言 SDK、采集器 Collector、OTLP 协议,以及各类导出器。它不是某个监控产品的替代品,而是监控产品之上的公共管道。

所以,OTel 对 LLM 应用的意义,就像给所有包裹贴上了同一套可识别条码。从此,调度员不再需要看懂各分拣厂自创的编号,只需要一套系统就能追踪全局。

OTel=Trace∪Metric∪Log\displaystyle \text{OTel} = \text{Trace} \cup \text{Metric} \cup \text{Log}
OTel 相当于把三类数据装进同一个标准化管道。
  1. 统一管道OTel 不是单一信号,而是三大可观测信号的公共载体。
    OTel=Trace∪Metric∪Log\text{OTel} = \text{Trace} \cup \text{Metric} \cup \text{Log}
  2. 并集关系链路、指标、日志各有侧重,合在一起才构成完整真相。
    Trace∪Metric∪Log\text{Trace} \cup \text{Metric} \cup \text{Log}

2. 数据模型三支柱

快递员每到一个中转站都会“嘀”一下扫码枪,记录包裹在这个站点的到达和离开。在 OTel 里,这条完整的物流轨迹叫 Trace,而每一次扫码记录就是一个 Span。Span 是 Trace 的基本积木:它有名字、开始时间、结束时间、状态,以及一组可自定义的属性。

一个 LLM 请求的 Trace,可以简单理解成一串 Span。最外层 Span 代表“整个 LLM 请求”,它下面挂着“网关鉴权”“Prompt 构造”“向量检索”“模型调用”“结果校验”等子 Span。子 Span 再往下还可以有“数据库查询”“HTTP 调用”等更细的 Span。这些 Span 通过父子关系挂成一棵树,共同描述一次请求发生了什么。

除了 Trace,OTel 还有 Metric 和 Log。Metric 是“每分钟处理了多少包裹、平均耗时多长”这类可聚合统计;Log 则是“这个包裹包装破损”这类带时间的原始事件。三者在排障、容量规划和审计中缺一不可。

理解数据模型,就理解了 OTel 的“记账语言”。物流公司不会只靠一条总报表管理一切,它需要每个站点、每个包裹、每次异常都有独立记录;同样,LLM 应用也需要 Span 记录每一次调用细节,才能快速定位问题。

Trace={Span1,Span2,…,Spann}\displaystyle \text{Trace} = \{\text{Span}_1, \text{Span}_2, \dots, \text{Span}_n\}
一条 Trace 就是一组 Span 的集合,串起来就是一次请求的完整生命周期。
  1. Span 集合Trace 由 n 个 Span 组成,而不是只有一个笼统的时间段。
    Trace={Span1,Span2,…,Spann}\text{Trace} = \{\text{Span}_1, \text{Span}_2, \dots, \text{Span}_n\}
  2. 父子关系Span 之间通过 parent 字段形成树状结构,体现调用层级。
    Spanchild→Spanparent\text{Span}_{child} \to \text{Span}_{parent}

3. SDK 接入流程

给包裹贴条形码需要一套工具,这套工具在 OTel 里就是 SDK。使用 SDK 的流程很像“给快递员发放扫码枪并配置无线电网络”:先在应用里安装 OTel 依赖,再初始化一个 Provider,最后让业务代码产生 Span 并把数据交给导出器。

初始化 Provider 时,通常要设置 Service Name、环境、版本等资源信息。比如一个 Python 的 LLM 服务,可以叫 service.name="llm-gateway",这样所有数据都自动带上“这是哪个服务”的标签。SDK 启动后,你可以选择自动埋点,例如监听 HTTP 请求、数据库调用、OpenAI 客户端调用;也可以手动埋点,在关键业务逻辑外用 with tracer.start_as_current_span(...) 包一层。

接下来必须配置导出链:Span 先交给 BatchSpanProcessor 做批量缓冲,再交给 Exporter 发往后端。整个链条很像快递员扫完码后,不是立刻跑一趟总部送数据,而是先累积一批,再统一发车,从而降低对业务性能的影响。

接入 SDK 是 OTel 落地的第一公里。它解决的是“数据从哪来”的问题;数据一旦产生,后续的串联、采样、导出才有素材。

App→ SDK Provider→ Exporter Backend\displaystyle \text{App} \xrightarrow{\ \text{SDK}\ } \text{Provider} \xrightarrow{\ \text{Exporter}\ } \text{Backend}
应用数据经 SDK 进入 Provider,再经 Exporter 传到后端,是一条单向流水线。
  1. SDK 注入应用通过 SDK 产生 Span,而不是直接向后端发 HTTP。
    App→ SDK Provider\text{App} \xrightarrow{\ \text{SDK}\ } \text{Provider}
  2. Provider 装配Provider 负责管理 Tracer、Meter、Logger 等入口。
    Provider→Tracer+Meter+Logger\text{Provider} \to \text{Tracer} + \text{Meter} + \text{Logger}
  3. Exporter 发送最终数据由 Exporter 发往 OTLP 端点或第三方平台。
    Provider→ Exporter Backend\text{Provider} \xrightarrow{\ \text{Exporter}\ } \text{Backend}

4. 上下文传播

物流包裹在转运中心换车时,工作人员必须把原包裹单号同步到新的交接单上,否则后续扫码就接不上前一段。OTel 的上下文传播做的就是这件事:当请求从服务 A 调到服务 B 时,自动传递 Trace ID、Span ID、采样标记,以及若干自定义键值。

在 OTel 中,上下文 Context 是一个轻量容器。里面最核心的是 trace_id 和 span_id,它们决定一个新 Span 应该挂在哪棵树上。为了让不同语言、不同框架都能理解,业界普遍使用 W3C 制定的 traceparent HTTP 头来传输这些信息。浏览器、网关、微服务只要都能识别这个头,就能天然串联。

此外,Baggage 负责携带业务键值,比如用户 ID、租户 ID、会话 ID。它像包裹上额外贴的“易碎品”“加急”标签,一路随请求传递。对 LLM 应用来说,把 user.id 放进 Baggage,就能在排障时按用户维度过滤 Trace。

没有上下文传播,OTel 只能拿到一段段孤立的“扫码记录”。有了它,所有 Span 才能拼成一张完整物流地图,这也是全链路追踪的命脉。

Contextnext=Contextprev⊕Spannew\displaystyle \text{Context}_{next} = \text{Context}_{prev} \oplus \text{Span}_{new}
新上下文等于旧上下文加上一个新的 Span 信息,链路因此不断延长。
  1. 快照传递下一个服务拿到的是包含 trace_id 和 span_id 的上下文快照。
    Contextprev={trace_id,span_id}\text{Context}_{prev} = \{\text{trace\_id}, \text{span\_id}\}
  2. 新 Span 并入新 Span 把自己的 span_id 追加进上下文,继续向后传。
    Contextnext=Contextprev⊕Spannew\text{Context}_{next} = \text{Context}_{prev} \oplus \text{Span}_{new}

5. 采样策略

快递公司的质检组不可能拆开每一个包裹检查,只能按一定比例抽查。OTel 的采样策略也类似:不是每条 Trace 都必须采集入库,而是根据成本与价值做取舍。最常见的三类是 Head Sampling、ParentBased Sampling 和 Tail Sampling。

Head Sampling 是在请求刚进入系统时就决定“这条链路要不要采”,核心是快但粗。ParentBased Sampling 则规定:如果父 Span 被采样,子 Span 也一定被采样;如果父 Span 没采,子 Span 也不采,从而保持链路完整性。Tail Sampling 在链路全部结束后再做决策,可以结合状态码、耗时、是否报错来判断,更准确但需要额外的缓冲存储。

采样会直接影响成本和排障能力。采样率过高,存储费用暴涨;采样率过低,低频故障可能永远看不见。因此生产环境常用“错误链路全量采、正常链路按比例采”的混合策略。

采样不是“偷工减料”,而是用可控成本换取足够真实的全局统计。对 LLM 应用而言,token 费用和存储费用都高,采样策略因此成了运维治理的必答题。

E[cost]=p×Cfull+(1−p)×Creduced\displaystyle E[\text{cost}] = p \times C_{\text{full}} + (1 - p) \times C_{\text{reduced}}
期望存储成本 = 被采样链路的成本 + 未采样链路的低成本,p 是采样率。
  1. 采样率 pp 表示保留给后端的 Trace 比例,0 到 1 之间。
    0≤p≤10 \le p \le 1
  2. 全量成本被保留的链路需要完整存储、检索与展示。
    p×Cfullp \times C_{\text{full}}
  3. 缩减成本未采样的链路只留下极少量摘要或不留。
    (1−p)×Creduced(1 - p) \times C_{\text{reduced}}

6. 导出与配置

所有扫码数据最终要发回总部控制中心,快递公司绝不会让司机每次只送一个包裹。OTel 的导出器也有同样的批处理思想:数据先进入队列,攒够一批或到达时间阈值后统一发送。

最常用的导出协议是 OTLP,它支持 HTTP 和 gRPC 两种传输方式。配置导出器时,主要关注三个参数:Endpoint 指向哪,超时多久,是否开启压缩。比如把 OTLP 端点指向 http://collector.example.com:4318,就能让 Collector 统一接收并转发到后端。

网络总会有抖动,OTLP 导出器通常带重试与指数退避。第一次失败后等待 1 秒,第二次 2 秒、第三次 4 秒,直到封顶时间。这个机制很像快递线路拥堵时,司机先在网点排队,而不是反复猛打总部电话。

正确的导出配置,决定数据能否稳定送达。如果只埋点不导出,OTel 就像一套装好了条码机却从不联网的快递站,数据全部困在本地。

tretry=min⁡(τ0×2k, tmax⁡)\displaystyle t_{\text{retry}} = \min(\tau_0 \times 2^{k},\ t_{\max})
重试等待时间按指数增长,但仍设上限,防止对后端造成二次压力。
  1. 初始等待第一次重试前等待 τ₀。
    t0=τ0t_{0} = \tau_0
  2. 指数增长第 k 次重试的等待时间为 τ₀ × 2ᵏ。
    tk=τ0×2kt_{k} = \tau_0 \times 2^k
  3. 封顶保护等待时间不能超过 t_max。
    tretry=min⁡(tk, tmax⁡)t_{\text{retry}} = \min(t_k,\ t_{\max})

7. LLM 专属扩展

普通快递和 AI 专线快递需要不同类型的标签:AI 包裹上最好额外写明“模型名称、输入 token 数、输出 token 数、推理耗时”。OTel 社区为此定义了 GenAI 语义约定,专门描述大模型调用。

在一个 LLM Span 上,可以记录 gen_ai.request.model 表示模型名称,记录 gen_ai.usage.input_tokens 和 gen_ai.usage.output_tokens 表示输入输出 token 数,还可以记录 Prompt 摘要和 Completion 摘要。这些信息让链路不再只是“调用成功/失败”,而能回答“这次回答花了多少钱”。

有了 token 数,结合模型单价就能估算成本。假设输入每千 token 单价为 p_in,输出每千 token 单价为 p_out,则一次调用的成本可以写成下面的公式。把这些属性按模型、租户、应用聚合成 Metric,就能实时监控 AI 账单。

LLM 应用最大的运维焦虑之一就是“看不见的 token 账单”。OTel 的 Genre AI 扩展,相当于在快递包裹上自动贴了一张计价小票,让每一次 AI 推理都有据可查、有账可算。

Cost=Nin×pin+Nout×pout\displaystyle \text{Cost} = N_{\text{in}} \times p_{\text{in}} + N_{\text{out}} \times p_{\text{out}}
一次 LLM 调用的费用 = 输入 token 数×输入单价 + 输出 token 数×输出单价。
  1. 输入费用输入 Prompt 的 token 数量乘输入单价。
    Nin×pinN_{\text{in}} \times p_{\text{in}}
  2. 输出费用模型生成内容的 token 数量乘输出单价。
    Nout×poutN_{\text{out}} \times p_{\text{out}}
  3. 总成本两部分相加得到一次请求的模型成本。
    Cost=Nin×pin+Nout×pout\text{Cost} = N_{\text{in}} \times p_{\text{in}} + N_{\text{out}} \times p_{\text{out}}

8. 运维协作生态

统一物流网建好之后,快递公司往往还会在总部旁边设一个“客户体验分析台”,专门分析哪些包裹延迟、哪些用户投诉。OTel 负责的正是底层物流网;而 Langfuse 这类专用工具,则是在这张网上做 LLM 会话分析、Prompt 版本管理和人工反馈。

Langfuse 可以接收 OTel 数据,并把 Trace 转化成更贴近 LLM 产品的界面:用户会话、评论文本、Token 消耗、模型对比一目了然。也可以把 Langfuse 的 session_id 作为属性写进 Span,再导入通用监控平台,实现“业务视图”与“技术视图”双向切换。

在运维侧,你还能基于 OTel 指标建立告警:当 token 成本超过阈值、P95 延迟超过 3 秒、模型调用错误率超过 5% 时,自动触发值班通知。这样,物流网不再是静态地图,而是一个会主动报警的指挥系统。

OTel 不是终点,而是可观测性的地基。地基上面可以盖 Langfuse、Grafana、Prometheus、云厂商监控等各种建筑;只有地基扎实,LLM 应用才能真正做到“看得清、查得明、省得下”。

Alert=1[metric≥θ ∧ duration≥d]\displaystyle \text{Alert} = \mathbf{1}[\text{metric} \ge \theta \ \land \ \text{duration} \ge d]
告警触发条件是:某个指标超过阈值,并且持续超过一定时长。
  1. 指标越界例如 token 成本超过预算阈值。
    metric≥θ\text{metric} \ge \theta
  2. 持续时间需要持续 d 分钟才告警,避免瞬时抖动。
    duration≥d\text{duration} \ge d
  3. 组合条件两者同时满足时,告警位取 1 并通知值班人。
    1[metric≥θ∧duration≥d]\mathbf{1}[\text{metric} \ge \theta \land \text{duration} \ge d]

AI 应用场景

LLM 网关全链路排障

阶段:模型服务运维与 AgentOps

解决的问题:传统监控只能看到单服务日志,无法判断一次缓慢的 RAG 回答到底卡在向量检索还是模型推理。

具体案例:某客服助手在早晚高峰响应变慢,工程师通过 OTel 的 Trace 发现 70% 耗时发生在 Embedding 调用,而不是大模型本身;随后把向量库连接池扩容,P95 延迟直接下降一半。

Token 成本看板与预算告警

阶段:成本治理与 FinOps

解决的问题:OpenAI 账单按天延迟,团队无法实时掌握每个业务线的 token 消耗。

具体案例:团队在 OTel 的 LLM Span 上记录模型名、输入输出 token 数,用 OTLP 送到 Prometheus 后按租户聚合;当日成本超过预算 80% 时自动告警,并将用量最高的 Prompt 模板列出优化。

Langfuse 会话分析与产品迭代

阶段:模型评估与产品分析

解决的问题:Trace 能看到技术细节,但看不出用户在同一会话里的反馈和满意度。

具体案例:把 OTel 采集的 LLM 调用下发到 Langfuse,产品经理按用户会话查看每轮 Prompt、结果和用户评分,发现某类问题的负反馈率高达 40%,从而推动 Prompt 模板迭代。

Python 演示

python81 行
import randomimport timefrom dataclasses import dataclass, fieldfrom typing import Dict, Optional  @dataclassclass Span:    name: str    trace_id: str    span_id: str    parent_id: Optional[str]    start: int    end: int = 0    attributes: Dict[str, object] = field(default_factory=dict)     def finish(self):        self.end = time.perf_counter_ns()        return (self.end - self.start) / 1e3  class ParentBasedSampler:    def __init__(self, rate: float = 0.5):        self.rate = rate     def should_sample(self, parent_sampled: Optional[bool]) -> bool:        if parent_sampled is True:            return True        if parent_sampled is None:            return random.random() < self.rate        return False  class ConsoleExporter:    def export(self, span: Span) -> None:        latency = (span.end - span.start) / 1e3        print(            f"trace={span.trace_id} span={span.name} "            f"latency={latency:.2f}ms attrs={span.attributes}"        )  class Tracer:    def __init__(self, sampler: ParentBasedSampler, exporter: ConsoleExporter):        self.sampler = sampler        self.exporter = exporter        self._root_sampled = None     def start_span(self, name: str, parent: Optional[Span] = None) -> Span:        if parent is None:            trace_id = format(random.getrandbits(64), "016x")            self._root_sampled = self.sampler.should_sample(None)        else:            trace_id = parent.trace_id        span_id = format(random.getrandbits(64), "016x")        parent_id = None if parent is None else parent.span_id        return Span(name, trace_id, span_id, parent_id, time.perf_counter_ns())     def end_span(self, span: Span, attrs: Optional[Dict[str, object]] = None) -> None:        if attrs:            span.attributes.update(attrs)        span.finish()        if self.sampler.should_sample(self._root_sampled):            self.exporter.export(span)  def main():    sampler = ParentBasedSampler(rate=0.8)    exporter = ConsoleExporter()    tracer = Tracer(sampler, exporter)     root = tracer.start_span("llm-request")    db = tracer.start_span("vector-search", root)    tracer.end_span(db, {"db.collection": "docs"})    gen = tracer.start_span("chat-completion", root)    tracer.end_span(gen, {"gen_ai.usage.input_tokens": 120, "gen_ai.usage.output_tokens": 80})    tracer.end_span(root, {"http.status_code": 200})  if __name__ == "__main__":    main()
目的:用纯 Python 模拟 OTel 的 Span、ParentBasedSampler 和 ConsoleExporter,演示用户请求如何被拆成多个 Span 并按根节点采样决策统一导出。
  1. class ParentBasedSampler:定义父级采样器:根节点决定整棵链路是否保留。
  2. def should_sample(self, parent_sampled: Optional[bool]) -> bool:核心采样逻辑:父节点已采样则子节点跟进,根节点则按概率抽签。
  3. span_id = format(random.getrandbits(64), "016x")生成 16 位十六进制 Span ID,模拟 OTel 的全局唯一标识。
  4. self._root_sampled = self.sampler.should_sample(None)根 Span 启动时一次性决定整条 Trace 的命运。
  5. tracer.end_span(gen, {"gen_ai.usage.input_tokens": 120, "gen_ai.usage.output_tokens": 80})在 LLM Span 上附加 token 属性,作为成本监控的数据来源。

常见误区

误区OTel 能采集 Trace、Metric、Log,还能导出数据,那直接用它就够了,为什么还要 Langfuse、Grafana 这些平台?

正解OTel 本质上只是“采集管线和传输协议”,它不负责长期存储、多维统计、告警通知和产品化界面。就像快递公司建设了统一的扫码网络,但总部还需要专门的调度大屏和客服系统。LLM 应用尤其需要 Langfuse 这样的会话分析平台来辅助评估。

为何常见:因为 OTel 自带 SDK、Collector 和 Exporter,看起来已经是一条完整流水线,容易让人误以为它是“全家桶”。

误区把采样率调成 1% 能省下大量存储费用,反正大部分请求都是正常的。

正解过度降低采样率会让低频错误、边缘用户和特殊 Prompt 成为盲区。生产环境应采用混合策略:错误链路全量采、正常链路按比例采、关键业务用 Tail Sampling 兜底。采样是在“成本”和“可观测性覆盖度”之间做折中,而不是简单一刀切。

为何常见:在演示环境中数据量小,采样影响不明显;一旦线上流量变大,统计失真和盲区问题才会暴露。

误区只要在 Span 上设置了 `gen_ai.usage.input_tokens`,成本账单就会自动出现。

正解OTel 只负责记录“用了多少 token”,它并不知道每个模型每千 token 的价格,也不会自动跑账单。要得到成本,需要自己实现或借助平台根据价格表计算,再按模型、租户、应用聚合。

为何常见:因为“token 属性”和“模型报价”在界面里经常同时出现,容易让人误以为系统已经内置计价器。

误区LLM 应用出问题,看一条 Trace 就能定位,那指标和日志是不是多余?

正解Trace 擅长回答“某一次请求发生了什么”,但回答不了“最近一小时的 token 成本是否飙升”“错误率是否从 1% 涨到 10%”。Metric 提供趋势与聚合,Log 提供导致错误的原始细节,三类信号互相补充,缺一不可。

为何常见:因为 Trace 的瀑布图视觉冲击最强,初学者容易把个案当成全局。

面试题

Q1. OTel 最核心的目标是什么?

单选题 · easy

  • A.统一三类信号采集← 正确答案
  • B.训练更大的模型
  • C.自动生成业务代码
  • D.压缩日志存储成本

答案:A。OTel 的核心是统一 Trace、Metric、Log 三类信号的采集与导出,让可观测性数据标准化。训练模型、生成代码、压缩日志都不是它的职责。

Q2. 一次 LLM 请求的 Trace 由什么组成?

单选题 · easy

  • A.串成链的 Span 集合← 正确答案
  • B.单条独立的 Span
  • C.一组零散的时间点
  • D.一堆无结构的文本

答案:A。Trace 由多个 Span 按父子关系串成树或链。单个 Span 只是其中一环,零散时间点和无结构文本都不具备 Trace 的关联能力。

Q3. SDK 初始化 Provider 的主要作用是什么?

单选题 · mid

  • A.汇总链路并统一导出← 正确答案
  • B.训练 Prompt 并部署
  • C.压缩日志并做备份
  • D.替代 Trace 采集过程

答案:A。Provider 管理 Tracer、Meter、Logger,是 SDK 的核心入口,负责把业务代码产生的可观测性数据汇总并交给 Exporter。它不做模型训练或日志备份,也不是为了替代采集,而是组织采集。

Q4. 上下文传播时 Baggage 主要用于做什么?

单选题 · mid

  • A.跨服务携带业务键值← 正确答案
  • B.修改大型模型权重
  • C.删除旧的运维日志
  • D.生成随机新的 Span

答案:A。Baggage 像包裹上的附加标签,用来跨服务传递用户 ID、租户 ID 等业务信息。它不参与模型权重修改、日志删除,也不负责生成 Span。

Q5. 父级采样策略的基本原则是什么?

单选题 · mid

  • A.子 Span 跟随父采样决策← 正确答案
  • B.每个 Span 都重新抛硬币
  • C.优先丢弃根 Span 数据
  • D.所有请求必须全量采集

答案:A。ParentBasedSampler 规定子 Span 的采样结果跟随父 Span,保证整条 Trace 要么完整保留,要么整体丢弃。多次独立抛硬币会破坏链路完整性。

Q6. 在 LLM Span 上记录 token 成本主要依赖哪类信息?

单选题 · hard

  • A.GenAI 语义约定← 正确答案
  • B.随机价格字段
  • C.CPU 时钟周期数
  • D.网络包大小和

答案:A。OTel 的 GenAI 语义约定了模型名、输入输出 token 数等属性,成本才能基于真实用量计算。随机字段、CPU 周期和网络包大小都不是 token 计费依据。

Q7. 关于 OTel 与 Langfuse 的关系,理解正确的是?

单选题 · hard

  • A.OTel 采数据平台做分析← 正确答案
  • B.两者属于互斥替代关系
  • C.Langfuse 完全取代 OTel
  • D.OTel 无法接入 Langfuse

答案:A。OTel 负责数据采集与传输,Langfuse 负责 LLM 会话分析;Langfuse 可以接入 OTel 数据,两者是协作关系而非替代关系。

Q8. 下列属于 OTel 三大信号的是?

多选题 · mid

  • A.链路与跨度信号← 正确答案
  • B.指标聚合信号← 正确答案
  • C.结构化日志信号← 正确答案
  • D.提示词模板文本

答案:ABC。OTel 三大信号是 Trace、Metric、Log,分别对应链路、指标和日志。Prompt 模板是业务配置,不属于 OTel 信号体系。

Q9. 设计 LLM 应用采样策略时,需要考虑哪些因素?

多选题 · hard

  • A.存储成本与链路量← 正确答案
  • B.查询速度与覆盖率← 正确答案
  • C.分布式采样一致性← 正确答案
  • D.界面主题美观度

答案:ABC。采样影响存储成本、查询速度、数据覆盖率以及多个服务间的采样一致性。界面主题与可观测性系统设计无关。

Q10. 关于 OTel 在 LLM 运维中的应用,下列说法正确的是?

多选题 · extreme

  • A.生成请求级 Trace← 正确答案
  • B.采集 token 与费用← 正确答案
  • C.接入 Langfuse 平台← 正确答案
  • D.替换模型推理引擎

答案:ABC。OTel 可为 LLM 请求生成 Trace,通过 GenAI 属性记录 token 用量,并把数据导给 Langfuse 这类平台。它不负责模型推理,也无法替代推理引擎。