EROKE ORIGINAL WEBBOOK

AI 비용 폭탄을 막는 법

AI 비용 폭탄을 막는 법 웹북 표지
전체 목차16개 장
  1. AI 비용 폭탄을 막는 법: 1장 비용 문제가 아니라 의사결정 문제다
  2. AI 비용 폭탄을 막는 법: 2장 첫 장부는 공급자 청구서가 아니라 요청 영수증이다
  3. AI 비용 폭탄을 막는 법: 3장 토큰 계산을 직접 검증한다
  4. AI 비용 폭탄을 막는 법: 4장 가격표를 코드에서 분리한다
  5. AI 비용 폭탄을 막는 법: 5장 요청당 비용에서 해결 1건당 비용으로 이동한다
  6. AI 비용 폭탄을 막는 법: 6장 위험과 복잡도로 모델을 라우팅한다
  7. AI 비용 폭탄을 막는 법: 7장 context는 많이 넣을수록 좋은 것이 아니다
  8. AI 비용 폭탄을 막는 법: 8장 출력 길이는 UX 계약으로 줄인다
  9. AI 비용 폭탄을 막는 법: 9장 안전한 캐시는 값보다 경계를 먼저 설계한다
  10. AI 비용 폭탄을 막는 법: 10장 batch와 비동기는 기다릴 수 있는 일에만 쓴다
  11. AI 비용 폭탄을 막는 법: 11장 예산은 알림이 아니라 실행 정책이다
  12. AI 비용 폭탄을 막는 법: 12장 비용 절감은 반드시 품질 회귀 평가와 함께 배포한다
  13. AI 비용 폭탄을 막는 법: 13장 재시도 폭풍과 agent loop를 멈춘다
  14. AI 비용 폭탄을 막는 법: 14장 GPU와 자체 호스팅의 비용을 같은 언어로 본다
  15. AI 비용 폭탄을 막는 법: 15장 여러 공급자의 비용을 하나의 장부로 정규화한다
  16. AI 비용 폭탄을 막는 법: 16장 30일 도입 계획과 운영 회의를 설계한다

토큰부터 GPU까지, 품질을 지키며 AI 원가를 줄이는 Cost Engineering 실전

CostLab으로 요청 원가, 해결 1건당 비용, 모델 라우팅, 안전한 캐시, 예산 보호와 품질 회귀 평가를 익힌다.

상태: 출간 후보 웹교정쇄 · FinOps 실무자 감수 대기 · 16개 장

AI 기능은 만들기 쉬워졌지만 원가를 설명하기는 더 어려워졌다. 같은 질문도 문맥 길이, 출력 길이, 도구 호출, 재시도, 캐시 적중 여부에 따라 비용이 달라진다. 월 청구액만 보고 “비싼 모델을 싼 모델로 바꾸자”고 하면 숫자는 내려가도 해결률이 무너지고, 결국 사람이 다시 처리하는 비용이 늘어난다.

이 책은 가격표 암기책이 아니다. 고객문의 서비스 CostLab을 만들며 어떤 요청이 얼마를 쓰고 어떤 결과를 냈는지 연결한다. 외부 API 없이 고정 fixture로 계산과 정책을 먼저 익힌 뒤, 실제 공급자의 Usage·Costs API나 cloud billing data로 교체한다. 독자는 동일한 화면과 코드로 실습하므로 책의 그림과 자신의 결과를 바로 비교할 수 있다.

비용 측정·라우팅·캐시를 표현한 이 책의 독창적인 표지 비주얼
비용 측정·라우팅·캐시를 표현한 이 책의 독창적인 표지 비주얼

이 책을 마치면 다음을 할 수 있다.

  1. 월 청구서를 기능·tenant·요청·결과 단위로 분해한다.
  2. input·cached input·output·도구 호출을 별도 원가로 계산한다.
  3. 요청당 비용 대신 해결 1건당 비용과 품질을 함께 본다.
  4. 위험·복잡도·출력 길이로 모델을 라우팅한다.
  5. 개인정보와 정책 버전을 침범하지 않는 캐시 키를 설계한다.
  6. soft limit에서는 품질 저하 경로, hard limit에서는 차단·승인을 적용한다.
  7. 비용 최적화 전후에 같은 평가셋으로 품질 회귀를 막는다.
  8. API 비용, GPU, vector store, 검색 도구를 하나의 기술 가치 장부로 합친다.

이 책의 금액은 계산을 재현하기 위한 가상 가격표다. 실제 가격과 지원 기능은 적용 직전 공급자 공식 문서에서 확인한다. 비용 관리는 숫자를 고정하는 일이 아니라 가격표가 바뀌어도 같은 결정을 재현하는 일이다.

