analyzing-mlflow-trace について
個々の MLflow トレースを調査し、問題を特定するスキルです。スパン、評価、状態、所要時間、トークン情報の読み方を示し、トレースの情報をアプリケーションコードと照合して誤回答や性能問題の原因を探します。
主な機能
- 01トレース JSON とスパンツリーの確認
- 02評価と根拠の解釈
- 03エラーと時間的ボトルネックの特定
- 04スパンとアプリケーションコードの照合
- 05トークン使用状況メタデータの確認
活用シーン
- 01エージェントの誤回答の調査
- 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 トレースを分析する
トレースの構造
トレースには、AI/ML アプリケーションの実行全体が スパン のツリーとして記録されます。各スパンは、1 つの操作(LLM 呼び出し、ツールの実行、検索ステップなど)を表し、その入力、出力、タイミング、ステータスを記録します。トレースには 評価 も含まれ、人間や LLM の評価者からの品質に関するフィードバックが記録されます。
トレースを分析する前に、references/trace-structure.md を読むことをお勧めします。完全なデータモデル、すべてのフィールドと型、分析のガイダンス、OpenTelemetry との互換性に関する注意事項が記載されています。
トレースのバッチ、コンポーネントのボトルネック、または繰り返し発生するエラーパターンについては、retrieving-mlflow-traces を使って対象を絞ったサンプルを選択した後、references/cross-trace-analysis.md を読んでください。
CLI 出力の扱い
複雑なエージェントの実行では、トレースが 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
--extract-fields を使用するよりも、トレース全体を取得して JSON を直接解析する方法をお勧めします。--extract-fields フラグは、ネストされたスパンデータへの対応が限られています(たとえば、スパンの入力/出力が空のオブジェクトを返すことがあります)。トレース全体を一度取得し、必要に応じて解析してください。
JSON の構造
トレース JSON には、トップレベルのキーが 2 つあります。info(メタデータ、評価)と data(スパン)です。
{
"info": { "trace_id", "state", "request_time", "assessments", ... },
"data": { "spans": [ { "span_id", "name", "status", "attributes", ... } ] }
}
主なパス(実際の CLI 出力で確認済み):
| 項目 | jq パス |
|---|---|
| トレースの状態 | .info.state |
| すべてのスパン | .data.spans |
| ルートスパン | .data.spans[] | select(.parent_span_id == null) |
| スパンのステータスコード | .data.spans[].status.code(値:STATUS_CODE_OK、STATUS_CODE_ERROR、STATUS_CODE_UNSET) |
| スパンのステータスメッセージ | .data.spans[].status.message |
| スパンの入力 | .data.spans[].attributes["mlflow.spanInputs"] |
| スパンの出力 | .data.spans[].attributes["mlflow.spanOutputs"] |
| 評価 | .info.assessments |
| 評価名 | .info.assessments[].assessment_name |
| フィードバック値 | .info.assessments[].feedback.value |
| フィードバックエラー | .info.assessments[].feedback.error |
| 評価の根拠 | .info.assessments[].rationale |
重要:スパンの入力と出力は、トップレベルのスパンフィールドではなく、attributes 内にシリアライズされた JSON 文字列として保存されます。サードパーティの 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は、出力が正しいことを意味しません。 未処理の例外がなかったことを示すだけです。品質を示すシグナルがないか評価を確認し、評価が存在しない場合は、トレースの入力、出力、中間スパンのデータを直接分析して問題を探してください。- 評価値を解釈する際は、必ず
rationaleを確認してください。valueだけでは誤解を招く場合があります。たとえば、user_frustration評価のvalue: "no"は、スコアラーの設定によって「不満は検出されなかった」という意味にも、「不満のチェックに合格しなかった」(つまり、不満が存在する)という意味にもなり得ます。.rationaleフィールド(.feedbackの下ではなく、評価のトップレベルにあるフィールド)は、その値が文脈上何を意味するのかを説明し、多くの場合、スパンを調べる前に問題を平易な言葉で説明してくれます。 - 評価からは問題の「内容」が、スパンからは問題の「箇所」がわかります。 評価がある場合は、フィードバックや期待値をもとに仮説を立て、スパンツリーで確認してください。評価がない場合は、スパンの入力/出力を調べ、実行が期待される動作からどこで逸脱したのかを特定してください。
- 評価エラーはトレースのエラーではありません。 評価に
errorフィールドがある場合、そのトレースを評価したスコアラーまたは判定器が失敗したという意味であり、トレース自体に問題があるという意味ではありません。トレースに問題がなくても、評価のvalueは信頼できない場合があります。これは、スコアラーがクラッシュした場合(タイムアウトや解析できない出力を返した場合など)や、想定していない種類のトレースにスコアラーが適用された場合(検索ステップのないトレースに検索関連性スコアラーが適用された場合など)に起こり得ます。後者はトレースの問題ではなく、スコアラーの設定に関する問題です。 - スパンのタイミングからパフォーマンスの問題がわかります。 親スパンと子スパンの間隔はオーバーヘッドを示します。同じスパン名が繰り返されている場合はリトライが疑われます。また、個々のスパンの所要時間を比較してボトルネックを見つけてください。
- トークン使用量からレイテンシとコストの原因がわかります。 トレースのメタデータ(例:
mlflow.trace.tokenUsage)またはスパン属性(例:mlflow.chat.tokenUsage)でトークン使用量を確認してください。これらを設定しないクライアントもあるため、同等のフィールドがないか、生のattributes辞書を確認してください。入力トークン数の急増は、プロンプトインジェクションやコンテキストが大きすぎることを示している場合があります。
コードベースとの照合
MLflow Tracingは、アプリケーションの呼び出しスタックのさまざまな部分から入力、出力、メタデータを記録します。トレースの内容をソースコードと照合すると、トレースだけを調べるよりも正確に問題の根本原因を特定できます。
- スパン名は関数に対応します。 スパン名は通常、
@mlflow.traceでデコレートされた関数、またはmlflow.start_span()でラップされた関数と一致します(LangChainやOpenAIなどの自動ログ記録されたスパンでは、代わりにフレームワークの規約に従った名前が使われます。例:ChatOpenAI、RetrievalQA)。 - スパンツリーは呼び出しスタックを反映します。 スパンAがスパンBの親であれば、関数Aは関数Bを呼び出しています。
- スパンの入力/出力は関数の引数/戻り値に対応します。 それらをコードのロジックと比較すると、関数が設計どおりに動作したか、予期しない結果を生成したかがわかります。
- トレースからは「何が起きたか」が、コードからは「なぜ起きたか」がわかります。 関連性のない結果を返すリトリーバーは、誤った類似度のしきい値が原因かもしれません。スパンの入力が正しくない場合は、コードでモデルのパラメーターが誤って設定されていたり、環境変数が設定されていなかったりする可能性があります。
例:誤った回答の調査
ユーザーから、「返金ポリシーを教えてください」という問い合わせに対して、カスタマーサポートエージェントが誤った回答を返したという報告がありました。このトレースには評価がありません。
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..."}
エージェントは正しく「返金ポリシー」を検索することを決定しましたが、search_knowledge_baseツールは配送に関するドキュメントを返しました。その後、LLMは誤ったコンテキストを使って忠実に回答しました。問題はエージェントの推論やLLMの生成ではなく、ツールの検索にあります。
3. コードベースと照合します。
search_knowledge_baseスパンは、アプリケーションコード内の関数に対応しています。調査の結果、ベクトルインデックスが配送に関するFAQのみをもとに構築されており、返金ポリシーのドキュメントは一度もインデックスに登録されていないことが判明しました。
4. 推奨事項
- 返金ポリシーのドキュメントを含めて、ナレッジベースのインデックスを再作成します。
- 検索されたコンテキストが問い合わせのトピックと一致しない場合に検出できるよう、検索結果の関連度スコアラーを追加します。
- 回帰テストを可能にするため、よくある問い合わせに対する正解を含む期待値評価の追加を検討します。