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 νΈμΆ β
ββββββββββββββββ ββββββββββββββββββ ββββββββββββββββββββββ
λ°μ΄ν° νλ¦
- μ¬μ©μκ° μΏΌλ¦¬ μ λ ₯ + νν°(곡μ₯μ 보 / μ ν μ 보) μ ν
- React β
POST /api/search(Express BFF) - BFF β FastAPI
POST /searchνλ‘μ (filtersμapply_region,apply_productν¬ν¨) - FastAPI λ΄λΆμμ LangGraph νμ΄νλΌμΈ μ€ν (쿼리 λΆμ β λ©ν°μΏΌλ¦¬ μμ± β ν μ€νΈ/λΉμ λ³λ ¬ κ²μ β WRRF μ΅ν© β Answerability νκ°)
- μλ΅μ
SearchResult[]λ‘ λ§€ννμ¬ μΉ΄λ 그리λ + μμΈ λͺ¨λ¬λ‘ λ λλ§ - μΈλ€μΌμ
/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/streamSSE μ°λ β λ Έλλ³ μ§νλ₯ μ€μκ° νμ -
POST /search/doc-detailμ°λ β λ¬Έμ μΉ΄λ ν΄λ¦ μ VLM μ’ ν© λ΅λ³ νμ - μΈμ μμν (νμ¬λ λ©λͺ¨λ¦¬ 보κ΄, μλ‘κ³ μΉ¨ μ μμ€)
- λ€μ΄λ‘λ λ²νΌ β
attach_linkμ§μ λ€μ΄λ‘λ μ²λ¦¬ - λͺ¨λ°μΌ λ°μν μ¬μ΄λλ° ν κΈ
- λ‘κ·ΈμΈ / κΆν κΈ°λ° νν° μλ μ μ©
12. κ΄λ ¨ λ¬Έμ
- λ°±μλ:
qp_rag_pipeline.py - API μμ:
API_call_output_example.md,API_example.md - λ°°ν¬ κ°μ΄λ:
DEPLOY_GUIDE.md - CLAUDE κ·μΉ:
CLAUDE.md