Node.js 20 이상과 Chrome만 있으면 된다. 터미널에서 다음을 실행한다.


cd /Users/honi/WithAI/books/ai-cost-engineering
npm test
npm run lab

브라우저에서 http://127.0.0.1:4311을 연다. API key도 cloud 계정도 필요 없다. 배송 FAQ 분류, 환불 요청 초안, 분쟁 가능 답변 검토를 바꾸면 모델 경로와 예산 결정이 달라진다. 화면이 책과 다르면 먼저 node -v가 20 이상인지, 4311 port를 다른 process가 쓰는지 확인한다.

이 책의 실제 CostLab 실습 화면
이 책의 실제 CostLab 실습 화면

1장 비용 문제가 아니라 의사결정 문제다

월말 청구서가 예상보다 크면 팀은 보통 세 가지 반응을 보인다. 개발자는 prompt를 줄이고, 관리자는 한도를 낮추고, 현업은 더 좋은 모델을 요구한다. 각 반응은 일부만 맞다. 비용·품질·업무 결과를 같은 단위로 보지 않았기 때문이다.

AI 원가에는 적어도 네 층이 있다.

질문 나쁜 지표 쓸 수 있는 지표
소비 무엇을 얼마나 썼나 조직 전체 token 기능·tenant별 input/output/tool
시스템 왜 더 썼나 평균 latency 하나 retry·cache miss·context 크기
품질 결과가 쓸 만했나 좋아요 비율 task success·정정·escalation
가치 사람 일을 줄였나 요청 수 해결 1건당 비용·절약 시간

한 요청이 $0.01이어도 열 번 재시도하고 상담사가 다시 작성하면 싸지 않다. 반대로 $0.20 요청이 고액 분쟁을 정확히 분류해 사고를 막는다면 비싸다고 단정할 수 없다. 비용 회의의 첫 질문을 “모델이 얼마인가?”에서 “어떤 결과 단위의 원가를 줄일 것인가?”로 바꾼다.

CostLab의 결과 단위는 resolved_case다. AI 답변을 만들었다고 해결된 것이 아니다. 고객이 추가 문의 없이 해결했거나 상담사가 승인해 발송했고 재접수가 없을 때만 해결로 센다. 이 정의가 없으면 출력 token을 줄여도 사업 성과를 판단할 수 없다.

실무 기록:


기능: 배송 FAQ
결과 단위: 24시간 내 재문의 없는 해결 건
품질 하한: 근거 문서 일치 98%, 금지 표현 0건
비용 목표: 해결 1건당 $0.004 이하
보호 조건: 개인정보 질문은 자동 답변 금지

↑ 목차로 돌아가기

2장 첫 장부는 공급자 청구서가 아니라 요청 영수증이다

공급자 dashboard는 재무 정산에 중요하지만 애플리케이션의 사용자·기능·실패 이유까지 알지는 못한다. 따라서 application이 요청 직후 결정 영수증을 남겨야 한다. prompt 본문을 전부 기록하지 않고 식별과 계산에 필요한 metadata를 남긴다.


{
  "request_id": "req_01J...",
  "tenant_id": "tenant_green",
  "feature": "refund_draft",
  "policy_version": "refund-v3",
  "route": "balanced",
  "input_tokens": 2300,
  "cached_input_tokens": 900,
  "output_tokens": 520,
  "tool_calls": 1,
  "retry_count": 0,
  "estimated_cost_usd": 0.007,
  "result": "approved_with_edit",
  "latency_ms": 1840
}

request_id는 provider request ID와 내부 trace ID를 연결한다. feature는 URL이나 model명이 아니라 사용자가 한 일이다. policy_version이 있어야 prompt와 규칙 변경 전후를 비교할 수 있다. tenant_id는 실제 고객 이름 대신 내부 비식별 ID를 사용한다.

내용을 기록해야 디버깅할 수 있다는 주장도 있다. 하지만 고객 문장 전체를 무기한 남기면 개인정보와 영업 비밀 위험이 커진다. 기본 장부에는 길이·hash·분류·정책 version을 남기고, 승인된 sampling trace만 짧은 retention으로 별도 보관한다. 관측 가능성은 모든 내용을 모으는 일이 아니라 필요한 증거를 최소한으로 보존하는 일이다.

OpenAI 조직 Usage API는 model·project·user·API key 같은 기준으로 token 사용을 집계할 수 있고 Costs endpoint는 invoice와 맞는 재무 비용을 확인하는 데 사용한다. 둘이 약간 다를 수 있으므로 application의 요청 영수증은 원인 분석, Costs는 재무 정산으로 역할을 분리한다.

↑ 목차로 돌아가기

3장 토큰 계산을 직접 검증한다

