본문으로 건너뛰기

워커 개요

워커 리포지토리에 있는 것

lumie-worker에는 백그라운드 처리와 AI 중심 작업을 위한 독립적인 FastAPI 서비스가 들어 있습니다. 오케스트레이션 계층은 여전히 백엔드입니다. 백엔드는 RabbitMQ 작업을 발행하고, 워커 HTTP 엔드포인트를 호출하며, 제품 데이터를 기록하는 유일한 서비스로 남아 있습니다.

워커 리포지토리는 두 번째 백엔드가 아니라 제품 기능을 보조하는 처리기 집합으로 읽어야 합니다. 워커는 이미지를 렌더링하거나, LLM을 호출하거나, 큐를 소비하거나, 기술적 체크포인트 상태를 저장할 수 있지만, 학원 비즈니스 aggregate의 소유자가 되어서는 안 됩니다.

이 섹션의 현재 제품 문서 범위는 다음과 같습니다.

서비스주요 인터페이스주요 작업핵심 통합
GradingRabbitMQ 컨슈머와 백엔드 HTTP 대체 경로OMR 답안 이미지 채점aio-pika, MinIO, Redis, httpx, OpenTelemetry
ReportRabbitMQ 컨슈머와 동기 HTTP 대체 라우트학생별 시험 리포트 PDF 생성aio-pika, httpx, ReportLab, MinIO, OpenTelemetry
AnalysisHTTP API시험 코멘터리와 학생별 피드백 생성FastAPI, Pydantic, openai.AsyncOpenAI, OpenTelemetry
ChatbotSSE를 사용하는 HTTP API도구 사용과 사용자 확인이 포함된 학원 assistant 실행LangGraph, langchain-openai, httpx, Postgres checkpointer, OpenTelemetry

소스 경로

