OPEN HYPER STEP
← 목록으로 (master-project)
MASTER-PROJECT · 37 / 50
master-project
CHAPTER 37 / 50
읽기 약 2
FUNCTION

AI 비용 관리: 사용량 추적 + 제한


핵심 개념

토큰 카운팅·사용량 DB·rate limit·결제 한도·캐시 — AI 비용 폭발 방지.

본문

비용 구조 (2026)

📋 코드 (13줄)
[Anthropic Claude]
- Sonnet 4.6: $3/M input·$15/M output
- Opus 4.7: $15/M input·$75/M output

[OpenAI]
- GPT-5.5: $5/M input·$15/M output
- GPT-5.5-mini: $0.15/M input·$0.6/M output
- text-embedding-3-small: $0.02/M tokens

[일반 사용]
1 generation = 500 input + 200 output tokens
= ~$0.003/req (Sonnet)
1000 req/mo = $3/사용자

사용량 DB

SQL📋 코드 (13줄)
-- 일/월 단위 집계
create table usages (
  id uuid primary key default gen_random_uuid(),
  user_id uuid references users(id) on delete cascade,
  date date not null,
  generation_count int default 0,
  input_tokens bigint default 0,
  output_tokens bigint default 0,
  cost_cents int default 0,
  unique(user_id, date)
);

create index idx_usages_user_date on usages(user_id, date desc);

사용량 추적

TS📋 코드 (24줄)
// AI 호출 후 즉시 기록
async function trackUsage(userId: string, usage: { input: number; output: number; model: string }) {
  const supabase = createServiceClient()
  const today = new Date().toISOString().split('T')[0]

  const cost = calculateCost(usage)

  await supabase.rpc('upsert_usage', {
    p_user_id: userId,
    p_date: today,
    p_input: usage.input,
    p_output: usage.output,
    p_cost: cost,
  })
}

function calculateCost(usage: { input: number; output: number; model: string }) {
  const rates = {
    'claude-sonnet-4-6': { input: 0.003, output: 0.015 },
    'gpt-5.5': { input: 0.005, output: 0.015 },
  }
  const r = rates[usage.model as keyof typeof rates] ?? rates['claude-sonnet-4-6']
  return Math.ceil(((usage.input * r.input + usage.output * r.output) / 1000) * 100)  // cents
}

RPC 함수 (atomic upsert)

SQL📋 코드 (16줄)
create or replace function upsert_usage(
  p_user_id uuid,
  p_date date,
  p_input bigint,
  p_output bigint,
  p_cost int
)
returns void as $$
  insert into usages (user_id, date, generation_count, input_tokens, output_tokens, cost_cents)
  values (p_user_id, p_date, 1, p_input, p_output, p_cost)
  on conflict (user_id, date) do update set
    generation_count = usages.generation_count + 1,
    input_tokens = usages.input_tokens + p_input,
    output_tokens = usages.output_tokens + p_output,
    cost_cents = usages.cost_cents + p_cost;
$$ language sql;

사용량 한도 체크

TS📋 코드 (16줄)
async function checkUsage(userId: string, plan: 'free' | 'pro' | 'team'): Promise<{ allowed: boolean; remaining: number }> {
  const supabase = await createClient()
  const monthStart = new Date(Date.now() - 30 * 86400e3).toISOString().split('T')[0]

  const { data } = await supabase
    .from('usages')
    .select('generation_count')
    .eq('user_id', userId)
    .gte('date', monthStart)

  const count = data?.reduce((sum, u) => sum + u.generation_count, 0) ?? 0
  const limits = { free: 5, pro: 1000, team: 10000 }
  const limit = limits[plan]

  return { allowed: count < limit, remaining: limit - count }
}

Rate Limit (Upstash)

TS📋 코드 (11줄)
// 분당 10회 (스팸 방지)
import { Ratelimit } from '@upstash/ratelimit'
import { Redis } from '@upstash/redis'

const rl = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(10, '60 s'),
})

const result = await rl.limit(`ai:${userId}`)
if (!result.success) throw new Error(`분당 10회 초과. ${result.reset}초 후 재시도`)

캐시 (동일 prompt)

TS📋 코드 (14줄)
import { createHash } from 'crypto'

async function generateWithCache(prompt: string, userId: string) {
  const hash = createHash('sha256').update(prompt).digest('hex')

  // Redis 또는 DB 캐시
  const cached = await redis.get(`ai:${hash}`)
  if (cached) return JSON.parse(cached)

  const result = await generateText({ ... })

  await redis.setex(`ai:${hash}`, 3600, JSON.stringify(result))
  return result
}

비용 알림 (관리자)

TS📋 코드 (21줄)
// CRON: 매일 자정 비용 집계 → 알림
async function dailyCostAlert() {
  const supabase = createServiceClient()
  const today = new Date().toISOString().split('T')[0]

  const { data } = await supabase
    .from('usages')
    .select('cost_cents')
    .eq('date', today)

  const totalCents = data?.reduce((sum, u) => sum + u.cost_cents, 0) ?? 0
  const totalDollars = totalCents / 100

  if (totalDollars > 100) {
    // Slack 알림
    await fetch(process.env.SLACK_WEBHOOK!, {
      method: 'POST',
      body: JSON.stringify({ text: `🚨 일일 AI 비용 $${totalDollars} 초과` }),
    })
  }
}

다음 챕터

CH.38 "AI 품질 관리: 프롬프트 버전 관리 + 평가".


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

내 마스터 프로젝트의 AI 비용 관리 부분을 분석해서
실전 적용 + 개선 우선순위 3가지를 알려줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

AI 비용 관리 관련 모범 사례·안티패턴 5개를
비교 분석해서 실전 적용를 위한 추천 방안을 알려줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 프로젝트 전체에서 AI 비용 관리
최적화 가능 위치와 리스크를 보고해줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 한국 1인 개발자 시장의
AI 비용 관리 트렌드와 차별화 포인트를 정리해줘.

⭐ 이것만 기억하세요
AI 비용 관리: 사용량 추적 + 제한 이 3가지만 확실히 잡으세요
1.토큰 추적 + 한도 체크 = 비용 폭발 방지
2.Rate Limit + 캐시 = AI 비용 50% 절감
3.다음 챕터에서 AI 품질 관리


공유하기
진행도 37 / 50