章节摘要:Trace 是三支柱的骨架。第 2.1 节建立 span 分层模型:一次用户请求是 request → pipeline → 组件(检索/模型/工具)→ 子调用的树,每段工作是一个 span;你将用约 50 行纯标准库代码写出最小 tracer,跑出一棵带耗时的调用树。第 2.2 节解决关联与传播:trace_id 把用户、请求、日志、工具调用与 token 账本串成一条线,parent_id 还原父子,三方版本标签随 span 携带——成本与质量的归因全靠这根线。第 2.3 节面对现实约束:不可能全量记全文,讲采样(全量元数据 + 抽样正文 + 错误全采)、PII 脱敏(入库前处理)与留存分级(热/温/冷三档与存储成本权衡)。读完本章,能力清单 L1 的第 1、4、7 问应能转"能"。
request /answer(用户请求) ← 一切从这棵树开始 └── pipeline rag(编排) ├── retrieve(检索) ← 检索侧 │ └── embed(向量化) ├── llm.call(模型调用) ← 真正花钱的地方 │ └── retry(重试) └── tool.crm_lookup(工具执行) ← 副作用发生的地方 每个 span:名称 + 起止时间 + 属性 + parent_id 整棵树共享一个 trace_id ──▶ 贯穿日志与 token 账本 一句话记住本章的三个关键词: 分层(2.1)给结构,传播(2.2)给关联,闸门(2.3)给边界—— 三者齐备,"发生了什么"才从一句感叹变成一次可复查的记录。
一句话金句:没有 span 树的 LLM 应用排查,等于蒙着眼找一根掉进森林的针;trace_id 是拴在针上的那根线。
四层 span 模型 + 约 50 行纯标准库最小 tracer(span 树与耗时),以及 span 属性该记什么、不该记什么。
trace_id/span_id/parent_id 三 ID 分工;从用户请求到 token 账本的贯穿路径;三方版本标签;跨服务传播的写法示意。
数据量上来之后的三个现实问题:记什么不记什么(采样策略)、PII 如何在入库前脱敏、留存期限与存储成本的三档权衡。
┌──────────────┐ 先有树:span ┌──────────────┐ 再谈规模:量 ┌──────────────┐ │ 2.1 分层模型 │ ──────────────▶ │ 2.2 关联传播 │ ─────────────▶ │ 2.3 采样留存 │ │ 结构与耗时 │ parent_id 串树 │ trace_id 贯穿 │ 大了以后怎么办 │ └──────────────┘ └──────┬───────┘ └──────┬───────┘ │ │ │ ▼ ▼ ▼ span 上挂 token 用量 日志/账本/评分同键 合规与成本可控 (第 3 章成本记账的地基) (L2 归因的前提) (L3 第 19 问)
contextlib.contextmanager(第 2.1 节代码用到,不熟可先跑后懂)。gen_ai.* 属性族,实验态)。