경로역할
lumie-worker/services/grading/운영용 OMR 채점 워커
lumie-worker/services/report/리포트 렌더링 워커
lumie-worker/services/analysis/LLM 기반 코멘터리 및 피드백 워커
lumie-worker/services/chatbot/LangGraph 기반 assistant 워커
lumie-worker/libs/common/mq.py공유 RabbitMQ 메시지 처리 기본 요소
lumie-worker/libs/common/callback_mq.py워커에서 백엔드로 보내는 콜백용 공유 발행기
lumie-worker/libs/common/http_signing.py백엔드 /internal/** 호출용 HMAC 서명 헬퍼
lumie-worker/libs/common/observability.py공유 Prometheus 및 OpenTelemetry 헬퍼
lumie-worker/contracts/mq-schemas-v1.yamlgrading과 report용 수동 유지 MQ 계약 참고 자료

공유 런타임 패턴

대부분의 워커 서비스는 services/<name>/src/ 아래에서 같은 구조를 따릅니다.

  • config.py는 타입이 지정된 BaseSettings를 정의하여 누락된 환경 변수가 시작 시 실패하도록 만듭니다.
  • wiring.py는 어댑터와 유스케이스를 구성해 main.py를 얇게 유지합니다.
  • schema.py는 외부 입출력 계약을 정의하는 Pydantic 메시지 또는 요청 모델을 담습니다.
  • usecase.py는 HTTP, RabbitMQ, 환경 처리의 소유권 없이 워크플로를 오케스트레이션합니다.
  • adapters/에는 MinIO, Redis, 백엔드 HTTP 클라이언트, LLM 클라이언트 같은 구체적 통합이 들어갑니다.

모든 서비스는 FastAPI 수명주기 hook을 사용해 시작 시 장수명 리소스를 만들고 종료 시 닫습니다. Lumie는 여기에서 공유 httpx.AsyncClient를 열고, 렌더러를 예열하고, 콜백 발행기를 연결하고, 컴파일된 LangGraph를 부착합니다.

서비스 레이아웃 계약

새 워커 서비스는 구체적인 이유가 없는 한 다음 구조를 따라야 합니다.

파일 또는 디렉터리기대 책임
main.pyFastAPI 앱, lifespan, 라우트 마운트, 얇은 핸들러
src/config.pyPydantic 설정과 즉시 실패 환경 검증
src/schema.py외부 입출력에 노출되는 Pydantic 요청, 명령, 콜백 모델
src/usecase.py프레임워크 소유권이 없는 애플리케이션 오케스트레이션
src/wiring.py구체적 어댑터와 유스케이스 구성
src/adapters/HTTP, MQ, 스토리지, LLM, 브라우저, 외부 시스템 어댑터
src/domain/순수 데이터 가공, 프롬프트, 렌더링 모델, 도메인 변환
src/observability/서비스 로컬 metric 이름과 tracing wrapper
tests/외부 서비스 없이 실행 가능한 유스케이스 및 관측성 테스트

통합 경계

워커 리포지토리는 의도적으로 두 가지 상호작용 스타일로 나뉩니다.

  • grading-svcreport-svc는 RabbitMQ 컨슈머입니다. 명령 큐를 구독하고, 작업을 처리한 뒤, 콜백 페이로드를 lumie.commands exchange로 다시 발행합니다.
  • grading-svc는 백엔드가 업로드된 OMR 이미지 1장을 직접 호출하는 경로를 위해 동기 HTTP 채점 엔드포인트도 유지합니다.
  • analysis-svcchatbot-svc는 HTTP 서비스입니다. 다른 애플리케이션 레이어가 직접 호출하며, 같은 요청 경로에서 응답을 반환합니다.

워커끼리는 서로 호출하지 않습니다. 공유 백엔드 호출은 X-Tenant-Slug, X-Signature, X-Timestamp로 모든 /internal/** 요청에 서명하는 httpx 어댑터를 통해 이뤄집니다.

백엔드 소유권 규칙

워커는 CPU 집약적일 수도, IO 집약적일 수도, AI 중심일 수도 있지만, 소유권의 중심은 백엔드에 남아 있습니다.

데이터베이스 경계는 백엔드 쪽에 머뭅니다. 워커가 제품 데이터를 필요로 하면 백엔드 /internal/** API나 명령 페이로드에서 가져옵니다. 워커가 제품 상태를 만들어내면, 그 상태는 백엔드가 소유한 핸들러가 저장할 수 있도록 콜백 또는 응답으로 돌려줍니다.

신뢰성과 관측성

  • 공유 MQ 작업은 libs/common/mq.py::universal_process를 사용하며, 이 함수가 JSON 파싱, 재시도, 콜백 처리, ack/nack 동작을 표준화합니다.
  • 공유 콜백 발행은 libs/common/callback_mq.py에 있으며, 서비스 수명 동안 하나의 견고한 RabbitMQ 연결을 열어 둡니다.
  • 문서화된 모든 워커는 /metrics에 Prometheus metric을 마운트합니다.
  • OpenTelemetry는 서비스별 OTEL_ENABLED, OTEL_ENDPOINT, OTEL_SERVICE_NAME으로 활성화됩니다.

grading-svc, report-svc, analysis-svclibs/common/observability.py의 공유 tracing 헬퍼를 사용합니다. chatbot-svc는 LangGraph와 LangChain span을 깨지지 않게 내보내기 위해 별도의 tracing 구성을 사용합니다.

실패 의미

처리 경로잘못된 입력처리 실패콜백 실패
RabbitMQ 워커requeue 없이 거부하여 broker DLQ가 수집하도록 함universal_process를 통한 재시도 가능 실패는 nack(requeue=True)콜백 재시도 소진 후 nack(requeue=True)
동기 HTTP 라우트FastAPI 검증 오류 또는 명시적 HTTPExceptionHTTP 오류 응답해당 없음
LLM HTTP 라우트FastAPI 검증 오류상위 API 오류가 핸들러 실패 경로로 전파해당 없음
SSE chatbot 라우트스트림 시작 전 요청 검증실패 시점에 따라 error event 또는 닫힌 스트림해당 없음

즉, 큐 컨슈머는 콜백 발행을 작업 단위의 일부로 취급해야 합니다. 작업은 백엔드가 성공 또는 실패 페이로드를 받을 때까지 완료된 것이 아닙니다.

설정 패턴

모든 서비스는 Pydantic settings로 환경을 읽습니다. localhost RabbitMQ 같은 로컬 전용 값은 기본값을 둘 수 있지만, 운영에 중요한 secret과 base URL은 누락 시 시작 단계에서 실패해야 합니다. 예시는 다음과 같습니다.

  • analysis-svcLLM_API_KEY가 필요합니다.
  • report-svcLUMIE_BACKEND_URLLUMIE_INTERNAL_HMAC_SECRET이 필요합니다.
  • 큐 워커는 큐 이름과 prefetch 기본값을 코드에 두고, 배포 값으로 덮어씁니다.

어떤 페이지를 볼지

  • OMR 큐 계약, MinIO/Redis 사용, 콜백 수명주기는 Grading을 읽으세요.
  • 리포트 렌더링, 백엔드 데이터 분기 전달, RabbitMQ 및 동기 대체 라우트는 Report를 읽으세요.
  • 두 개의 LLM 기반 HTTP 엔드포인트와 프롬프트 기반 생성 플로우는 Analysis를 읽으세요.
  • LangGraph 상태, SSE 스트리밍, 사용자 확인, 영속화 동작은 Chatbot를 읽으세요.