# Ghi chú tích hợp ingest Kênh Xây

Tài liệu này tóm tắt cách ingest bộ hồ sơ Kênh Xây theo đúng tinh thần của DSCons: ingest lặp lại được, metadata rõ, truy vết được nguồn, và có điểm xác nhận sau mỗi batch.

## 1. Mục tiêu

- nạp hồ sơ Kênh Xây vào lớp knowledge của dự án
- giữ metadata thống nhất với `workflow.md` và `docs/next-steps-five-data-flows.md`
- dùng manifest làm nguồn kiểm soát file-level
- sinh summary cuối batch để rà soát ingest, skip, lỗi và rủi ro

## 2. Nguồn đầu vào cần đọc

### Tệp cấu hình chính
- `docs/kenh-xay-document-manifest.json`
  - quyết định file nào được ingest
  - chứa metadata file-level ban đầu
- `docs/kenh-xay-gold-reference-metadata-schema.json`
  - chứa default chung
  - allowed values
  - các mapping hỗ trợ chuẩn hóa metadata

### Nguồn nội dung thực tế
- file trên disk theo `relative_path` từ manifest
- root mặc định là thư mục dự án hiện tại

## 3. Thứ tự ingest nên áp dụng

1. load schema
2. load manifest
3. duyệt từng record manifest
4. chuẩn hóa metadata file-level
5. kiểm tra điều kiện ingest
6. đọc text từ file
7. chuẩn hóa text
8. chia chunk
9. gắn metadata cấp chunk
10. upsert vào pipeline ingest
11. ghi summary cuối batch

Thứ tự này giúp:
- dễ rerun
- dễ kiểm tra file nào bị loại ở bước nào
- giảm nguy cơ ingest dữ liệu bẩn hoặc metadata lệch chuẩn

## 4. Rule chọn file để ingest

### Chỉ ingest khi
- `is_ingest_candidate = true`
- file tồn tại trên disk
- đọc ra được text không rỗng sau normalize

### Không ingest khi
- manifest đánh dấu `is_ingest_candidate = false`
- file không tồn tại
- không trích được text
- file là bản bìa, bản trùng hoặc chỉ để tham chiếu phụ

### Lưu ý vận hành
- record bị skip vẫn phải đi vào summary audit
- không xóa dấu vết record bị skip
- manifest là nguồn quyết định ingest trước, sau đó mới áp rule override metadata nếu cần

## 5. Cách đọc và chunk text

### Thứ tự đọc text khuyến nghị
1. `.docx`: đọc XML nội bộ
2. `.pdf`, `.doc`, `.xls`, `.xlsx`: đọc bằng extractor đang dùng trong pipeline
3. fallback: đọc text thô nếu phù hợp

### Normalize text
- gom whitespace về một chuẩn
- bỏ khoảng trắng thừa
- giữ text đủ sạch trước khi chunk

### Cỡ chunk gợi ý
| Định dạng | Chunk size | Overlap |
| --- | ---: | ---: |
| pdf | 1200 | 160 |
| doc, docx | 1400 | 180 |
| xls, xlsx | 1000 | 120 |
| fallback | 1400 | 180 |

### Lưu ý
- PDF scan thường nhiễu hơn, nên chunk ngắn hơn
- bảng tính nên chunk nhỏ để tránh lẫn nhiều sheet
- hợp đồng và biên bản thường cần chunk dài hơn để giữ ngữ cảnh

## 6. Cấu trúc metadata nên giữ

## 6.1 Các lớp metadata
Metadata mỗi chunk nên ghép từ 4 lớp:

1. default từ schema
2. field gốc từ manifest
3. field derive theo taxonomy
4. field cấp chunk

## 6.2 Metadata lõi bắt buộc
Các key nên có trên mọi chunk:

| Nhóm | Trường |
| --- | --- |
| Định danh dự án | `project_code`, `project_name`, `template_code`, `schema_version` |
| Truy vết nguồn | `raw_path`, `source_file`, `source_filename`, `source_format` |
| Phân loại hồ sơ | `document_group`, `document_type`, `doc_family`, `business_group`, `knowledge_type`, `task_type` |
| Bối cảnh nghiệp vụ | `stage`, `status`, `package_label`, `package_code`, `package_name` |
| Kiểm soát chất lượng | `version_role`, `gold_reference_role`, `is_gold_reference`, `requires_ocr`, `confidence_note` |
| Mục đích sử dụng | `used_for_tasks`, `required_for`, `evidence_role`, `retrieval_priority`, `training_value` |
| Vận hành ingest | `ingest_batch`, `chunk_index`, `id` |

## 6.3 Nguyên tắc metadata
- metadata phải đủ để truy vết về đúng file gốc
- không để trống các field phân loại bắt buộc
- không dùng raw manifest nguyên xi nếu đã biết sai hoặc mơ hồ
- mọi rule override nên nhất quán trong toàn batch

## 7. Các rule derive cần ưu tiên

### `stage`
Manifest đang có nhiều giá trị không khớp schema. Nên normalize trước khi ingest.

| Manifest | Nên đổi thành |
| --- | --- |
| `project_setup` | `overview` |
| `approval` | `legal_setup` |
| `procurement_approval` | `procurement` |
| `consulting_assignment` | `legal_setup` |
| `contract_award` | `procurement` |
| `pre_contract` | `contracting` |
| `contract_execution` | `contracting` hoặc `execution` theo loại hồ sơ |
| `execution_quality` | `execution` |
| `completion` | `acceptance` |

