Files
llm-gateway-sub-backup/docs/ADR-4.md
2025-08-11 18:56:38 +09:00

4.3 KiB

ADR-004

  • 제목: LLM Gateway의 비동기 추론 구조 개선: OCR 및 추론 파이프라인 요청 처리 방식 전환
  • 날짜: 2025-06-23
  • 상태: 채택됨 (Proposed)
  • 작성자: [김용연 연구원]

1. 컨텍스트 (Context)

기존 LLM Gateway에서는 /ocr, /extract/*, /general/* 요청 처리 시 다음과 같은 문제가 발생하였다:

  • Gateway가 OCR 결과를 최대 85초간 polling하여 기다린 뒤, 후속 작업(LLM 추론 또는 최종 결과 응답)을 수행
  • 이 구조는 Gateway가 해당 요청을 점유한 상태로 유지되므로, 동시에 여러 사용자의 요청을 처리하기 어려워짐
  • 클라이언트는 장시간 대기해야 하며, 요청 실패 시 다시 처음부터 재시도해야 하는 구조였음

2. 결정 (Decision)

LLM Gateway는 모든 OCR 및 LLM 요청을 비동기 백그라운드 처리 방식으로 전환하여, Gateway가 요청을 즉시 반환하고 작업은 asyncio.create_task()를 통해 처리되도록 구조를 개선하였다.

📌 asyncio.create_task()를 사용한 이유:

  • asyncio.create_task()는 FastAPI와 잘 통합되는 간단한 백그라운드 실행 방식으로,

    • Gateway의 요청 핸들러를 차단하지 않으면서
    • 요청 수신 즉시 응답을 반환하고
    • 이후 파이프라인 작업을 비동기 이벤트 루프에서 독립적으로 처리할 수 있게 한다.
  • FastAPI의 BackgroundTasks는 요청 스코프에 종속되어 작업 진행 중 연결이 끊기면 실행되지 않을 수 있는 단점이 있음.

  • create_task()를 사용하면 상태 추적, 결과 저장 등 복합 처리가 필요한 OCR + LLM 파이프라인에도 유연하게 대응 가능.

📌 주요 변경 사항:

  • 클라이언트 요청 시 request_idprogress_url만 응답
  • 전체 파이프라인(OCR → LLM → 후처리)은 백그라운드에서 실행
  • 최종 결과는 Redis에 저장되며, 클라이언트는 /progress/{request_id}를 통해 상태 및 결과를 직접 조회

/ocr에서 요청

변경 전

  • Gateway가 OCR API에 요청한 후, 최대 85초간 polling
  • 완료 여부에 따라 최종 응답을 직접 반환

변경 후

  • Gateway는 OCR API에 요청만 전송하고 다른 작업 요청 수행

  • 클라이언트에는 다음 정보만 반환:

    • request_id: OCR 작업 식별자
    • status: 작업 접수
    • message: 사용자 안내 문구
    • status_check_url: /ocr/progress/{request_id}
  • 클라이언트는 해당 URL로 결과 조회


/extract/*, /general/*에서 요청

변경 전

  • Gateway가 내부에서:

    1. OCR API 요청 → 결과 polling
    2. 결과 수신 후 LLM API 요청
    3. 최종 결과 응답

변경 후

  • 전체 파이프라인(OCR → LLM → 후처리)을 asyncio.create_task()백그라운드 비동기 실행

  • Gateway는 즉시 아래 정보 응답:

    • message: 작업이 백그라운드에서 실행 중
    • request_id: 상태 추적용
    • status_check_url: /extract/progress/{request_id}
  • 최종 결과는 Redis에 저장되고, /extract/progress/{result_id}로 확인 가능

Client
  │
  ├── POST /extract/outer (input + prompt)
  │       ↓
  │   Gateway → OCR → LLM → Result
  │       ↓
  └── return: request_id + progress URL

백그라운드 작업
 ├── OCR API 호출
 ├── 추출 텍스트 Redis 저장
 ├── LLM API 호출
 └── 최종 결과 Redis 저장

3. 고려된 대안

  • FastAPI BackgroundTasks 사용: → 요청 스코프와 연결되어 있어 상태 추적 및 작업 흐름 관리에 제한적
  • Celery를 통한 전체 파이프라인 비동기화 → 복잡성 증가, 구현 부담이 커서 1차 개선으로는 적절하지 않음
  • 기존 polling 방식 유지 + 타임아웃 설정 개선 → 구조적 병목 문제 해결 불가

4. 결과

  • Gateway가 작업을 점유하지 않고 완전한 비동기 구조 확보
  • 클라이언트 응답 속도 향상 및 사용자 경험 개선
  • Redis 기반 상태 추적 및 결과 조회 API 완비
  • 확장성 및 고부하 처리 능력 증가