晚上八点,一家面馆忙得不可开交。顾客点了“牛肉面,少辣多葱”,前台在小票上记下原话;后厨大厨按菜单起锅烧油,需要牛肉时让跑堂去隔壁肉铺取货;最后装盘上桌。整个过程看似顺畅,但若顾客投诉“面等太久”,店长怎么知道是前台记错、大厨手慢、还是肉铺缺货?答案是一张能实时显示每张订单走到哪一步、每步花了多久的“厨房监控屏”。 大模型应用和这家面馆一模一样:用户的一条指令(Prompt)进入应用后,会依次经过提示词加工、模型推理、工具调用、响应输出多个环节,这就是“调用链路”(Trace)。LLM Trace 可视化要做的,就是给每个环节盖上时间戳、记下消耗,再把整条链路画成清晰的时间线,让开发者像店长看监控屏一样,一眼定位到“哪一步慢了、哪一步失败了、花了多少钱”。

岗位关联

学完本节,你将掌握 LLM 调用链路的核心概念与可视化方法论,能借助 LangSmith、Phoenix 等工具构建大模型应用的可观测性体系,成为团队中懂得“给 AI 看病”的 MLOps 关键角色。

目录
  1. 可视化演示
  2. 调用链路全景
  3. 提示词输入追踪
  4. 模型推理监控
  5. 工具调用记录
  6. 响应输出分析
  7. 可视化工具
  8. 异常定位优化
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

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

LLM Trace 瀑布图可视化:展示 Prompt 构建、模型推理、工具调用、后处理各环节的延迟分布和 Token 消耗。

调用链路全景

面馆的订单小票从进店那一刻起,就被盖上了时间戳:几点几分前台接单、几点几分大厨起锅、几点几分跑堂出门取肉、几点几分装盘上桌。店长不用跑去后厨逐一追问,只要看一眼监控屏上的小票流转图,就知道整家店此刻在忙什么。LLM 应用里的“订单小票”就是 Trace(调用链路),小票上的每一道工序记录叫做 Span(环节片段)。

一次典型的 LLM 调用,用户只看到“输入一句话、输出一段回答”,但背后是一条完整的调用链:提示词输入捕获、模型推理、可能的工具调用、最后的响应输出。Trace 把这条链路上的每个环节都记录下来,包括开始时间、结束时间、输入输出摘要、Token 用量和状态码;Span 之间还有父子嵌套关系——比如“工具调用”内部又包含“请求搜索 API”和“解析搜索结果”两个子 Span。

在 LangSmith、Phoenix 这类工具里,每一条 Trace 都有全局唯一的 trace ID,对应一次用户请求;链路中的每个 Span 也有自己的 span ID 和父 Span ID。这些 ID 把分散在日志、中间件、模型服务中的数据串成一条可以回放的时间线。量化一次请求快不快,最朴素的指标就是链路总延迟,它可以拆解为各环节耗时的总和。

有了这份“小票分解账”,店长就能指着监控屏说:不是厨师慢,是跑堂去肉铺那趟花了 1.2 秒。LLM 应用同理,总延迟只能告诉你“慢”,Trace 才能告诉你“慢在哪一环”。

Ltotal=∑i=1nLi=Lprompt+Linfer+Ltool+Loutput\displaystyle L_{\text{total}} = \sum_{i=1}^{n} L_i = L_{\text{prompt}} + L_{\text{infer}} + L_{\text{tool}} + L_{\text{output}}
这条公式说的是:整桌菜上齐的时间,等于前台接单、大厨烹饪、跑堂取料、装盘上菜每一道工序耗时之和——哪个环节耗时长,一加一减就能看出占比。
  1. L_total(链路总耗时)一次请求从发出到收到完整响应的总时长,单位通常为毫秒。
    Ltotal\displaystyle L_{\text{total}}
  2. 求和符号把调用链上所有环节的耗时逐一累加。
    ∑i=1nLi\displaystyle \sum_{i=1}^{n} L_i
  3. 四项展开最常见的四个环节——提示词输入、模型推理、工具调用、响应输出——相加得到总延迟。
    Lprompt+Linfer+Ltool+Loutput\displaystyle L_{\text{prompt}} + L_{\text{infer}} + L_{\text{tool}} + L_{\text{output}}

