425 lines
12 KiB
Plaintext
425 lines
12 KiB
Plaintext
$ uv run tools/flow.py test cases/replay-normal.json -v
|
||||
|
|
✔ before: POST http://localhost:8800/admin/fault · HTTP 200 · 0.0s · {"faq": "ok", "tickets": "ok", "prompts": "ok", "usage": "ok", "dlq": "ok", "slow_seconds": 1.2}
|
|||
|
|
→ request POST http://localhost:8800/admin/fault
|
|||
|
|
{
|
|||
|
|
"faq": "ok"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"faq": "ok",
|
|||
|
|
"tickets": "ok",
|
|||
|
|
"prompts": "ok",
|
|||
|
|
"usage": "ok",
|
|||
|
|
"dlq": "ok",
|
|||
|
|
"slow_seconds": 1.2
|
|||
|
|
}
|
|||
|
|
POST http://localhost:5678/webhook/my-helpdesk · 10 case(s) × 1
|
|||
|
|
✔ normal · 회의실 와이파이가 안 · 2.3s
|
|||
|
|
→ request POST /webhook/my-helpdesk
|
|||
|
|
{
|
|||
|
|
"question": "회의실 와이파이가 안 잡혀요",
|
|||
|
|
"user": "이준호",
|
|||
|
|
"tag": "normal"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"route": "자동 답변",
|
|||
|
|
"status": "success",
|
|||
|
|
"topic": "와이파이",
|
|||
|
|
"answer": "회의실에서 와이파이가 잡히지 않으면 가까운 공유기 번호를 IT 포털에 신고해 주세요. 사내 와이파이는 'CORP-WIFI'에 사번으로 로그인합니다.",
|
|||
|
|
"error": null
|
|||
|
|
}
|
|||
|
|
✔ normal · 사내 Wi-Fi 비밀번 · 1.1s
|
|||
|
|
→ request POST /webhook/my-helpdesk
|
|||
|
|
{
|
|||
|
|
"question": "사내 Wi-Fi 비밀번호가 뭐예요?",
|
|||
|
|
"user": "박서연",
|
|||
|
|
"tag": "normal"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"route": "자동 답변",
|
|||
|
|
"status": "success",
|
|||
|
|
"topic": "와이파이",
|
|||
|
|
"answer": "사내 와이파이는 'CORP-WIFI'에 사번으로 로그인합니다. 비밀번호는 별도로 없으며, 사번으로 인증합니다. 회의실에서 연결이 안 되면 가까운 공유기 번호를 IT 포털에 신고해 주세요.",
|
|||
|
|
"error": null
|
|||
|
|
}
|
|||
|
|
✔ normal · 와이파이가 자주 끊겨요 · 1.2s
|
|||
|
|
→ request POST /webhook/my-helpdesk
|
|||
|
|
{
|
|||
|
|
"question": "와이파이가 자주 끊겨요",
|
|||
|
|
"user": "최유진",
|
|||
|
|
"tag": "normal"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"route": "자동 답변",
|
|||
|
|
"status": "success",
|
|||
|
|
"topic": "와이파이",
|
|||
|
|
"answer": "사내 와이파이는 'CORP-WIFI'에 사번으로 로그인합니다. 회의실 등 특정 장소에서 와이파이가 자주 끊기면 가까운 공유기 번호를 IT 포털에 신고해 주세요.",
|
|||
|
|
"error": null
|
|||
|
|
}
|
|||
|
|
✔ normal · 노트북이 와이파이에 연 · 0.9s
|
|||
|
|
→ request POST /webhook/my-helpdesk
|
|||
|
|
{
|
|||
|
|
"question": "노트북이 와이파이에 연결이 안 돼요",
|
|||
|
|
"user": "한지훈",
|
|||
|
|
"tag": "normal"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"route": "자동 답변",
|
|||
|
|
"status": "success",
|
|||
|
|
"topic": "와이파이",
|
|||
|
|
"answer": "사내 와이파이는 'CORP-WIFI'에 사번으로 로그인합니다. 회의실에서 와이파이가 잡히지 않으면 가까운 공유기 번호를 IT 포털에 신고해 주세요.",
|
|||
|
|
"error": null
|
|||
|
|
}
|
|||
|
|
✔ normal · 손님용 wifi도 있나 · 1.2s
|
|||
|
|
→ request POST /webhook/my-helpdesk
|
|||
|
|
{
|
|||
|
|
"question": "손님용 wifi도 있나요?",
|
|||
|
|
"user": "김민지",
|
|||
|
|
"tag": "normal"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"route": "자동 답변",
|
|||
|
|
"status": "success",
|
|||
|
|
"topic": "와이파이",
|
|||
|
|
"answer": "손님용 와이파이에 대한 안내는 제공되지 않습니다. 사내 와이파이는 'CORP-WIFI'에 사번으로 로그인하여 사용합니다. 추가 문의 사항은 IT 포털에 문의해 주세요.",
|
|||
|
|
"error": null
|
|||
|
|
}
|
|||
|
|
✔ normal · VPN이 자꾸 끊겨요 · 0.9s
|
|||
|
|
→ request POST /webhook/my-helpdesk
|
|||
|
|
{
|
|||
|
|
"question": "VPN이 자꾸 끊겨요",
|
|||
|
|
"user": "정우성",
|
|||
|
|
"tag": "normal"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"route": "자동 답변",
|
|||
|
|
"status": "success",
|
|||
|
|
"topic": "VPN",
|
|||
|
|
"answer": "VPN 클라이언트를 최신 버전으로 업데이트하고, 인증서 만료 여부를 확인한 뒤 다시 접속합니다.",
|
|||
|
|
"error": null
|
|||
|
|
}
|
|||
|
|
✔ normal · 비밀번호를 잊어버렸어요 · 0.8s
|
|||
|
|
→ request POST /webhook/my-helpdesk
|
|||
|
|
{
|
|||
|
|
"question": "비밀번호를 잊어버렸어요",
|
|||
|
|
"user": "오세훈",
|
|||
|
|
"tag": "normal"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"route": "자동 답변",
|
|||
|
|
"status": "success",
|
|||
|
|
"topic": "비밀번호",
|
|||
|
|
"answer": "사내 포털 로그인 화면의 '비밀번호 찾기'에서 휴대폰 인증 후 새 비밀번호를 설정합니다.",
|
|||
|
|
"error": null
|
|||
|
|
}
|
|||
|
|
✔ normal · 프린터 출력이 안 돼요 · 1.2s
|
|||
|
|
→ request POST /webhook/my-helpdesk
|
|||
|
|
{
|
|||
|
|
"question": "프린터 출력이 안 돼요",
|
|||
|
|
"user": "윤하늘",
|
|||
|
|
"tag": "normal"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"route": "자동 답변",
|
|||
|
|
"status": "success",
|
|||
|
|
"topic": "프린터",
|
|||
|
|
"answer": "프린터 전원과 네트워크 연결을 확인하고, 인쇄 대기열을 비운 뒤 다시 출력합니다.",
|
|||
|
|
"error": null
|
|||
|
|
}
|
|||
|
|
✔ normal · 메일함 용량이 꽉 찼대 · 1.0s
|
|||
|
|
→ request POST /webhook/my-helpdesk
|
|||
|
|
{
|
|||
|
|
"question": "메일함 용량이 꽉 찼대요",
|
|||
|
|
"user": "강민수",
|
|||
|
|
"tag": "normal"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"route": "자동 답변",
|
|||
|
|
"status": "success",
|
|||
|
|
"topic": "메일",
|
|||
|
|
"answer": "오래된 메일과 큰 첨부 파일을 보관함으로 옮기거나 삭제해 용량을 확보합니다.",
|
|||
|
|
"error": null
|
|||
|
|
}
|
|||
|
|
✔ normal · 새 프로그램 설치는 어 · 1.1s
|
|||
|
|
→ request POST /webhook/my-helpdesk
|
|||
|
|
{
|
|||
|
|
"question": "새 프로그램 설치는 어떻게 신청하나요?",
|
|||
|
|
"user": "서지아",
|
|||
|
|
"tag": "normal"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"route": "자동 답변",
|
|||
|
|
"status": "success",
|
|||
|
|
"topic": "설치",
|
|||
|
|
"answer": "새 프로그램 설치는 IT 포털의 '소프트웨어 신청' 메뉴에서 승인 요청을 올리면 승인 후 원격으로 설치됩니다.",
|
|||
|
|
"error": null
|
|||
|
|
}
|
|||
|
|
Passed 10/10
|
|||
|
|
report: runs/replay-normal-20261031-075225.json
|
|||
|
|
|
|||
|
|
$ uv run tools/flow.py test cases/lab03-cost.json -v
|
|||
|
|
POST http://localhost:5678/webhook/my-log-report · 4 case(s) × 1
|
|||
|
|
✔ 고치기 전 · 느린 FAQ · 1초에 끊김 · 0.1s · 0 calls · $0.000000
|
|||
|
|
→ request POST /webhook/my-log-report
|
|||
|
|
{
|
|||
|
|
"tag": "before",
|
|||
|
|
"source": "live"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"total": 10,
|
|||
|
|
"errors": 10,
|
|||
|
|
"error_rate": 1,
|
|||
|
|
"p50_ms": 1043,
|
|||
|
|
"p95_ms": 1098,
|
|||
|
|
"by_route": {
|
|||
|
|
"오류": 10
|
|||
|
|
},
|
|||
|
|
"by_day": {
|
|||
|
|
"2026-10-31": {
|
|||
|
|
"total": 10,
|
|||
|
|
"errors": 10,
|
|||
|
|
"error_rate": 1
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"by_release": {},
|
|||
|
|
"steps": {
|
|||
|
|
"faq_ms": {
|
|||
|
|
"runs": 10,
|
|||
|
|
"p50": 1043,
|
|||
|
|
"p95": 1098
|
|||
|
|
},
|
|||
|
|
"answer_ms": {
|
|||
|
|
"runs": 0,
|
|||
|
|
"p50": 0,
|
|||
|
|
"p95": 0
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"cost_usd": 0,
|
|||
|
|
"cost_per_run": 0,
|
|||
|
|
"llm_calls": 0,
|
|||
|
|
"failures": [
|
|||
|
|
{
|
|||
|
|
"node": "Search FAQ",
|
|||
|
|
"message": "timeout of 1000ms exceeded",
|
|||
|
|
"count": 10
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"unanswered_topics": [],
|
|||
|
|
"anomalies": [],
|
|||
|
|
"repeat_topics": [],
|
|||
|
|
"unanswered_rate": 0,
|
|||
|
|
"slo": {
|
|||
|
|
"ok": false,
|
|||
|
|
"breaches": [
|
|||
|
|
"error_rate"
|
|||
|
|
],
|
|||
|
|
"limits": {
|
|||
|
|
"error_rate": 0.01,
|
|||
|
|
"p95_ms": 3000,
|
|||
|
|
"unanswered_rate": 0.02
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
✔ 고친 뒤 · 느린 FAQ · 기다려서 답함 · 0.1s · 10 calls · $0.000000
|
|||
|
|
→ request POST /webhook/my-log-report
|
|||
|
|
{
|
|||
|
|
"tag": "after",
|
|||
|
|
"source": "live"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"total": 10,
|
|||
|
|
"errors": 0,
|
|||
|
|
"error_rate": 0,
|
|||
|
|
"p50_ms": 2342,
|
|||
|
|
"p95_ms": 3560,
|
|||
|
|
"by_route": {
|
|||
|
|
"자동 답변": 10
|
|||
|
|
},
|
|||
|
|
"by_day": {
|
|||
|
|
"2026-10-31": {
|
|||
|
|
"total": 10,
|
|||
|
|
"errors": 0,
|
|||
|
|
"error_rate": 0
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"by_release": {
|
|||
|
|
"1.1.0": {
|
|||
|
|
"answers": 10,
|
|||
|
|
"repeats": 0,
|
|||
|
|
"repeat_rate": 0
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"steps": {
|
|||
|
|
"faq_ms": {
|
|||
|
|
"runs": 10,
|
|||
|
|
"p50": 1238,
|
|||
|
|
"p95": 1278
|
|||
|
|
},
|
|||
|
|
"answer_ms": {
|
|||
|
|
"runs": 10,
|
|||
|
|
"p50": 1103,
|
|||
|
|
"p95": 2282
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"cost_usd": 0,
|
|||
|
|
"cost_per_run": 0,
|
|||
|
|
"llm_calls": 10,
|
|||
|
|
"failures": [],
|
|||
|
|
"unanswered_topics": [],
|
|||
|
|
"anomalies": [],
|
|||
|
|
"repeat_topics": [],
|
|||
|
|
"unanswered_rate": 0,
|
|||
|
|
"slo": {
|
|||
|
|
"ok": false,
|
|||
|
|
"breaches": [
|
|||
|
|
"p95_ms"
|
|||
|
|
],
|
|||
|
|
"limits": {
|
|||
|
|
"error_rate": 0.01,
|
|||
|
|
"p95_ms": 3000,
|
|||
|
|
"unanswered_rate": 0.02
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
✔ 고친 뒤 · 평소 FAQ · 기다릴 일이 없음 · 0.0s · 10 calls · $0.000000
|
|||
|
|
→ request POST /webhook/my-log-report
|
|||
|
|
{
|
|||
|
|
"tag": "normal",
|
|||
|
|
"source": "live"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"total": 10,
|
|||
|
|
"errors": 0,
|
|||
|
|
"error_rate": 0,
|
|||
|
|
"p50_ms": 1015,
|
|||
|
|
"p95_ms": 2147,
|
|||
|
|
"by_route": {
|
|||
|
|
"자동 답변": 10
|
|||
|
|
},
|
|||
|
|
"by_day": {
|
|||
|
|
"2026-10-31": {
|
|||
|
|
"total": 10,
|
|||
|
|
"errors": 0,
|
|||
|
|
"error_rate": 0
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"by_release": {
|
|||
|
|
"1.1.0": {
|
|||
|
|
"answers": 10,
|
|||
|
|
"repeats": 0,
|
|||
|
|
"repeat_rate": 0
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"steps": {
|
|||
|
|
"faq_ms": {
|
|||
|
|
"runs": 10,
|
|||
|
|
"p50": 17,
|
|||
|
|
"p95": 39
|
|||
|
|
},
|
|||
|
|
"answer_ms": {
|
|||
|
|
"runs": 10,
|
|||
|
|
"p50": 997,
|
|||
|
|
"p95": 2108
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"cost_usd": 0,
|
|||
|
|
"cost_per_run": 0,
|
|||
|
|
"llm_calls": 10,
|
|||
|
|
"failures": [],
|
|||
|
|
"unanswered_topics": [],
|
|||
|
|
"anomalies": [],
|
|||
|
|
"repeat_topics": [],
|
|||
|
|
"unanswered_rate": 0,
|
|||
|
|
"slo": {
|
|||
|
|
"ok": true,
|
|||
|
|
"breaches": [],
|
|||
|
|
"limits": {
|
|||
|
|
"error_rate": 0.01,
|
|||
|
|
"p95_ms": 3000,
|
|||
|
|
"unanswered_rate": 0.02
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
✔ 고친 뒤 · 답 단계는 FAQ 속도와 상관없음 · 0.1s · 10 calls · $0.000000
|
|||
|
|
→ request POST /webhook/my-log-report
|
|||
|
|
{
|
|||
|
|
"tag": "normal",
|
|||
|
|
"source": "live"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"total": 10,
|
|||
|
|
"errors": 0,
|
|||
|
|
"error_rate": 0,
|
|||
|
|
"p50_ms": 1015,
|
|||
|
|
"p95_ms": 2147,
|
|||
|
|
"by_route": {
|
|||
|
|
"자동 답변": 10
|
|||
|
|
},
|
|||
|
|
"by_day": {
|
|||
|
|
"2026-10-31": {
|
|||
|
|
"total": 10,
|
|||
|
|
"errors": 0,
|
|||
|
|
"error_rate": 0
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"by_release": {
|
|||
|
|
"1.1.0": {
|
|||
|
|
"answers": 10,
|
|||
|
|
"repeats": 0,
|
|||
|
|
"repeat_rate": 0
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"steps": {
|
|||
|
|
"faq_ms": {
|
|||
|
|
"runs": 10,
|
|||
|
|
"p50": 17,
|
|||
|
|
"p95": 39
|
|||
|
|
},
|
|||
|
|
"answer_ms": {
|
|||
|
|
"runs": 10,
|
|||
|
|
"p50": 997,
|
|||
|
|
"p95": 2108
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
"cost_usd": 0,
|
|||
|
|
"cost_per_run": 0,
|
|||
|
|
"llm_calls": 10,
|
|||
|
|
"failures": [],
|
|||
|
|
"unanswered_topics": [],
|
|||
|
|
"anomalies": [],
|
|||
|
|
"repeat_topics": [],
|
|||
|
|
"unanswered_rate": 0,
|
|||
|
|
"slo": {
|
|||
|
|
"ok": true,
|
|||
|
|
"breaches": [],
|
|||
|
|
"limits": {
|
|||
|
|
"error_rate": 0.01,
|
|||
|
|
"p95_ms": 3000,
|
|||
|
|
"unanswered_rate": 0.02
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
Passed 4/4
|
|||
|
|
report: runs/lab03-cost-20261031-075226.json
|
|||
|
|
|
|||
|
|
$ uv run tools/flow.py ops
|
|||
|
|
fault switch: all ok
|
|||
|
|
live run logs: 30 (tag before 10 · tag after 10 · tag normal 10)
|
|||
|
|
added FAQ: 1 (FAQ-007)
|
|||
|
|
created tickets: 0
|
|||
|
|
DLQ: 0 (parked 0)
|
|||
|
|
alerts: 0
|