Community실험 리포트
LLM API 비용 새는 곳 체크리스트 (본인용 메모)
임
임도윤
@rag_master
LLM API 비용 새는 곳, 매번 같은 데서 줄줄 새서 본인용 체크리스트로 박아둠. 38만원 나오던 거 9만원대까지 내린 항목 순서대로. 위에서부터 효과 큼.
1. 모델 라우팅 — 단순 작업을 큰 모델에 안 보내기
전 요청을 최상위 모델에 때려박는 게 디폴트 함정. 분류·추출 같은 단순 작업은 트래픽의 절반 이상인 경우가 많은데 그걸 다 비싼 모델로 돌리고 있음.
- 앞에 라우터 한 겹: 단순 → Haiku급, 추론 필요 → 상위 모델
- 우리 케이스는 단순 작업이 한 70%였고 이거 하나로 거의 반 깎임
model = "claude-haiku" if is_simple(task) else "claude-sonnet"
is_simple은 룰 기반으로 시작해도 충분. 라우팅 자체를 LLM으로 하면 그게 또 비용이라 본말전도.
2. max_tokens 작업별로 빡세게
출력 토큰은 안 박아두면 모델이 신날 때 길게 뱉음. 그게 다 돈.
- 응답 평균이 200토큰인데
max_tokens=4096으로 열어두고 있었음 - 작업별 상한 + 프롬프트에 "3문장 이내" 같은 길이 제약 병행
- 길이 제약은 프롬프트로만 주면 안 지킬 때 있어서 max_tokens로 하드캡까지
3. prompt caching — 반복되는 앞부분
system 프롬프트 + few-shot이 2천 토큰쯤 되는데 매 요청 풀로 보내고 있으면 입력 비용 누수.
- 안정적인 prefix(system, few-shot)에 cache 마킹
- 캐시 hit 시 그 구간 input 단가가 확 떨어짐
- 단, TTL 짧으니(5분쯤) 트래픽 뜸하면 효과 미미. prefix 자주 바뀌어도 hit 안 됨
- 적용은 코드 몇 줄
4. 로깅으로 범인 찾기 (제일 먼저 할 것)
위 셋 다 해도 엉뚱한 데서 새면 의미 없음. 엔드포인트별로 누가 토큰을 먹는지 안 보고 있으면 그게 근본.
- 요청마다
endpoint / model / input_tokens / output_tokens로깅 - 엔드포인트별로 집계해서 상위부터 봄
이거 붙이고 나서 진짜 범인 나왔는데, 검색 자동완성이 전체 비용의 40%를 먹고 있었음. 원인은 LLM이 아니라 디바운스 누락 — 타자 한 글자마다 호출이 나가고 있었던 거. debounce(300ms) 한 줄로 끝.
const search = debounce((q) => callLLM(q), 300)
비용 항목이 모델 단가처럼 보여도 실제론 프론트 코드인 경우가 흔함. 그래서 4번부터. 측정 없이 1~3번부터 손대면 엉뚱한 데 시간 날림. 측정부터.