### `package_label`
- nếu có giá trị hợp lệ thì giữ
- nếu rỗng nhưng là hồ sơ dùng chung toàn công trình thì gán `package_project_wide`
- chỉ dùng `package_unknown` khi thật sự không suy ra được

### `version_role`
- `duplicate`: file trùng, file bìa, record non-candidate
- `template_form`: mẫu biểu như `mau_bieu_02a`
- `effective`: hồ sơ chính đang dùng
- `unknown`: file mơ hồ, cần kiểm tra tay

### `gold_reference_role`
- `required`: hồ sơ trụ cột, có giá trị nền cho retrieval và readiness
- `optional`: hồ sơ bổ trợ
- `example`: mẫu biểu, tài liệu tham khảo
- `exclude`: cover, duplicate, noise

### `requires_ocr`
- PDF: mặc định `true` nếu chưa có detector text layer
- DOC, DOCX, XLS, XLSX: thường `false`
- đây chỉ là cờ vận hành, không đồng nghĩa đã OCR thật

### `used_for_tasks`
Tối thiểu nên có:
- `template_training`
- `retrieval_grounding`

Theo loại hồ sơ có thể bổ sung:
- `inventory_mapping`
- `missing_doc_detection`
- `legal_timeline_check`
- `contract_review`
- `execution_guidance`
- `quality_check`
- `payment_check`
- `settlement_check`
- `audit_preparation`

## 8. Các điểm cần override so với manifest

### Không nên tin hoàn toàn manifest ở các trường sau
- `stage`
- `package_label` khi đang `null`
- `document_type` của file bìa
- các file tên mơ hồ đang `needs_verification`

### Cách xử lý
- dùng manifest để quyết định ingest hay không ingest
- dùng lớp normalize để sửa metadata trước khi upsert
- giữ lý do override trong summary hoặc log nếu pipeline cho phép

## 9. Nhóm hồ sơ nên ingest trước

Ưu tiên ingest trước các hồ sơ anchor:

1. danh mục hồ sơ gốc
2. bản vẽ, khối lượng, dự toán
3. quyết định pháp lý chính
4. hợp đồng TCXD
5. nghiệm thu khối lượng hoàn thành
6. bộ hồ sơ thanh toán chính

Lý do:
- đây là nhóm có giá trị retrieval cao
- ảnh hưởng trực tiếp tới gap analysis và readiness
- giúp trả lời nhanh 4 câu hỏi lõi: có gì, thiếu gì, bản nào mạnh hơn, đang ở giai đoạn nào

## 10. Summary cuối batch nên có gì

### Mức batch
- `status`
- `project_code`
- `template_code`
- `ingest_batch`
- `manifest_path`
- `schema_path`
- `total_manifest_records`
- `total_files_ready`
- `total_files_skipped`
- `total_chunks`

### Mức file
- `file`
- `relative_path`
- `document_type`
- `package_label`
- `status`
- `chunks`
- `reason`

### Trạng thái file nên dùng
- `ingested`
- `skipped`
- `missing`
- `empty`

### Lý do skip tối thiểu
- `manifest_marked_non_candidate`
- `file_not_found`
- `no_extractable_text`

## 11. Điểm xác nhận sau khi ingest

Sau mỗi batch, cần xác nhận nhanh:

| Điểm xác nhận | Câu hỏi kiểm tra |
| --- | --- |
| Đủ nguồn | đã đọc đúng manifest và schema chưa |
| Đúng phạm vi | chỉ ingest record candidate chưa |
| Đúng truy vết | mọi chunk có `source_file`, `project_code`, `ingest_batch` chưa |
| Đúng phân loại | `stage`, `package_label`, `document_type`, `version_role` đã normalize chưa |
| Đúng chất lượng | có file `empty`, `missing`, `unknown` cần xem lại không |
| Rerun an toàn | chạy lại có tránh chunk trùng không |
| Dùng được cho retrieval | nhóm hồ sơ anchor đã vào store chưa |

## 12. Rủi ro chính

| Rủi ro | Tác động | Cách kiểm soát |
| --- | --- | --- |
| Dùng raw metadata sai từ manifest | retrieval và readiness lệch | normalize trước khi upsert |
| Ingest nhầm file bìa hoặc file trùng | nhiễu kết quả truy hồi | loại theo `is_ingest_candidate`, override `exclude` |
| PDF scan text kém | chunk vô nghĩa, AI hiểu sai | gắn `requires_ocr`, rà soát file empty |
| Stage không thống nhất | khó lọc theo giai đoạn | map về allowed values của schema |
| Rerun sinh chunk trùng | store bẩn, khó audit | giữ chunk ID ổn định và `ingest_batch` rõ |
| File mơ hồ vẫn ingest như hồ sơ chính | retrieval sai trọng số | gắn `confidence_note`, `version_role = unknown`, hạ vai trò xuống `optional` |

## 13. Kết luận ngắn

Cách làm nên bám 3 nguyên tắc:

- manifest quyết định phạm vi ingest
- lớp normalize quyết định metadata chuẩn
- summary quyết định khả năng kiểm tra và rerun

Nếu giữ đúng ba điểm này, ingest Kênh Xây sẽ phù hợp với hai luồng ưu tiên của DSCons:
- hồ sơ công trình
- manifest và gap analysis làm lớp kiểm soát tri thức