lab/src/cost-engine.mjsestimateCost는 신선한 input, cached input, output을 분리한다.


const freshInput = inputTokens - cachedInputTokens;
const cost = (
  freshInput * price.inputPerMillion +
  cachedInputTokens * price.cachedInputPerMillion +
  outputTokens * price.outputPerMillion
) / 1_000_000;

예를 들어 input 1,000개 중 cached input이 600개이고 output이 100개라면, 전체 input을 일반 단가로 곱하면 캐시 효과를 과소평가한다. 반대로 provider가 실제로 cached token을 인정하지 않은 요청을 임의로 cached라고 기록하면 원가가 축소된다. response usage의 실제 값을 사용한다.

테스트는 계산 예시를 고정한다.


node --test test/cost-engine.test.mjs

실패 사례도 계약이다.

  • cached input이 input보다 많으면 CACHED_INPUT_EXCEEDS_INPUT
  • 음수 token이면 INVALID_*
  • 가격표에 없는 model이면 UNKNOWN_MODEL

부동소수점 금액은 표시 단계에서 반올림하되 원장에는 충분한 정밀도를 유지한다. 요청 하나의 작은 오차가 수백만 건에서 커질 수 있다. 통화 환산은 요청 시점마다 하지 말고 재무가 승인한 일별 또는 월별 환율과 기준일을 장부에 기록한다.

↑ 목차로 돌아가기

4장 가격표를 코드에서 분리한다

model 이름과 가격을 business logic 곳곳에 박으면 가격 변경 때 계산과 배포를 함께 고쳐야 한다. PRICE_BOOK은 실습 편의를 위해 코드 안에 있지만 운영에서는 version이 있는 data로 분리한다.


{
  "version": "2026-08-12-demo",
  "currency": "USD",
  "models": {
    "economy": {"inputPerMillion": 0.25, "cachedInputPerMillion": 0.025, "outputPerMillion": 2.0},
    "balanced": {"inputPerMillion": 1.25, "cachedInputPerMillion": 0.125, "outputPerMillion": 10.0}
  }
}

여기서 economybalanced는 공급자 model명이 아니라 내부 서비스 등급이다. router가 실제 model snapshot에 mapping한다. 이 간접층 덕분에 application은 공급자를 바꾸어도 risk=high 같은 의도를 유지한다.

가격표 변경 절차:

  1. 공식 가격 문서와 적용 시각을 보관한다.
  2. 이전 version을 수정하지 않고 새 version을 만든다.
  3. 최근 7일 사용량을 새 가격표로 재계산한다.
  4. budget alert가 예상치 않게 바뀌는지 확인한다.
  5. 재무 담당자가 차이를 승인한 뒤 활성화한다.

“최신 가격 자동 scraping”은 편해 보이지만 페이지 구조와 과금 조건을 잘못 해석할 수 있다. 자동 감지는 변경 알림까지만 맡기고, 활성 가격표는 사람이 공식 조건을 확인해 승인한다.

↑ 목차로 돌아가기

5장 요청당 비용에서 해결 1건당 비용으로 이동한다

CostLab은 requestCost / resolutionRate로 해결 1건당 예상 비용을 보여 준다. 단순식이지만 대화가 달라진다. 싼 model의 요청 단가가 절반이어도 해결률이 크게 떨어지면 결과 원가는 오를 수 있다.


요청 비용 $0.006, 해결률 75% → 해결 1건당 $0.008
요청 비용 $0.009, 해결률 95% → 해결 1건당 약 $0.00947

두 번째가 여전히 비싸지만 차이는 요청 단가의 50%가 아니라 약 18%다. 여기에 상담사 수정 시간, 재문의, 환불 사고를 포함하면 판단이 뒤집힐 수 있다.

결과 원가에 넣을 항목:

  • model과 tool 직접 비용
  • vector database·검색·storage 비용
  • retry와 fallback 비용
  • 사람 검토 시간 × 내부 표준 단가
  • 오류 처리와 보상 비용의 기대값

모든 것을 처음부터 정교하게 넣으려다 중단하지 않는다. 1단계는 model 비용과 해결률, 2단계는 사람 수정 시간, 3단계는 사고 기대비용이다. 추정치는 estimated, invoice 확정 값은 billed, 내부 배분 값은 allocated로 구분한다.

↑ 목차로 돌아가기

6장 위험과 복잡도로 모델을 라우팅한다

가장 강한 model 하나로 모든 요청을 처리하면 간단하지만 낮은 위험의 반복 작업까지 비싼 경로를 탄다. 가장 싼 model 하나로 통일하면 어려운 요청이 실패해 retry와 사람 비용이 는다. router는 “싼 model 선택기”가 아니라 품질 하한을 지키는 자원 배분기다.

