W4D5 学习手册 1.Trace本质2.固定字段3.自定义Span4.层级结构 5.埋点6.排错7.成本归因8.评测 9.技术选型10.流式回调11.理赔实践达标① 达标②自测速记

FDE W4D5 学习手册 · Trace 与成本

W4 Day5 · A 级(必须掌握,面试核心)· 4h · 学会给 Agent 装上"黑匣子":一次调用全程可观测、成本可归因、结果可评测

本日定位:Agent 是个"黑盒",没有 Trace 你永远不知道它为什么慢、为什么贵、为什么错。本日定义一套贯穿全链路的 Trace 字段与 Span 规范,并讲清它如何服务排错、成本、评测三件事。
学完能回答:① 一次 Agent 调用的 Trace 结构(固定字段 + 自定义 Span);② Trace 怎么用于排错、成本归因、评测。
使用方法:通读原理 → 重点背「面试话术」「易错点」→ 做自测清单 → 配合《FDE-W4D5-评测题.md》。选中不熟的词可标注(左下★重要 / 右下📌待查)。
候选人视角:36 岁,Java + 大数据 + 医疗保险。你的大数据背景在这里是加分项——Trace 本质是"结构化日志 + 指标 + 血缘",正是你熟悉的领域。

一、Trace 的本质:Agent 的黑匣子

Trace(追踪)是对一次完整请求从入口到出口的全过程记录,由一棵有序的 Span(跨度)树组成。对 Agent 而言,一次用户提问可能触发多次 LLM 调用、RAG 检索、工具调用、人工审批——Trace 把它们串成一条可回放的因果链。

1.1 为什么 Agent 特别需要 Trace

Trace 不是"多打几行日志",而是结构化的、带父子关系的、可聚合的观测数据。它的价值在于既要能"看一条"(排错),也要能"看一片"(成本/质量趋势)。这正是可观测性三支柱(Logs/Metrics/Traces)里 Trace 的位面。
Trace 就是 Agent 的黑匣子:一次请求全程的 Span 树。没有它你不知道 Agent 为什么慢、为什么贵、为什么错。它既能单条回放排错,也能批量聚合做成本和评测分析。
① Trace 不等于"打印日志"——日志是扁平文本,Trace 是带 parent/child 关系的树,能还原因果。② 不要等出问题才想接 Trace,应在架构设计期就定好字段和 Span 规范。③ Trace 数据量大,要权衡"全量采样 vs 按比例采样",医疗高风险场景建议关键链路全量。

二、固定 Trace 字段:全链路统一埋点

无论底层用什么框架(LangChain/LangGraph/Spring AI),都应有一组统一、必填的顶层字段,保证跨系统可聚合、可比对。

字段含义用途
trace_id一次请求全局唯一 ID串联所有 Span,定位单次会话
user_id_hash用户的脱敏哈希(非明文)用户级成本/质量分析,保护隐私
tenant_id租户/机构 ID(多租户)按机构拆分成本与权限
model_provider模型厂商(如 qwen/deepseek)厂商维度成本/质量对比
model_name具体模型(如 qwen-max)模型维度归因
prompt_version提示词版本提示迭代的 A/B 与回归
knowledge_version知识库版本RAG 效果归因
agent_versionAgent/工作流版本整体迭代归因
tool_name调用的工具名工具成功率/耗时分析
input_tokens输入 token 数成本计算
output_tokens输出 token 数成本计算
latency_ms耗时(毫秒)性能/SLA 监控
cost本次花费(金额)成本归因
status成功/失败成功率监控
error_type错误类型故障归类
版本字段(prompt/knowledge/agent_version)是隐藏重点:它们让"效果变化"可归因到"哪次改动"。比如某天拒赔率突增,一查是 knowledge_version 从 v3 升 v4 引入脏数据——没有版本字段你只能瞎猜。
固定字段是"全链路统一身份证":trace_id 串联、user_id_hash/tenant_id 做隐私与多租户拆分、model/prompt/knowledge/agent 四个 version 做归因、token/cost/latency/status/error 做成本与质量。版本字段最能体现代码素养。
user_id_hash 一定要脱敏,不能直接存明文身份证/手机号,否则合规事故。② token 字段要在"单次 LLM 调用"粒度记录,而非只在最外层记总数,否则无法定位哪次调用最贵。③ cost 建议服务端按厂商单价计算后落库,别让前端传,避免被篡改且单价易变。

