YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

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/<doc_id>/<image> 경둜둜 정적 μ„œλΉ™

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)

μš”μ²­:

{
  "query": "TTV 규격 κΈ°μ€€",
  "region": "3곡μž₯",
  "product": "300mm",
  "topK": 10
}

응닡 (PipelineResult):

{
  "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/<rel-path>

νŽ˜μ΄μ§€ μŠ€ν¬λ¦°μƒ· 정적 μ„œλΉ™. 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 <repo>/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/μ—λŠ” <doc_id>_<λ¬Έμ„œλͺ…>/<doc_id>_<λ¬Έμ„œλͺ…>_<page>.jpg ν˜•μ‹μœΌλ‘œ νŽ˜μ΄μ§€λ³„ μŠ€ν¬λ¦°μƒ·μ΄ μ €μž₯λœλ‹€.


8. μ‹€ν–‰

8.1 개발 λͺ¨λ“œ

cd q-pids
npm install
npm run dev
# β†’ http://localhost:3000

8.2 ν”„λ‘œλ•μ…˜ λΉŒλ“œ

npm run build
NODE_ENV=production npm start

8.3 ν™˜κ²½λ³€μˆ˜ μ˜ˆμ‹œ (μ‹€μ„œλ²„)

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/<encoded path>
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. κ΄€λ ¨ λ¬Έμ„œ

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support