AI 요약 API 비용 폭탄 막기: max_tokens 하드캡과 Redis 레이트리밋
클라이언트 제한만 믿으면 AI 요약 엔드포인트는 언제든 비용 폭탄이 돼요. 서버에서 max_tokens를 하드캡으로 고정하고 Redis로 호출 횟수를 막는 방법을 백엔드 관점으로 정리했어요.
AI 요약 API, 비용은 왜 서버에서 막아야 할까요
AI 요약 엔드포인트를 하나 열어두면 편해요. 긴 글을 넣으면 짧게 정리해서 돌려주니까요. 그런데 이 엔드포인트가 조용히 비용 폭탄이 되는 경우가 있어요. 클라이언트에서 "요약은 300자까지"라고 막아둔 걸로 안심하기 쉽거든요.
문제는 그 제한이 언제든 우회된다는 점이에요. 개발자 도구로 요청을 복사해서 max_tokens 없이 그대로 던지면, 서버는 순순히 긴 응답을 만들어내요. 요약 한 번이 본문 전체를 다시 쓰는 수준으로 커질 수 있고, 누가 이걸 반복문으로 1000번 돌리면 그날 청구서가 달라져요.
플랜엘(plan-l)에서 법령 요약 기능을 붙여 보니, 비용은 결국 서버에서 두 겹으로 막아야 안전했어요. 한 겹은 응답 한 건의 크기, 다른 한 겹은 호출 횟수예요.
1단계 — max_tokens를 서버 상수로 고정하기
가장 먼저 할 일은 max_tokens를 요청 바디에서 받지 않는 거예요. 클라이언트가 보낸 값을 그대로 쓰면, 그 값이 곧 비용 상한이 돼버려요.
서버 코드에 상수로 박아두고, 요청에 뭐가 들어오든 덮어써요.
MAX_OUTPUT_TOKENS = 500 # server-side hard cap
payload = {
"model": MODEL_ID, # 서버 설정에서 고정
"messages": messages,
"max_tokens": MAX_OUTPUT_TOKENS, # 요청값 무시하고 덮어쓰기
}이러면 응답 한 건의 최대 토큰이 500으로 고정돼요. 요약이라면 500토큰이면 대체로 충분하고, 누가 값을 키워서 보내도 서버가 무시해요. 직접 붙여 보니 코드 세 줄로 끝나는데 효과는 확실했어요.
2단계 — Redis로 호출 횟수 세기
응답 크기를 막아도 호출이 무제한이면 곱셈이 문제예요. 그래서 사용자나 IP 단위로 호출 횟수를 세는 레이트리밋을 붙여요. Redis의 INCR과 만료(EXPIRE)만으로 간단하게 만들 수 있어요.
key = f"ratelimit:summary:{user_id}"
count = redis.incr(key)
if count == 1:
redis.expire(key, 60) # 첫 요청에만 60초 만료
if count > 20:
raise TooManyRequests() # 429 반환키 하나에 카운트를 올리고, 처음 만들 때만 60초 만료를 걸어요. 분당 20회를 넘으면 429를 돌려주고요. 돌려 보니 Redis 왕복 한 번이면 되니까 지연도 거의 느껴지지 않았어요.
3단계 — 넘쳤을 때 조용히 넘어가지 않기
마지막은 관측이에요. 레이트리밋에 걸린 요청 수, 하드캡에 잘린 응답 수를 로그나 메트릭으로 남겨요. 테스트해 보면 평소엔 0에 가깝다가 어느 순간 확 튀는데, 그게 곧 이상 신호예요. 숫자가 튀는 걸 봐야 원인을 찾으러 갈 수 있어요.
- max_tokens 서버 고정
- Redis 분당 카운트
- 초과 시 429
- 지표로 관측
정리하면
AI 엔드포인트의 비용은 클라이언트가 아니라 서버에서 정해져요. 응답 크기는 상수로 고정하고, 호출 횟수는 Redis로 세고, 넘친 건 지표로 남기는 것. 이 세 가지만 배선해두면 요약 기능 하나 때문에 청구서를 걱정하는 일은 줄어들어요. 저처럼 혼자 운영한다면 특히, 눈에 안 보이는 곳에서 새는 비용부터 잠가두는 게 마음이 편해요.
관련 글
댓글
아직 댓글이 없어요. 첫 댓글을 남겨주세요.