三、自定义 Span:把 Agent 的关键动作都埋进去

除了框架自动生成的 LLM Span,必须按业务手动埋点以下 Span 类型,才能覆盖 Agent 特有环节。

Span 类型代表动作关键属性
llm.call一次大模型推理model, input/output tokens, latency, prompt_version
rag.retrieve向量检索召回query, top_k, 命中数, knowledge_version, 命中得分
rerank.call重排序模型, 重排前后 top 变化, latency
agent.stepAgent 一个推理-决策步step_index, 选定工具, 思考摘要
tool.call工具/外部接口调用tool_name, 入参(脱敏), 出参摘要, 状态码
human.approval人工审批节点审批人, 决定, 等待时长, 是否修改
eval.case评测用例执行case_id, 指标, 期望/实际, 评分
自定义 Span 把"Agent 专有动作"显性化。比如 human.approval Span 记录了"等了多久、人改了什么",这是纯 LLM 观测工具看不到的——而它恰恰是医疗理赔成本与风险的核心。埋点规范要进代码规范,而非临时打印。
除了框架自带的 llm.call,我们还要埋 rag.retrieve、rerank.call、agent.step、tool.call、human.approval、eval.case。尤其 human.approval 记录等待时长和人的决定,是医疗理赔成本和风险的关键观测点。
① 别只在最外层记一个总耗时,要细分到每个 Span,否则"慢"无从定位。② tool.call 的入参可能含敏感信息(身份证、病历),必须脱敏后再进 Trace。③ human.approval 的"等待时长"很重要——审批排队会直接拉高端到端延迟,是成本隐性来源。

四、一次 Agent 调用的 Trace 层级结构

Trace 是一棵树:根 Span 是本次请求,子 Span 按调用嵌套。

Trace (trace_id=T1, user_id_hash=U*, tenant_id=HospitalA)
└─ agent.step#1            # 规划:决定先检索
   └─ rag.retrieve         # 召回 8 条,knowledge_version=v4
      └─ rerank.call       # 重排后取 top3
   └─ llm.call             # 生成工具调用参数(qwen-max, p_v2)
└─ tool.call(查询医保目录)  # 成功,12ms
└─ agent.step#2            # 规划:需人工审批
   └─ human.approval       # 等待 8min,人改金额 8w→5w,通过
└─ tool.call(放款)          # 幂等键保护,成功
└─ llm.call                # 生成最终答复(deepseek, p_v1)
Trace = 根Span(请求) → 嵌套 Span(agent.step → rag/rerank/llm/tool/human.approval) 每Span带固定字段 + 自定义属性
一次 Agent 调用的 Trace 是棵树:根是本次请求,下面是 agent.step(每步决策),再嵌套 rag.retrieve、rerank、llm.call、tool.call、human.approval。每个 Span 都带固定字段(token/cost/latency/status)。
① Span 必须有正确的 parent 关系,否则树会被拉平、因果丢失。② 同一 trace_id 下的 Span 要在不同服务间传播(用 W3C traceparent 头),分布式部署时最容易断链。③ 别把"并行分支"强行串成串行,会歪曲 latency 归因。

五、埋点落地:在哪插、怎么传上下文

5.1 上下文传播

Agent 常跨进程/跨服务(编排层、模型网关、工具服务),trace_id 与父 Span 上下文需通过请求头/上下文对象传递,保证 Span 能正确挂到同一棵树。

5.2 自动 vs 手动

方式覆盖说明
自动埋点llm.call(框架集成)LangChain/LangGraph 与 Langfuse/OTel 集成自动出 LLM Span
手动埋点rag/rerank/tool/human.approval/eval在业务代码里显式 start/end Span 并附属性

5.3 Java/Spring AI 视角

埋点的工程难点不在"写一行 start_span",而在上下文跨服务传播属性规范化。建议封装一个内部 SDK,统一把固定字段自动注入每个 Span,业务只需填业务属性,杜绝"有人漏填 trace_id"。
埋点靠"上下文传播"把跨服务的 Span 挂到同一棵树:自动埋点覆盖 llm.call(框架集成),rag/rerank/tool/human.approval 要手动埋。建议封装内部 SDK 自动注入固定字段,避免有人漏填。

