# Q-PIDS — QP Manual Search System SK실트론 사내 지침서·가이드·매뉴얼 문서를 멀티모달 RAG 파이프라인으로 검색하는 웹 서비스. 백엔드 FastAPI(`qp_rag_pipeline.py`)의 `/search` 엔드포인트를 호출하여 텍스트/비전 트랙 통합 검색 결과를 사용자에게 시각적으로 제공한다. --- ## 1. 개요 | 항목 | 내용 | |------|------| | 서비스명 | Q-PIDS (QP Process Information Document Search) | | 도메인 | 반도체 웨이퍼 제조 공정 사내 문서 검색 | | 프런트엔드 | React 19 + TypeScript + Vite + Tailwind CSS v4 + Motion | | 백엔드 (BFF) | Node.js + Express (프록시 + 정적 서빙) | | 검색 엔진 | FastAPI + LangGraph 멀티모달 RAG 파이프라인 (`qp_rag_pipeline.py`) | | 기본 포트 | 3000 (웹 UI), 18504 (FastAPI), 4275/4276 (Search/Dict API) | --- ## 2. 아키텍처 ``` ┌──────────────┐ ┌────────────────┐ ┌────────────────────┐ │ Browser │──────►│ Express BFF │───────►│ FastAPI Pipeline │ │ (React UI) │ /api │ (server.ts) │ /search│ (qp_rag_pipeline) │ │ │ │ │ │ │ │ │ │ /snap_data/* │ │ Search/Dict/LLM/ │ │ │◄──────│ (정적 이미지) │ │ Reranker 호출 │ └──────────────┘ └────────────────┘ └────────────────────┘ ``` ### 데이터 흐름 1. 사용자가 쿼리 입력 + 필터(공장정보 / 제품 정보) 선택 2. React → `POST /api/search` (Express BFF) 3. BFF → FastAPI `POST /search` 프록시 (filters에 `apply_region`, `apply_product` 포함) 4. FastAPI 내부에서 LangGraph 파이프라인 실행 (쿼리 분석 → 멀티쿼리 생성 → 텍스트/비전 병렬 검색 → WRRF 융합 → Answerability 평가) 5. 응답을 `SearchResult[]`로 매핑하여 카드 그리드 + 상세 모달로 렌더링 6. 썸네일은 `/snap_data/ / ` 경로로 정적 서빙 --- ## 3. 주요 화면 ### 3.1 검색 화면 (`view: 'search'`) - 중앙 정렬된 검색 입력창 (예시 placeholder: "300mm DSP공정 Pad 교체주기 알려줘") - **검색조건** 토글 → 2개 필터(공장정보 / 제품 정보) 노출 - "제품Size와 공정명을 함께 기재하면 정보탐색의 정확도를 올릴 수 있습니다" 가이드 문구 ### 3.2 결과 화면 (`view: 'results'`) - **좌 사이드바**: 새 검색 / 검색 조건 설정 / 과거 세션 목록 - **메인 영역**: 결과 카드 그리드 (1/2/3 columns 반응형, 최대 9개, "더보기" 토글로 6→9) - **우 사이드바** (xl 이상): 파이프라인 진행률, 인사이트(Complexity / Strategy / Answerability), Top Results 리스트 ### 3.3 상세 모달 (`DetailModal`) - 좌 60% — 페이지 이미지 (4:3, 클릭 시 전체화면 확대), 페이지 네비게이션 - 우 40% — 검색 쿼리, 문서 제목, 선택 페이지 / 관련 페이지 버튼, AI 분석 요약 + 페이지 본문 발췌 - 시스템 링크(`main_doc_link`) / 다운로드 버튼 --- ## 4. 검색 필터 기존 3개 필터(공장정보 / 제품 정보 / Document Type) 중 Document Type을 제거하고 **2개로 축소**. ### 4.1 공장정보 (`apply_region`) 실데이터 분포(`doc_cate_2`) 기반: | 옵션 | 문서 수 | |------|---------| | 전체 | (필터 없음) | | 3공장 | 710 | | 전사공통 | 376 | | 2공장 | 349 | | 2공장SiC | 263 | | 공장공통 | 244 | | 1공장 | 138 | | 청주공장 | 123 | | 서울 | 1 | ### 4.2 제품 정보 (`apply_product`) 실데이터 분포(`doc_cate_3`) 기반: | 옵션 | 문서 수 | |------|---------| | 전체 | (필터 없음) | | 300mm | 686 | | 지원부문 | 584 | | 제품공통 | 486 | | 200mm | 286 | | 150mm | 162 | > "전체" 선택 시 해당 키는 filters dict에서 제외 → 백엔드에 무필터로 전달. --- ## 5. API 명세 ### 5.1 `POST /api/search` (BFF) 요청: ```json { "query": "TTV 규격 기준", "region": "3공장", "product": "300mm", "topK": 10 } ``` 응답 (`PipelineResult`): ```json { "results": [ { "id": "I812-E8001-1_300mm 청주 EPI Auto Box Cleaning 작업 운전 지침서", "title": "300mm 청주 EPI Auto Box Cleaning 작업 운전 지침서", "summary": "...", "relevance": 87, "priority": "Standard", "type": "Both", "thumbnail": "/snap_data/I812-.../I812-..._3.jpg", "url": "https://mail.sksiltron.co.kr/...", "page": 3, "relatedPages": [3, 5, 12], "totalPages": 24, "docId": "I812-E8001-1_...", "applyRegion": "3공장", "applyProduct": "300mm", "deptName": "EPI기술1팀", "regDate": "2025-...", "pages": [{ "page": 3, "thumbnail": "...", "content": "..." }] } ], "meta": { "complexity": "Complex", "strategy": "Hybrid", "answerabilityScore": 0.83, "total": 9 } } ``` ### 5.2 `GET /snap_data/ ` 페이지 스크린샷 정적 서빙. `display_rel_path`(예: `I000-50001-0_출하차량 작업 지침/I000-50001-0_출하차량 작업 지침_5.jpg`)를 그대로 사용. --- ## 6. 환경변수 | 변수 | 기본값 | 설명 | |------|--------|------| | `PORT` | `3000` | Express 서버 포트 | | `QP_API_BASE` | `http://10.150.6.46:18504` | FastAPI 베이스 URL | | `SNAP_DATA_DIR` | ` /snap_data` | 페이지 이미지 정적 폴더 절대경로 | | `SNAP_DATA_PUBLIC_BASE` | `/snap_data` | 클라이언트 노출 prefix | | `NODE_ENV` | (없음) | `production`이면 `dist/` 정적 서빙 | --- ## 7. 디렉토리 구조 ``` q-pids/ ├── server.ts # Express BFF (프록시 + snap_data 서빙) ├── vite.config.ts ├── package.json ├── index.html ├── src/ │ ├── App.tsx # 메인 React 컴포넌트 │ ├── main.tsx │ ├── index.css # Tailwind v4 + 디자인 토큰 │ ├── types.ts # SearchResult / SearchMeta / SearchSession │ └── services/ │ └── searchPipeline.ts # FastAPI 클라이언트 + 응답 매퍼 └── README.md ``` 상위 폴더의 `snap_data/`에는 ` _ / _ _ .jpg` 형식으로 페이지별 스크린샷이 저장된다. --- ## 8. 실행 ### 8.1 개발 모드 ```bash cd q-pids npm install npm run dev # → http://localhost:3000 ``` ### 8.2 프로덕션 빌드 ```bash npm run build NODE_ENV=production npm start ``` ### 8.3 환경변수 예시 (실서버) ```bash PORT=3000 \ QP_API_BASE=http://10.150.6.46:18504 \ SNAP_DATA_DIR=/data/qp/snap_data \ NODE_ENV=production \ node server.ts ``` --- ## 9. 응답 매핑 규칙 FastAPI `SearchResponse.doc_results[i]` → 프런트 `SearchResult` 변환 (`searchPipeline.ts` 내 `mapDocToResult`): | 백엔드 필드 | 프런트 필드 | 변환 | |-------------|-------------|------| | `doc_id` | `id`, `docId` | 그대로 | | `doc_id` (앞 ID 제거) | `title` | `_` 이후 부분 | | `pages[0].content[:220]` | `summary` | content 있으면 우선 | | `best_rerank_score` 또는 `best_score` | `relevance` | `× 100`, 0~100 클램프 | | `source` | `type` | Text / Vision / Both | | `pages[*].display_rel_path` | `thumbnail` | `/snap_data/ ` | | `main_doc_link` | `url` | 그대로 | | `representative_page` | `page` | fallback: pages 첫 항목 | | `pages[*].page` | `relatedPages` | 페이지 번호 배열 | | `page_count` | `totalPages` | 그대로 | | `complexity` | `meta.complexity` | "Low"→Simple, 그 외→Complex | | `query_type` | `meta.strategy` | Text / Vision / Hybrid 그대로 | | `answerability_score` | `meta.answerabilityScore` | 0~1 | --- ## 10. 디자인 시스템 ### 색상 토큰 (Tailwind 사용자 지정) - **Primary**: `#E1251B` (SK 레드) - **Primary Hover**: `#C01F18` / `#B00020` - **Surface**: `surface`, `surface-container-{low/lowest/high/highest}` - **Text**: `on-surface`, `on-surface-variant`, `tertiary` - **Outline**: `outline-variant` ### 타이포그래피 - **Headline**: 굵은 헤드라인용 (`font-headline font-black`) - **Sans**: 본문 - 한국어 + 영문 혼용, 영문은 uppercase + tracking-widest로 라벨화 ### 모션 - `motion/react`(Motion One) 기반 등장/소실 애니메이션 - 카드 hover 시 `scale-105` 줌, 드롭다운 `rotate-180` 등 --- ## 11. 향후 작업 (선택) - [ ] FastAPI `/search/stream` SSE 연동 — 노드별 진행률 실시간 표시 - [ ] `POST /search/doc-detail` 연동 — 문서 카드 클릭 시 VLM 종합 답변 표시 - [ ] 세션 영속화 (현재는 메모리 보관, 새로고침 시 소실) - [ ] 다운로드 버튼 → `attach_link` 직접 다운로드 처리 - [ ] 모바일 반응형 사이드바 토글 - [ ] 로그인 / 권한 기반 필터 자동 적용 --- ## 12. 관련 문서 - 백엔드: [`qp_rag_pipeline.py`](../qp_rag_pipeline.py) - API 예시: [`API_call_output_example.md`](../API_call_output_example.md), [`API_example.md`](../API_example.md) - 배포 가이드: [`DEPLOY_GUIDE.md`](../DEPLOY_GUIDE.md) - CLAUDE 규칙: [`CLAUDE.md`](../CLAUDE.md)