提示词输入追踪

面馆前台有个好习惯:客人说“牛肉面少辣多葱”,她会把“少辣”“多葱”这两个定制要求原封不动写在小票上,后厨才不会做成默认口味。提示词输入追踪做的正是这件事——把用户发的原始指令连同参数一起留档,而不是等模型跑完只剩一句“已处理”。

很多 LLM 应用不是把用户的话直接丢给模型,而是套进一个提示词模板:模板里挖好槽位,把用户输入和系统指令、上下文数据填进去。比如客服机器人会拼出“你是客服小助手,用户的问题是:{},请用礼貌语气回答”。Trace 会记录模板渲染前后的差异:原始输入是什么、最终发给模型的长提示词是什么、用到了哪个版本的模板。

记录输入不只是为了审计,更是为了复现和对比。线上出问题时,如果没有输入快照,你根本不知道模型是被哪句怪话带偏的。LangSmith 会在 Trace 详情里展示每一步的输入输出,并给模板打上版本号,方便团队回滚或 A/B 对比。此外,提示词的规模直接影响计费——模型按 Token 收费,Token 是文本被切分成的最小单位。

就像小票上会同时记录“客人要了什么(输入)”和“后厨做了什么(输出)”一样,Token 账本把前后两本账分开记,哪边超支一目了然。

Ttotal=Tprompt+Tcompletion\displaystyle T_{\text{total}} = T_{\text{prompt}} + T_{\text{completion}}
这句公式是 Token 账单的骨架:一次对话的总 Token 数,等于喂给模型的输入 Token 加上模型吐出来的输出 Token,两者分别计量、分别计费。
  1. T_total(总 Token 数)一次请求计费时使用的 Token 总量。
    Ttotal\displaystyle T_{\text{total}}
  2. T_prompt(输入 Token)用户指令和模板合并后发送给模型的文本,切词后得到输入 Token 数。
    Tprompt\displaystyle T_{\text{prompt}}
  3. T_completion(输出 Token)模型生成的回答被切词后的数量。
    Tcompletion\displaystyle T_{\text{completion}}

模型推理监控

大厨是店里最贵的资产,也是最大的煤气消耗户。监控屏专门给他装了一块“燃气表”和一块“秒表”:炒一碗面用了多少方气(Token)、花了多少秒(延迟),都要记在小票上。模型推理环节正是 LLM 调用链上的“大厨”——它决定了响应质量,也吃掉了大部分延迟和费用。

模型推理监控围绕三个数字展开:延迟、Token、成本。延迟看分布而不是看单次:线上请求忽快忽慢时,P50、P95 延迟能告诉你大多数用户是快是慢、最差的情况有多糟。Token 则分输入输出两类,OpenAI 等厂商的计费表里,输入和输出单价往往不同,输出通常更贵。最后把三者相乘相加,就得到单次调用的成本。

成本公式看起来吓人,其实就是一个“单价 × 数量”的乘法。价格通常以每百万 Token(1M tokens)计,所以要除以 1000 换算成每千 Token 再乘消耗量。Trace 工具会在每个推理 Span 上标注 model 名称、输入输出 Token 数,LangSmith 还能按天聚合出“哪个模型花了多少钱”。

知道了每道菜的燃气成本,店长就能算出“爆炒系列”是不是该涨价、要不要换成节能灶——对应到工程上,就是根据 Trace 数据决定是否换更便宜的模型、精简输入。

Cost=Tprompt1000×Pin+Tcompletion1000×Pout\displaystyle \text{Cost} = \frac{T_{\text{prompt}}}{1000} \times P_{\text{in}} + \frac{T_{\text{completion}}}{1000} \times P_{\text{out}}
把输入 Token 数除以 1000 后乘输入单价,输出 Token 同理,两项相加就是一次调用的美元成本——相当于后厨把“燃气费 = 用气量 × 气价”写进了每张小票。
  1. Cost(单次调用成本)这一次模型请求花了多少钱。
    Cost\displaystyle \text{Cost}
  2. 输入 Token 费用输入 Token 数量除以 1000,再乘以输入单价。
    Tprompt1000×Pin\displaystyle \frac{T_{\text{prompt}}}{1000} \times P_{\text{in}}
  3. 输出 Token 费用输出 Token 数量除以 1000,再乘以输出单价。
    Tcompletion1000×Pout\displaystyle \frac{T_{\text{completion}}}{1000} \times P_{\text{out}}
  4. 两项相加输入部分与输出部分合计为总成本。
    Tprompt1000×Pin+Tcompletion1000×Pout\displaystyle \frac{T_{\text{prompt}}}{1000} \times P_{\text{in}} + \frac{T_{\text{completion}}}{1000} \times P_{\text{out}}

