원 레포랑 완전 분리

This commit is contained in:
ai-cell-a100-1
2025-08-11 18:56:38 +09:00
commit 7217d3cbaa
86 changed files with 6631 additions and 0 deletions

121
docs/ADR-4.md Normal file
View File

@@ -0,0 +1,121 @@
# **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_id``progress_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 완비
- 확장성 및 고부하 처리 능력 증가
---