import mlflow
import pandas as pd
traces_df = mlflow.search_traces(
experiment_ids=["123456789"],
max_results=1000,
)
# Span 목록을 플랫하게 펼치기
span_records = []
for _, row in traces_df.iterrows():
for span in row["spans"]:
span_records.append({
"trace_id": row["trace_id"],
"span_name": span["name"],
"span_type": span.get("span_type", "UNKNOWN"),
"latency_ms": (span["end_time_ns"] - span["start_time_ns"]) / 1e6,
"status": span["status"]["status_code"],
})
spans_df = pd.DataFrame(span_records)
# Span 유형별 Latency 통계
latency_stats = (
spans_df.groupby("span_type")["latency_ms"]
.agg(["mean", "median", lambda x: x.quantile(0.95), "count"])
.rename(columns={"mean": "avg_ms", "median": "p50_ms", "<lambda_0>": "p95_ms", "count": "n"})
.sort_values("p95_ms", ascending=False)
)
print(latency_stats)
# span_type avg_ms p50_ms p95_ms n
# LLM 1200.0 1100.0 2500.0 890
# RETRIEVER 80.0 65.0 200.0 890
# EMBEDDING 25.0 20.0 50.0 890
# → LLM이 P95 기준 전체 지연의 90% 이상을 차지