실습 정책은 세 신호를 쓴다.


if (risk === 'high') return 'premium';
if (complexity >= 7 || expectedOutputTokens > 1200) return 'balanced';
return 'economy';

운영에서는 risk를 model에게만 분류시키지 않는다. 환불 금액, 법률·의료 keyword, 개인정보 포함, VIP 계약 같은 결정적 조건은 code rule로 고정한다. model 분류는 애매한 의미를 보조하고, 고위험으로 올리는 방향의 오류를 허용한다.

라우팅 영수증에는 선택 이유를 남긴다. “premium 사용”만 남기면 다음 달 절감 대상인지 알 수 없다. 분쟁 가능, 정책 예외, 긴 문서 비교처럼 사람이 검토 가능한 reason code를 쓴다.

↑ 목차로 돌아가기

7장 context는 많이 넣을수록 좋은 것이 아니다

긴 context는 비용만 늘리지 않는다. 서로 충돌하는 오래된 규정, 관계없는 문서, prompt instruction이 섞이면 품질도 떨어진다. context 최적화는 글자 삭제가 아니라 결정에 필요한 근거 집합을 좁히는 일이다.

실습 순서:

  1. 질문을 배송·환불·계정 등 domain으로 분류한다.
  2. tenant와 사용자 권한으로 검색 범위를 제한한다.
  3. 유효 기간이 지난 문서를 제외한다.
  4. top-k를 무작정 늘리지 않고 평가셋으로 정한다.
  5. 인용되지 않은 chunk가 반복되면 검색 규칙을 고친다.

요약을 cache할 때 원문 version과 정책 version을 함께 묶는다. 원문이 바뀌었는데 오래된 요약을 재사용하면 싸고 빠르게 틀린 답을 낸다. document_id:version:summary_policy가 최소 key다.

↑ 목차로 돌아가기

8장 출력 길이는 UX 계약으로 줄인다

max_output_tokens만 낮추면 문장이 중간에 끊기거나 필수 항목이 빠진다. 먼저 사용자에게 필요한 output schema를 정한다.


{
  "decision": "approve | ask | escalate",
  "answer": "최대 3문장",
  "evidence_ids": ["POLICY-17"],
  "next_action": "한 문장"
}

장문의 친절한 답변이 항상 좋은 것은 아니다. 배송 날짜 질문에는 날짜·조건·다음 행동이면 충분하다. 분쟁 검토에는 근거와 불확실성이 더 필요하다. feature별 출력 예산을 두고 truncation rate와 필수 field 누락률을 함께 본다.

출력 축소 전후 평가:

지표 변경 전 통과 조건
필수 사실 정확도 98.5% 98.5% 이상
근거 ID 존재 99% 99% 이상
평균 output token 680 420 이하
상담사 수정 시간 42초 45초 이하

마지막 지표가 중요하다. token을 줄였는데 사람이 다시 문장을 보충하면 전체 비용은 늘어난다.

↑ 목차로 돌아가기

9장 안전한 캐시는 값보다 경계를 먼저 설계한다

AI cache는 단순한 prompt hash가 아니다. 같은 질문이라도 tenant, 권한, 정책 version, locale, model, tool 결과가 다르면 답을 공유할 수 없다. 실습의 cacheKey는 다음을 포함한다.


cacheKey({ tenantId, policyVersion, model, normalizedInput })

운영 key에는 데이터 민감도와 tool snapshot도 검토한다. 개인정보가 포함된 답변은 shared cache를 금지하거나 암호화된 tenant 전용 cache에 짧게 둔다. “홍길동의 주문 상태”에서 이름만 지운다고 같은 답을 재사용할 수 있는 것도 아니다.

cache 정책 표:

응답 scope TTL 무효화
공개 배송 FAQ global 6시간 정책 게시
tenant 계약 조건 tenant 30분 계약 version 변경
개인 주문 상태 none 0 저장 금지
문서 요약 document version 24시간 원문 hash 변경

적중률 하나만 높이면 오래된 답을 오래 보관하게 된다. cache hit rate와 stale answer rate를 쌍으로 본다.

↑ 목차로 돌아가기

10장 batch와 비동기는 기다릴 수 있는 일에만 쓴다

실시간 상담 화면은 사용자가 기다리므로 latency가 품질이다. 반면 밤에 만드는 분류 통계, embedding 재생성, 월간 요약은 즉시 응답할 필요가 없다. 업무를 latency class로 나눈다.

  • interactive: 사용자가 화면에서 기다림
  • nearline: 수분 안에 처리
  • batch: 마감 시각 전 완료
  • deferred: 자원이 쌀 때 실행 가능