工具调用记录

面馆的招牌面需要特制牛肉,后厨自己没备货,跑堂得去隔壁肉铺买。肉铺不是自家开的,可能排队、可能缺货,这一来一回的时间全记在小票上。LLM 应用里的“跑堂”就是工具调用:模型遇到不会算的数学题、查不到的信息、需要操作的外部系统时,会发起一次函数调用(Function Calling),把结果拿回来再继续生成。

工具调用是 LLM 应用中不确定性最高的环节——它的耗时和成败往往不归模型管,而归搜索引擎、数据库、第三方 API 管。Trace 必须记录工具名、传入参数、返回结果摘要和状态码。工具调用失败时,工程上常见的做法是有限重试(比如最多 2 次),仍失败就走兜底回复,而不是让用户干等。

在可视化时间线上,工具调用通常表现为模型推理下方的一个子 Span,内部再嵌套网络请求、解析等子 Span。多次工具调用的平均耗时是有价值的健康指标:它突然升高,往往意味着下游服务变慢或被限流。Phoenix 会把工具调用的输入输出单独抽出来,方便检查“模型是否把参数传错了”。

店长如果发现最近肉铺平均要 5 分钟才送到,就知道该换供应商了——工具调用的平均耗时,就是提醒你“外部依赖是否该换”的温度计。

Lˉtool=1m∑j=1mLtool,j\displaystyle \bar{L}_{\text{tool}} = \frac{1}{m} \sum_{j=1}^{m} L_{\text{tool}, j}
它计算的是平均一趟“跑堂取料”要花多久:把最近 m 次工具调用的耗时加起来除以 m,得到一个稳定的基准线。偏离基准线就是警报。
  1. 平均工具耗时多次工具调用的平均延迟,衡量外部依赖的健康度。
    Lˉtool\displaystyle \bar{L}_{\text{tool}}
  2. 算术平均1 除以调用次数 m,表示“取平均”。
    1m\displaystyle \frac{1}{m}
  3. 求和把第 1 次到第 m 次工具调用的耗时全部累加。
    ∑j=1mLtool,j\displaystyle \sum_{j=1}^{m} L_{\text{tool}, j}

响应输出分析

客人坐下后最焦虑的是“我的面好了吗”。就算整碗面要 10 分钟,只要 2 分钟内先端上一碟小菜,客人的体验就好很多。LLM 应用也讲究“先出声”:模型不是憋 10 秒一次性吐完,而是像打字机一样逐字生成,第一个字出来的速度,直接决定了用户觉得“快不快”。

这个指标叫 TTFT(Time to First Token,首字延迟):从用户发出请求到收到模型返回的第一个 Token 的耗时。首字延迟取决于排队时间、网络往返、模型预处理和首轮推理速度。Trace 会把请求发出时刻和首个 Token 返回时刻都记录下来,让这两个时间戳的差无可争议。响应输出的另一面是质量和长度:输出 Token 越多,费用越高、等待越久,所以工程上常给 max_tokens 设上限。

输出环节还包含校验:检查答案是否为合法 JSON、是否包含敏感词、是否符合格式要求。校验失败时,好的应用会走兜底策略——重试一次或返回预设文案,而不是把错误裸奔给用户。Trace 会记录校验结果与兜底是否被触发,帮助团队统计“模型答非所问”的真实比例。

“先上小菜再等主菜”的策略,让客人不再盯着空桌面;监控 TTFT 就是确保每一桌都能及时看到“锅气”。