六、Trace 用于排错:从"慢/错"到"根因"

当一次调用异常,Trace 让你"不靠猜"地定位。

6.1 排错 checklist

  1. 用 trace_id 拉出完整 Span 树,看哪个 Span status=failedlatency_ms 异常。
  2. 若是 rag.retrieve 命中数为 0 → 知识库/检索问题,查 knowledge_version
  3. 若是 llm.call 慢 → 看 model_provider、是否排队、是否上下文过长(input_tokens 大)。
  4. 若是 tool.call 失败 → 看 error_type、入参脱敏副本、下游状态码。
  5. 若是 human.approval 等待极长 → 审批队列瓶颈,非模型问题。
真实案例:某次理赔答复"答非所问",查 Trace 发现 rag.retrieve 命中 0 条(knowledge_version 刚升 v4 把目录表误删),模型无知识只能硬编 → 回滚知识版本即恢复。版本字段在此立功。
排错的本质是"用结构化 Span 把猜测变验证"。没有 Trace,你只能问"模型是不是抽风了";有 Trace,你能精确到"第 3 步检索命中 0 条导致幻觉"。这把 MTTR(平均修复时间)从小时级降到分钟级。
排错就看 trace_id 拉出的 Span 树:哪个 Span 失败或慢。rag 命中 0→知识库问题;llm 慢→上下文过长或厂商排队;tool 失败→看 error_type;human.approval 久等→审批队列瓶颈。版本字段能秒定位"哪次改动引入的"。
① 只看最外层 status 不够,必须下钻到失败的具体 Span。② 排错若发现是 human.approval 慢,别去调模型——那是流程/人力问题。③ 入参脱敏副本要保留足够信息用于复盘,又不能含明文隐私,需平衡。

七、Trace 用于成本归因:钱花在哪一步

成本是 Agent 上线后的头号运营指标。Trace 的 token/cost 字段让成本可按维度下钻

7.1 成本下钻维度

维度分析价值
tenant_id哪个机构最烧钱,是否要调价/限流
model_provider / model_name贵模型是否必要,能否换便宜模型
prompt_version提示改动是否让 token 变多
tool_name / agent.step哪类工具/步骤最贵
user_id_hash是否有异常高频用户(刷接口)

7.2 成本公式与优化

单次成本 = Σ(各 llm.call 的 input_tokens × 输入单价 + output_tokens × 输出单价) 端到端成本 = 模型成本 + 检索/重排成本 + 工具调用成本 + 人工审批人力成本
成本归因常暴露"反直觉"事实:比如你以为贵在模型,Trace 一拉发现 human.approval 等待导致重试、或 rag 召回太多片段把 input_tokens 撑爆。把"端到端成本"拆成"模型+检索+工具+人工",才能精准优化。这也是面试官爱问的"怎么给老板算 Agent 账单"。
成本靠 Trace 的 token/cost 按 tenant/模型/prompt/tool 维度下钻。端到端成本=模型+检索+工具+人工审批。常见反直觉:真凶是 rag 召回太多撑爆 input_tokens,或 human.approval 等待引发重试。降输入、降输出、换便宜模型、降人工触发率。
① 别只算模型 API 账单,人工审批人力也是成本,human.approval 的等待时长×人力单价要计入。② 重试会放大成本——Trace 里重试次数要记,否则成本对不上。③ 缓存命中(prompt cache)要单独标记,否则把"免费"算成"付费"。

八、Trace 用于评测:从"跑过"到"跑对"

离线和在线评测都依赖 Trace 作为数据源。

8.1 评测类型与 Trace 的关系

评测Trace 作用
离线回归用历史真实 Trace 当 case,新版本跑后对比指标
在线监控实时聚合 status/error_type/latency 出质量看板
失败样本挖掘筛 status=failed 或低分 eval.case 做归因
A/B 对比按 prompt_version / model_name 分组比对指标

8.2 eval.case Span 的价值

把每个评测用例也写成一个 eval.case Span,记录 case_id、指标、期望/实际、评分。这样"评测"本身也进入可观测体系,能和线上 Trace 用同一套工具分析。

