2026/02/01

김기훈·2026년 2월 1일

TIL

목록 보기
127/191
# 어제 무엇을 했나요?
- 1. 개인프로젝트 포스트 등록api 구현 
- 2. 알고리즘 기초 공부 

# 오늘은 무엇을 할 것인가요?
- 1. 쿼리 최적화를 제외한 중간점검 반영 
- 2. 리뷰 전체 긁어오기에서 장르 처리 

# 진행하는데 어려운 부분(도움이 필요한 부분)이 있나요?



오늘 학습 내용 ✅

중간 점검 반영

  • 대부분의 필요한 기능들은 라이브러리가 존재한다. ✅
    • alt-profanity-check
      • 욕설 필터는 라이브러리를 찾아보자
  • 코드 구조를 좀더 확실하게 보자 ✅
    • user_prompt
      • 메서드로 선언
  • 코드 진행과정 수정 ✅
    • 요약
      • 타임아웃이 아닌 진행중에 완료가 되면 캐시를 지우는 코드 필요
      • ai테스크를 돌리기 위한 벨리데이션도 celery으로 넘기기

욕설 필터는 라이브러리

  • 현재

    • ai/utils.py에 하드코딩된 정규표현식(BAD_PATTERNS)은
      • 새로운 욕설 패턴에 유연하게 대응하기 어렵고, 관리 비용이 듬
  • 해결

    • alt-profanity-check 라이브러리를 도입하여 머신러닝 기반의 필터링으로 교체
      • 기존 정규표현식 리스트를 제거하고,
        • 라이브러리를 래핑(Wrapping)하는 함수를 utils.py에 작성하여
        • 서비스 계층에서 호출하도록 변경
      • alt-profanity-check 한국어 탐지 불가 따라서 다른 라이브러리로 변경
    • korcen
      • ai에게 넘겨줄지 말지만 결정하면되기 때문에 굳이 마스킹은 필요없음
        • 리뷰에 작성된 욕설은 보여줄거임
      • 통과 기준 단순화 (utils.py):
        • 욕설이 없으면 -> 통과 (True)
        • 욕설이 있고 내용이 짧으면 (단순 비방) -> 탈락 (False)
        • 욕설이 있지만 내용이 길면 (정보 포함) -> 통과 (True, AI가 알아서 문맥 파악)

코드 구조 수정

  • "메서드화해서 위에서 관리하라"

    • 문제점
      • 비즈니스 로직(데이터 조회, 저장 등)과 데이터(프롬프트 텍스트)가 섞여 있어
      • 코드가 길어지고 가독성이 떨어짐
      • 프롬프트만 수정하고 싶을 때도 로직 코드를 뒤져야 함
    • 해결책 ("위에서 관리")
      • 프롬프트 템플릿을 클래스 상단(속성)이나
      • __init__ 메서드에서 정의하여 설정값처럼 관리
    • 해결책 ("메서드화")
      • 프롬프트를 생성하는 역할만 전담하는 별도의 메서드(_build_prompt 등) 로 분리하여 호출

캐시

  • 타임아웃이 아닌 진행 중에 완료가 되면 캐시를 지우는 코드 필요

    • 현재

      • cache.set(cache_key, "processing", timeout=10)
      • timeout=10으로 설정하여 10초가 지나면 무조건 캐시가 사라집니다.
      • 만약 분석이 2초 만에 끝나도 캐시는 8초간 남아있어 "진행 중"으로 뜰 수 있고,
      • 반대로 20초가 걸리면 중간에 캐시가 풀려 중복 실행될 위험이 있습니다.
    • 수정

      • API에서는 캐시를 설정하기만 하고(Lock),
      • Celery Task(백그라운드 작업)가 작업을 완료한 직후 스스로 캐시를 삭제(Unlock)해야
        • 가장 정확
  • AI 태스크를 돌리기 위한 밸리데이션도 Celery로 넘기기

    • 현재

      • (코드에는 안 보이지만) 만약 AI 분석 전 "데이터가 충분한가?" 등을 검사하는 로직이
        • 이 함수 안에 있다면, 그 계산 시간만큼 사용자는 기다려야 함
    • 수정

      • API는 "요청 접수"만 하고 즉시 응답합니다.
      • 데이터가 충분한지, 분석이 가능한지는 백그라운드 워커(Celery)가 나중에 판단하여
      • 불가능하면 '실패' 상태를 DB에 남기는 방식이 더 효율적임

캐시를 지워야 하는 이유