TTTFT=tfirst−trequest\displaystyle T_{\text{TTFT}} = t_{\text{first}} - t_{\text{request}}
首字延迟 = 收到第一个字的时刻 − 发出请求的时刻。它只在乎“第一口面多久能吃到嘴”,和后面整碗面吃多久无关。
  1. TTFT(首字延迟)衡量应用响应体感的关键指标。
    TTTFT\displaystyle T_{\text{TTFT}}
  2. t_first(首字到达时刻)客户端收到模型第一个输出 Token 的时间点。
    tfirst\displaystyle t_{\text{first}}
  3. t_request(请求发出时刻)用户请求离开客户端的时间点。
    trequest\displaystyle t_{\text{request}}
  4. 作差用到达时刻减去发出时刻,差值即首字延迟。
    tfirst−trequest\displaystyle t_{\text{first}} - t_{\text{request}}

可视化工具

前面讲的所有“小票记录”,如果只是锁在抽屉里,店长永远发现不了问题。可视化工具就是那面挂在墙上的监控屏:把每张订单的流转、每道工序的耗时画成图表。LangSmith 和 Phoenix 就是 LLM 领域最常用的两块“监控屏”。

LangSmith 由 LangChain 团队开发,提供云端一站式追踪:注册后埋点 SDK,就能在网页上看到每条 Trace 的输入输出、Token 消耗、延迟瀑布,还能把调试样本转成数据集做回归测试。Phoenix 则是开源自托管的可观测性平台,强调本地部署和数据私有化,适合对数据合规要求高的团队。两者的核心视图殊途同归:瀑布图(Waterfall)和火焰图(Flame Graph)。

瀑布图是最直观的 Trace 视图:一条横向时间轴,根 Span 是一条大横条,子 Span 在下方按时间位置错落排开,宽度即耗时。火焰图则把每个 Span 的耗时占比叠放成“横条堆叠”,一眼看出哪一段最宽——最宽处往往就是瓶颈。占比的计算很简单:某个环节耗时除以总耗时。

监控屏不是挂了就完事,它要让人 3 秒内看懂问题在哪。瀑布图和火焰图能做到这一点,正因为它把“哪里最宽”用最直白的方式怼到你眼前。

Ri=Li∑j=1nLj×100%\displaystyle R_i = \frac{L_i}{\sum_{j=1}^{n} L_j} \times 100\%
某个环节的耗时占比 = 该环节耗时 ÷ 链路总耗时 × 100%。厨房监控屏上,“模型推理”那条横条占了一大半,店长就知道该给大厨添个帮手了。
  1. 占比 R_i第 i 个环节在整条链路中的耗时百分比。
    Ri\displaystyle R_i
  2. 分子(环节耗时)被考察环节独自消耗的时间。
    Li\displaystyle L_i
  3. 分母(总耗时)所有环节耗时的总和。
    ∑j=1nLj\displaystyle \sum_{j=1}^{n} L_j
  4. 乘以 100%把比值换算成百分比形式。
    ×100%\displaystyle \times 100\%

异常定位优化

监控屏最大的价值不在平时,而在出事那 5 分钟:深夜突然有 3 桌客人同时投诉“面没上”,店长扫一眼屏,发现跑堂去肉铺的订单全卡在“缺货”状态。异常定位就是顺着 Trace 找到“卡住的订单”,优化则是从根上解决:给肉铺装个库存告警、或者干脆换一家供货商。

异常定位的第一步是成功率统计:把一段时间内成功响应与总请求数相除,低于阈值就告警。第二步是延迟分布,P95 比平均值更靠谱——少数慢请求把平均值拉高时,P95 能暴露“最差的一批人到底有多慢”。第三步是看 Trace 细节:把失败的 Trace 按错误类型聚合,最常见的错误就是优化的方向。

优化手段和厨房如出一辙:缓存相当于“把常点的招牌面提前备好料”,命中后模型都不用跑;精简提示词相当于“少放点配料”——输入 Token 少了,费用和延迟一起降;简单任务换小模型相当于“炸薯条不用请大厨”,成本能省一个量级。LangSmith 的 Trace 对比功能可以并排看优化前后的耗时和成本,让每次优化都有数据背书。

面馆靠监控屏熬过了最忙的晚高峰,靠的是“发现缺货 → 预制备料 → 换供应商”的闭环;LLM 应用也要跑通“监控 → 定位 → 优化”的循环,Trace 可视化正是这个循环的起点和终点。