评测不是"评完扔掉",而是把 Trace 变成可复用的质量资产。线上真实失败 Trace 沉淀为回归 case,版本升级自动跑;eval.case Span 让"评测"和"生产"用同一观测栈,避免两套体系对不齐。
Trace 是评测的燃料:历史真实 Trace 当回归 case,线上实时聚合出质量看板,失败 Trace 沉淀为评测集。eval.case Span 把"评测"也纳入可观测体系,和生产用同一套工具。
① 评测不能只用"合成数据",要混入线上真实 Trace,否则测不出真实分布的问题。② eval.case 评分要可解释,别只存总分,期望/实际都要留,方便定位错在哪步。③ 评测指标(如任务完成率)要能从 Trace 自动算,别靠人工标注每条。

九、技术选型:Langfuse / OpenTelemetry / LangChain 回调

工具定位适用
LangfuseLLM/Agent 专用观测平台,自带 Trace 可视化、评测、Prompt 管理快速给 Agent 接上专业观测,开箱即用
OpenTelemetry (OTel)通用可观测性标准,AI Agent 可观测性有官方指南要和标准 APM(Prometheus/Jaeger)打通、不锁定
LangChain CallbacksLangChain 的回调机制,流式与 Span 钩子在 LangChain 代码里细粒度埋点/流式
推荐组合:用 Langfuse 做 Agent 专属观测与评测(最快出效果);底层走 OpenTelemetry 标准把 Span 导出到统一 APM,避免厂商锁定;LangChain 侧用 Callbacks 做流式与细粒度钩子。你的大数据背景可把 Trace 旁路进数仓做自定义聚合。
选型要平衡"开箱即用"和"不锁定"。Langfuse 专而快,OTel 通用不锁,两者可通过 OTel 导出器打通。关键决策:是否要把 LLM 观测并入公司统一可观测平台(通常要,因为 SRE 团队只认 OTel/Jaeger)。
推荐 Langfuse(Agent 专用、开箱即用)+ OpenTelemetry(通用标准、不锁定、打通公司 APM)+ LangChain Callbacks(流式与细粒度钩子)。大数据背景还能把 Trace 旁路进数仓做自定义聚合。
① 不要"Langfuse 和 OTel 各接一套"导致数据双写不一致,应 OTel 为底座、Langfuse 做上层。② Langfuse 默认采样/存储策略要看清,医疗数据可能涉及合规存储地域。③ 别把 Trace 当永久存储,要设 TTL 和归档,否则成本爆炸。

十、流式输出与回调:Trace 与体验的平衡

Agent 常用流式(streaming)提升体验,但流式下 Trace 的 token/latency 统计要特殊处理。

10.1 流式下的观测要点

流式是"体验优化"不是"性能优化"——总 latency 不变,只是用户更早看到内容。Trace 要把 TTFT 单列,因为它才是用户体感指标;同时流式下 token 统计必须等结束,避免"边流边算"导致成本少算。
流式提升体感但不降总耗时。Trace 要单列 TTFT(首 token 延迟)作为用户体感指标;output_tokens 必须等流结束才落库,否则成本少算。LangChain 用 callbacks 钩子做增量处理,但钩子里别写重逻辑。
① 把"流式"误当"更快"是常见误解,它只改善体感、不改善总延迟。② 流式下若在每个 on_llm_new_token 做重计算会拖慢流、甚至 OOM,钩子要轻。③ output_tokens 在流未结束时报 0 是 bug,必须在 end 事件结算。

十一、特药理赔 Agent 的 Trace 实践

场景:用户提交特药理赔,Agent 完成抽取→合规校验→规则判断→人工审批→放款→答复。一次请求背后是多次 LLM + 检索 + 工具 + 1 次人工审批。

11.1 落地要点

对医疗理赔,Trace 还是合规证据链:监管要能复盘"这次拒赔,模型当时检索到了什么知识、人批了什么、用的哪个知识库版本"。固定字段 + human.approval Span 正好构成这份证据。
特药理赔 Agent 的 Trace:顶层四个 version 全记,每步一个 agent.step 父 Span 挂 rag/rerank/llm/tool,human.approval 记等待和决定。它不仅是排错工具,还是给监管的合规证据链。

十二、面试达标线①:一次 Agent 调用的 Trace 结构(字段 + Span)

