288 lines
9.7 KiB
Plaintext
288 lines
9.7 KiB
Plaintext
$ uv run tools/flow.py push answers/75-lab03-challenge2-what-if.json
|
||||
|
|
! unpublished '75 Cost report (answer)' (w1f9c668c0305daf): it used the same webhook path
|
|||
|
|
✔ pushed '75 Cost report + what-if (answer)' (id wc7211a27bb523f0)
|
|||
|
|
POST http://localhost:5678/webhook/my-cost-report
|
|||
|
|
|
|||
|
|
$ uv run tools/flow.py test cases/lab03-challenge2.json -v
|
|||
|
|
✔ before: POST http://localhost:8800/usage-clear · HTTP 200 · 0.0s · {"cleared": 0}
|
|||
|
|
→ request POST http://localhost:8800/usage-clear
|
|||
|
|
{}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"cleared": 0
|
|||
|
|
}
|
|||
|
|
✔ before: POST http://localhost:8800/budget/reset · HTTP 200 · 0.0s · {"daily_usd": 1.0, "user_limit_per_min": 20, "max_question_chars": 500, "used_usd": 0, "remaining_usd": 1.0, "over": fal
|
|||
|
|
→ request POST http://localhost:8800/budget/reset
|
|||
|
|
{}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"daily_usd": 1.0,
|
|||
|
|
"user_limit_per_min": 20,
|
|||
|
|
"max_question_chars": 500,
|
|||
|
|
"used_usd": 0,
|
|||
|
|
"remaining_usd": 1.0,
|
|||
|
|
"over": false
|
|||
|
|
}
|
|||
|
|
✔ before: POST http://localhost:8800/usage · HTTP 200 · 0.0s · {"stored": 4, "total": 4}
|
|||
|
|
→ request POST http://localhost:8800/usage
|
|||
|
|
{
|
|||
|
|
"items": [
|
|||
|
|
{
|
|||
|
|
"request_id": "r1",
|
|||
|
|
"user": "이준호",
|
|||
|
|
"step": "answer",
|
|||
|
|
"model": "gpt-4.1-mini",
|
|||
|
|
"prompt_tokens": 1000,
|
|||
|
|
"completion_tokens": 100,
|
|||
|
|
"cost_usd": 0.00056,
|
|||
|
|
"route": "자동 답변"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"request_id": "r1",
|
|||
|
|
"user": "이준호",
|
|||
|
|
"step": "classify",
|
|||
|
|
"model": "gpt-5.4-nano",
|
|||
|
|
"prompt_tokens": 100,
|
|||
|
|
"completion_tokens": 20,
|
|||
|
|
"cost_usd": 4.5e-05,
|
|||
|
|
"route": "자동 답변"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"request_id": "r2",
|
|||
|
|
"user": "박서연",
|
|||
|
|
"step": "answer",
|
|||
|
|
"model": "gpt-4.1-mini",
|
|||
|
|
"prompt_tokens": 2000,
|
|||
|
|
"completion_tokens": 200,
|
|||
|
|
"cost_usd": 0.00112,
|
|||
|
|
"route": "자동 답변"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"request_id": "r3",
|
|||
|
|
"user": "이준호",
|
|||
|
|
"step": "answer",
|
|||
|
|
"model": "gpt-4.1-mini",
|
|||
|
|
"prompt_tokens": 500,
|
|||
|
|
"completion_tokens": 40,
|
|||
|
|
"cost_usd": 0.000264,
|
|||
|
|
"route": "자동 답변"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"stored": 4,
|
|||
|
|
"total": 4
|
|||
|
|
}
|
|||
|
|
POST http://localhost:5678/webhook/my-cost-report · 5 case(s) × 1
|
|||
|
|
✔ 모두 nano였다면 · 0.9s · $0.001989
|
|||
|
|
→ request POST /webhook/my-cost-report
|
|||
|
|
{
|
|||
|
|
"requests_per_day": 100,
|
|||
|
|
"workdays": 22,
|
|||
|
|
"what_if_model": "gpt-5.4-nano"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"requests": 3,
|
|||
|
|
"calls": 4,
|
|||
|
|
"cost_usd": 0.001989,
|
|||
|
|
"avg_usd": 0.000663,
|
|||
|
|
"by_model": {
|
|||
|
|
"gpt-4.1-mini": 0.001944,
|
|||
|
|
"gpt-5.4-nano": 4.5e-05
|
|||
|
|
},
|
|||
|
|
"top_user": "박서연",
|
|||
|
|
"projected_month_usd": 1.4586,
|
|||
|
|
"daily_budget_usd": 1,
|
|||
|
|
"remaining_usd": 0.998011,
|
|||
|
|
"over_budget": false,
|
|||
|
|
"what_if": {
|
|||
|
|
"model": "gpt-5.4-nano",
|
|||
|
|
"cost_usd": 0.00117,
|
|||
|
|
"saving_usd": 0.000819,
|
|||
|
|
"projected_month_usd": 0.858
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
✔ 원래 숫자는 그대로 · 0.1s · $0.001989
|
|||
|
|
→ request POST /webhook/my-cost-report
|
|||
|
|
{
|
|||
|
|
"requests_per_day": 100,
|
|||
|
|
"workdays": 22,
|
|||
|
|
"what_if_model": "gpt-5.4-nano"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"requests": 3,
|
|||
|
|
"calls": 4,
|
|||
|
|
"cost_usd": 0.001989,
|
|||
|
|
"avg_usd": 0.000663,
|
|||
|
|
"by_model": {
|
|||
|
|
"gpt-4.1-mini": 0.001944,
|
|||
|
|
"gpt-5.4-nano": 4.5e-05
|
|||
|
|
},
|
|||
|
|
"top_user": "박서연",
|
|||
|
|
"projected_month_usd": 1.4586,
|
|||
|
|
"daily_budget_usd": 1,
|
|||
|
|
"remaining_usd": 0.998011,
|
|||
|
|
"over_budget": false,
|
|||
|
|
"what_if": {
|
|||
|
|
"model": "gpt-5.4-nano",
|
|||
|
|
"cost_usd": 0.00117,
|
|||
|
|
"saving_usd": 0.000819,
|
|||
|
|
"projected_month_usd": 0.858
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
✔ 모두 mini였다면 · 아끼는 돈이 음수 · 0.0s · $0.001989
|
|||
|
|
→ request POST /webhook/my-cost-report
|
|||
|
|
{
|
|||
|
|
"what_if_model": "gpt-4.1-mini"
|
|||
|
|
}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"requests": 3,
|
|||
|
|
"calls": 4,
|
|||
|
|
"cost_usd": 0.001989,
|
|||
|
|
"avg_usd": 0.000663,
|
|||
|
|
"by_model": {
|
|||
|
|
"gpt-4.1-mini": 0.001944,
|
|||
|
|
"gpt-5.4-nano": 4.5e-05
|
|||
|
|
},
|
|||
|
|
"top_user": "박서연",
|
|||
|
|
"projected_month_usd": 0.043758,
|
|||
|
|
"daily_budget_usd": 1,
|
|||
|
|
"remaining_usd": 0.998011,
|
|||
|
|
"over_budget": false,
|
|||
|
|
"what_if": {
|
|||
|
|
"model": "gpt-4.1-mini",
|
|||
|
|
"cost_usd": 0.002016,
|
|||
|
|
"saving_usd": -2.7e-05,
|
|||
|
|
"projected_month_usd": 0.044352
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
✔ 없는 모델은 400 · 0.2s
|
|||
|
|
→ request POST /webhook/my-cost-report
|
|||
|
|
{
|
|||
|
|
"what_if_model": "gpt-9"
|
|||
|
|
}
|
|||
|
|
← response HTTP 400
|
|||
|
|
{
|
|||
|
|
"error": "unknown model",
|
|||
|
|
"model": "gpt-9",
|
|||
|
|
"known": [
|
|||
|
|
"gpt-4.1-mini",
|
|||
|
|
"gpt-5.4-nano"
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
✔ what_if 없이 부르면 과제 1과 같음 · 0.0s · $0.001989
|
|||
|
|
→ request POST /webhook/my-cost-report
|
|||
|
|
{}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"requests": 3,
|
|||
|
|
"calls": 4,
|
|||
|
|
"cost_usd": 0.001989,
|
|||
|
|
"avg_usd": 0.000663,
|
|||
|
|
"by_model": {
|
|||
|
|
"gpt-4.1-mini": 0.001944,
|
|||
|
|
"gpt-5.4-nano": 4.5e-05
|
|||
|
|
},
|
|||
|
|
"top_user": "박서연",
|
|||
|
|
"projected_month_usd": 0.043758,
|
|||
|
|
"daily_budget_usd": 1,
|
|||
|
|
"remaining_usd": 0.998011,
|
|||
|
|
"over_budget": false
|
|||
|
|
}
|
|||
|
|
Passed 5/5
|
|||
|
|
report: runs/lab03-challenge2-20261028-211231.json
|
|||
|
|
✔ after: POST http://localhost:8800/budget/reset · HTTP 200 · 0.0s · {"daily_usd": 1.0, "user_limit_per_min": 20, "max_question_chars": 500, "used_usd": 0.001989, "remaining_usd": 0.998011,
|
|||
|
|
→ request POST http://localhost:8800/budget/reset
|
|||
|
|
{}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"daily_usd": 1.0,
|
|||
|
|
"user_limit_per_min": 20,
|
|||
|
|
"max_question_chars": 500,
|
|||
|
|
"used_usd": 0.001989,
|
|||
|
|
"remaining_usd": 0.998011,
|
|||
|
|
"over": false
|
|||
|
|
}
|
|||
|
|
✔ after: POST http://localhost:8800/usage-clear · HTTP 200 · 0.0s · {"cleared": 4}
|
|||
|
|
→ request POST http://localhost:8800/usage-clear
|
|||
|
|
{}
|
|||
|
|
← response HTTP 200
|
|||
|
|
{
|
|||
|
|
"cleared": 4
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$ uv run tools/flow.py test cases/lab03-challenge.json
|
|||
|
|
✔ before: POST http://localhost:8800/usage-clear · HTTP 200 · 0.0s · {"cleared": 0}
|
|||
|
|
✔ before: POST http://localhost:8800/budget/reset · HTTP 200 · 0.0s · {"daily_usd": 1.0, "user_limit_per_min": 20, "max_question_chars": 500, "used_usd": 0, "remaining_usd": 1.0, "over": fal
|
|||
|
|
✔ before: POST http://localhost:8800/usage · HTTP 200 · 0.0s · {"stored": 4, "total": 4}
|
|||
|
|
POST http://localhost:5678/webhook/my-cost-report · 5 case(s) × 1
|
|||
|
|
✔ 요약 숫자 · 0.1s · $0.001989
|
|||
|
|
✔ 모델별 · 한 달 예상 · 0.1s · $0.001989
|
|||
|
|
✔ 작은 모델 몫 · 0.1s · $0.001989
|
|||
|
|
✔ 예산 남은 금액 · 0.0s · $0.001989
|
|||
|
|
✔ before: POST http://localhost:8800/budget · HTTP 200 · 0.0s · {"daily_usd": 0.001, "user_limit_per_min": 20, "max_question_chars": 500, "used_usd": 0.001989, "remaining_usd": -0.0009
|
|||
|
|
✔ 예산을 넘으면 · 0.0s · $0.001989
|
|||
|
|
Passed 5/5
|
|||
|
|
report: runs/lab03-challenge-20261028-211232.json
|
|||
|
|
✔ after: POST http://localhost:8800/budget/reset · HTTP 200 · 0.0s · {"daily_usd": 1.0, "user_limit_per_min": 20, "max_question_chars": 500, "used_usd": 0.001989, "remaining_usd": 0.998011,
|
|||
|
|
✔ after: POST http://localhost:8800/usage-clear · HTTP 200 · 0.0s · {"cleared": 4}
|
|||
|
|
|
|||
|
|
$ uv run tools/flow.py test cases/lab02-challenge.json
|
|||
|
|
POST http://localhost:5678/webhook/my-cost · 7 case(s) × 1
|
|||
|
|
✔ faq-vpn · LLM 한 번 · $0.0002 이하 · 1.7s · 자동 답변 · 1 call · $0.000156
|
|||
|
|
✔ faq-password · LLM 한 번 · $0.0002 이하 · 1.4s · 자동 답변 · 1 call · $0.000136
|
|||
|
|
✔ faq-printer · LLM 한 번 · $0.0002 이하 · 1.2s · 자동 답변 · 1 call · $0.000150
|
|||
|
|
✔ faq-mail · LLM 한 번 · $0.0002 이하 · 1.4s · 자동 답변 · 1 call · $0.000166
|
|||
|
|
✔ ticket-own · LLM 한 번 · $0.0002 이하 · 1.0s · 자동 답변 · 1 call · $0.000115
|
|||
|
|
✔ ticket-done · LLM 한 번 · $0.0002 이하 · 1.1s · 자동 답변 · 1 call · $0.000108
|
|||
|
|
✔ 규칙으로 모르는 질문은 분류 + 답 · 2.2s · 자동 답변 · 2 calls · $0.000097
|
|||
|
|
Passed 7/7
|
|||
|
|
report: runs/lab02-challenge-20261028-211242.json
|
|||
|
|
|
|||
|
|
$ uv run tools/flow.py call my-cost-report '{"requests_per_day": 1000, "what_if_model": "gpt-5.4-nano"}'
|
|||
|
|
HTTP 200 · 0.1s
|
|||
|
|
{
|
|||
|
|
"requests": 7,
|
|||
|
|
"calls": 8,
|
|||
|
|
"cost_usd": 0.000929,
|
|||
|
|
"avg_usd": 0.000133,
|
|||
|
|
"by_model": {
|
|||
|
|
"gpt-4.1-mini": 0.000904,
|
|||
|
|
"gpt-5.4-nano": 2.5e-05
|
|||
|
|
},
|
|||
|
|
"top_user": "이준호",
|
|||
|
|
"projected_month_usd": 2.920971,
|
|||
|
|
"daily_budget_usd": 1,
|
|||
|
|
"remaining_usd": 0.999071,
|
|||
|
|
"over_budget": false,
|
|||
|
|
"what_if": {
|
|||
|
|
"model": "gpt-5.4-nano",
|
|||
|
|
"cost_usd": 0.00061,
|
|||
|
|
"saving_usd": 0.00032,
|
|||
|
|
"projected_month_usd": 1.9162
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$ uv run tools/flow.py usage --clear
|
|||
|
|
✔ usage cleared: {"cleared": 8}
|
|||
|
|
|
|||
|
|
$ uv run tools/flow.py budget --reset
|
|||
|
|
✔ budget back to data/budget.json
|
|||
|
|
budget $1.0 / used $0.000000 · remaining $1.000000 · over False · per user 20/min · question 500 chars
|
|||
|
|
|
|||
|
|
$ uv run tools/flow.py doctor
|
|||
|
|
! n8n install folder /Users/mcchae/day65-n8n
|
|||
|
|
→ day 65 SETUP-N8N 5단계 (get.n8n.io 설치). 다른 곳에 설치했다면 Last3Mon/65/n8n/.env 에 N8N_HOME=<폴더>
|
|||
|
|
✔ n8n container day65-n8n-n8n-1
|
|||
|
|
✔ n8n http://localhost:5678
|
|||
|
|
✔ data API http://localhost:8800
|
|||
|
|
✔ prices /prices · budget /budget (day 75 data API)
|
|||
|
|
✔ n8n → http://data-api:8800
|
|||
|
|
✔ credential 'OpenAI (.env)' (openAiCourse0001)
|
|||
|
|
✔ node catalog (for check)
|
|||
|
|
✔ CLI coding agent: codex, claude, agy
|
|||
|
|
ready
|