S=NsuccessNtotal×100%\displaystyle S = \frac{N_{\text{success}}}{N_{\text{total}}} \times 100\%
成功率 = 成功响应的次数 ÷ 总请求次数 × 100%。就像店里一天的出餐成功率 = 成功上桌的订单 ÷ 全部订单,低于九成就该复盘流程了。
  1. 成功率 S链路监控中最基础的健康指标。
    S\displaystyle S
  2. 成功次数 N_success返回正常结果且无报错的请求数。
    Nsuccess\displaystyle N_{\text{success}}
  3. 总请求数 N_total统计周期内全部请求数(含失败)。
    Ntotal\displaystyle N_{\text{total}}
  4. 百分比换算相除后乘以 100% 得到百分比。
    ×100%\displaystyle \times 100\%

AI 应用场景

场景一:客服机器人的“事故复盘”

阶段:生产环境监控与排障

解决的问题:客服机器人上线后收到大量差评,传统日志只能看到“调用失败”四个字,无法回答“是哪一步失败、失败前模型看到了什么”。

具体案例:某电商客服机器人出现“答非所问”,工程师在 LangSmith 上打开失败的 Trace,发现是工具调用环节把商品 ID 传反了参数,导致查询结果与问题无关。修复参数映射后,差评率一周内下降 60%。

场景二:A/B 选型与成本审计

阶段:模型选型与成本优化

解决的问题:团队不知道该用 GPT-4o 还是更便宜的小模型,也不知道每月 Token 钱花在哪。

具体案例:通过 Phoenix 聚合一周的 Trace 数据,发现 70% 的请求属于“摘要归类”类简单任务,但全部走了大模型。改用小模型 + 缓存后,单日推理成本下降 45%,P95 延迟从 2.1s 降到 1.2s。

场景三:金融合规审计留痕

阶段:安全合规与审计

解决的问题:金融行业要求对 AI 回复的每句话都能追溯“它依据了什么、经过了哪些处理环节”。

具体案例:某银行智能投顾系统接入 Trace 后,每次对话都完整保留提示词原文、工具调用的行情数据源、模型版本和输出校验结果,稽查时可一键导出某个客户全部会话的调用链。

Python 演示

python100 行
# -*- coding: utf-8 -*-"""简易 LLM 调用链路追踪器:模拟一次带工具调用的问答,输出各环节耗时与成本"""import randomimport timefrom collections import OrderedDict  class Span:    """一个环节的耗时记录,相当于厨房里的一道工序"""     def __init__(self, name):        self.name = name        self.start = None        self.end = None        self.children = []     def __enter__(self):        self.start = time.time()        return self     def __exit__(self, exc_type, exc_val, exc_tb):        self.end = time.time()     @property    def duration_ms(self):        return (self.end - self.start) * 1000  class Tracer:    """链路追踪器:像订单小票一样记录整条调用链的嵌套关系"""     def __init__(self, trace_name):        self.trace_name = trace_name        self.root = Span(trace_name)        self.root.start = time.time()        self._stack = [self.root]     def span(self, name):        child = Span(name)        self._stack[-1].children.append(child)        self._stack.append(child)        return child     def end_span(self):        self._stack.pop()     def finish(self):        self.root.end = time.time()     def to_dict(self):        def conv(s):            return OrderedDict([                ("name", s.name),                ("duration_ms", round(s.duration_ms, 2)),                ("children", [conv(c) for c in s.children]),            ])        return conv(self.root)  def call_llm(prompt, trace):    """模拟一次 LLM 调用链:输入-推理-工具-输出,返回成本"""    with trace.span("prompt_capture"):        time.sleep(random.uniform(0.01, 0.03))        prompt_tokens = max(1, len(prompt) // 2)     with trace.span("model_inference"):        time.sleep(random.uniform(0.1, 0.4))        completion_tokens = random.randint(80, 200)     with trace.span("tool_query"):        time.sleep(random.uniform(0.05, 0.2))     with trace.span("response_output"):        time.sleep(random.uniform(0.01, 0.02))     cost = prompt_tokens * 0.02 / 1000 + completion_tokens * 0.06 / 1000    return cost  def main():    results = []    for i in range(5):        trace = Tracer("customer_query")        cost = call_llm("帮我查一下上海明天的天气", trace)        trace.finish()        total_ms = trace.root.duration_ms        results.append((total_ms, cost))        print("调用 %d 总耗时 %.1f ms,成本 $%.5f" % (i + 1, total_ms, cost))        print(trace.to_dict())        print()     times = sorted(r[0] for r in results)    avg = sum(times) / len(times)    p95 = times[-1] if len(times) < 20 else times[int(len(times) * 0.95) - 1]    total_cost = sum(r[1] for r in results)    print("平均耗时 %.1f ms,P95 耗时 %.1f ms,总成本 $%.5f" % (avg, p95, total_cost))  if __name__ == "__main__":    main()
目的:用 60 行代码实现一个微型链路追踪器,模拟一次带工具调用的 LLM 请求,输出嵌套 Span 耗时与 Token 成本统计。
  1. self._stack = [self.root]用栈保存嵌套上下文,新 Span 总是挂在栈顶父节点之下。
  2. def span(self, name):创建子 Span 并压栈,返回对象供 with 语句使用。
  3. with trace.span("model_inference"):模拟模型推理环节,进入时记开始时间、退出时自动记结束时间。
  4. cost = prompt_tokens * 0.02 / 1000 + completion_tokens * 0.06 / 1000按输入 0.02、输出 0.06 美元每千 Token 计算单次成本。
  5. trace.finish()给根 Span 盖上结束时间戳,总耗时才可以计算。
  6. print(trace.to_dict())把嵌套链路序列化为字典打印,相当于把订单小票摊开给人看。
  7. p95 = times[-1] if len(times) < 20 else times[int(len(times) * 0.95) - 1]样本不足 20 时用最大耗时近似 P95,防止索引越界。