内容
顶层固定字段trace_id / user_id_hash / tenant_id / model_provider / model_name / prompt_version / knowledge_version / agent_version / tool_name / input_tokens / output_tokens / latency_ms / cost / status / error_type
Span 树根=请求;agent.step 为决策步;下挂 llm.call / rag.retrieve / rerank.call / tool.call / human.approval;eval.case 用于评测
关键属性每 Span 带固定字段子集 + 业务属性(如 rag 的命中数、human 的等待时长)
一次 Agent 调用的 Trace = 一棵 Span 树(根是请求,agent.step 为决策步,下挂 llm/rag/rerank/tool/human.approval)+ 一组统一固定字段(trace_id 串联、四个 version 归因、token/cost/latency/status 算成本质量)。

十三、面试达标线②:Trace 怎么用于排错 / 成本归因 / 评测

  1. 排错:用 trace_id 拉 Span 树,下钻到失败/异常慢的具体 Span;rag 命中 0→知识库问题,llm 慢→上下文/厂商,tool 失败→error_type,human.approval 久→流程瓶颈;版本字段秒定位"哪次改动引入"。
  2. 成本归因:token/cost 按 tenant/模型/prompt/tool 维度下钻;端到端成本=模型+检索+工具+人工;常见反直觉根因(检索片段过多撑爆 input、人工等待引发重试)。
  3. 评测:历史真实 Trace 当回归 case,线上聚合出质量看板,失败 Trace 沉淀为评测集,eval.case Span 让评测与生产同栈。
Trace 三用:排错(下钻 Span 树定位根因)、成本(按维度下钻+端到端=模型+检索+工具+人工)、评测(真实 Trace 当 case、eval.case 同栈)。一句话:看一条排错,看一片算钱与评测。

十四、W4D5 自测清单

十五、高频面试题速记卡

Q:Trace 和普通日志有什么不同?
Trace 是带父子关系的 Span 树,能还原因果、可聚合;日志是扁平文本,难定位链路。
Q:15 个固定字段里哪几个最体现素养?
四个 version(prompt/knowledge/agent/model):让"效果变化"可归因到"哪次改动"。
Q:自定义 Span 为什么要有 human.approval?
记录审批等待时长与决定,是医疗理赔成本与风险的关键观测点,纯 LLM 工具看不到。
Q:用 Trace 怎么排错"答非所问"?
拉 Span 树看 rag.retrieve 命中数;命中 0 即知识库/检索问题,再查 knowledge_version。
Q:Agent 成本只算模型 API 吗?
不是,端到端=模型+检索+工具+人工审批人力;human.approval 等待也计入成本。
Q:Trace 怎么服务评测?
历史真实 Trace 当回归 case,线上聚合质量看板,失败 Trace 沉淀评测集,eval.case 同栈。
Q:Langfuse 和 OpenTelemetry 怎么选?
Langfuse 专而快(Agent 观测/评测),OTel 通用不锁(打通公司 APM);OTel 为底座、Langfuse 上层。
Q:流式输出会让总 latency 变短吗?
不会,只改善体感;Trace 单列 TTFT,output_tokens 必须等流结束才结算。
Q:user_id_hash 为什么必须脱敏?
避免存明文身份证/病历,符合医疗数据合规;同时仍能做用户级成本/质量分析。
Q:一次理赔 Agent 调用的 Trace 一句话?
根是请求,agent.step 为决策步,下挂 llm/rag/rerank/tool,human.approval 记等待与决定,四 version 全记录。
FDE W4D5 学习手册 · Trace 与成本(面试级)· 配合《FDE-W4D5-评测题.md》自测
延伸学习资源(中文 / 非 OpenAI):
① Langfuse 官网:langfuse.com——LLM/Agent 专用观测与评测平台,Trace 可视化、Prompt 管理、评测集一体。
② OpenTelemetry 官方博客《AI Agent 可观测性》:opentelemetry.io/blog/2025/ai-agent-observability——用 OTel 标准做 Agent 全链路追踪的官方指南。
③ LangChain 流式与回调文档:python.langchain.com/docs/how_to/streaming——streaming + callbacks 的细粒度钩子用法,配合 Trace 统计 Token/延迟。
📌 待查★ 重要