242 lines
4.8 KiB
Markdown
242 lines
4.8 KiB
Markdown
# Extraction & Normalization – OCR + MarkItDown Playbook (Reusable)
|
||
|
||
> Tài liệu này nối tiếp **SharePoint Ingestion Playbook**. Mục tiêu: biến file ingest thành **Markdown sạch, có cấu trúc, có thể search – RAG – truy vết trang gốc**. Viết để **tái sử dụng lâu dài**, không phụ thuộc session.
|
||
|
||
---
|
||
|
||
## Mục lục
|
||
1. Vị trí của Extraction trong kiến trúc
|
||
2. Nguyên tắc thiết kế
|
||
3. Luồng xử lý tổng thể
|
||
4. Phân loại tài liệu & chiến lược xử lý
|
||
5. OCR Strategy cho tài liệu scan
|
||
6. MarkItDown – tích hợp & cấu hình
|
||
7. Page Mapping & Anchoring (đi tới đúng trang)
|
||
8. Normalization & Cleanup
|
||
9. Chunking Strategy (chuẩn cho Search & RAG)
|
||
10. Output Contract (interface dữ liệu)
|
||
11. Error handling & Retry
|
||
12. Performance & Scale
|
||
13. Checklist triển khai
|
||
|
||
---
|
||
|
||
## 1. Vị trí của Extraction trong kiến trúc
|
||
|
||
```text
|
||
Ingestion (file + metadata + ACL)
|
||
│
|
||
▼
|
||
Extraction Layer (OCR + MarkItDown)
|
||
│
|
||
▼
|
||
Normalization & Chunking
|
||
│
|
||
▼
|
||
Index / Search / RAG
|
||
```
|
||
|
||
Extraction **không biết Search**, **không biết User**, chỉ biết:
|
||
- Input: file + metadata
|
||
- Output: Markdown + page mapping + structural hints
|
||
|
||
---
|
||
|
||
## 2. Nguyên tắc thiết kế
|
||
|
||
1. **Deterministic**: cùng file + version → output giống nhau
|
||
2. **Lossless về nội dung**: ưu tiên giữ text hơn làm đẹp
|
||
3. **Trang là đơn vị neo (anchor)** – đặc biệt với PDF
|
||
4. **Tách OCR khỏi Markdown** (để thay engine sau này)
|
||
5. **Không embed business logic** vào bước này
|
||
|
||
---
|
||
|
||
## 3. Luồng xử lý tổng thể
|
||
|
||
```text
|
||
[Receive File Job]
|
||
↓
|
||
[Detect File Type]
|
||
↓
|
||
[If Scan → OCR]
|
||
↓
|
||
[MarkItDown Convert → Markdown]
|
||
↓
|
||
[Normalize Markdown]
|
||
↓
|
||
[Split by Page / Heading]
|
||
↓
|
||
[Emit Document Units]
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Phân loại tài liệu & chiến lược xử lý
|
||
|
||
| Loại | Dấu hiệu | Chiến lược |
|
||
|----|--------|-----------|
|
||
| PDF scan | Không có text layer | OCR → MD |
|
||
| PDF text | Có selectable text | Direct → MD |
|
||
| DOCX | Word | Direct → MD |
|
||
| PPTX | Slide | Slide-wise MD |
|
||
| Image | jpg/png | OCR → MD |
|
||
|
||
✅ Phân loại phải tự động, **không dựa vào extension duy nhất**.
|
||
|
||
---
|
||
|
||
## 5. OCR Strategy
|
||
|
||
### 5.1 Khi nào OCR?
|
||
- PDF không có text layer
|
||
- Image-based document
|
||
|
||
### 5.2 Output OCR yêu cầu tối thiểu
|
||
```json
|
||
{
|
||
"page": 5,
|
||
"text": "Nội dung nhận dạng...",
|
||
"confidence": 0.92
|
||
}
|
||
```
|
||
|
||
### 5.3 Nguyên tắc
|
||
- OCR **theo từng trang**
|
||
- Không gộp toàn file thành một blob text
|
||
|
||
---
|
||
|
||
## 6. MarkItDown – tích hợp & cấu hình
|
||
|
||
### 6.1 Vai trò
|
||
- Biến input (PDF/DOCX/image) thành **Markdown có cấu trúc**
|
||
|
||
### 6.2 Mode sử dụng
|
||
- Input: file path hoặc stream
|
||
- Output: Markdown + page breaks
|
||
|
||
### 6.3 Quy ước page break (rất quan trọng)
|
||
```markdown
|
||
<!-- page:1 -->
|
||
# Trang 1
|
||
...
|
||
<!-- page:2 -->
|
||
# Trang 2
|
||
```
|
||
|
||
➡️ Page marker này là **khóa để click mở đúng trang PDF**.
|
||
|
||
---
|
||
|
||
## 7. Page Mapping & Anchoring
|
||
|
||
### 7.1 Mục tiêu
|
||
- Người dùng search → click → mở **đúng trang, đúng vị trí**
|
||
|
||
### 7.2 Cách làm
|
||
- Mỗi block Markdown phải mang theo:
|
||
```json
|
||
{
|
||
"file_id": "...",
|
||
"page_from": 3,
|
||
"page_to": 4,
|
||
"sharepoint_url": "...?page=3"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 8. Normalization & Cleanup
|
||
|
||
### 8.1 Những việc NÊN làm
|
||
- Remove header/footer lặp
|
||
- Strip ký tự OCR rác
|
||
- Normalize whitespace
|
||
- Chuẩn hóa heading
|
||
|
||
### 8.2 Những việc KHÔNG NÊN làm
|
||
- Rewrite nội dung
|
||
- Tóm tắt
|
||
- Suy diễn
|
||
|
||
➡️ Bước này **không dùng LLM**.
|
||
|
||
---
|
||
|
||
## 9. Chunking Strategy
|
||
|
||
### 9.1 Thứ tự ưu tiên
|
||
1. Heading (##, ###)
|
||
2. Trang PDF
|
||
3. Đoạn văn
|
||
|
||
### 9.2 Kích thước gợi ý
|
||
- 300–800 tokens
|
||
- Không cắt giữa câu
|
||
|
||
### 9.3 Schema chunk
|
||
```json
|
||
{
|
||
"chunk_id": "uuid",
|
||
"text": "...",
|
||
"file_id": "...",
|
||
"page_from": 5,
|
||
"page_to": 6,
|
||
"section": "Điều 3",
|
||
"source_url": "..."
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 10. Output Contract
|
||
|
||
### 10.1 Đầu ra cho Index Layer
|
||
```json
|
||
{
|
||
"file_id": "...",
|
||
"chunks": [ ... ],
|
||
"metadata": { ... }
|
||
}
|
||
```
|
||
|
||
### 10.2 Tính chất
|
||
- Self-contained
|
||
- Không cần gọi lại SharePoint
|
||
- Có thể re-index lại từ output này
|
||
|
||
---
|
||
|
||
## 11. Error handling & Retry
|
||
|
||
| Lỗi | Xử lý |
|
||
|---|------|
|
||
| OCR fail | Retry / flag manual |
|
||
| File corrupt | Log + skip |
|
||
| MarkItDown error | Retry with fallback |
|
||
|
||
Mỗi file có **processing status riêng**.
|
||
|
||
---
|
||
|
||
## 12. Performance & Scale
|
||
|
||
- OCR là bottleneck → async
|
||
- 1 file lớn = nhiều page jobs
|
||
- Scale theo số trang, không theo số file
|
||
|
||
---
|
||
|
||
## 13. Checklist triển khai
|
||
|
||
✅ Detect scan vs text
|
||
✅ OCR page-wise
|
||
✅ Page marker trong Markdown
|
||
✅ Chunk có page mapping
|
||
✅ Output contract rõ ràng
|
||
|
||
---
|
||
|
||
*Kết thúc Extraction & Normalization Playbook. File này nối trực tiếp sang Index/Search.*
|