Add read-only production runtime audit

This commit is contained in:
2026-08-17 11:17:40 +07:00
parent 057d4ed9dc
commit a1de4715a4
106 changed files with 6869 additions and 1782 deletions
@@ -0,0 +1,92 @@
# Vì sao hệ thống dùng structured RAG thay vì dense search thuần
## Phân loại
**Loại tài liệu:** Explanation.
**Reader job:** hiểu mental model, lựa chọn thiết kế và trade-off của pipeline.
## Vấn đề
Dược thư không phải một tập đoạn văn đồng nhất. Mỗi thuốc có các section mang
quan hệ khác nhau: chỉ định, chống chỉ định, thận trọng, liều và tương tác. Hai
section có thể dùng cùng từ vựng nhưng trả lời hai câu hỏi đối nghịch. Nếu để
vector similarity tự chọn section, đoạn lớn và giàu từ chung dễ trở thành
“attractor” dù không đúng quan hệ mà người dùng hỏi.
Đo đạc lịch sử của dự án cho dense-only cho hit@1 `0,544`; riêng câu hỏi chống
chỉ định chỉ đạt `0,05`. Vì vậy similarity không đủ tư cách quyết định phần nào
của sách là nguồn sự thật.
## Mental model
Hãy xem pipeline như ba lớp quyền hạn:
```text
Understanding xác định người dùng đang hỏi gì
Retrieval quyết định evidence nào được phép dùng
Generation chỉ quyết định evidence được trình bày ra sao
```
LLM không được chọn tùy ý một thuốc trong toàn catalog và không được bổ sung kiến
thức y khoa ngoài evidence. Candidate thuốc được giới hạn trước; section được
validate theo closed vocabulary; claim cuối phải trỏ lại đúng evidence.
## Cách retrieval hoạt động
### Biết thuốc và section
Qdrant `scroll` theo payload `drug_id + section_key`, lấy toàn bộ section và sắp
theo `part_index`. Đây là exact lookup, không phải similarity search.
### Biết thuốc nhưng câu hỏi tự do
Hệ thống lấy các section của thuốc, rerank rồi đóng gói evidence trong token
budget. Reranker chỉ sắp thứ tự; lỗi reranker không được làm mất size bound.
### Biết condition nhưng chưa biết thuốc
Hệ thống tìm trong `chi_dinh`: phrase match chính xác trước, dense fallback sau.
Candidate được nhóm theo thuốc và bị giới hạn trước generation. Kết quả là danh
sách factual theo Dược thư, không phải ranking điều trị.
## Safety model sau retrieval
Một evidence pool chỉ được đi tiếp khi:
- có source reference;
- có printed-page provenance;
- không chứa block buộc phải xem ảnh PDF.
Generation trả structured claims. Code kiểm tra citation và số theo từng block;
một LLM judge khác kiểm tra entailment. Failure ở bất kỳ gate nào dẫn đến
abstain hoặc `VERIFY_PDF`, không dẫn đến một câu trả lời “gần đúng”.
## Trade-off
| Lựa chọn | Điểm mạnh | Chi phí |
|---|---|---|
| Exact section routing | Đúng quan hệ, lấy đủ section | Phụ thuộc query understanding và metadata tốt |
| Dense search | Bắt được paraphrase | Luôn trả nearest neighbours, kể cả query vô nghĩa |
| Rerank | Chọn evidence tốt trong một thuốc | Thêm latency/cost; chỉ là ordering aid |
| Quarantine bảng/công thức | Không bịa số từ cấu trúc 2D sai | Một số câu hỏi phải yêu cầu xem PDF |
| Grounding + entailment | Claim có thể audit | Nhiều provider calls và fail-closed nhiều hơn |
## Hệ quả
- Không gọi runtime hiện tại là BM25 hoặc hybrid RRF; các module liên quan chưa
tạo thành live hybrid pipeline.
- Không diễn giải “không tìm thấy” thành “không có” hoặc “an toàn”.
- Không so score `1.0` của exact section lookup với cosine score; chúng khác bản
chất.
- Mở rộng corpus phải bảo toàn section metadata và provenance, không chỉ thêm
vector.
## Liên quan
- [Retrieval pipeline](../09-retrieval-pipeline.md)
- [Generation and grounding](../11-generation-and-grounding.md)
- [Document model and chunking](../06-document-model-and-chunking.md)
- [Known limitations](../26-known-limitations.md)