batch 할인 여부는 공급자마다 바뀔 수 있다. 할인보다 중요한 것은 queue의 완료 deadline, 중복 제출 방지, 부분 실패 재시도다. job에 idempotency key와 source snapshot을 넣고 결과가 늦게 도착했을 때 최신 데이터를 덮지 않게 한다.

↑ 목차로 돌아가기

11장 예산은 알림이 아니라 실행 정책이다

월 80% 알림만 보내면 담당자가 자는 동안 비용은 계속 발생한다. CostLab은 세 결정을 명시한다.

  • allow: 정상 경로
  • degrade: 경제 model, 짧은 output, 비필수 tool 생략
  • block: 고위험 승인 요청을 제외하고 신규 호출 차단

soft limit을 넘었다고 모든 품질을 낮추면 중요한 고객 요청까지 훼손된다. 예산 정책은 feature tier와 risk를 함께 본다.


critical + high risk → premium 유지, 사람 승인, 담당자 호출
critical + low risk  → balanced로 저하
standard             → economy와 cache-only
experimental         → 다음 예산 주기까지 차단

hard limit은 공급자 dashboard 한도와 application gate를 함께 둔다. dashboard는 최후 방어선이고 application gate는 사용자에게 설명 가능한 fallback을 제공한다. 차단 화면에는 “오류” 대신 처리 지연, 대체 경로, 담당자 연락을 보여 준다.

↑ 목차로 돌아가기

12장 비용 절감은 반드시 품질 회귀 평가와 함께 배포한다

model·prompt·context·output 길이를 바꾸면 behavior change다. 코드 변경처럼 test가 필요하다. 평가셋은 실제 개인정보를 제거한 대표 요청과 사람이 승인한 기대 조건으로 만든다.


{
  "case_id": "refund-014",
  "input_fixture": "상품 개봉 후 환불 문의",
  "must_include": ["개봉 여부 확인", "정책 근거"],
  "must_not_include": ["무조건 환불", "법적 보장"],
  "route_expected": "balanced"
}

release gate 예시:


정확도 하락 <= 0.5%p
고위험 false negative = 0
해결률 하락 <= 1%p
해결 1건당 비용 15% 이상 절감
p95 latency 악화 <= 10%

offline eval을 통과해도 5% canary로 실제 수정률과 재문의를 본다. 전체 rollout 후에는 이전 경로를 즉시 되돌릴 수 있어야 한다. 비용 절감률만 dashboard에 크게 표시하면 팀이 품질 손상을 숨기게 된다. 품질 하한을 먼저 고정한다.

계측에서 품질 회귀까지 이어지는 AI 비용 제어 루프
계측에서 품질 회귀까지 이어지는 AI 비용 제어 루프

↑ 목차로 돌아가기

13장 재시도 폭풍과 agent loop를 멈춘다

비용 사고는 정상 요청 증가보다 실패 loop에서 더 빠르게 커진다. timeout 뒤 provider가 실제로 처리했는데 client가 다시 보내거나, tool 결과를 agent가 이해하지 못해 같은 검색을 반복하거나, 두 agent가 서로 일을 되돌려 보내는 경우다.

필수 guardrail:

  • 요청별 최대 model call 수
  • tool별 최대 호출 수와 동일 인자 반복 차단
  • wall-clock deadline
  • 누적 token·금액 한도
  • 동일 error의 exponential backoff
  • idempotency key
  • circuit breaker와 kill switch

if (trace.modelCalls >= 4) return escalate('MODEL_CALL_LIMIT');
if (trace.estimatedCost >= 0.25) return escalate('TRACE_COST_LIMIT');
if (sameToolArguments >= 2) return stop('REPEATED_TOOL_CALL');

kill switch는 dashboard의 숨은 버튼이 아니라 운영 runbook에 owner와 권한, 사용자 fallback, 복구 조건까지 적는다. 차단 후 queue가 쌓이는지도 관측해야 한다.

↑ 목차로 돌아가기

14장 GPU와 자체 호스팅의 비용을 같은 언어로 본다

API는 token 단가가 보이지만 자체 GPU는 유휴 시간, reservation, 전력, 운영 인력, model loading, 실패 재처리까지 포함해야 한다. “GPU를 샀으니 inference는 공짜”가 아니다.


시간당 유효 원가 = compute + storage + network + platform labor + idle allocation
요청당 원가 = 시간당 유효 원가 / 시간당 성공 요청 수
해결당 원가 = 요청당 원가 / 해결률

GPU utilization 90%만 목표로 하면 queue latency가 길어질 수 있다. throughput, p95 latency, error, energy·cost를 함께 본다. Kubernetes request와 limit을 잘못 잡아 GPU가 예약만 되고 사용되지 않는 경우도 있다. model 크기와 batch size, quantization은 정확도 평가와 함께 조정한다.

