75일차 자료 추가 (답 제외): 실습 15개 · 실행 결과, gpt-5.4-nano · 단가, 교안 개요 30장 · 4단계 정리, 바이브 코딩 tcost 요청서

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mcchaeandClaude Opus 5.5 committed 2026-10-28 22:38:01 +09:00
1 parent d663d045e3
commit 01dc892303
70 files changed
+10890

No files matched your search

+420
View File
@@ -0,0 +1,420 @@
# 75일차 개요 · 컴퓨팅 자원·API 사용량 관리와 비용 최적화
> 노코드 멀티 에이전트 워크플로우 설계 및 운영 · 2026-10-29
> 30장 · 각 장은 가로줄(`---`)로 나뉩니다. 1교시에는 1~6장을 보고, 나머지 장은 각 단계 강의(1 · 3 · 5교시) 때 함께 띄웁니다.
> 숫자는 모두 강사 노트북 실측입니다 (65일차 n8n 2.42.6, OpenAI `gpt-4.1-mini` · `gpt-5.4-nano`, 10/28 정답 워크플로우를 학생 순서대로 1회). 단가는 OpenAI 모델 문서에서 2026-10-28에 확인한 값입니다.
| 장 | 범위 | 띄우는 때 |
| --- | --- | --- |
| 1~6 | 표지 · 목표 · 시간표 · 비싼 헬프데스크 · 일하는 순서 · 실습 15개 | 1교시 시작 |
| 7~14 | 1단계 · 사용량 재기 | 1교시 강의 |
| 15~21 | 2단계 · 비용 줄이기 | 3교시 강의 |
| 22~28 | 3단계 · 예산과 한도 | 5교시 강의 |
| 29~30 | 바이브 코딩 · 정리와 예고 (8교시 35분 정리는 [04-STAGE4-WRAPUP](04-STAGE4-WRAPUP.md)) | 7교시 · 8교시 |
---
## 1 / 30 · 표지
```mermaid
flowchart LR
M["재기<br/>토큰 · 비용 · 기록"] --> R["줄이기<br/>보내는 것 · 모델 · 호출 수"] --> K["지키기<br/>예산 · 한도 · 보고서"]
classDef d fill:#0F3D3E,stroke:#0F3D3E,color:#fff
classDef o fill:#F2A541,stroke:#F2A541,color:#fff
class M,K o
class R d
```
**75일차**
# 컴퓨팅 자원·API 사용량 관리와 비용 최적화
질문 하나에 얼마인지 재고, 품질은 그대로 두고 줄이고, 넘치지 않게 지킨다
<sub>노코드 멀티 에이전트 워크플로우 설계 및 운영 · 2026-10-29</sub>
---
## 2 / 30 · 오늘 할 수 있게 될 세 가지
| | 목표 | 내용 |
| --- | --- | --- |
| 1 | **잰다** | 자원 · 토큰 · 돈을 구분하고, 단계마다 비용을 결과에 남기고, 종류별로 한 달을 어림하고, 요청마다 기록한다 (멈춰도 답은 나감) |
| 2 | **줄인다** | 보내는 것 · 단가 · 호출 수를 한 칸씩, 품질 테스트와 답 읽기로 확인하고, 긴 입력에도 상한을 둔다 |
| 3 | **지킨다** | 하루 예산을 넘으면 원문으로, 몰아 부르면 429, 예산이 언제 멈추는지 재고, 보고서 · what-if는 코드로 |
---
## 3 / 30 · 오늘의 시간표
| 교시 | 시간 | 내용 |
| --- | --- | --- |
| 1 | 09:00~09:50 | 개요 · **1단계 강의** · 사용량 재기 |
| 2 | 10:00~10:50 | **Lab 01 실습 5개** · 자원 · 비용 · 종류별 비용 · 기록 · 기록이 멈추면 |
| 3 | 11:00~11:50 | **2단계 강의** · 비용 줄이기 |
| 4 | 12:00~12:50 | **Lab 02 실습 5개** · 보내는 것 · 모델 · 답까지 nano? · LLM 한 번 · 긴 질문 |
| - | 13:00~14:00 | 점심 |
| 5 | 14:00~14:50 | **3단계 강의** · 예산과 한도 |
| 6 | 15:00~15:50 | **Lab 03 실습 5개** · 하루 예산 · 1분 한도 · 예산 바꿔 보기 · 보고서 · what-if |
| 7 | 16:00~16:50 | 바이브 코딩 `tcost`: 요청서 → TODO → SPEC → IMP-PLAN → 만들기 → 설치 |
| 8 | 17:00~17:50 | 발표 · **4단계 정리** (의미 · 효과 · 회사에서 쓰는 법) · 76일차 예고 |
---
## 4 / 30 · 오늘 고치는 것: 비싼 헬프데스크
```mermaid
flowchart LR
Q(["질문"]) --> C{{"분류 LLM"}} --> A{{"답 LLM<br/>+ 사내 규정 전체"}} --> R{{"검토 LLM"}} --> O(["답"])
```
| 수업 준비 때 | VPN 질문 하나 | LLM 호출 |
| --- | --- | --- |
| 시작 (`base-cost`) | **$0.001040** (입력 1,999 · 출력 150) | 3 |
| 하루 뒤 (Lab 02 과제 1) | **$0.000156** | 1 |
- 72~74일차와 같은 IT 문의 헬프데스크 (FAQ · 접수 건). 오늘은 **같은 답을 더 싸게**, 그리고 **넘치지 않게**.
---
## 5 / 30 · 일하는 순서 (오늘은 "재기 → 줄이기 → 품질 확인")
```mermaid
flowchart LR
A["① 재기<br/>call · test 줄 끝 비용"] --> B["② 요청문을<br/>메모장에"] --> C["③ 에이전트에게"] --> D["④ 에이전트가<br/>my-work · check"] --> E["⑤ 내가<br/>push · test -v"]
E -->|✘| F["⑥ 실패 줄 · 보고서 경로<br/>그대로 붙여 주기"] --> C
E -->|✔| G["⑦ 답 읽기 · COST.md 한 줄"]
```
- 예산 · 한도 · 글자 수 상한은 **내가** `flow.py budget`으로. 끝나면 `budget --reset`.
- 오늘은 호출마다 실제로 돈이 듭니다 (질문 하나에 약 $0.0001~$0.0012). 같은 테스트를 수십 번 반복하지 않습니다.
---
## 6 / 30 · 오늘의 실습 15개
| | 예제 1 | 예제 2 | 예제 3 | 과제 1 | 과제 2 |
| --- | --- | --- | --- | --- | --- |
| Lab 01 | 자원 · 단계별 토큰 (에이전트 없이) | 결과에 `cost_usd` | 종류별 비용 · 한 달 (에이전트 없이) | 요청마다 기록 | 기록이 멈춰도 답 |
| Lab 02 | 보내는 것 줄이기 | 단계마다 맞는 모델 | 답까지 nano면? (에이전트 없이) | LLM 한 번 · $0.0002 | 긴 질문의 상한 |
| Lab 03 | 하루 예산 → 원문 | 1분 한도 → 429 | 예산을 바꿔 가며 (에이전트 없이) | 비용 보고서 | 바꾸면 얼마 (what-if) |
- 실습 문서에 복사해 붙일 요청문은 없습니다. 막히면 `▶`, 요청문은 **빈칸 4개**를 채워서.
---
## 7 / 30 · 1단계 · 왜 비용인가
| | 일반 웹 서비스 | LLM API |
| --- | --- | --- |
| 무엇에 돈을 내나 | 서버 시간 · 저장 · 전송 | **보낸 · 받은 토큰** |
| 요청 하나의 비용 | 작고 거의 같음 | 요청마다 크게 다름 |
| 실수 하나의 크기 | 작음 | 지시문에 긴 자료 → **모든 요청**이 비쌈 |
- FinOps 세 단계: **알기**(1단계) → **줄이기**(2단계) → **운영하기**(3단계). 재지 않고 줄이면 무엇을 잃었는지 모릅니다.
- 쓸모 있는 숫자는 **요청 하나의 비용** (단위 경제).
---
## 8 / 30 · 1단계 · 자원: 내 컴퓨터와 공급자 (Lab 01 예제 1)
| 컨테이너 (`docker stats`) | CPU | 메모리 |
| --- | --- | --- |
| n8n | 0.27% | 642.6MiB |
| runners | 0.21% | 100.5MiB |
| data-api | 0.02% | 20.3MiB |
- API로 부르면 LLM 계산은 공급자 서버에서 → 내 CPU는 거의 쓰지 않음. 돈은 **토큰**에서.
- 내 쪽에서 늘어나는 것: 동시 실행 · 실행 기록 · 로그 (3단계 7절, 76 · 77일차).
---
## 9 / 30 · 1단계 · 토큰과 단가
```text
비용 = (입력 토큰 × 입력 단가 + 출력 토큰 × 출력 단가) ÷ 1,000,000
```
| 모델 (1M 토큰당 $) | 입력 | 캐시된 입력 | 출력 |
| --- | --- | --- | --- |
| `gpt-4.1-mini` | 0.40 | 0.10 | 1.60 |
| `gpt-5.4-nano` | 0.20 | 0.02 | 1.25 |
- VPN 질문: (1,999 × 0.40 + 150 × 1.60) ÷ 10⁶ = **$0.00104**. 하루 1,000번 · 22일 ≈ $22.9.
- **출력이 더 비싸고, 가격은 바뀝니다** (단가표에 확인한 날짜).
---
## 10 / 30 · 1단계 · 토큰이 보이는 호출 (Lab 01 예제 1 · 2)
| `base-cost` VPN | 입력 | 출력 |
| --- | --- | --- |
| classify | 78 | 6 |
| answer | **1,781** | 78 |
| review | 140 | 66 |
- 응답의 `usage`가 청구의 기준. AI Agent 노드는 답만 주고 토큰을 버림 → 오늘은 **HTTP로 OpenAI를 직접**.
- 입력의 89%가 `answer` 하나. 접수 질문도 1,791 → **매번 같이 보내는 것**이 있다.
---
## 11 / 30 · 1단계 · 단계별 비용, 단가는 밖에 (Lab 01 예제 2)
```mermaid
flowchart LR
P[("/prices<br/>모델 → 단가")] -.-> B["Build result<br/>단계마다 토큰 × 그 모델 단가"] --> O(["usage.by_step.*.cost_usd<br/>+ cost_usd"])
```
- 단가를 코드에 숫자로 → 가격 · 모델이 바뀌면 **조용히 틀림**. 70일차 설정 표 · 74일차 저장소와 같은 생각.
- 모르는 모델은 0원이 아니라 **오류**. 소수 8자리.
- 결과: VPN **$0.001040** (손 계산과 같음), `lab01` 3/3.
---
## 12 / 30 · 1단계 · 종류별 비용과 한 달 (Lab 01 예제 3)
| 종류 | 평균 (`lab01-mix`) | 비중 (가정) |
| --- | --- | --- |
| FAQ 넷 | $0.000980 | 60% |
| 접수 둘 | $0.000918 | 30% |
| 그 밖 | $0.000830 | 10% |
- 가중 평균 $0.000946 × 1,000건 × 22일 ≈ **한 달 $20.8**.
- 일곱 질문이 **$0.00083 ~ 0.00104로 비슷** → 고정비(규정 전체)가 대부분. 고정비부터 줄인다.
---
## 13 / 30 · 1단계 · 기록: 요청 · 호출 · 사람 (Lab 01 과제 1)
| 요약 (`/usage/summary`) | 질문 3개 뒤 |
| --- | --- |
| requests (요청) | 3 |
| calls (호출) | 9 |
| 합계 | $0.002951 |
| 사람별 | 이준호 $0.001040 · 박서연 $0.000959 · 한지훈 $0.000953 |
- 호출마다 한 줄, 같은 요청은 같은 `request_id` (`$execution.id`). 기록이 없으면 **예산 · 한도도 없다**.
- 기록에는 숫자와 분류 칸만 (질문 원문 · 개인정보 · 키는 남기지 않음).
---
## 14 / 30 · 1단계 · 기록이 멈추면 (Lab 01 과제 2)
| 기록 API | 고치기 전 | 고친 뒤 (`timeout` 3초 · 실패해도 계속) |
| --- | --- | --- |
| 고장 (500) | 답 · `recorded` 없음 | 답 · `recorded: false` |
| 느림 (8초) | **11.2초** | **6.1초** · `recorded: false` |
- 부가 기능(기록)이 본 기능(답)을 막지 않게. 값: 빠진 기록은 **예산에서도 빠짐** → 표시를 남김.
- 수업 준비 때: 3초에 포기했는데 서버가 8초 뒤 **결국 저장** → 다음 테스트의 요청 수가 하나 많았음. **포기해도 상대의 일은 끝나지 않을 수 있다.**
---
## 15 / 30 · 2단계 · 비용의 세 칸
```text
요청 하나의 비용 ≈ 호출 수 × 호출당 토큰 × 토큰 단가
```
| 칸 | 줄이는 방법 | 오늘 |
| --- | --- | --- |
| 호출당 토큰 | 필요한 것만 보내기 · RAG · 출력 상한 · 긴 입력 자르기 | 예제 1 · 과제 2 |
| 토큰 단가 | 단계에 맞는 작은 모델 · 캐시 · 배치 | 예제 2 · 3 |
| 호출 수 | 규칙으로 먼저 · 중복 단계 빼기 · 캐시 | 과제 1 |
- **품질 테스트를 먼저 고정**하고, 한 번에 한 칸, 가장 큰 몫부터.
---
## 16 / 30 · 2단계 · 보내는 것 줄이기 (Lab 02 예제 1)
| | 전 | 후 |
| --- | --- | --- |
| `answer` 입력 (VPN) | 1,781 | **165** (91% 줄임) |
| VPN 비용 | $0.001007 | **$0.000346** |
| 품질 테스트 | ✔ | ✔ |
- 규정 전체 빼기, FAQ 3칸 · 접수 5칸 (연락처 · 담당자 빼기 = **데이터 최소화**), `max_completion_tokens` 200.
- 규정이 필요하면 통째로가 아니라 **검색해서 관련 부분만** (71일차 RAG).
---
## 17 / 30 · 2단계 · 단계마다 맞는 모델 (Lab 02 예제 2)
| 모델 | 입력 | 출력 |
| --- | --- | --- |
| `gpt-4.1-mini` | 0.40 | 1.60 |
| `gpt-5.4-nano` | 0.20 (절반) | 1.25 (약 0.78배) |
- 분류 · 검토(쉬운 일)만 nano, 답은 mini → VPN $0.000346 → **$0.000278**.
- "작은 모델이면 몇 배 싸다"는 늘 맞지 않음 → **단가표로 계산**. 노드와 함께 **계산의 모델 이름도**.
---
## 18 / 30 · 2단계 · 싸졌는데 나빠졌다면 (Lab 02 예제 3)
| 답 단계 | 낱말 검사 | 일곱 질문 평균 |
| --- | --- | --- |
| mini (내 것) | 5/5 | $0.000233 |
| nano (비교본) | **5/5** | $0.000198 (약 15% 덜) |
- nano 답을 읽으면: `**처리 중**` 마크다운, "ticket_id가 없어…" 안쪽 말, "접수 건은 찾지 못했습니다" 군더더기.
- **통과 ≠ 같은 품질.** 사람이 읽고, 찾은 것은 테스트로. 오늘은 답을 mini로 둔다.
---
## 19 / 30 · 2단계 · 가장 싼 호출은 하지 않은 호출 (Lab 02 과제 1)
```mermaid
flowchart LR
Q(["질문"]) --> R{"규칙이 아나?<br/>T-숫자 · FAQ 검색"}
R -->|예 · 대부분| A{{"답 LLM 1번"}}
R -->|아니오| C{{"분류 nano"}} --> A
```
| | 전 | 후 |
| --- | --- | --- |
| FAQ · 접수 | 3 calls · 다섯이 $0.0002 넘음 | **1 call · $0.000108 ~ 0.000166** |
| `lab02-challenge` | 0/7 | **7/7** |
| 시간 | 3초대 | 1초대 |
---
## 20 / 30 · 2단계 · 긴 입력의 상한 (Lab 02 과제 2)
| 6,000자 넘는 로그 질문 | 전 | 후 (앞 200 + 뒤 300자) |
| --- | --- | --- |
| 프린터 (끝에 질문) | **$0.001196** (짧은 질문의 7배 넘게) | **$0.000237** · "대기열" |
| VPN (앞에 질문) | $0.001099 | $0.000260 · "인증서" |
- 입력 상한이 없으면 **요청 하나의 비용에도 상한이 없다** (Denial of Wallet).
- 입력 상한 + 출력 상한 → 요청 하나의 **최대 비용** → 예산을 지킬 수 있다.
---
## 21 / 30 · 2단계 · 한 번에 한 칸씩
| 단계 | 바꾼 칸 | VPN 비용 | 호출 |
| --- | --- | --- | --- |
| 기준 | | $0.001007 | 3 |
| 예제 1 | 호출당 토큰 | $0.000346 | 3 |
| 예제 2 | 단가 | $0.000278 | 3 |
| 과제 1 | 호출 수 | **$0.000156** | 1 |
- 바꿀 때마다 `COST.md`에 한 줄: 바꾼 것 · 전 → 후 · 품질 테스트 · **잃은 것**.
---
## 22 / 30 · 3단계 · 넘치지 않게
| 장치 | 막는 것 | 오늘 |
| --- | --- | --- |
| 예산 | 전체가 너무 많이 | 하루 `daily_usd` $1.0 |
| 속도 제한 | 한 사람이 짧은 시간에 몰아서 | 1분 `user_limit_per_min` 20 |
| 요청 상한 | 요청 하나가 너무 큼 | `max_question_chars` 500 · `max_completion_tokens` 200 |
- 공급자 한도는 **계정 전체**에 걸림 → 한 사람 때문에 모두 막힘. 그래서 내 쪽에 사람별 한도.
- 값은 **사람이** 정하고(`/budget`), 워크플로우는 읽기만.
---
## 23 / 30 · 3단계 · 하루 예산, 넘으면 원문 (Lab 03 예제 1)
```mermaid
flowchart LR
D["FAQ · 접수 조회"] --> B{"예산 안?"}
B -->|예| L{{"LLM 답"}}
B -->|아니오| O(["한도 초과 · 원문 · $0"])
```
- 멈추는 대신 **낮춰서 답하기** (graceful degradation). 확인은 LLM 앞 · 데이터 뒤.
- 72일차 LLM 장애의 `간단 답변`과 `route`를 구분 → 장애인지 예산인지 가른다.
- 결과: `한도 초과 · 0 calls · $0`, "인증서" · "처리 중" (3/3).
---
## 24 / 30 · 3단계 · 사용자별 한도와 429 (Lab 03 예제 2)
| 세는 방법 | 특징 |
| --- | --- |
| 고정 창 | 쉬움, 경계에서 두 배 |
| 이동 창 (오늘) | 고르게 막음 |
| 토큰 버킷 · 새는 통 | 짧은 몰림 허용 · 속도를 고르게 |
- **가장 앞**에서 429 + `retry_after` → 이준호 세 번째: **0.0초 · $0**, 다른 사람은 그대로.
- 세는 곳은 하나 (서버가 여러 대여도). 사람은 로그인 정보로 가린다.
---
## 25 / 30 · 3단계 · 예산은 넘은 뒤 멈춘다 (Lab 03 예제 3)
| 예산 $0.0003 | 결과 | 누적 |
| --- | --- | --- |
| 1 · 2번째 | 자동 답변 | $0.000293 (아래) |
| 3번째 | 자동 답변 | **$0.000430 (43% 넘음)** |
| 4 · 5 · 6번째 | 한도 초과 · $0 | 그대로 |
- 넘지 않으려면 "남은 돈 < 한 건 최대 비용이면 멈춤" → **상한이 있어야 예산도 지킨다**.
- 경고는 멈추기 **전에** (80%). 한도 초과 답도 기록해야 몇 명이 원문을 받았는지 센다.
---
## 26 / 30 · 3단계 · 비용 보고서 (Lab 03 과제 1)
| 넣은 네 줄 | 손 계산 = 보고서 |
| --- | --- |
| 요청 · 호출 · 합계 | 3 · 4 · $0.001989 |
| 평균 (요청 수로) · 100건 × 22일 | $0.000663 · **$1.4586** |
| 가장 많이 쓴 사람 · 남은 예산 | 박서연 · $0.998011 |
- 숫자는 **코드가** 계산 (틀리지 않고 · 공짜 · 늘 같게), LLM은 설명만 (79일차).
- 실제 사용량 일곱 건 · 하루 1,000건 → **한 달 $2.80** (아침 어림 $20.8의 약 7분의 1).
---
## 27 / 30 · 3단계 · 바꾸면 얼마: what-if (Lab 03 과제 2)
| what-if (넣은 네 줄) | 비용 | 아끼는 돈 |
| --- | --- | --- |
| 모두 nano | $0.00117 | $0.000819 |
| 모두 mini | $0.002016 | **−$0.000027** |
- 실제 사용량: $0.000929 → nano였다면 $0.00061 (34% 덜). **같은 토큰 · 같은 품질을 가정한 숫자.**
- 계산은 "해 볼 만한가", 결정은 "재고 · 읽고 · 게이트로" (74일차). 모르는 모델은 400.
---
## 28 / 30 · 3단계 · 운영: 재기 → 줄이기 → 지키기
```mermaid
flowchart LR
M["재기<br/>usage · 기록"] --> R["줄이기<br/>한 칸씩 · 품질 테스트"] --> K["지키기<br/>예산 · 한도 · 상한"] --> P["보고<br/>정기적으로 · what-if"] --> M
```
- 누가 값을 정하나(사람) · 언제 보나(매주 · 매달) · 넘으면 무엇을 주나(원문 · 429) · 무엇을 남기나(`COST.md`).
- 내 쪽 자원(동시 실행 · 실행 기록)도 같은 보고서에.
---
## 29 / 30 · 7교시 · 바이브 코딩 `tcost`
- LLM을 부르기 **전에** 글 · 워크플로우의 토큰과 비용을 계산하고, 테스트 보고서(`runs/*.json`)의 **실제 사용량을 모아** 한 달을 예상하는 TUI. **OpenAI를 부르지 않습니다.**
- 순서: [요청서](../../Last3Mon/75/VIBE-REQ-TCOST.md) → `Doc/TODO.md` → `Doc/SPEC.md` → `Doc/IMP-PLAN.md` → 단계별 구현 → `uv tool install` → 다른 폴더에서.
- 요구 14개 (R1~R14). 50분 안에 엔진 1 · 2단계 · TUI 1단계 · 설치.
```mermaid
flowchart LR
R["요청서"] --> T["TODO"] --> S["SPEC"] --> P["IMP-PLAN"] --> B["엔진 → TUI"] --> I["uv tool install"]
```
---
## 30 / 30 · 오늘의 정리 · 76일차 예고
| 오늘 | 한 줄 |
| --- | --- |
| 1단계 | 응답의 `usage`로 단계마다 비용, 단가는 밖에, 종류별로 한 달, 호출마다 기록 (멈춰도 답) |
| 2단계 | 보내는 것 · 단가 · 호출 수를 한 칸씩, 통과해도 답을 읽고, 입력 · 출력 상한 |
| 3단계 | 예산을 넘으면 원문, 몰아 부르면 429, 예산은 넘은 뒤 멈춘다, 보고서 · what-if는 코드로 |
**76일차 · 에러 처리와 예외 대응**: 오늘 기록 API가 멈췄을 때 답은 보냈지만, 빠진 기록은 `recorded: false`로 남기기만 했습니다. 내일은 실패한 일을 **모아 두고 다시 처리하고, 사람에게 알리는** 운영 체계를 만듭니다.