Lab 01 · 자원과 토큰을 재고, 비용을 계산하고, 기록하기
강사용 정답본 · 학생 저장소에 올리지 않습니다. 학생용 문제는 LAB-01-Q-MEASURE-USAGE.md.
요청문은 예시이며 CLI 에이전트로 보내 재지는 않았습니다. 결과 숫자는 실습을 5개로 늘린 뒤 정답 워크플로우를 학생 순서대로 2026-10-28에 1회씩 실행한 값입니다 (강사 Mac, gpt-4.1-mini · gpt-5.4-nano, 단가는 OpenAI 모델 문서 2026-10-28 확인). 명령 · 출력 전부: answers/LAB-TEST-RESULT.md.
예제 1 · 결과 (에이전트 없이)
자원 (docker stats, answers/01) |
CPU |
메모리 |
| n8n |
0.27% |
642.6MiB |
| runners |
0.21% |
100.5MiB |
| data-api |
0.02% |
20.3MiB |
call base-cost |
단계 |
입력 |
출력 |
| VPN |
classify |
78 |
6 |
| VPN |
answer |
1,781 |
78 |
| VPN |
review |
140 |
66 |
| VPN |
합 |
1,999 |
150 |
| T-1002 |
합 (answer) |
1,973 (1,791) |
97 |
- 손 계산: (1,999 × 0.40 + 150 × 1.60) ÷ 1,000,000 = $0.00104. 하루 1,000건 × 22일 ≈ $22.9.
- 풀이 때: "answer 입력이 왜 질문 종류와 관계없이 1,780토큰인가?" → 지시문에 붙은 사내 규정 전체. Lab 02 예제 1로.
예제 2 · 요청문 예
빈칸 답 (Q 문서 ▶ 빈칸 채우기 ____①~____④)
| 빈칸 |
답 |
왜 |
| ① |
my-cost |
cases/lab01.json의 webhook (AGENTS.md 3절) |
| ② |
prices |
단가를 주는 주소 GET /prices (AGENTS.md 2절) |
| ③ |
1000000 |
단가 단위가 "per 1M tokens" |
| ④ |
8 |
AGENTS.md 3절 cost_usd 반올림 자리 |
정답: reference/lab01-example2-cost.json
| 10/28 결과 |
|
cases/lab01.json (answers/02) |
3/3 · VPN $0.001040 (손 계산과 같음) · 접수 $0.000946 |
예제 3 · 결과 (에이전트 없이)
lab01-mix (answers/03) |
비용 ($) |
| FAQ · VPN · 프린터 · 비밀번호 · 메일 |
0.001040 · 0.000960 · 0.000953 · 0.000965 (평균 0.000980) |
| 접수 · T-1002 · T-1001 |
0.000946 · 0.000890 (평균 0.000918) |
| 규칙에 없는 질문 |
0.000830 |
| 합계 |
7/7, 모두 3 calls |
- 가중(60 · 30 · 10%): $0.000946 × 1,000 × 22 ≈ $20.8. 단순 평균: ≈ $20.7. 두 어림이 거의 같은 까닭이 이 예제의 답입니다 — 고정비(규정 전체)가 커서 질문 종류가 비용을 거의 바꾸지 않습니다.
- Lab 02 과제 1 뒤에는 질문마다 $0.000097 ~ $0.000166으로 벌어집니다 (고정비가 사라지면 변동비가 보임). 시간이 되면 이것을 마지막에 다시 돌려 보게 합니다.
과제 1 · 요청문 예
빈칸 답 (Q 문서 ▶ 빈칸 채우기 ____①~____④)
| 빈칸 |
답 |
왜 |
| ① |
$execution.id |
이번 실행의 번호 — 한 요청의 호출 세 줄을 묶음 (AGENTS.md 5절) |
| ② |
user |
요청 본문의 사람 이름 칸 (requests/faq-vpn.json) |
| ③ |
neverError: true |
4xx · 5xx 응답도 성공 쪽으로 (74일차 Lab 02 과제 2와 같은 옵션) |
| ④ |
Build result |
사용자에게 보낼 답을 만든 노드. Record usage 뒤의 $json은 기록 API의 응답 |
정답: answers/75-lab01-challenge-record.json
| 10/28 결과 |
고치기 전 (예제 2 정답, answers/04) |
고친 뒤 (answers/05) |
cases/lab01-challenge.json |
3/4 (요약 requests 0) |
4/4 |
flow.py usage |
|
requests 3 · calls 9 · $0.002951 (이준호 $0.001040 · 박서연 $0.000959 · 한지훈 $0.000953) |
과제 2 · 요청문 예
빈칸 답 (Q 문서 ▶ 빈칸 채우기 ____①~____④)
| 빈칸 |
답 |
왜 |
| ① |
3000 |
3초를 ms로 |
| ② |
continueRegularOutput |
실패한 항목을 같은 출력으로 계속 (74일차의 continueErrorOutput은 두 번째 출력으로 따로) |
| ③ |
stored |
기록 API가 성공하면 {"stored": <항목 수>, "total"} |
| ④ |
그대로 |
기록은 운영 쪽 일. 답은 바뀌면 안 됨 |
정답: answers/75-lab01-challenge2-safe-record.json (과제 1 정답 + Record usage의 timeout · onError, Result again의 recorded)
10/28 결과 (cases/lab01-challenge2.json) |
고치기 전 (과제 1 정답, answers/06) |
고친 뒤 (answers/07) |
기록 API 고장 (usage error) |
✘ 답은 나감 · recorded 없음 (3.4초) |
✔ recorded: false (4.4초) |
기록 API 느림 (usage slow 8초) |
✘ 11.2초 · recorded 없음 |
✔ recorded: false · 6.1초 |
| 고친 뒤 · 기록됨 |
✘ recorded 없음 |
✔ recorded: true |
| 요약 · 기록된 요청 1건 |
✔ (고장 두 건은 기록되지 않음) |
✔ |
| 합계 |
1/4 |
4/4 |
lab01-challenge |
|
4/4 |
- 고치기 전의 고장 케이스도 답은 나갑니다 (과제 1의
neverError 덕분에 500 응답을 받아 넘김). 그래서 이 과제의 핵심은 **시간(느림)**과 **표시(recorded)**입니다. 풀이 때 이 차이를 짚습니다.
- 수업 준비 중 실제로 본 것: 처음 데이터 API는 느림 모드에서 8초 뒤 결국 저장했습니다. 워크플로우는 3초에 포기해
recorded: false라고 답했는데, 다음 테스트를 시작할 때 늦게 저장된 한 줄이 끼어들어 requests가 하나 많았습니다. "시간 초과로 포기해도 상대 서버의 일은 끝나지 않을 수 있다"는 실제 운영 문제라 풀이 때 이야기합니다. 데이터 API는 "늦게 답하고 저장하지 않음"(503)으로 바꿨습니다.
- 다음 단계로 넘기는 질문: "기록이 빠진 요청은 Lab 03의 예산에서도 빠진다. 그럼 예산은 실제보다 남아 보이지 않나?" → Lab 03 예제 1 ▶ 2단계.