heyingyue's picture
Add docs/DATAFLOW.md
5de1d21 verified
# ScholarMind ๆ•ฐๆฎๆต่ฏฆ็ป†่ฎพ่ฎก
## 1. ็ซฏๅˆฐ็ซฏๆ•ฐๆฎๆต
```
ScholarMind ๆ•ฐๆฎๆตๅ…จๆ™ฏๅ›พ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Phase 1: ๆ•ฐๆฎๆ‘„ๅ…ฅ (Ingestion) โ”‚
โ”‚ โ”‚
โ”‚ PDFๆ–‡ไปถ โ”€โ”€โ–ถ MinIOๅญ˜ๅ‚จ โ”€โ”€โ–ถ Redis้˜Ÿๅˆ— โ”€โ”€โ–ถ PDF่ทฏ็”ฑๅ™จ โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ–ผ โ–ผ โ–ผ โ”‚
โ”‚ PyMuPDF MinerU Pipeline MinerU 2.5 VLM โ”‚
โ”‚ (ๆ•ฐๅญ—PDF) (ๆ•ฐๅญ—+ๅ›พ่กจ) (ๆ‰ซๆไปถ/ๅคๆ‚) โ”‚
โ”‚ โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ–ผ โ”‚
โ”‚ ParsedPaper JSON โ”‚
โ”‚ (็ป“ๆž„ๅŒ–ๅ†…ๅฎนๅ—) โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ–ผ โ–ผ โ–ผ โ”‚
โ”‚ PostgreSQL MinIO(ๅŽŸๅง‹) Redis(็Šถๆ€) โ”‚
โ”‚ (ๅ…ƒๆ•ฐๆฎ) (PDF+JSON) (่ฟ›ๅบฆ) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Phase 2: ็Ÿฅ่ฏ†ๆŠฝๅ– (Extraction) โ”‚
โ”‚ โ”‚
โ”‚ ParsedPaper โ”€โ”€โ–ถ ๅญฆๆœฏๅˆ†ๅ—ๅ™จ(256 tokens) โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ โ”œโ”€โ”€โ–ถ GLiNER NER (ๅฎžไฝ“ๆŠฝๅ–, ๆœฌๅœฐGPU) โ”‚
โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ โ”‚ โ–ผ โ”‚
โ”‚ โ”‚ ๅฎžไฝ“ๅˆ—่กจ: [(text, type, score), ...] โ”‚
โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ โ”‚ โ–ผ โ”‚
โ”‚ โ”œโ”€โ”€โ–ถ LLMGraphTransformer (ๅ…ณ็ณปๆŠฝๅ–) โ”‚
โ”‚ โ”‚ โ”‚ ่พ“ๅ…ฅ: ๆ–‡ๆœฌๅ— + ๅฎžไฝ“ๆ็คบ โ”‚
โ”‚ โ”‚ โ”‚ LLM: local(Qwen2.5-14B) ๆˆ– API(GPT-4o-mini) โ”‚
โ”‚ โ”‚ โ–ผ โ”‚
โ”‚ โ”‚ ไธ‰ๅ…ƒ็ป„ๅˆ—่กจ: [(head, rel, tail, props), ...] โ”‚
โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ โ”‚ โ–ผ โ”‚
โ”‚ โ””โ”€โ”€โ–ถ Graphusion ่žๅˆๅผ•ๆ“Ž โ”‚
โ”‚ โ”‚ - ๅตŒๅ…ฅ็›ธไผผๅบฆๅฎžไฝ“ๅˆๅนถ (>0.92) โ”‚
โ”‚ โ”‚ - LLMๅ†ฒ็ชๆถˆ่งฃ โ”‚
โ”‚ โ”‚ - ็ผบๅคฑๅ…ณ็ณปๆŽจๆ–ญ โ”‚
โ”‚ โ–ผ โ”‚
โ”‚ ่ง„่ŒƒๅŒ–ไธ‰ๅ…ƒ็ป„ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Phase 3: ็ดขๅผ•ๆž„ๅปบ (Indexing) โ”‚
โ”‚ โ”‚
โ”‚ ๅนถ่กŒไธ‰่ทฏ็ดขๅผ•ๆž„ๅปบ: โ”‚
โ”‚ โ”‚
โ”‚ ่ทฏๅพ„A: ๅ‘้‡็ดขๅผ• โ”‚
โ”‚ ๆ–‡ๆœฌๅ— โ”€โ”€โ–ถ Embedding Model โ”€โ”€โ–ถ Dense Vector โ”€โ”€โ” โ”‚
โ”‚ ๆ–‡ๆœฌๅ— โ”€โ”€โ–ถ BM42/SPLADE โ”€โ”€โ–ถ Sparse Vector โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ–ถ Qdrant Collection โ”‚
โ”‚ ๅ…ƒๆ•ฐๆฎ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ (papers, 1M+ vectors) โ”‚
โ”‚ โ”‚
โ”‚ ่ทฏๅพ„B: ็Ÿฅ่ฏ†ๅ›พ่ฐฑ โ”‚
โ”‚ ่ง„่ŒƒๅŒ–ไธ‰ๅ…ƒ็ป„ โ”€โ”€โ–ถ Neo4j Batch Import โ”€โ”€โ–ถ Neo4j Graph โ”‚
โ”‚ ๅฎžไฝ“ๅตŒๅ…ฅ โ”€โ”€โ–ถ Neo4j Vector Index โ”€โ”€โ–ถ ๅ›พๅ†…ๅ‘้‡ๆœ็ดข โ”‚
โ”‚ ๅ…จๆ–‡็ดขๅผ• โ”€โ”€โ–ถ Neo4j Fulltext Index โ”€โ”€โ–ถ ๅ›พๅ†…ๆ–‡ๆœฌๆœ็ดข โ”‚
โ”‚ โ”‚
โ”‚ ่ทฏๅพ„C: RAPTORๅฑ‚ๆฌกๆ ‘ โ”‚
โ”‚ ๆ–‡ๆœฌๅ— โ”€โ”€โ–ถ SBERTๅตŒๅ…ฅ โ”€โ”€โ–ถ GMM่š็ฑป โ”€โ”€โ–ถ LLMๆ‘˜่ฆ โ”€โ”€โ–ถ ้‡ๆ–ฐๅตŒๅ…ฅ โ”€โ”€โ–ถ ้€’ๅฝ’ โ”‚
โ”‚ Level 0 (ๅŽŸๅง‹) โ†’ Level 1 (ๆฎต่ฝ) โ†’ Level 2 (ไธป้ข˜) โ†’ Level 3 (้ข†ๅŸŸ) โ”‚
โ”‚ ๆ‰€ๆœ‰ๅฑ‚็บง่Š‚็‚น โ”€โ”€โ–ถ Qdrant Collection (raptor_tree) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Phase 4: ๆฃ€็ดขไธŽ้—ฎ็ญ” (Query) โ”‚
โ”‚ โ”‚
โ”‚ ็”จๆˆทๆŸฅ่ฏข โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ โ”œโ”€โ”€โ–ถ ๆ„ๅ›พๅˆ†็ฑป (Router LLM) โ”‚
โ”‚ โ”‚ โ”‚ โ”‚
โ”‚ โ”‚ โ”œโ”€โ”€ factual โ†’ ๅ‘้‡+BM25ๆฃ€็ดข (Qdrant) โ”‚
โ”‚ โ”‚ โ”œโ”€โ”€ reasoning โ†’ ๅ›พ่ฐฑ้ๅކ (Neo4j) + ๅ‘้‡ๆฃ€็ดข โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ global โ†’ RAPTOR้ซ˜ๅฑ‚ๆ‘˜่ฆ + ็คพๅŒบๆฃ€็ดข โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ โ”œโ”€โ”€โ–ถ HyDEๆŸฅ่ฏขๅขžๅผบ โ”‚
โ”‚ โ”‚ LLM็”Ÿๆˆๅ‡่ฎพ็ญ”ๆกˆ โ†’ ๅตŒๅ…ฅ โ†’ ๅœจๆ–‡ๆกฃ็ฉบ้—ดๆœ็ดข โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ–ถ ๅคš่ทฏ็ป“ๆžœ โ”€โ”€โ–ถ RRF่žๅˆ โ”€โ”€โ–ถ bge-reranker-large้‡ๆŽ’ โ”€โ”€โ–ถ Top-5 โ”‚
โ”‚ โ”‚
โ”‚ Top-5 + ๆŸฅ่ฏข โ”€โ”€โ–ถ Generator LLM โ”€โ”€โ–ถ ็ญ”ๆกˆ + ๅผ•็”จ โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ โ–ผ โ”‚
โ”‚ ็ญ”ๆกˆ โ”€โ”€โ–ถ Validator LLM (่‡ชๆฃ€) โ”€โ”€โ”ฌโ”€โ”€ ็ฝฎไฟกๅบฆ>0.8 โ†’ ่ฟ”ๅ›ž โ”‚
โ”‚ โ””โ”€โ”€ ็ฝฎไฟกๅบฆ<0.8 โ†’ ่กฅๅ……ๆฃ€็ดข (max 3่ฝฎ) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```
## 2. ็Ÿฅ่ฏ†ๅ›พ่ฐฑๆŸฅ่ฏขๆต็คบไพ‹
### ็คบไพ‹1: "BERTๆจกๅž‹ๅœจๅ“ชไบ›ๆ•ฐๆฎ้›†ไธŠ่ถ…่ฟ‡ไบ†GPT-2?"
```
ๆŸฅ่ฏข โ†’ ๆ„ๅ›พๅˆ†็ฑป: reasoning
โ†’ ๅ›พ่ฐฑๆŸฅ่ฏข:
MATCH (bert:Method {name: "BERT"})-[r1:EVALUATED_ON]->(d:Dataset)
<-[r2:EVALUATED_ON]-(gpt2:Method {name: "GPT-2"})
WHERE r1.score > r2.score AND r1.metric = r2.metric
RETURN d.name as dataset,
r1.metric as metric,
r1.score as bert_score,
r2.score as gpt2_score
ORDER BY (r1.score - r2.score) DESC
โ†’ ็ป“ๆžœ:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ dataset โ”‚ metric โ”‚ bert_score โ”‚ gpt2_score โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ GLUE โ”‚ accuracy โ”‚ 82.1 โ”‚ 75.4 โ”‚
โ”‚ SQuAD โ”‚ F1 โ”‚ 93.2 โ”‚ 89.1 โ”‚
โ”‚ ... โ”‚ ... โ”‚ ... โ”‚ ... โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
+ ๅ‘้‡ๆฃ€็ดข่กฅๅ……: ็›ธๅ…ณ่ฎบๆ–‡ๆฎต่ฝไฝœไธบsupporting evidence
โ†’ LLM็ปผๅˆ็”Ÿๆˆ็ญ”ๆกˆ
```
### ็คบไพ‹2: "Transformerๆžถๆž„่ฟ‘3ๅนด็š„ไธป่ฆๆ”น่ฟ›ๆ–นๅ‘ๆœ‰ๅ“ชไบ›?"
```
ๆŸฅ่ฏข โ†’ ๆ„ๅ›พๅˆ†็ฑป: global
โ†’ RAPTOR Level 2-3 ๆฃ€็ดข:
"Transformerๆ”น่ฟ›" ็›ธๅ…ณ็š„้ซ˜ๅฑ‚ๆ‘˜่ฆ่Š‚็‚น
โ†’ ๅ›พ่ฐฑๆŸฅ่ฏข:
MATCH (t:Concept {name: "Transformer"})<-[:IMPROVES_ON]-(m:Method)
WHERE m.year >= 2022
RETURN m.name, m.description, m.year
ORDER BY m.year DESC
โ†’ LLM็ปผๅˆ: ไปŽๆ‘˜่ฆ+ๅ›พ่ฐฑ็ป“ๆž„็”Ÿๆˆ่ถ‹ๅŠฟๅˆ†ๆž
```
## 3. ๅนถๅ‘ๅค„็†ๆจกๅž‹
```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ๅนถๅ‘ๅค„็†ๆžถๆž„ โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ โ”‚
โ”‚ FastAPI (asyncio) โ”€โ”€โ”€โ”€โ”€โ”€ ๆŸฅ่ฏข่ฏทๆฑ‚ๅค„็† โ”‚
โ”‚ โ”‚ ๅนถๅ‘: 100+ concurrent requests โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ Celery Workers โ”€โ”€โ”€โ”€โ”€โ”€โ”€ PDF่งฃๆžไปปๅŠก โ”‚
โ”‚ โ”‚ GPU Worker: 1 per GPU โ”‚
โ”‚ โ”‚ CPU Worker: 4-8 per node โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ vLLM Server โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ LLMๆŽจ็† โ”‚
โ”‚ โ”‚ Async batching (่‡ชๅŠจ) โ”‚
โ”‚ โ”‚ max_num_seqs: 32 โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ Qdrant โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ๅ‘้‡ๆฃ€็ดข โ”‚
โ”‚ โ”‚ RPS: 3000+ (p99 < 10ms) โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ Neo4j โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ๅ›พ่ฐฑๆŸฅ่ฏข โ”‚
โ”‚ โ”‚ Connection pool: 50 โ”‚
โ”‚ โ”‚ Query timeout: 5s โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ Redis โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ็ผ“ๅญ˜ + ้˜Ÿๅˆ— โ”‚
โ”‚ LLMๅ“ๅบ”็ผ“ๅญ˜ โ”‚
โ”‚ ไปปๅŠก้˜Ÿๅˆ— โ”‚
โ”‚ Session็Šถๆ€ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
ๅ…ณ้”ฎ่ฎพ่ฎกๅ†ณ็ญ–:
1. MinerU VLM Worker: ๆฏGPUไธ€ไธช่ฟ›็จ‹ (vLLMๅ†…้ƒจๅทฒๅšbatch)
2. GLiNER: GPU batch inference, ๅ…ฑไบซๅ•ไธชGPU
3. LLM่ฐƒ็”จ: ๅผ‚ๆญฅ (litellm.acompletion), ่‡ชๅŠจbatch
4. ๅ›พ่ฐฑๅ†™ๅ…ฅ: ๆ‰น้‡UNWINDๅฏผๅ…ฅ (1000 triplets/batch)
5. ๅ‘้‡ๅ†™ๅ…ฅ: Qdrant batch upload (100 points/batch)
```
## 4. ็ผ“ๅญ˜็ญ–็•ฅ
```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ๅคš็บง็ผ“ๅญ˜็ญ–็•ฅ โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ โ”‚
โ”‚ L1: LLMๅ“ๅบ”็ผ“ๅญ˜ (Redis, TTL: 24h) โ”‚
โ”‚ Key: hash(model + messages + temperature) โ”‚
โ”‚ ๅ‘ฝไธญ็އ้ข„ไผฐ: 30-40% (ๅญฆๆœฏๆŸฅ่ฏข้‡ๅคๅบฆ้ซ˜) โ”‚
โ”‚ โ”‚
โ”‚ L2: ๅตŒๅ…ฅ็ผ“ๅญ˜ (Redis, TTL: 7d) โ”‚
โ”‚ Key: hash(text + model_name) โ”‚
โ”‚ ้ฟๅ…้‡ๅค่ฎก็ฎ—ๅตŒๅ…ฅๅ‘้‡ โ”‚
โ”‚ โ”‚
โ”‚ L3: ๆŸฅ่ฏข็ป“ๆžœ็ผ“ๅญ˜ (Redis, TTL: 1h) โ”‚
โ”‚ Key: hash(query + mode + top_k) โ”‚
โ”‚ ๅฎŒๆ•ดๆฃ€็ดข็ป“ๆžœ็ผ“ๅญ˜ โ”‚
โ”‚ โ”‚
โ”‚ L4: ๅ›พ่ฐฑๅญๅ›พ็ผ“ๅญ˜ (Application Memory, LRU) โ”‚
โ”‚ ็ƒญ้—จๅฎžไฝ“็š„2่ทณๅญๅ›พ้ข„ๅŠ ่ฝฝ โ”‚
โ”‚ ๅฎน้‡: top 1000 entities โ”‚
โ”‚ โ”‚
โ”‚ ๅคฑๆ•ˆ็ญ–็•ฅ: โ”‚
โ”‚ - ๆ–ฐ่ฎบๆ–‡ๅฏผๅ…ฅ โ†’ ๆธ…้™ค็›ธๅ…ณquery็ผ“ๅญ˜ (L3) โ”‚
โ”‚ - ๅ›พ่ฐฑๆ›ดๆ–ฐ โ†’ ๆธ…้™คๅ›พ่ฐฑ็ผ“ๅญ˜ (L4) โ”‚
โ”‚ - ๆจกๅž‹ๆ›ดๆข โ†’ ๆธ…้™คLLM+ๅตŒๅ…ฅ็ผ“ๅญ˜ (L1+L2) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```
## 5. ้”™่ฏฏๅค„็†ไธŽ็›‘ๆŽง
```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ๅฏ่ง‚ๆต‹ๆ€งๆžถๆž„ โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ โ”‚
โ”‚ Metrics (Prometheus + Grafana): โ”‚
โ”‚ - pdf_parse_duration_seconds (histogram) โ”‚
โ”‚ - pdf_parse_total{status="success|failed"} (counter) โ”‚
โ”‚ - query_latency_seconds{mode="factual|reasoning|global"}โ”‚
โ”‚ - llm_tokens_total{model, task} (counter) โ”‚
โ”‚ - llm_cost_usd_total{model} (counter) โ”‚
โ”‚ - qdrant_search_latency_seconds (histogram) โ”‚
โ”‚ - neo4j_query_latency_seconds (histogram) โ”‚
โ”‚ - cache_hit_ratio{level="L1|L2|L3|L4"} (gauge) โ”‚
โ”‚ โ”‚
โ”‚ Logging (Structured JSON โ†’ ELK/Loki): โ”‚
โ”‚ - ๆฏๆฌกๆŸฅ่ฏขๅฎŒๆ•ดtrace (queryโ†’retrievalโ†’generation) โ”‚
โ”‚ - PDF่งฃๆžๅผ‚ๅธธ่ฏฆๆƒ… โ”‚
โ”‚ - LLM่ฐƒ็”จ่ฏฆๆƒ… (token count, latency, model) โ”‚
โ”‚ โ”‚
โ”‚ Alerts: โ”‚
โ”‚ - PDF่งฃๆžๅคฑ่ดฅ็އ > 5% โ†’ ๆฃ€ๆŸฅPDF่ดจ้‡/MinerU็Šถๆ€ โ”‚
โ”‚ - ๆŸฅ่ฏขP99ๅปถ่ฟŸ > 10s โ†’ ๆฃ€ๆŸฅLLM/ๅ‘้‡ๅบ“่ดŸ่ฝฝ โ”‚
โ”‚ - LLMๆˆๆœฌๆ—ฅ่ถ… $X โ†’ ๅˆ‡ๆขๆ›ดๅคšๆต้‡ๅˆฐๆœฌๅœฐๆจกๅž‹ โ”‚
โ”‚ - Neo4jๅ†…ๅญ˜ > 80% โ†’ ๆ‰ฉๅฎนๆˆ–ๆธ…็†ๆ—งๆ•ฐๆฎ โ”‚
โ”‚ โ”‚
โ”‚ Health Checks: โ”‚
โ”‚ GET /health โ†’ ๆฃ€ๆŸฅๆ‰€ๆœ‰ไพ่ต–ๆœๅŠก็Šถๆ€ โ”‚
โ”‚ - Redis: PING โ”‚
โ”‚ - Qdrant: collection info โ”‚
โ”‚ - Neo4j: RETURN 1 โ”‚
โ”‚ - LiteLLM: /health โ”‚
โ”‚ - MinerU Worker: Celery inspect โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```