API와 자체 호스팅 비교는 평균 트래픽이 아니라 peak, 데이터 경계, 필요한 운영 역량을 포함한다. 초기에는 API가 비싸 보여도 당직과 보안 운영을 포함하면 총비용이 낮을 수 있다.

↑ 목차로 돌아가기

15장 여러 공급자의 비용을 하나의 장부로 정규화한다

cloud, AI API, SaaS, data platform은 column 이름과 할인 표현이 다르다. FOCUS는 비용·사용 data를 공급자 중립 형태로 정규화하려는 공개 specification이다. 이 책에서는 최소 공통 column을 먼저 만든다.


BilledCost, EffectiveCost, Currency
ServiceName, SkuName, ChargeCategory
BillingAccountId, SubAccountId
ChargePeriodStart, ChargePeriodEnd
Tags: feature, tenant, environment, owner

application 요청 영수증과 재무 장부를 project, feature, 시간 bucket으로 조정한다. 두 합계가 완전히 같지 않을 수 있다. sampling 지연, 환율, credit, 세금, invoice 조정 때문이다. 차이를 숨기지 않고 reconciliation report에 원인을 분류한다.

비용 allocation tag가 없는 공유 자원은 억지로 정확한 척하지 않는다. request 수, compute time, storage byte 같은 driver로 배분하고 allocation_method를 남긴다. owner 없는 비용은 unallocated로 보여 주어 개선 대상으로 만든다.

↑ 목차로 돌아가기

16장 30일 도입 계획과 운영 회의를 설계한다

1주차: 보이게 한다

상위 세 기능만 고른다. request ID, feature, model class, token, retry, outcome을 기록한다. invoice 총액과 application 추정액 차이를 확인한다. 이때 최적화하지 않는다.

2주차: 결과 단위를 연결한다

해결, 승인, 재문의 같은 outcome을 정한다. 해결 1건당 비용과 사람 수정 시간을 계산한다. 비싼 상위 10개 trace를 비용이 아니라 원인으로 분류한다.

3주차: 안전한 절감 하나를 배포한다

불필요 context 제거, output schema, route 분리, cache 중 하나만 선택한다. 고정 평가셋과 canary를 통과시킨다. 절감과 품질 차이를 decision log에 남긴다.

4주차: 예산과 책임을 운영한다

soft·hard limit, owner, escalation, kill switch를 rehearsal한다. 팀별 showback부터 시작하고 데이터가 안정된 뒤 chargeback을 검토한다.

주간 회의는 30분이면 충분하다.


5분  결과: 해결 건수·품질 하한
10분 원가: 해결 1건당 비용과 큰 변화
10분 원인: retry·cache miss·route drift 상위 3개
5분  결정: 다음 한 가지 실험, owner, rollback 조건

비용 목표를 개발자 개인 평가에 연결하면 안전하게 필요한 호출까지 숨길 수 있다. 팀의 제품 outcome과 시스템 개선으로 평가한다. 좋은 Cost Engineering은 AI를 덜 쓰는 기술이 아니라 가치가 있는 곳에 설명 가능하게 쓰는 운영 능력이다.

부록 A 실습 정답과 확장 과제

기본 검증

npm test의 다섯 test가 통과해야 한다. 배송 FAQ는 economy, 분쟁 가능 답변은 premium으로 간다. tenant가 다른 입력은 같은 문장이어도 cache key가 달라야 한다.

과제 1: 가격표 외부화

PRICE_BOOKlab/data/prices.json으로 옮기고 version을 결정 영수증에 포함한다. 없는 version은 최신 값으로 조용히 대체하지 말고 요청을 실패시킨다.

과제 2: 예산 보호 개선

risk=high 요청은 hard limit을 넘더라도 바로 block하지 않고 human_approval queue로 보낸다. 단, queue 자체의 일일 상한을 둔다.

과제 3: 실제 사용량 연결

관리자 key를 browser에 넣지 않는다. server-side collector가 공식 Usage·Costs API를 호출하고 원본 response는 접근 통제된 storage에 보관한다. application dashboard에는 집계 값만 노출한다. OpenAI 공식 문서 기준으로 Usage는 상세 활동 분석, Costs는 invoice와 조정하는 재무 확인에 사용한다.

부록 B 트러블슈팅

