Files
aio-01d4-stu/Last3Mon/75/VIBE-A-TCOST.md
T

124 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 7교시 바이브 코딩 · `tcost` 정답본
> **강사용 정답본** · 학생 저장소에는 수업 뒤에 올립니다. 학생용은 [VIBE-REQ-TCOST.md](VIBE-REQ-TCOST.md)(요청서) → [VIBE-Q-TCOST.md](VIBE-Q-TCOST.md).
> 강사가 직접 만든 본: [tcost/](tcost/README.md) (2026-10-28, Claude Code가 아래 SPEC · IMP-PLAN을 보고 직접 씀, 테스트 13개). CLI 에이전트에 아래 요청문을 보내 재지는 않았습니다. 강사 바이브 코딩 시간은 6절에 수업 때 적습니다.
## 1. `Doc/TODO.md` 예
```markdown
# tcost TODO
## 만들고 싶은 것
어느 폴더에서나 `tcost`로 LLM을 부르기 전에 글 · 워크플로우의 토큰과 비용을 계산하고,
테스트 보고서의 실제 사용량을 모아 한 달을 예상하는 도구. 화면(TUI)도, 다른 프로그램용 결과도. OpenAI는 부르지 않음.
## 요청의 말 → 할 일
| # | 요청의 말 | 할 일 | 꼭 · 나중 |
| --- | --- | --- | --- |
| ① | 글 파일의 토큰 · 모델마다 비용 | 토큰 수, 한 번 · 1,000번 | 꼭 |
| ② | 출력도 | 출력 토큰을 가정해 더함 | 꼭 |
| ③ | 단가는 파일로, 날짜 · 출처, 한 달 넘으면 알림 | 단가 파일 · 오래됨 알림 | 꼭 |
| ④ | 워크플로우의 LLM 단계 | 노드 · 모델 · 고정 지시문 토큰 | 나중 |
| ⑤ | 보고서 모으기 | 합 · 평균 · 모델별 · 사람별 · 시간대별 | 꼭 |
| ⑥ | 한 달에 얼마 | 평균 × 하루 × 일하는 날 | 꼭 |
| ⑦ | 두 모델 나란히 | 몇 % 싼지 | 나중 |
| ⑧ | 화면 | 탭 셋 · 막대 | 꼭 |
| ⑨ | 예산이면 하루 몇 번 | 예산 ÷ 한 번 비용 | 나중 |
| ⑩ | 다른 프로그램 · 넘으면 실패 | JSON · 종료 코드 | 나중 |
| ⑪ | 폴더 통째로 | 글 · 워크플로우 · 보고서로 나눔 | 나중 |
| ⑫ | 없는 모델은 0원 아님 | 오류 · 목록 | 나중 |
| 끝 | OpenAI를 부르지 않기 | 토큰은 이 컴퓨터에서, 테스트도 | 꼭 |
## 걱정되는 것
- 내가 센 토큰과 OpenAI가 센 토큰이 다를 수 있다 → 보고서의 prompt_tokens와 비교
- 평균의 분모 (요청 수 · 호출 수)
- 보고서에 usage가 없는 결과 (400 · 429 · 요약)
- 오늘 날짜에 따라 달라지는 테스트
```
## 2. `Doc/SPEC.md` 요점
VIBE-Q의 요구 표(R1~R14)와 같습니다. 학생 SPEC과 비교할 때 자주 빠지는 것:
| 자주 빠지는 것 | 왜 필요한가 |
| --- | --- |
| 비용 식 · 반올림을 데이터 API 계약과 같게 (소수 8자리) | 보고서의 `cost_usd`와 나란히 놓으려면 |
| 평균은 요청 수로 | `calls`로 나누면 한 달이 작게 나옴 (Lab 03 과제 1) |
| `usage`가 없는 결과는 **건너뛰고 수를 알림** | 건너뛴 것을 0원으로 세면 평균이 작아짐 |
| "오늘"을 함수에 넘김 | 날짜 알림 테스트가 날마다 같게 |
| 고정 지시문만 센다고 밝힘 | 실제 입력(질문 · FAQ 포함)보다 작게 나옴 |
| 단가 파일을 패키지에 함께 | `uv tool install` 뒤 다른 폴더에서 단가를 못 찾음 |
## 3. `Doc/IMP-PLAN.md`
[tcost/Doc/IMP-PLAN.md](tcost/Doc/IMP-PLAN.md) — 엔진 1단계(R1 · R2 · R3 · R13) → 엔진 2단계(R5 · R6) → TUI 1단계(R8) → 설치(R14) → 엔진 3단계(R4 · R7 · R12) → 엔진 4단계(R9 · R10 · R11).
## 4. 단계별 요청문 예
### 엔진 1단계
```text
Doc/SPEC.md 와 Doc/IMP-PLAN.md 를 읽고 "엔진 1단계"만 만들어 줘. uv 프로젝트, 명령 이름 tcost, 코드와 화면 글자는 영어.
- prices.json: {"checked": "2026-10-28", "source": ..., "models": {"gpt-4.1-mini": {"input": 0.40, "output": 1.60}, "gpt-5.4-nano": {"input": 0.20, "output": 1.25}}}
패키지 안에 두고 --prices 로 바꿀 수 있게. cost(model, in, out) = (in × input + out × output) / 1,000,000, 소수 8자리.
warning(today): checked 가 30일 넘었거나 없으면 알림 글.
- tokens.count(text): tiktoken o200k_base. API 는 부르지 않는다.
- tcost count <파일> [--out N] [--model M]: 파일마다 토큰과 모델마다 한 번 · 1,000번 비용 표.
- tests: 1,000토큰 mini → 0.0004, --out 100 → 0.00056, checked + 45일 → 알림. 네트워크 없이.
끝나면 IMP-PLAN 체크를 표시하고 확인 명령을 알려 줘.
```
### 엔진 2단계
```text
엔진 2단계만: usage.collect(paths) 가 flow.py 테스트 보고서(runs/*.json, results[].request · response)를 읽어
response.usage.by_step 이 있는 결과만 요청 하나로 세고, 단계마다 호출 하나로 토큰 · cost_usd 를 모델별 · 사람별(request.user) · 시간대별(파일 이름 -YYYYMMDD-HHMMSS 의 HH) 로 더해 줘.
usage 가 없는 결과는 skipped 로 센다. avg = 비용 ÷ 요청 수, month(per_day, days) = avg × per_day × days (소수 6자리).
tcost usage <폴더> [--per-day N --days 22]. tests: 결과 셋 중 400 하나 → 요청 2 · skipped 1, 사람별 합, 한 달.
```
### TUI 1단계
```text
TUI 1단계만: tcost <폴더> [폴더 …] 이면 Textual 화면. TabbedContent 탭 셋:
Prompts(글 파일 · 워크플로우 LLM 단계마다 토큰과 모델마다 1,000번 비용 DataTable), Usage(보고서 합 · 모델별 · 사람별 표, 시간대별 막대 ▁▂▃▄▅▆▇█),
Compare(토큰이 많은 지시문 열 개, 모델마다 출력 100 가정 한 번 비용). [r] 다시 읽기, [q] 끝.
엔진은 고치지 말고 불러 쓰기만. pytest run_test 로 세 탭이 채워지는지.
```
## 5. 결과 확인 (강사 본, 2026-10-28)
| 요구 | 확인 | 결과 |
| --- | --- | --- |
| R1 · R2 | pytest (1,000토큰 · `--out 100`) | $0.0004 · $0.00056 |
| R3 | pytest (확인 + 45일, 날짜 없는 단가표) | 알림 둘 |
| R4 | `tcost workflow reference/baseline-cost.json` | `Answer` 지시문 **1,670토큰** (n8n이 잰 답 단계 입력 1,781 중 고정 몫, 나머지 약 110이 질문 · FAQ · 접수 건) |
| R4 | `tcost workflow answers/75-lab02-challenge2-long-question.json` | `Answer` 75토큰 · 출력 상한 200, `Classify` nano |
| R5 · R6 | `tcost usage answers --per-day 1000` | 보고서 23 · 요청 82 · $0.038746 · skipped 26 (요약 · 400 · 429 · 보고서 케이스) |
| R7 | 긴 프린터 질문 `compare --out 60` | mini $0.001141 · nano $0.000598 (48% cheaper) |
| R8 | pytest `run_test`, `tcost reference runs` | 세 탭, 지시문 19줄 · 보고서 51개 |
| R9 | 긴 프린터 질문 `budget 1.0 --out 60` | mini 876번 · nano 1,673번 |
| R10 | 긴 프린터 질문 `count --out 60 --max-usd 0.0003` | 종료 코드 1 |
| R11 | `tcost scan .` (75일차 폴더) | `cases/*.json` · `.md` 문서는 skipped |
| R12 | `tcost count x --model gpt-4.1-nano` | `unknown model 'gpt-4.1-nano' (known: gpt-4.1-mini, gpt-5.4-nano)`, 종료 코드 2 |
| R13 | 테스트 13개 | 네트워크 · 키 없이 |
| R14 | `uv tool install --editable .`, `/tmp`에서 `tcost --help` | 됨 |
부르기 전 계산과 실제의 비교 (긴 프린터 질문 6,298자):
| | 입력 토큰 | 비용 (mini) |
| --- | --- | --- |
| `tcost count --out 60` (질문 글만) | 2,613 | $0.001141 |
| n8n 실제 (Lab 02 과제 1 정답, `answers/14`) | (질문 + 지시문 + FAQ) | $0.001196 |
- 풀이 거리: 미리 계산은 질문 글만 셌고, 실제는 지시문 · FAQ가 더해져 조금 더 큽니다. "부르기 전 계산은 **하한**에 가깝다"는 것, 그래서 `tcost workflow`(고정 지시문)와 `count`(질문)를 **더해** 어림해야 한다는 것을 짚습니다.
- 처음 만든 본은 폴더의 `.md`를 모두 지시문으로 셌습니다. 75일차 폴더를 열면 실습 문서 · 결과 기록까지 "지시문"으로 나와 쓸 수 없어서, 글 파일을 `.txt` · `.prompt`로 좁히고 화면은 폴더 여럿(`tcost reference runs`)을 받게 바꿨습니다. **요청서의 ⑪ "알아서 나눠"가 무엇을 뜻하는지는 직접 써 봐야 드러난다**는 예입니다.
## 6. 강사 바이브 코딩 (8교시, 수업 때 적음)
| 주제 | 요청문 요지 | 걸린 시간 · 결과 |
| --- | --- | --- |
| 실제와 맞춰 보기 | "보고서의 질문 글을 세어 prompt_tokens와 차이를 % 로" | |
| 캐시 입력 단가 | "cached_tokens 가 있으면 cached input 단가로" | |
| 비용 관문 붙이기 | "tcost workflow --max-usd 를 tver save 앞에" | |