챗봇 공부 노트

[21편] 토큰 사용량 제한

frontend-diary-log 2026. 2. 27. 15:07

 

[Aura AI] 토큰 사용량 제한 / 응답 안정화 작업 정리

(gpt-5-nano, 일일 제한, 재시도 및 fallback 적용)


1️⃣ 문제 배경

최근 GPT 모델 호출 과정에서 다음과 같은 문제가 반복적으로 발생했습니다.

  • 특정 요청에서 응답이 비어오는 현상
  • 과도한 프롬프트 길이로 인한 비용 증가 위험
  • 무제한 호출 가능 구조로 인한 과금 폭주 가능성

운영 환경에서 가장 위험한 요소는 예측 불가능한 비용 증가와 API 실패 누적이었습니다.

이에 따라:

  • 사용자별 일일 토큰 제한
  • 요청 길이 사전 차단
  • 응답 비어올 경우 재시도 및 fallback 적용

을 통해 비용 통제 + 응답 안정화 구조를 구현했습니다.


2️⃣ 적용 목표

✅ 1. 사용자별 일일 토큰 제한 적용

  • 과금 리스크 감소
  • 무한 호출 방지

✅ 2. 프롬프트 길이 사전 차단

  • 비정상적으로 긴 입력 방어
  • 서버 리소스 보호

✅ 3. 응답 안정성 강화

  • 응답이 비어올 경우 자동 재시도
  • 재시도 실패 시 fallback 모델 사용

3️⃣ 변경 파일 및 주요 구현 내용


3-1. usage_service.py (신규)

📌 역할

사용자별 일일 토큰 사용량 저장 및 조회

📌 주요 구현

  • user_daily_usage 테이블 생성
  • get_daily_usage(user_id) → 오늘 사용량 조회
  • add_daily_usage(user_id, tokens_in, tokens_out) → 사용량 누적
  • 서버 시작 시 테이블 자동 생성
def init_usage_db():
    # user_daily_usage 테이블 생성

사용자 단위로 일별 토큰 사용량을 DB에 저장하여 누적 관리하도록 설계했습니다.


3-2. gpt_service.py

📌 역할

GPT 호출 + 토큰 제한 적용 + fallback 처리


🔹 환경변수 기반 제한값 적용

max_prompt_tokens = int(os.getenv("MAX_REQUEST_PROMPT_TOKENS", "500"))
max_response_tokens = int(os.getenv("MAX_RESPONSE_TOKENS", "200"))
daily_limit = int(os.getenv("MAX_DAILY_TOKENS_PER_USER", "2000"))

운영 환경에서 코드 수정 없이 조정 가능하도록 환경변수 기반 제어 구조로 설계했습니다.


🔹 프롬프트 길이 초과 시 즉시 차단

if prompt_tokens > max_prompt_tokens:
    return '{"message":"요청이 너무 깁니다. 입력을 줄여 주세요."}'

→ 불필요한 모델 호출 자체를 방지


🔹 일일 토큰 제한 초과 시 차단

if projected > daily_limit:
    return '{"message":"오늘 사용 가능한 토큰을 초과했습니다. 내일 다시 시도해 주세요."}'

→ 비용 통제 장치


🔹 응답 안정화 로직

content = (response.choices[0].message.content or "").strip()

if not content:
    logging.warning("GPT empty content; retrying without response_format")
    # gpt-5-nano 재시도

if not content:
    logging.warning("GPT empty content after retry; falling back to gpt-4o-mini")
    # gpt-4o-mini fallback

처리 흐름

  1. 기본 모델: gpt-5-nano
  2. 응답이 비어있으면 → 동일 모델 재시도
  3. 재시도 실패 → gpt-4o-mini fallback

단일 실패가 전체 기능 실패로 이어지지 않도록 설계했습니다.


3-3. chats.py

📌 역할

채팅 시작 시 토큰 사용량 DB 초기화

from services.usage_service import init_usage_db

init_usage_db()

→ 서버 기동 시 자동으로 사용량 테이블 생성


3-4. summary_service.py

요약 모델을 통일했습니다.

model="gpt-5-nano"

→ 모델 일관성 확보 및 비용 관리


3-5. token_utils.py

기본 모델 상수화

DEFAULT_MODEL = "gpt-5-nano"

→ 모델 변경 시 유지보수 용이


4️⃣ 환경변수 설정 예시

.env 또는 Vercel 환경 변수에 다음 값 설정

MAX_REQUEST_PROMPT_TOKENS=500
MAX_RESPONSE_TOKENS=200
MAX_DAILY_TOKENS_PER_USER=2000

운영 상황에 따라 유연하게 조정 가능하도록 구성했습니다.


5️⃣ 적용 결과

✔ 무한 호출 및 과금 폭주 위험 감소

✔ 과도한 프롬프트 사전 차단

✔ 응답 비어오는 현상 완화

✔ fallback 모델 적용으로 안정성 향상

특히, “응답이 가끔 비어오는 문제”를
재시도 + 모델 대체 구조로 완화한 것이 가장 체감 효과가 컸습니다.


6️⃣ 기술적으로 의미 있었던 부분

이번 작업은 단순 기능 추가가 아니라 다음을 설계한 작업이었습니다.

  • 비용 통제 장치 설계
  • 실패를 전제로 한 복구 구조 설계
  • 환경변수 기반 운영 유연성 확보
  • 모델 변경 가능성을 고려한 구조화

즉,

기능 구현이 아니라 “운영 안정성 설계”에 초점을 둔 작업이었습니다.


📌 정리

이번 개선을 통해:

  • 토큰 사용량을 안전하게 제한하고
  • GPT 응답 안정성을 높이며
  • 운영 환경에서 과금 리스크를 줄일 수 있는 구조를 구축했습니다.

실제 운영 환경에서 발생할 수 있는
비용 폭주, 무한 호출, 응답 실패를 방지하는 안정화 작업이었습니다.