코디챗봇 프로젝트

[Aura_AI] [7편] GPT 호출 안정화 및 토큰 사용량 제한 설계

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

 

[Aura_AI] [7편] GPT 호출 안정화 및 토큰 사용량 제한 설계

(운영 환경에서 비용 폭주를 막기 위한 구조 개선)


1️⃣ 왜 이 작업을 하게 되었는가

프로젝트를 실제 배포 후 운영하면서 단순 기능 구현 단계에서는 보이지 않던 문제가 드러났습니다.

✔ GPT 호출 비용 예측이 어렵다

✔ 사용자가 반복 요청을 보내면 호출이 무한히 누적될 수 있다

✔ 일부 요청에서 응답이 비어오는 현상이 발생한다

특히 가장 위험했던 부분은:

“호출이 제한되지 않으면 과금이 통제되지 않는다”는 점이었습니다.

기능은 정상 동작했지만,
운영 가능한 구조는 아니었습니다.

그래서 단순 기능 수정이 아니라
비용 통제 + 응답 안정성 개선 설계 작업을 진행했습니다.


2️⃣ 설계 목표

이번 작업의 목표는 명확했습니다.

1. 사용자 단위 일일 토큰 사용량 제한

→ 무한 호출 방지

2. 과도한 프롬프트 사전 차단

→ 비정상 입력 방어

3. 응답 실패 시 자동 복구 로직 추가

→ 빈 응답 대응

4. 모델 정책 변경에 유연한 구조 설계

→ 파라미터 충돌 방지


3️⃣ 사용자별 일일 토큰 제한 설계


3-1. 왜 사용자 단위인가?

전역 제한이 아니라 사용자 단위로 설계한 이유는:

  • 특정 사용자의 과도한 사용이 전체 비용에 영향을 주지 않도록 하기 위함
  • 향후 유료 플랜 확장 가능성 고려

3-2. 사용량 저장 구조

user_daily_usage 테이블 생성

def init_usage_db():
    # user_daily_usage 테이블 생성

구현 기능:

  • get_daily_usage(user_id) → 오늘 사용량 조회
  • add_daily_usage(user_id, tokens_in, tokens_out) → 사용량 누적

3-3. 환경변수 기반 제한

운영 중 유연하게 조정할 수 있도록 하드코딩하지 않았습니다.

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"))

환경 변수:

MAX_REQUEST_PROMPT_TOKENS=500
MAX_RESPONSE_TOKENS=200
MAX_DAILY_TOKENS_PER_USER=2000

→ 코드 수정 없이 운영 정책 조정 가능


3-4. 프롬프트 길이 사전 차단

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

모델 호출 이전에 차단하여
불필요한 비용 발생 방지


3-5. 일일 사용량 초과 차단

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

→ 무한 호출 구조 제거


4️⃣ GPT 응답 안정화 설계

운영 중 다음 문제가 발생했습니다.

  • 일부 요청에서 응답이 빈 문자열로 반환됨
  • 모델 정책 변경으로 400 오류 발생

4-1. 파라미터 정책 변경 대응

  • max_tokens → max_completion_tokens로 변경
  • 모델 정책에 맞지 않는 temperature 값 수정

모델은 고정된 API가 아니라, 정책이 변할 수 있는 외부 의존성입니다.
이를 고려한 구조 수정이 필요했습니다.


4-2. 빈 응답 대응 로직

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

if not content:
    # 동일 모델 재시도

if not content:
    # gpt-4o-mini fallback

처리 흐름

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

→ 단일 실패가 전체 실패로 이어지지 않도록 개선


5️⃣ 설계적으로 의미 있었던 부분

이번 작업은 단순 “기능 추가”가 아니었습니다.

✔ 비용 통제 구조 설계

✔ 실패를 전제로 한 복구 설계

✔ 외부 API 정책 변화 대응

✔ 환경변수 기반 운영 유연성 확보

기능 구현자에서
운영 환경을 고려하는 개발자로 사고가 확장된 작업이었습니다.


6️⃣ 적용 결과

✔ 무한 호출 구조 제거

✔ 과금 폭주 위험 감소

✔ 빈 응답 문제 완화

✔ 모델 변경에도 유연한 구조 확보

특히 사용자 단위 제한 설계는
향후 요금제 확장 시 그대로 활용 가능한 구조입니다.


7️⃣ 정리

이전까지의 프로젝트는 “잘 동작하는 서비스”였다면,
이번 개선 이후에는 “운영 가능한 서비스”에 가까워졌습니다.

GPT를 사용하는 서비스에서 중요한 것은
모델 호출 자체보다:

  • 비용 통제
  • 실패 복구
  • 정책 변화 대응

이라는 것을 직접 경험하며 설계에 반영했습니다.


다음 편에서는
실제 서버가 반복적으로 불안정해졌던 원인과, 인스턴스를 재생성하고 자동 복구까지 구축한 과정을 정리하겠습니다.