증상 먼저 확인 원인 처리
dashboard가 비어 있음 /api/scenarios server 미실행·port 충돌 npm run lab, 4311 process 확인
예상 비용이 0 token field string·누락 schema validation 후 숫자 변환
invoice보다 추정액이 작음 tool·storage·retry model token만 계산 line item과 trace 보강
cache hit인데 답이 오래됨 policy version·TTL 무효화 key 누락 version을 key에 포함, purge
절감 후 문의 증가 resolution·수정 시간 출력 과축소·싼 route 이전 version rollback, eval 보강
월초에 hard limit 차단 기간 timezone UTC·KST 경계 오류 billing period를 명시적 UTC로 저장
특정 tenant 비용 급증 feature·retry loop 또는 공격 tenant circuit breaker, trace 조사

부록 C 저작권·보안·출간 확인

원고, CostLab code, SVG 도식은 이 책을 위해 독자적으로 작성했다. 표지 비주얼은 외부 reference 없이 생성했고 prompt와 원본 경로를 figures/PROVENANCE.md에 기록했다. 실습의 회사·서비스·금액은 가상이다. 공식 문서의 화면을 복제하지 않고 사실을 요약해 URL과 검토일을 research/SOURCES.md에 남겼다.

실제 환경에서는 API key, prompt 원문, 고객 개인정보를 repository나 screenshot에 넣지 않는다. 책의 예시 key는 존재하지 않는 placeholder만 사용한다. 출간 직전 가격, API field, FOCUS version, Kubernetes 지원 상태를 공식 자료에서 다시 확인하고 FinOps 실무자 감수를 마친다.

부록 D 10일 실전 워크북

이 워크북은 읽은 내용을 자신의 서비스 산출물로 바꾼다. 하루 결과를 한 file에 남기고 다음 날 그 file을 입력으로 사용한다. service가 없다면 CostLab의 세 시나리오로 수행한다.

1일차 비용 경계 그리기

model 호출 전후의 모든 과금 가능 자원을 그린다. embedding, 검색, storage, network, observability와 사람 검토를 빼먹지 않는다. 완료 증거는 “AI 비용” 한 줄이 아니라 자원별 owner와 billing source가 있는 표다. 알 수 없는 항목은 0원으로 쓰지 말고 unknown으로 둔다.

2일차 요청 영수증 schema

필수 field 12개를 정하고 개인정보를 분류한다. raw prompt를 저장하고 싶다면 목적, 접근자, retention, 삭제 절차를 먼저 쓴다. fixture 요청 세 개로 schema validation을 통과시킨다.

3일차 가격표와 조정

공식 가격을 code에 복사하기 전에 billing unit을 확인한다. per-token, per-second, per-image, storage-day는 같은 식으로 계산할 수 없다. 가격표 version과 effective_from을 넣고 어제 사용량을 두 version으로 재계산한다.

4일차 결과 단위

현업과 함께 resolved를 정의한다. AI response 생성, 발송, 고객 해결을 구분한다. 사람 수정 시간 20건을 sampling해 평균과 p95를 기록한다.

5일차 route matrix

20개 실제 유형을 risk·complexity로 표시한다. model 이름부터 고르지 말고 품질 하한과 사람 승인 여부를 먼저 정한다.

risk 낮은 복잡도 높은 복잡도
low economy balanced
medium balanced 또는 rule balanced + 검토 sampling
high premium + 승인 premium + 전문가 승인

6일차 context diet

대표 trace 다섯 개에서 실제 인용되지 않은 chunk를 표시한다. top-k를 한 단계 낮추고 정확도·근거 recall·비용을 비교한다. 한 번에 chunk 크기와 검색 model도 함께 바꾸지 않는다.

7일차 cache threat model

공유 가능한 응답과 금지 응답을 분류한다. tenant A의 답을 tenant B key로 읽는 negative test, 정책 version 변경 뒤 miss가 나는 test, TTL 뒤 만료 test를 만든다.

8일차 budget game day

soft limit과 hard limit을 fixture에서 강제로 넘긴다. 중요 요청, 일반 요청, 실험 요청이 각각 어떤 사용자 메시지와 queue 상태를 만드는지 확인한다. 담당자가 kill switch를 5분 안에 찾는지 측정한다.

9일차 회귀 평가와 canary

절감 후보 하나를 골라 30개 고정 case를 실행한다. 평균 점수 하나로 합치지 말고 high-risk false negative를 별도 gate로 둔다. canary 종료 조건과 rollback owner를 release note에 쓴다.

10일차 경영 가능한 한 장


이번 주 해결 건수와 품질 하한
해결 1건당 유효 원가와 전주 차이
증가 원인 상위 3개
검증된 절감 효과와 회귀 결과
다음 실험, owner, 예상 절감, 중단 조건

비용 review용 SQL 골격

warehouse 문법에 맞게 수정한다. estimated_cost와 invoice 비용을 섞지 않는다.


