ai-service는 SK 쉴더스 루키즈 개발 5기 AI 기반 자동차 스마트팩토리 관제 시스템 AIMS에서 발생하는 제조 이벤트를 기반으로 병목 분석, 불량 전이 예측, SHAP 기반 원인 분석, AI 메뉴얼 생성을 제공하는 FastAPI 기반 AI 서비스입니다.
제조 이벤트를 수집하고 분석 결과를 DB와 Elasticsearch에 함께 반영한 뒤, 운영 화면이 빠르게 최신 상태를 볼 수 있도록 돕는 역할을 합니다.
핵심적으로는 다음을 수행합니다.
- 공정별 병목을 계산합니다.
- 어떤 차량이 다음 공정에서 불량으로 이어질 가능성이 있는지 예측합니다.
- SHAP으로 불량 전이 원인을 설명합니다.
- 운영자가 바로 읽을 수 있는 AI 메뉴얼을 생성합니다.
- Kafka로 입력과 분석을 분리하고, Elasticsearch로 조회 성능을 확보합니다.
- 차량 단위로 다음 공정 불량 가능성을 예측하고 전이 경로를 함께 봅니다.
- 현재 공정, 다음 공정, 설비 신호, 사이클 타임, 대기 시간, 재공 수량, 진동/온도/도막 두께를 함께 봅니다.
- 결과는
defect_transfer_prediction_result에 저장됩니다. - 조회 시에는 ES의
predictedAt날짜를 기준으로 날짜 옵션을 만듭니다. - 목록은 차량별 최신 1건을 보여줍니다.
DefectTransferAnalysisService.get_predictions()가 날짜 옵션을 읽고, 요청 날짜가 없으면 최신 날짜를 선택합니다.ProcessAnalysisSearchRepository.list_defect_transfer_date_options()가 ES의predictedAt날짜를 집계합니다.- ES가 가능하면
list_defect_prediction_page()에서 차량별 최신 1건을 가져옵니다. - ES가 실패하면 Redis 캐시를 먼저 보고, 없으면 DB의
list_prediction_page()로 fallback합니다. - 저장 단계에서 같은 이벤트가 다시 들어오면 기존 row를 덮어써 중복 예측을 줄입니다.
- 재색인 시 해당 날짜의 문서를 다시 읽어 ES에 최신 상태를 맞춥니다.
ColumnTransformer로 수치형과 범주형 feature를 분리 처리합니다.- 범주형은
OneHotEncoder로 변환하고, 희귀 범주는min_frequency를 활용해 묶습니다. - 후보 모델은
LightGBM,XGBoost,CatBoost,Logistic Regression계열을 비교합니다. - 평가 지표는
accuracy,precision,recall,f1,PR-AUC,ROC-AUC를 함께 봅니다. - 최종 결과는 차량별
predictedDefectProcess,transferProbability,riskLevel형태로 내려갑니다. - SHAP으로 주요 원인을 계산하고, API에서는
main_causes,detailCauses로 제공합니다. - 예측 결과는 Kafka 분석 이벤트로 이어져 ES와 화면이 동기화됩니다.
불량 예측 및 전이 예측에서 함께 보는 맥락은 아래와 같습니다.
- 현재 공정
- 다음 공정으로의 전이 가능성
- 설비 신호
- 사이클 타임
- 대기 시간
- 재공 수량
- 진동, 온도, 도막 두께 같은 공정 특성
즉, 차량 단위 예측이지만 실제 판단은 제조 이벤트 feature 전체를 보는 구조입니다.
sampledb.manufacturing_event_json에서 SENT 이벤트를 읽습니다.- 모델이 차량별 전이 확률을 계산합니다.
- 예측 결과를 DB와 ES에 저장합니다.
- ES의
predictedAt을 기준으로 최신 1건을 보여줍니다.
- 원인 분석은 불량 탐지 및 전이 예측 결과를 해석하는 단계입니다.
- SHAP 값을 이용해 주요 원인 1개와 상세 원인 여러 개를 분리합니다.
main_causes는 대표 원인,detailCauses는 보조 원인입니다.
DefectTransferAnalysisService.get_cause_analysis()가 차량 ID와 날짜 옵션을 기준으로 조회 대상을 결정합니다.- ES가 있으면
get_latest_defect_cause_document()에서 차량별 최신 문서를 가져옵니다. - 조회된 문서의 대표 원인과 상세 원인을 분리합니다.
- 대표 원인은 화면의 summary 영역으로, 상세 원인은 리스트 형태로 보여줍니다.
- 차량 ID가 없으면 최신 차량 기준으로 조회할 수 있습니다.
- 최신 불량 탐지 및 전이 예측 문서를 찾습니다.
- SHAP 기반 원인을 정리합니다.
- 대표 원인과 상세 원인을 나눠 반환합니다.
sampledb.manufacturing_event_json의 제조 이벤트를 읽어 공정별 병목을 계산합니다.- 결과는 공정 순위, 지연 시간, 영향 차량 수, 위험도 형태로 정리됩니다.
- 결과는
bottleneck_analysis_result에 저장됩니다. - 조회 시에는 ES의
detectedAt날짜를 기준으로 날짜 옵션을 만듭니다. - Elasticsearch가 살아 있으면 ES 우선으로 조회하고, 실패하면 DB와 Redis에서 다시 읽습니다.
- 같은 날짜 구간을 다시 계산하는 백필 / 재색인 기능도 함께 제공합니다.
BottleneckAnalysisService.get_realtime_bottlenecks()가 날짜 옵션을 읽고, 요청 날짜가 없으면 최신 날짜를 선택합니다.ProcessAnalysisSearchRepository.list_bottleneck_date_options()가 ES의detectedAt날짜를 집계해 날짜 옵션을 만듭니다.BottleneckAnalysisService는 ES에서list_bottleneck_page()를 먼저 호출해 최신 병목 row를 가져옵니다.- ES 조회가 실패하면 Redis 캐시를 확인하고, 캐시도 없으면 DB 조회로 fallback합니다.
- 백필이나 재색인이 실행되면 해당 날짜의 기존 결과를 지우고 다시 계산해서 저장합니다.
- 따라서 병목 화면은 최신 분석 결과를 기본으로 보여주되, 날짜 선택 시 과거 분석도 다시 볼 수 있습니다.
- 기본 모델은
IsolationForest입니다. - 연속형 공정 지표는
StandardScaler로 정규화한 뒤 학습합니다. - 공정별 지연 특성을 반영한 규칙 기반 feature를 함께 사용합니다.
bottleneck_station처럼 병목이 발생한 공정을 설명 가능한 형태로 정리합니다.- 결과는 공정 단위로 집계하고, station 요약과 KPI 요약도 함께 생성합니다.
- SHAP은
IsolationForest의decision_function이 어떤 feature에 반응했는지를 설명하는 용도로 사용됩니다.
병목에서 보는 핵심 feature는 아래와 같습니다.
- 공정 체류 시간
- 최대 station span
- 활성 공정 수
- rule risk score
- iforest risk score
병목은 단일 점수만 보는 게 아니라, 어느 공정이 막혔는지와 왜 그렇게 판단했는지를 같이 보여주는 구조입니다.
sampledb.manufacturing_event_json에서 제조 이벤트를 읽습니다.- 공정별 지연 feature를 계산합니다.
IsolationForest와 규칙 기반 점수로 병목 순위를 산출합니다.- 결과를 DB와 ES에 저장합니다.
- ES의
detectedAt을 기준으로 날짜 옵션과 목록을 만듭니다.
| 이상 이벤트 발생 | 주니어 | 시니어 |
|---|---|---|
![]() |
![]() |
![]() |
- JWT 인증을 통과한 사용자만 메뉴얼을 생성합니다.
- 이벤트, 설비 맥락, 사내 지침, 검색된 문서를 함께 사용합니다.
- 메뉴얼은 현장 조치용 설명서로 반환됩니다.
- 사용자는
Junior/Senior로 구분되며,Junior는 실행 절차 중심,Senior는 원인·판단 근거와 운영 관점까지 포함한 메뉴얼을 받습니다.
ManualService.generate_manual(user_id)가 요청의 시작점입니다.- 현재 위험도가 높은 알람 이벤트를
AlertEventRepository에서 먼저 가져옵니다. - 사용자의 ID로 사용자의 권한을 읽고, 없으면
Junior로 기본 처리합니다. CriticalEvent,OperatorInfo,FactoryContext,RagContext를 묶어 LLM 입력 객체를 만듭니다.VectorStore.search()로 관련 문서를 검색해 RAG 컨텍스트를 구성합니다.- 권한이
Junior면 즉시 수행할 점검 항목과 순서를 강조하고,Senior면 원인 해석과 판단 근거를 더 자세히 포함하도록 프롬프트를 구성합니다. manual_prompt에 컨텍스트를 넣고ChatOpenAI로 응답을 생성합니다.- 최종적으로 이벤트 정보와 권한별로 다른 깊이의 메뉴얼을 함께 반환합니다.
- JWT와 권한을 확인합니다.
- 현재 알람과 관련 이벤트를 가져옵니다.
- 운영 문서를 검색해 RAG 컨텍스트를 구성합니다.
- 권한에 따라 프롬프트의 상세 수준을 다르게 구성합니다.
- LLM이 역할별 메뉴얼을 생성합니다.
- 운영자 조치 가이드로 반환합니다.
- Kafka raw topic(
factory.manufacturing.raw)은 외부 제조 시스템의 원천 이벤트 진입점입니다. raw_event_consumer는 raw topic을 읽어sampledb.manufacturing_event_json에 저장합니다.- 분석 대상 이벤트는 병목 / 불량 전이 추론을 수행하고, 결과를
factory.manufacturing.analysistopic으로 발행합니다. analysis_sync_consumer는factory.manufacturing.analysistopic을 다시 받아 Elasticsearch에 색인합니다.
- Elasticsearch는 분석 결과를 빠르게 조회하기 위한 검색 인덱스입니다.
- 병목 인덱스는
detectedAt기준으로 날짜 옵션과 목록 조회에 사용됩니다. - 불량 전이 인덱스는
predictedAt기준으로 날짜 옵션, 목록 조회, 원인 조회에 사용됩니다. - 조회 API는 ES 우선으로 응답하고, ES가 실패하면 DB/Redis로 fallback합니다.
- ES에서는 날짜 집계를
date_histogram으로 처리하고, 차량별 최신 결과는 대표 문서 1건만 보여줍니다.
flowchart TD
A["외부 제조 시스템"] --> B["Kafka Raw Topic\nfactory.manufacturing.raw"]
B --> C["raw_event_consumer"]
C --> D["sampledb.manufacturing_event_json"]
D --> E["병목 / 불량 전이 추론"]
E --> F["Kafka Analysis Topic\nfactory.manufacturing.analysis"]
F --> G["analysis_sync_consumer"]
G --> H1["Elasticsearch Bottleneck Index"]
G --> H2["Elasticsearch Defect Transfer Index"]
H1 --> I1["병목 조회 API"]
H2 --> I2["불량 전이 / 원인 조회 API"]
| 구분 | 이름 | 역할 |
|---|---|---|
| Raw Topic | factory.manufacturing.raw |
제조 원천 이벤트 입력 |
| Analysis Topic | factory.manufacturing.analysis |
분석 결과 발행 및 ES 동기화 입력 |
| Raw Consumer Group | ai-analysis-consumer-group |
원천 이벤트 소비 |
| Sync Consumer Group | ai-analysis-sync-consumer-group |
분석 결과 ES 동기화 |
| Bottleneck Index | settings.elasticsearch_bottleneck_index |
병목 결과 검색 |
| Defect Transfer Index | settings.elasticsearch_defect_transfer_index |
불량 전이 / 원인 검색 |
flowchart LR
A["외부 제조 시스템"] --> B["Kafka Raw Topic"]
B --> C["raw_event_consumer"]
C --> D["DB / 원천 저장"]
D --> E["병목 / 불량 전이 추론"]
E --> F["Kafka Analysis Topic"]
F --> G["analysis_sync_consumer"]
G --> H["Elasticsearch"]
H --> I["조회 API"]
sequenceDiagram
participant API as API
participant ES as Elasticsearch
participant Cache as Redis
participant DB as DB
API->>ES: dateOptions / content 조회
alt ES success
ES-->>API: 최신 결과
else ES fail
API->>Cache: 캐시 조회
alt Cache hit
Cache-->>API: cached page
else Cache miss
API->>DB: fallback query
DB-->>API: db rows
end
end
app/
├─ api/ # FastAPI router 계층
│ ├─ routers/
│ │ ├─ process.py # 병목 / 불량 전이 조회
│ │ ├─ defect_transfer.py # 불량 전이 / 원인 조회
│ │ ├─ analysis_maintenance.py # 병목 / 불량 전이 백필·재색인
│ │ ├─ manual.py # AI 메뉴얼
│ │ └─ health.py # 헬스 체크
├─ service/
│ ├─ analysis/ # 분석 조회 / 백필 / 재색인
│ ├─ manufacturing/ # 제조 이벤트 처리
│ └─ llm/ # LLM 연동
├─ repository/ # DB 접근 계층
├─ search/ # Elasticsearch 저장 / 조회
├─ kafka/ # Kafka 소비 / 발행
├─ ml/ # 모델 학습 / 추론 / SHAP
├─ ai_manual/ # AI 메뉴얼 생성
├─ dto/ # 요청 / 응답 스키마
├─ batch/ # 배치 / 백필 작업
└─ scheduler/ # 주기 실행 작업
app/service/analysis: 분석 결과 조회와 관리 작업을 담당합니다.app/search: Elasticsearch 인덱싱과 조회를 담당합니다.app/kafka: 제조 이벤트 수집과 분석 결과 동기화를 담당합니다.app/ml: 병목 탐지와 불량 전이 모델을 담당합니다.app/ai_manual: 메뉴얼 생성 로직을 담당합니다.
GET /api/ai/process/bottleneckGET /api/ai/process/defect-transfer/predictionsGET /api/ai/process/defect-transfer/causes
- 병목 목록과 날짜 옵션을 함께 조회합니다.
- 기본적으로 ES의
detectedAt기준 최신 날짜를 우선 보여줍니다. - 응답에는 공정 순위, 지연 시간, 영향 차량 수, 위험도, 다음 페이지 여부가 포함됩니다.
- 날짜를 지정하면 해당 일자의 병목 결과만 다시 조회합니다.
예시 응답 필드:
mostBottleneckProcessmostBottleneckRiskLeveldatedateOptionscontenthasNextnextCursor
- 차량별 불량 예측 결과와 전이 경로를 조회합니다.
- 기본적으로 ES의
predictedAt기준 최신 날짜를 우선 보여줍니다. - 응답에는 차량 ID, 현재 공정, 예측 공정, 전이 확률, 위험도, 다음 페이지 여부가 포함됩니다.
- 날짜를 지정하면 해당 일자의 예측 결과만 다시 조회합니다.
예시 응답 필드:
datedateOptionscontentvehicleIdcarMasterIdcurrentProcesspredictedDefectProcessdefectProbabilityriskLevelhasNextnextCursor
- 특정 차량의 최신 불량 예측 결과를 기반으로 원인을 조회합니다.
main_causes는 대표 원인,detailCauses는 상세 원인입니다.- 차량 ID가 없으면 최신 차량 기준으로 조회할 수 있습니다.
- 응답은
대표 원인과상세 원인을 분리해 화면에 바로 뿌릴 수 있는 형태입니다.
POST /api/ai/admin/analysis/backfill/bottleneckPOST /api/ai/admin/analysis/backfill/defect-transferPOST /api/ai/admin/analysis/reindex/bottleneckPOST /api/ai/admin/analysis/reindex/defect-transfer
GET /api/ai/manual
PowerShell 기준:
python -m venv venv
.\venv\Scripts\Activate.ps1가상환경이 정상적으로 활성화되면 프롬프트 앞에 (venv)가 표시됩니다.
(venv) PS C:\rookies\aims\ai-service>의존성 설치:
pip install -r requirements.txtrequirements.txt에는 FastAPI, LLM/API 연동, Kafka, 데이터 처리, ML 관련 의존성을 모두 포함합니다.
Windows에서 Python 3.14를 사용하는 경우 일부 패키지의 사전 빌드 wheel이 없으면 pydantic-core, orjson, pandas, scipy, scikit-learn 등이 소스 빌드를 시도할 수 있습니다. 이 경우 Visual Studio Build Tools가 필요할 수 있으므로, 설치 문제가 반복되면 Python 3.12 또는 3.13 사용을 권장합니다.
개발 서버 실행:
uvicorn app.main:app --reload서버 실행 후 아래 주소에서 확인할 수 있습니다.
- API Root:
http://127.0.0.1:8000/ - Health Check:
http://127.0.0.1:8000/api/health - Swagger UI:
http://127.0.0.1:8000/docs - OpenAPI Schema:
http://127.0.0.1:8000/openapi.json
가상환경 비활성화:
deactivate주요 주소:
- API Root:
http://127.0.0.1:8000/ - Health:
http://127.0.0.1:8000/api/health - Swagger:
http://127.0.0.1:8000/docs