常见误区

误区我只要把每一步都 print 出来,出了问题翻日志就行,没必要用 Trace 工具。

正解日志是一条条孤立的“流水账”,每行之间没有关联;Trace 则有全局 trace ID 把各个环节串成树形结构。好比厨房里每道工序各写各的记录,找“这碗面为什么慢”时还得凭时间瞎猜;监控屏把订单小票按 ID 串起来,一查便知。日志是素材,Trace 是关系图,分布式系统里没有关联的日志等于没有日志。

为何常见:小项目里日志确实够用,一旦并发请求变多、链路变深,日志排序混乱的问题才会暴露,初学者容易低估关联性的价值。

误区接口变慢了,肯定是模型推理拖后腿,换个更快的模型就行。

正解Trace 数据常常打脸:瓶颈可能是工具调用——一个慢速搜索 API 吃掉 60% 的延迟;也可能是排队、网络重试甚至 JSON 解析。就像客人抱怨上菜慢,老板第一反应怪大厨,结果发现是跑堂去肉铺堵车了。不拆分环节就优化,等于盲人摸象。

为何常见:模型推理名词最响、占比最大,直觉上最“像”瓶颈,而工具调用、序列化这些环节容易被忽视。

误区埋点会影响线上的性能,测不准还拖慢应用,不如不搞。

正解成熟方案的采样策略把开销控制在 1% 以内——只记录部分请求、异步上报、只存摘要不存全量原文。监控系统本身也要“记账”,但记账的成本远低于事故排查的成本。就像监控屏本身耗不了几度电,却能让整个厨房少出乱子。

为何常见:听过“监控有侵入性”的说法,但没有区分“全量同步记录”和“采样异步上报”两种截然不同的实现。

误区用户只看模型回答,生成的输出才是主要成本,输入不用管。

正解输入 Token 同样计费,而且很多应用输入比输出长得多——把整篇文档塞进提示词做总结,输入可能占账单的 70% 以上。公式是成本 = 输入价 + 输出价,两边都要记账。好比客人点菜时一次性说了 20 个要求,前台誊写的小票纸也是要花钱的。

为何常见:直觉上“回答是模型最费力的部分”,忽略了 Token 计费按字面量计算、与模型算力上的“费不费力”无关。

面试题

Q1. LLM Trace 的核心作用是什么?

单选题 · easy

  • A.提升模型自身准确率
  • B.追踪请求的完整调用链← 正确答案
  • C.辅助提示词工程调优
  • D.压缩模型的参数量

答案:B。Trace 的价值在于把一次请求经过的各个环节记录并串联起来,让开发者看清“慢在哪、错在哪”,而不是直接提高模型准确率。它解决的是可观测性问题,与模型调优和压缩无关。