SELECT feature, route,
  COUNT(*) AS requests,
  SUM(estimated_cost_usd) AS estimated_cost,
  SUM(CASE WHEN outcome = 'resolved' THEN 1 ELSE 0 END) AS resolved,
  SUM(estimated_cost_usd) /
    NULLIF(SUM(CASE WHEN outcome = 'resolved' THEN 1 ELSE 0 END), 0)
    AS cost_per_resolved
FROM ai_request_receipts
WHERE occurred_at >= :start_at AND occurred_at < :end_at
GROUP BY feature, route
ORDER BY estimated_cost DESC;

결정 기록 template


# COST-DECISION-___
- 문제: 어떤 결과 원가가 왜 커졌는가
- baseline: 품질, 비용, latency, sample 기간
- 변경: 한 번에 바꿀 변수
- 안전 조건: 절대 낮아지면 안 되는 지표
- canary: traffic, 기간, owner
- rollback: 자동/수동 조건과 실행 명령
- 결과: 절감, 품질 차이, 예상 밖 영향
- 후속: 유지/확대/폐기와 재검토일

워크북을 마치면 숫자보다 먼저 네 가지를 설명할 수 있어야 한다. 어느 기능이 비용을 만들었는지, 그 비용으로 무엇을 해결했는지, 절감이 품질을 해치지 않았는지, 예산을 넘을 때 시스템이 어떻게 안전하게 멈추는지다.

부록 E 캡스톤 통합 시나리오: 환불 초안 비용을 20% 줄인다

상황은 분명하다. 환불 초안 기능의 월 비용이 40% 늘었지만 문의 수는 10%만 늘었다. “싼 model로 바꾼다”는 해결책을 보류하고 증거부터 모은다.

1단계 증가분을 분해한다

같은 기간과 timezone으로 요청 수, fresh input, cached input, output, retry, tool call을 비교한다. 조사 결과 정책 문서가 매 요청 전체 첨부되면서 input이 1,400에서 2,300으로 늘었고, 답변 형식 변경으로 output도 360에서 520으로 늘었다. model 가격은 바뀌지 않았다.


요청 수 효과       +10%
평균 input 효과    +18%
평균 output 효과    +8%
retry 효과          +4%
가격·환율 효과       0%
상호작용·반올림      잔여

비율은 단순 합계가 정확히 40이 되지 않을 수 있다. 설명 목적의 decomposition 방법과 잔여를 기록한다.

2단계 품질 하한을 고정한다

최근 승인된 50건을 비식별 fixture로 만든다. 정책 근거 일치 98%, 금지 표현 0건, 상담사 수정 p50 45초 이하를 하한으로 정한다. 이 값은 절감 후 협상하지 않는다.

3단계 한 변수씩 바꾼다

먼저 검색 범위를 현재 판매 채널·상품 유형·정책 유효일로 제한한다. 다음 실험에서만 output schema를 3문장과 evidence ID로 바꾼다. 두 변경을 동시에 배포하면 어느 것이 품질을 바꿨는지 모른다.

4단계 캐시 경계를 세운다

공개 정책 요약은 policyVersion:locale로 cache하지만 고객 주문과 상담 기록은 cache하지 않는다. 정책 게시 event가 cache를 무효화한다. stale answer negative test를 release gate에 넣는다.

5단계 canary와 예산을 연결한다

10% traffic에서 24시간 실행한다. 해결 1건당 비용이 20% 이상 낮고 품질 하한을 통과하면 50%로 늘린다. high-risk false negative 한 건, 수정 시간 10% 악화, stale answer 한 건이면 자동 rollback한다.

6단계 최종 영수증


변경 전: 해결당 $0.0121, 근거 일치 98.4%, 수정 p50 41초
변경 후: 해결당 $0.0093, 근거 일치 98.6%, 수정 p50 40초
절감: 23.1%
결정: 유지, 14일 뒤 재검토
남은 위험: 신규 정책 게시 event 누락 감시

이 통합 시나리오의 정답은 숫자가 아니다. 원인을 요청 수와 unit usage로 분해하고, 품질 하한을 먼저 고정하고, 한 변수씩 canary하며, rollback과 남은 위험을 기록하는 순서가 정답이다.

장별 산출물 지도

독자가 남길 산출물
1–2 결과 단위 정의와 요청 영수증 schema
3–4 테스트된 계산기와 versioned 가격표
5–6 해결 원가 dashboard와 route matrix
7–10 context budget·출력 계약·cache·latency class
11–13 budget policy·eval gate·kill switch runbook
14–15 GPU TCO sheet와 정규화 비용 장부
16 30일 도입 backlog와 주간 review agenda

↑ 목차로 돌아가기

공식 참고 자료

기술·가격·정책은 바뀔 수 있으므로 실제 적용 전에 아래 원문을 다시 확인하세요.