关于 analyzing-mlflow-trace
用于检查和排查单条 MLflow 追踪的技能,指导读取跨度、评估结果、状态、耗时和令牌数据。它还说明如何将追踪证据与应用代码关联,以定位错误输出或性能问题的原因。
主要功能
- 01检查追踪 JSON 和跨度树
- 02解读评估结果及其理由
- 03查找错误和耗时瓶颈
- 04将跨度与应用代码关联
- 05检查令牌使用元数据
适用场景
- 01排查 Agent 的错误回答
- 02定位故障工具或检索步骤
- 03识别追踪中的延迟瓶颈
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mlflow/ skills --skill analyzing-mlflow-trace安装后在 Claude Code 中输入/analyzing-mlflow-trace确认已加载。
附带文件references/cross-trace-analysis.mdreferences/trace-structure.md
详细介绍
分析单条 MLflow 追踪
追踪结构
追踪会以 span 树的形式记录 AI/ML 应用的完整执行过程。每个 span 代表一项操作(LLM 调用、工具调用、检索步骤等),并记录其输入、输出、耗时和状态。追踪还包含 评估结果——来自人工或 LLM 评审者的质量反馈。
分析追踪前,建议先阅读 references/trace-structure.md——其中涵盖完整的数据模型、所有字段和类型、分析指南,以及 OpenTelemetry 兼容性说明。
对于一批追踪、组件瓶颈或反复出现的错误模式,在使用 retrieving-mlflow-traces 选取有界样本后,请阅读 references/cross-trace-analysis.md。
处理 CLI 输出
复杂的 Agent 执行过程可能会生成 100KB 以上的追踪。始终将输出重定向到文件——不要将 mlflow traces get 的输出直接管道传递给 jq、head 或其他命令,因为管道可能会悄无声息地不产生任何输出。
# Fetch full trace to a file (traces get always outputs JSON, no --output flag needed)
mlflow traces get --trace-id <ID> > /tmp/trace.json
# Then process the file
jq '.info.state' /tmp/trace.json
jq '.data.spans | length' /tmp/trace.json
优先获取完整追踪并直接解析 JSON,而不是使用 --extract-fields。--extract-fields 标志对嵌套 span 数据的支持有限(例如,span 的输入/输出可能会返回空对象)。获取一次完整追踪,并根据需要进行解析。
JSON 结构
追踪 JSON 包含两个顶层键:info(元数据、评估结果)和 data(spans)。
{
"info": { "trace_id", "state", "request_time", "assessments", ... },
"data": { "spans": [ { "span_id", "name", "status", "attributes", ... } ] }
}
关键路径(已根据实际 CLI 输出验证):
| 内容 | jq 路径 |
|---|---|
| 追踪状态 | .info.state |
| 所有 spans | .data.spans |
| 根 span | .data.spans[] | select(.parent_span_id == null) |
| Span 状态码 | .data.spans[].status.code(值:STATUS_CODE_OK、STATUS_CODE_ERROR、STATUS_CODE_UNSET) |
| Span 状态消息 | .data.spans[].status.message |
| Span 输入 | .data.spans[].attributes["mlflow.spanInputs"] |
| Span 输出 | .data.spans[].attributes["mlflow.spanOutputs"] |
| 评估结果 | .info.assessments |
| 评估名称 | .info.assessments[].assessment_name |
| 反馈值 | .info.assessments[].feedback.value |
| 反馈错误 | .info.assessments[].feedback.error |
| 评估理由 | .info.assessments[].rationale |
重要:Span 输入和输出以序列化 JSON 字符串的形式存储在 attributes 中,而不是 span 的顶层字段中。来自第三方 OpenTelemetry 客户端的追踪可能会使用不同的属性名称(例如 GenAI Semantic Conventions、OpenInference 或自定义键)——请检查原始 attributes 字典,找到对应字段。
如果路径不匹配(结构可能因 MLflow 版本而异),请按以下方法查找:
# Top-level keys
jq 'keys' /tmp/trace.json
# Span keys
jq '.data.spans[0] | keys' /tmp/trace.json
# Status structure
jq '.data.spans[0].status' /tmp/trace.json
快速健康检查
将追踪获取到文件后,运行以下命令以获取摘要:
jq '{
state: .info.state,
span_count: (.data.spans | length),
error_spans: [.data.spans[] | select(.status.code == "STATUS_CODE_ERROR") | .name],
assessment_errors: [.info.assessments[] | select(.feedback.error) | .assessment_name]
}' /tmp/trace.json
分析洞察
state: OK不代表输出正确。 它只表示没有未处理的异常。请检查评估结果中是否有质量信号;如果没有,请直接分析跟踪记录的输入、输出和中间 Span 数据,查找问题。- 解读评估值时,务必查看
rationale。 单看value可能会产生误导——例如,user_frustration评估结果的value: "no"可能表示“未检测到挫败感”,也可能表示“挫败感检查未通过”(也就是说,确实存在挫败感),具体取决于评分器的配置方式。.rationale字段(评估结果的顶层字段,不嵌套在.feedback下)会解释该值在当前语境中的含义,通常会先用直白的语言描述问题,无需检查任何 Span。 - 评估结果告诉你出了什么问题;Span 告诉你问题出在哪里。 如果存在评估结果,请根据反馈/预期形成假设,然后在 Span 树中确认。如果没有评估结果,请检查 Span 的输入/输出,确定执行过程从何处偏离预期行为。
- 评估错误不等于跟踪错误。 如果评估结果包含
error字段,表示评估该跟踪记录的评分器或判定器出错了,而不是跟踪记录本身有问题。跟踪记录可能完全正常;评估结果的value只是不可靠。这可能是评分器崩溃导致的(例如超时、返回无法解析的输出),也可能是评分器被用于其设计范围之外的跟踪类型(例如,将检索相关性评分器用于没有检索步骤的跟踪记录)。后一种情况属于评分器配置问题,而不是跟踪记录问题。 - Span 耗时可以揭示性能问题。 父 Span 与子 Span 之间的间隔表示开销;重复的 Span 名称可能表示发生了重试;比较各个 Span 的耗时可以找出瓶颈。
- 令牌用量有助于解释延迟和成本。 请在跟踪元数据(例如,
mlflow.trace.tokenUsage)或 Span 属性(例如,mlflow.chat.tokenUsage)中查找令牌用量。并非所有客户端都会设置这些字段——请检查原始的attributes字典,查看是否有等效字段。输入令牌突然增加可能表示提示词注入或上下文过大。
与代码库关联
MLflow Tracing 会捕获应用程序调用栈不同部分的输入、输出和元数据。将跟踪记录内容与源代码关联起来,能比仅凭跟踪记录更准确地定位根本原因。
- Span 名称对应函数。 Span 名称通常与使用
@mlflow.trace装饰的函数或由mlflow.start_span()包装的函数相同。对于自动记录的 Span(LangChain、OpenAI 等),名称则遵循相应框架的惯例(例如,ChatOpenAI、RetrievalQA)。 - Span 树映射调用栈。 如果 Span A 是 Span B 的父级,则函数 A 调用了函数 B。
- Span 输入/输出对应函数的参数/返回值。 将它们与代码逻辑进行比较,可以看出函数是否按设计运行,或是否产生了意外结果。
- 跟踪记录展示发生了什么;代码揭示为什么。 检索器返回无关结果,可能是因为相似度阈值设置错误。Span 输入不正确,可能表明代码中设置了错误的模型参数,或缺少环境变量。
示例:调查错误答案
一位用户报告称,其客户支持 Agent 在回答查询“我们的退款政策是什么?”时给出了错误答案。该跟踪记录没有评估结果。
1. 获取跟踪记录并检查高层信号。
该跟踪记录的 state: OK,表示没有发生崩溃。由于没有评估结果,请直接检查跟踪记录的输入和输出。response_preview 显示 “我们的配送政策规定,订单会在 3-5 个工作日内送达……”,这回答的是与用户提问不同的问题。
2. 检查跨度以定位问题。
跨度树如下所示:
customer_support_agent (AGENT) — OK
├── plan_action (LLM) — OK
│ outputs: {"tool_call": "search_knowledge_base", "args": {"query": "refund policy"}}
├── search_knowledge_base (TOOL) — OK
│ inputs: {"query": "refund policy"}
│ outputs: [{"doc": "Shipping takes 3-5 business days...", "score": 0.82}]
├── generate_response (LLM) — OK
│ inputs: {"messages": [..., {"role": "user", "content": "Context: Shipping takes 3-5 business days..."}]}
│ outputs: {"content": "Our shipping policy states..."}
Agent 正确地决定搜索“退款政策”,但 search_knowledge_base 工具返回了一份配送文档。随后,大模型根据错误的上下文如实作答。问题出在工具的检索,而不是 Agent 的推理或大模型的生成。
3. 与代码库关联。
跨度 search_knowledge_base 对应应用代码中的一个函数。调查后发现,向量索引仅根据配送常见问题构建,退款政策文档从未被编入索引。
4. 建议。
- 重新建立知识库索引,将退款政策文档纳入其中。
- 添加检索相关性评分器,以检测检索到的上下文是否与查询主题不匹配。
- 考虑为常见查询添加包含正确答案的预期评估,以支持回归测试。