임원 팀이 2초 안에 로드되는 KPI 대시보드를 원할 때 /business-analytics-kpi-dashboard-design는 지표와 레이아웃을 고릅니다. — Claude Skill
Claude Code용 Claude 스킬 · 제공: Seth Hobson · 실행: /business-analytics-kpi-dashboard-design (Claude 내)·업데이트: 2026년 6월 14일·v1.0.0
지표 선택, 레이아웃, 실시간 알림이 포함된 KPI 대시보드를 설계합니다
- 지표 선택: 선행 vs 후행, 주요 지표 vs 보조 지표, 부서별 분류
- 레이아웃 패턴: KPI 카드, 시계열, 코호트 히트맵, 알림 섹션
- cron 트리거와 표준편차 알림이 포함된 실시간 새로고침 패턴
- 청중별 설계: 임원 스냅샷, 운영 실시간 모니터, 제품 코호트 보기
- 안티패턴 체크리스트: 허영 지표, 상충 KPI, 알림 피로
대상
기능
CEO가 '숫자가 한 화면에 보이는 것'을 요청했습니다. /business-analytics-kpi-dashboard-design는 MRR, 이탈, LTV/CAC, 현금 지속 기간을 주요 KPI로 고르고 한 페이지 임원 보기를 배치합니다.
당직 담당자에게 실시간 대시보드가 필요합니다. /business-analytics-kpi-dashboard-design는 요청 처리량, 오류율, P95 지연 시간, 큐 깊이를 5분 새로고침과 2-시그마 알림으로 지정합니다.
새 기능 출시 후 유지율 조사가 필요합니다. /business-analytics-kpi-dashboard-design는 주간 코호트 히트맵과 이를 채울 SQL을 생성합니다.
재무팀은 $2.1M, 영업팀은 $2.3M이라고 합니다. /business-analytics-kpi-dashboard-design는 두 계산을 감사하고 시간대와 비례 계산 불일치를 찾아 하나의 표준 정의를 만듭니다.
작동 방식
청중(임원, 운영, 제품)과 그들이 내리는 결정을 알려줍니다
공통 + 부서별 목록에서 선행/후행 태그가 있는 KPI 5-9개를 고릅니다
스냅샷, 실시간 모니터, 코호트 히트맵, 임원 페이지 중 레이아웃 패턴을 선택합니다
데이터 출처, 새로고침 주기, 알림 기준값을 연결합니다
BI 도구 또는 맞춤 구축에 바로 쓸 수 있는 대시보드 명세을 생성합니다
예시
청중: CEO + 리더십 팀 모델: B2B SaaS, ARR $4M 새로고침: 매일 오전 8시 BI 도구: Metabase 현재: 연결되지 않은 대시보드 5개
주요 지표: ARR, 순신규 ARR, NDR, 현금 소진 배수 보조 지표: 신규 로고, 확장 ARR, 이탈 금액, 현금 지속 개월 수 선행 지표: 파이프라인 커버리지, MQL 규모, 데모-계약 전환율 북극성 지표: 월 순신규 ARR
상단 행: 큰 KPI 카드 4개(ARR, 순신규 ARR, NDR, 현금 지속 기간) 중간: 12주 ARR 추세선, 주간 순신규 막대 하단: 파이프라인 퍼널, 상위 3개 이탈 사유, 현금 차트 총 시각화 9개 이하
ARR 일일 스냅샷 > 30일 이동 평균보다 2시그마 아래 순신규 ARR 주간 < 계획의 70% 현금 소진 배수 월간 >2.0x 전달: Slack #leadership 채널
제거: 페이지 조회수, 이탈률, MAU(B2B SaaS에는 허영 지표) 통합: 매출 대시보드 3개를 하나의 표준 ARR 정의로 병합 알림 피로 점검: 주당 알림 최대 5개
개선되는 지표
지원 도구
KPI 대시보드 설계을(를) 사용해 보시겠어요?
시작 방법을 선택하세요.
이 스킬을 컴퓨터에 로컬로 설치하고 실행합니다.
컴퓨터에서 터미널을 열고 이 명령을 붙여넣으세요:
이 명령은 스킬과 모든 파일을 컴퓨터에 다운로드합니다:
모든 프로젝트에서 사용하려면 끝에 -g를 추가하세요.
Claude Code를 시작한 다음 명령을 입력하세요:
KPI 대시보드 설계
비즈니스 의사결정을 이끄는 효과적인 핵심 성과 지표(KPI) 대시보드를 설계하기 위한 종합 패턴입니다.
이 스킬을 사용할 때
- 임원용 대시보드를 설계할 때
- 의미 있는 KPI를 선택할 때
- 실시간 모니터링 화면을 만들 때
- 부서별 지표 화면을 만들 때
- 기존 대시보드 레이아웃을 개선할 때
- 지표 거버넌스를 확립할 때
핵심 개념
1. KPI 프레임워크
| 수준 | 초점 | 갱신 주기 | 대상자 |
|---|---|---|---|
| 전략 | 장기 목표 | 월간/분기별 | 임원 |
| 전술 | 부서 목표 | 주간/월간 | 관리자 |
| 운영 | 일상 운영 | 실시간/일간 | 팀 |
2. SMART KPI
Specific: 명확한 정의
Measurable: 정량화 가능
Achievable: 현실적인 목표
Relevant: 목표와 정렬
Time-bound: 기간이 정의됨
3. 대시보드 계층
├── 임원 요약(1페이지)
│ ├── 대표 KPI 4-6개
│ ├── 추세 지표
│ └── 핵심 알림
├── 부서별 화면
│ ├── 영업 대시보드
│ ├── 마케팅 대시보드
│ ├── 운영 대시보드
│ └── 재무 대시보드
└── 상세 드릴다운
├── 개별 지표
└── 근본 원인 분석
부서별 일반 KPI
영업 KPI
매출 지표:
- 월 반복 매출(MRR)
- 연 반복 매출(ARR)
- 사용자당 평균 매출(ARPU)
- 매출 성장률
파이프라인 지표:
- 영업 파이프라인 금액
- 수주율
- 평균 계약 규모
- 영업 주기 길이
활동 지표:
- 담당자별 전화/이메일 수
- 예약된 데모
- 발송된 제안서
- 계약 전환율
마케팅 KPI
획득:
- 획득당 비용(CPA)
- 고객 획득 비용(CAC)
- 리드 규모
- 마케팅 적격 리드(MQL)
참여:
- 웹사이트 트래픽
- 전환율
- 이메일 열람/클릭률
- 소셜 참여
ROI:
- 마케팅 ROI
- 캠페인 성과
- 채널 기여도
- CAC 회수 기간
제품 KPI
사용:
- 일간/월간 활성 사용자(DAU/MAU)
- 세션 지속 시간
- 기능 채택률
- 고착도(DAU/MAU)
품질:
- 순추천지수(NPS)
- 고객 만족도(CSAT)
- 버그/이슈 수
- 해결까지 걸린 시간
성장:
- 사용자 성장률
- 활성화율
- 유지율
- 이탈률
재무 KPI
수익성:
- 매출총이익률
- 순이익률
- EBITDA
- 영업이익률
유동성:
- 유동비율
- 당좌비율
- 현금흐름
- 운전자본
효율:
- 직원당 매출
- 영업비용 비율
- 매출채권 회수일수
- 재고 회전율
대시보드 레이아웃 패턴
패턴 1: 임원 요약
┌─────────────────────────────────────────────────────────────┐
│ 임원 대시보드 [기간 ▼] │
├─────────────┬─────────────┬─────────────┬─────────────────┤
│ 매출 │ 이익 │ 고객 │ NPS 점수 │
│ $2.4M │ $450K │ 12,450 │ 72 │
│ ▲ 12% │ ▲ 8% │ ▲ 15% │ ▲ 5pts │
├─────────────┴─────────────┴─────────────┴─────────────────┤
│ │
│ 매출 추세 │ 제품별 매출 │
│ ┌───────────────────────┐ │ ┌──────────────────┐ │
│ │ /\ /\ │ │ │ ████████ 45% │ │
│ │ / \ / \ /\ │ │ │ ██████ 32% │ │
│ │ / \/ \ / \ │ │ │ ████ 18% │ │
│ │ / \/ \ │ │ │ ██ 5% │ │
│ └───────────────────────┘ │ └──────────────────┘ │
│ │
├─────────────────────────────────────────────────────────────┤
│ 🔴 알림: 이탈률이 기준값을 초과함(>5%) │
│ 🟡 경고: 지원 티켓 수가 평균보다 20% 높음 │
└─────────────────────────────────────────────────────────────┘
패턴 2: SaaS 지표 대시보드
┌─────────────────────────────────────────────────────────────┐
│ SAAS 지표 2024년 1월 [월간 ▼] │
├──────────────────────┬──────────────────────────────────────┤
│ ┌────────────────┐ │ MRR 성장 │
│ │ MRR │ │ ┌────────────────────────────────┐ │
│ │ $125,000 │ │ │ /── │ │
│ │ ▲ 8% │ │ │ /────/ │ │
│ └────────────────┘ │ │ /────/ │ │
│ ┌────────────────┐ │ │ /────/ │ │
│ │ ARR │ │ │ /────/ │ │
│ │ $1,500,000 │ │ └────────────────────────────────┘ │
│ │ ▲ 15% │ │ J F M A M J J A S O N D │
│ └────────────────┘ │ │
├──────────────────────┼──────────────────────────────────────┤
│ 단위 경제성 │ 코호트 유지율 │
│ │ │
│ CAC: $450 │ 1개월: ████████████████████ 100% │
│ LTV: $2,700 │ 3개월: █████████████████ 85% │
│ LTV/CAC: 6.0x │ 6개월: ████████████████ 80% │
│ │ 12개월: ██████████████ 72% │
│ 회수 기간: 4개월 │ │
├──────────────────────┴──────────────────────────────────────┤
│ 이탈 분석 │
│ ┌──────────┬──────────┬──────────┬──────────────────────┐ │
│ │ 총 이탈 │ 순 이탈 │ 로고 이탈│ 확장 │ │
│ │ 4.2% │ 1.8% │ 3.1% │ 2.4% │ │
│ └──────────┴──────────┴──────────┴──────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
패턴 3: 실시간 운영
┌─────────────────────────────────────────────────────────────┐
│ 운영 센터 실시간 ● 마지막: 10:42:15 │
├────────────────────────────┬────────────────────────────────┤
│ 시스템 상태 │ 서비스 상태 │
│ ┌──────────────────────┐ │ │
│ │ CPU MEM DISK │ │ ● API Gateway 정상 │
│ │ 45% 72% 58% │ │ ● User Service 정상 │
│ │ ███ ████ ███ │ │ ● Payment Service 저하 │
│ │ ███ ████ ███ │ │ ● Database 정상 │
│ │ ███ ████ ███ │ │ ● Cache 정상 │
│ └──────────────────────┘ │ │
├────────────────────────────┼────────────────────────────────┤
│ 요청 처리량 │ 오류율 │
│ ┌──────────────────────┐ │ ┌──────────────────────────┐ │
│ │ ▁▂▃▄▅▆▇█▇▆▅▄▃▂▁▂▃▄▅ │ │ │ ▁▁▁▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁ │ │
│ └──────────────────────┘ │ └──────────────────────────┘ │
│ 현재: 12,450 req/s │ 현재: 0.02% │
│ 최고: 18,200 req/s │ 기준값: 1.0% │
├────────────────────────────┴────────────────────────────────┤
│ 최근 알림 │
│ 10:40 🟡 payment-service 고지연(p99 > 500ms) │
│ 10:35 🟢 해결됨: Database connection pool 복구 │
│ 10:22 🔴 Payment service circuit breaker 작동 │
└─────────────────────────────────────────────────────────────┘
구현 패턴
KPI 계산용 SQL
-- 월 반복 매출(MRR)
WITH mrr_calculation AS (
SELECT
DATE_TRUNC('month', billing_date) AS month,
SUM(
CASE subscription_interval
WHEN 'monthly' THEN amount
WHEN 'yearly' THEN amount / 12
WHEN 'quarterly' THEN amount / 3
END
) AS mrr
FROM subscriptions
WHERE status = 'active'
GROUP BY DATE_TRUNC('month', billing_date)
)
SELECT
month,
mrr,
LAG(mrr) OVER (ORDER BY month) AS prev_mrr,
(mrr - LAG(mrr) OVER (ORDER BY month)) / LAG(mrr) OVER (ORDER BY month) * 100 AS growth_pct
FROM mrr_calculation;
-- 코호트 유지율
WITH cohorts AS (
SELECT
user_id,
DATE_TRUNC('month', created_at) AS cohort_month
FROM users
),
activity AS (
SELECT
user_id,
DATE_TRUNC('month', event_date) AS activity_month
FROM user_events
WHERE event_type = 'active_session'
)
SELECT
c.cohort_month,
EXTRACT(MONTH FROM age(a.activity_month, c.cohort_month)) AS months_since_signup,
COUNT(DISTINCT a.user_id) AS active_users,
COUNT(DISTINCT a.user_id)::FLOAT / COUNT(DISTINCT c.user_id) * 100 AS retention_rate
FROM cohorts c
LEFT JOIN activity a ON c.user_id = a.user_id
AND a.activity_month >= c.cohort_month
GROUP BY c.cohort_month, EXTRACT(MONTH FROM age(a.activity_month, c.cohort_month))
ORDER BY c.cohort_month, months_since_signup;
-- 고객 획득 비용(CAC)
SELECT
DATE_TRUNC('month', acquired_date) AS month,
SUM(marketing_spend) / NULLIF(COUNT(new_customers), 0) AS cac,
SUM(marketing_spend) AS total_spend,
COUNT(new_customers) AS customers_acquired
FROM (
SELECT
DATE_TRUNC('month', u.created_at) AS acquired_date,
u.id AS new_customers,
m.spend AS marketing_spend
FROM users u
JOIN marketing_spend m ON DATE_TRUNC('month', u.created_at) = m.month
WHERE u.source = 'marketing'
) acquisition
GROUP BY DATE_TRUNC('month', acquired_date);
Python 대시보드 코드(Streamlit)
import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
st.set_page_config(page_title="KPI 대시보드", layout="wide")
# 날짜 필터가 있는 헤더
col1, col2 = st.columns([3, 1])
with col1:
st.title("임원 대시보드")
with col2:
date_range = st.selectbox(
"기간",
["최근 7일", "최근 30일", "지난 분기", "연초 이후"]
)
# KPI 카드
def metric_card(label, value, delta, prefix="", suffix=""):
delta_color = "green" if delta >= 0 else "red"
delta_arrow = "▲" if delta >= 0 else "▼"
st.metric(
label=label,
value=f"{prefix}{value:,.0f}{suffix}",
delta=f"{delta_arrow} {abs(delta):.1f}%"
)
col1, col2, col3, col4 = st.columns(4)
with col1:
metric_card("매출", 2400000, 12.5, prefix="$")
with col2:
metric_card("고객", 12450, 15.2)
with col3:
metric_card("NPS 점수", 72, 5.0)
with col4:
metric_card("이탈률", 4.2, -0.8, suffix="%")
# 차트
col1, col2 = st.columns(2)
with col1:
st.subheader("매출 추세")
revenue_data = pd.DataFrame({
'Month': pd.date_range('2024-01-01', periods=12, freq='M'),
'Revenue': [180000, 195000, 210000, 225000, 240000, 255000,
270000, 285000, 300000, 315000, 330000, 345000]
})
fig = px.line(revenue_data, x='Month', y='Revenue',
line_shape='spline', markers=True)
fig.update_layout(height=300)
st.plotly_chart(fig, use_container_width=True)
with col2:
st.subheader("제품별 매출")
product_data = pd.DataFrame({
'Product': ['Enterprise', 'Professional', 'Starter', 'Other'],
'Revenue': [45, 32, 18, 5]
})
fig = px.pie(product_data, values='Revenue', names='Product',
hole=0.4)
fig.update_layout(height=300)
st.plotly_chart(fig, use_container_width=True)
# 코호트 히트맵
st.subheader("코호트 유지율")
cohort_data = pd.DataFrame({
'Cohort': ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
'M0': [100, 100, 100, 100, 100],
'M1': [85, 87, 84, 86, 88],
'M2': [78, 80, 76, 79, None],
'M3': [72, 74, 70, None, None],
'M4': [68, 70, None, None, None],
})
fig = go.Figure(data=go.Heatmap(
z=cohort_data.iloc[:, 1:].values,
x=['M0', 'M1', 'M2', 'M3', 'M4'],
y=cohort_data['Cohort'],
colorscale='Blues',
text=cohort_data.iloc[:, 1:].values,
texttemplate='%{text}%',
textfont={"size": 12},
))
fig.update_layout(height=250)
st.plotly_chart(fig, use_container_width=True)
# 알림 섹션
st.subheader("알림")
alerts = [
{"level": "error", "message": "이탈률이 기준값을 초과했습니다(>5%)"},
{"level": "warning", "message": "지원 티켓 수가 평균보다 20% 높습니다"},
]
for alert in alerts:
if alert["level"] == "error":
st.error(f"🔴 {alert['message']}")
elif alert["level"] == "warning":
st.warning(f"🟡 {alert['message']}")
모범 사례
해야 할 것
- KPI를 5-7개로 제한 - 중요한 것에 집중합니다
- 맥락을 보여주기 - 비교, 추세, 목표를 함께 둡니다
- 일관된 색상 사용 - 빨강=나쁨, 초록=좋음
- 드릴다운 제공 - 요약에서 상세로 내려갈 수 있게 합니다
- 적절한 주기로 갱신 - 지표의 빈도에 맞춥니다
하지 말 것
- 허영 지표를 보이지 않기 - 행동 가능한 데이터에 집중합니다
- 과밀하게 만들지 않기 - 여백은 이해를 돕습니다
- 3D 차트를 쓰지 않기 - 인식을 왜곡합니다
- 계산 방식을 숨기지 않기 - 계산을 문서화합니다
- 모바일을 무시하지 않기 - 반응형 설계를 보장합니다
문제 해결
대시보드의 MRR이 재무팀 수치와 다를 때
가장 흔한 원인은 연간 요금제를 다루는 방식이 일관되지 않은 것입니다. 재무팀은 일할 계산할 수 있지만 대시보드는 월 단위로 정규화할 수 있습니다. 하나의 공식에 합의하고 대시보드 카드에 직접 문서화합니다:
-- 툴팁 / 데이터 사전에 표시되는 명시적 공식
-- 연간 요금제: 총 계약 금액을 12로 나눔
-- 분기별 요금제: 3으로 나눔
-- 월간 요금제: 그대로 사용
CASE subscription_interval
WHEN 'monthly' THEN amount
WHEN 'quarterly' THEN amount / 3.0
WHEN 'yearly' THEN amount / 12.0
END AS normalized_mrr
대시보드는 초록색인데 제품팀은 사용자가 불평한다고 보고할 때
대시보드는 시스템 가동 시간(후행 지표)을 추적하지만 사용자 체감 품질 지표는 추적하지 않을 가능성이 큽니다. 인프라 지표 옆에 고객이 체감하는 지표를 추가합니다:
| 인프라(초록) | 사용자 체감(추가할 지표) |
|---|---|
| API 가동 시간 99.9% | P95 페이지 로드 시간 |
| 오류율 0.1% | 작업 완료율 |
| 큐 깊이 정상 | 지원 티켓 수 |
유지율 코호트가 평평하고 코호트 간 차이가 없을 때
코호트 쿼리가 가입 월 기준으로 올바르게 분할되는지 확인합니다. 흔한 버그는 DATE_TRUNC('month', created_at) 대신 created_at::date를 사용하는 것입니다. 이렇게 하면 일 단위로 묶여 코호트가 너무 작아져 추세가 보이지 않습니다:
-- 잘못됨: 너무 세분화되어 코호트가 너무 작음
DATE_TRUNC('day', created_at) AS cohort_date
-- 올바름: 월별 코호트
DATE_TRUNC('month', created_at) AS cohort_month
실시간 대시보드가 데이터베이스를 과도하게 두드릴 때
복잡한 코호트 SQL을 10초마다 새로고침하는 실시간 대시보드는 운영 쿼리 성능을 저하시킵니다. 예약 작업으로 사전 집계 지표를 요약 테이블에 쓰고, 대시보드는 그 테이블에서 읽게 하여 OLAP 작업을 OLTP와 분리합니다:
# cron/Celery로 5분마다 예약 실행
def refresh_mrr_summary():
conn.execute("""
INSERT INTO kpi_snapshot (metric, value, snapshot_at)
SELECT 'mrr', SUM(...), NOW()
FROM subscriptions WHERE status = 'active'
ON CONFLICT (metric) DO UPDATE SET value = EXCLUDED.value
""")
알림 기준값이 계속 울려 팀이 무시할 때
한 번 설정하고 검토하지 않는 고정 기준값은 알림 피로를 만듭니다. 이동 평균 기반 동적 기준값을 사용해 지표가 자기 기준선에서 유의미하게 벗어날 때만 알림이 울리게 합니다:
# 현재 값이 30일 이동 평균에서 표준편차 2배를 넘으면 알림
def is_anomalous(current: float, history: list[float]) -> bool:
mean = statistics.mean(history)
stdev = statistics.stdev(history)
return abs(current - mean) > 2 * stdev
관련 스킬
data-storytelling- 대시보드 발견 사항을 임원 의사결정을 이끄는 이야기로 바꿉니다