Q2. 在链路追踪中,"Span"指的是什么?

单选题 · easy

  • A.一个独立子环节的计时段← 正确答案
  • B.一条完整的业务日志
  • C.模型的词表文件内容
  • D.工具的接口认证密钥

答案:A。Span 是链路中的一个环节片段,记录该环节的开始时间、结束时间、属性等;多个 Span 通过父子关系组成一条 Trace。日志是文本记录,词表和密钥与追踪无关。

Q3. 关于 Token 消耗的计算,下列说法正确的是?

单选题 · mid

  • A.输出 Token 不计费用
  • B.总 Token 为输入加输出← 正确答案
  • C.输入输出 Token 必相等
  • D.Token 与延迟无关联

答案:B。总 Token 数 = 输入 Token + 输出 Token,两者分别计费。输入输出长度没有必然相等的约束;Token 数量影响计费,也常与生成耗时正相关。

Q4. “首字延迟(TTFT)”衡量的是什么?

单选题 · mid

  • A.生成最后一个字的耗时
  • B.请求到首个字的耗时← 正确答案
  • C.工具调用的往返耗时
  • D.提示词模板渲染耗时

答案:B。TTFT 是从用户发出请求到收到模型第一个 Token 的耗时,决定用户的第一感受。生成结尾耗时是总延迟的一部分,工具往返和模板渲染只是链路中的子环节。

Q5. 下列属于 LLM 调用链主要环节的是?

多选题 · mid

  • A.Prompt 输入捕获← 正确答案
  • B.模型推理处理← 正确答案
  • C.工具调用执行← 正确答案
  • D.模型训练任务

答案:ABC。调用链覆盖一次推理请求的生命周期:输入捕获、模型推理、工具调用、响应输出。模型训练属于离线开发阶段,不在线上单次请求的调用链内。

Q6. 某次请求中“模型推理”耗时 800ms,“工具调用”耗时 1200ms,“输出”耗时 300ms,总链路 2300ms,瓶颈是?

单选题 · hard

  • A.模型推理环节
  • B.工具调用环节← 正确答案
  • C.响应输出环节
  • D.提示词捕获环节

答案:B。四个给定环节中工具调用耗时 1200ms 最长,占总耗时一半以上,是首要优化对象。瓶颈判断看各环节耗时占比,而非名称是否“重要”,这正是 Trace 拆分归因的价值。

Q7. 关于火焰图在 Trace 可视化中的作用,下列说法正确的是?

多选题 · hard

  • A.展示各环节耗时占比← 正确答案
  • B.识别最长耗时调用路径← 正确答案
  • C.替代日志存储原始文本
  • D.帮助定位性能瓶颈点← 正确答案

答案:ABD。火焰图把各 Span 耗时段按占比叠放,最宽的横条即瓶颈路径,用于快速定位性能问题;它是分析视图而非存储系统,不能替代日志保存原始文本。

Q8. 工具调用失败后,工程上常见的可靠处理策略是?

单选题 · easy

  • A.直接报错返回给用户
  • B.记录重试并兜底回复← 正确答案
  • C.忽略失败继续生成
  • D.无限重试直到成功

答案:B。可靠做法是记录失败原因 + 有限次重试 + 兜底回复,避免用户看到裸错误。直接报错体验差,忽略失败会污染生成结果,无限重试会拖垮下游服务。

Q9. P95 延迟的含义是?

单选题 · mid

  • A.九成五请求延迟低于此值← 正确答案
  • B.最慢 95 个请求平均延迟
  • C.九成五请求都会失败
  • D.所有请求延迟的中位值

答案:A。P95 表示排序后 95% 位置的延迟值,即 95% 的请求比它快。它比平均值更能暴露长尾慢请求,用于评估最差一批用户的真实体验。

Q10. 下列哪些手段可以有效降低 LLM 应用的 Token 成本?

多选题 · hard

  • A.精简提示词减少冗余← 正确答案
  • B.复用缓存结果避免重复← 正确答案
  • C.简单任务选用小模型← 正确答案
  • D.完全关闭输出长度上限

答案:ABC。精简输入 Token、缓存命中避免重复计费、简单任务用小模型(单价低、输出少)都是降本手段。完全关闭输出上限会让单次成本失控,反而推高费用。