구분캐시 삭제 안 함 (Timeout만 의존)캐시 직접 삭제 (Task 완료 시)
비유화장실 쓰고 문 잠근 채로 창문으로 탈출함 (문은 5분 뒤에 자동으로 열림)화장실 다 쓰고 나오면서 문을 열어둠
작업 성공 시작업은 3초에 끝났지만, 5분간 재요청 불가작업 끝나자마자 즉시 재요청/결과 확인 가능
작업 실패 시실패했는데도 계속 "처리 중"이라고 거짓말 함즉시 "처리 중" 해제 -> 유저가 바로 재시도 가능
사용자 경험답답함 (왜 안 되지?)쾌적함 (빠릿빠릿함)
  • "작업이 끝났는데도 사용자가 하염없이 기다리는 상황을 막기 위해서"

    • 상황 1: 캐시를 안 지울 때 (기존 방식)

      • 상황: 손님이 탈의실에 들어가며 "사용 중" 팻말을 겁니다. (캐시 설정, 타임아웃 5분)
      • 작업: 손님이 옷을 갈아입는 데 3초밖에 안 걸렸습니다.
      • 문제: 손님은 이미 나갔는데, "사용 중" 팻말은 5분 동안 문에 그대로 걸려있습니다.
      • 결과
        • 다음 손님(혹은 본인이 다시 들어가려 할 때)은 탈의실이 비어있는데도
        • 4분 57초 동안 문 밖에서 기다려야 합니다.
    • 상황 2: 캐시를 지울 때 (수정 방식)

      • 상황: 손님이 들어갈 때 "사용 중" 팻말을 겁니다.
      • 작업: 옷을 3초 만에 갈아입었습니다.
      • 해결: 나오면서 직접 "사용 중" 팻말을 뗍니다(Cache Delete).
      • 결과: 팻말이 사라지자마자 다음 손님이 바로 들어갈 수 있습니다.
  • 기술적 이유

    • 즉각적인 상태 동기화 (UX 향상)

      • AI 분석이 예상보다 빨리 끝나서 5초 만에 성공했다면,
        • 시스템은 즉시 "처리 중" 상태를 해제해야 합니다.
        • 그래야 프론트엔드에서 새로고침을 하거나 재요청을 했을 때 막히지 않고 결과를 볼 수 있음
    • 재시도 기회 부여 (Error Handling)

      • 만약 AI 서버가 잠깐 오류가 나서 작업이 1초 만에 실패했다고 가정해 봅시다.
      • 캐시를 안 지우면, 유저는 실패했음에도 불구하고 타임아웃(5분)이 끝날 때까지
        • "분석 중입니다..." 메시지만 보게 됩니다.
      • 작업이 실패하자마자 캐시를 지워주면, 유저는 바로 "다시 시도" 버튼을 눌러볼 수 있습니다.

수정방향

구분AS-IS (기존)TO-BE (수정 방향)이점
캐시 해제 시점timeout=10 (10초 후 자동 만료)Celery Task 완료(finally) 시점cache.delete() 호출작업 시간이 10초를 넘거나 1초 만에 끝나도, 정확한 작업 종료 시점에 상태 동기화 가능
타임아웃 역할작업 종료 예상 시간 (불확실)비상 안전 장치 (Zombie Lock 방지용, 5분 등 넉넉히 설정)서버 장애 등으로 Task가 비정상 종료되어도 영원히 락이 걸리는 것 방지
데이터 검증API 뷰/서비스(메인 스레드)에서 수행Celery Task 내부로 이동검증 로직이 복잡해져도 API 응답 속도(Response Time)는 항상 빠름
역할 분담API가 상태 추측 및 검증 혼합API는 트리거(Trigger), Task가 실제 처리/상태관리관심사의 분리(SoC)를 통해 코드가 간결해지고 유지보수성 향상

결과

  • 락(Lock)이 중복 실행을 막아줌 (6번 호출 → 1번 실행)
    • 사용자가 태그 6개를 다다닥 누르면 API 요청은 6번 날아옴
  • 첫 번째 요청
    • "어? 락(Lock)이 없네? 내가 Task 실행 시키고 문 잠글게(Lock 설정)!" -> Task 시작
  • 두 번째 ~ 여섯 번째 요청
    • "어? 문 잠겨있네(Processing)? 이미 누가 하고 있구나. 난 그냥 갈게." -> Task 실행X


새롭게 알게된 내용 ✅


오늘 발생한 문제(발생 했다면) ✅

profile
안녕하세요.

0개의 댓글