Files
duocthu/docs/rag-chat.md
T
VuQuangBao 454edfa492 Document the 2 known RAG gaps instead of leaving them unwritten
Weight-based dosing and multi-drug comparison were measured live and
recorded as fixtures (known_gaps.jsonl) but never showed up in the
canonical docs describing chat capabilities.
2026-08-25 17:31:16 +07:00

82 lines
4.4 KiB
Markdown

# Pipeline RAG và chat
> Loại chính: Explanation
> Đối tượng: backend/RAG engineer
## Một lượt hỏi diễn ra thế nào
1. Browser gửi message tới Next.js BFF `/api/chat`.
2. BFF tạo/chuyển correlation ID và gọi `POST /v1/rag/query`.
3. Query understanding xác định scope, intent, drug candidates, thuộc tính, route
và dữ kiện lâm sàng còn thiếu.
4. Deterministic guard chặn câu ngoài phạm vi hoặc yêu cầu làm rõ trước retrieval.
5. Router chọn đường drug + section, overview similarity hoặc condition → drug.
6. Retrieval lấy chunks, hydrate context và tạo evidence có provenance.
7. Evidence policy quyết định đủ bằng chứng, cần xem PDF hay phải abstain.
8. Generator tạo claims có source IDs khi generation được bật.
9. Validator kiểm tra citation, con số, semantic support và completeness; có repair
có giới hạn, sau đó fail closed nếu vẫn sai.
10. Backend ghi trace/hội thoại, trả decision/reason/answer/citations; BFF map sang DTO UI.
## Retrieval routes
Khi drug và section đã rõ, filter payload theo `drug_id` + `section_key` được ưu
tiên để tránh chunk gần nghĩa của thuốc khác. Similarity search dùng cho overview
hoặc khi section chưa rõ. Rerank mặc định tắt và chỉ áp dụng trên đường
similarity/overview, không áp dụng route section chính xác.
Câu hỏi condition → drug thử keyword trước, chỉ fallback dense khi không có
candidate keyword. Candidate phải tiếp tục được kiểm tra indication và safety;
retrieval match không được biến thành khuyến cáo điều trị.
## Decision
| Decision | Ý nghĩa |
|---|---|
| `answerable` | có answer đã vượt qua các cổng kiểm tra |
| `clarify` | thiếu dữ kiện; có thể kèm quick replies |
| `verify_pdf` | đã có evidence nhưng nguồn bảng/công thức cần đối chiếu PDF |
| `abstain` | không phát hành nội dung chuyên môn cho lượt này |
## Conversation state
Conversation turns được lưu PostgreSQL theo `conversation_id` và dùng lại trong
multi-turn. Store hoạt động fail-open để lỗi history không làm sập toàn bộ query.
Một phần state chống clarify loop nằm trong process; đây chưa phải state phân tán
bền vững giữa nhiều replica. Circuit breaker dừng chuỗi clarify không hội tụ.
## Lịch sử truy vấn & duyệt chuyên luận
`conversation_id` là session id sinh phía client và giữ trong `localStorage`
của `apps/web` (không phải server session — hệ thống chưa có auth). `GET
/v1/rag/history` liệt kê lại các truy vấn cũ của đúng session đó cho Sidebar,
để bấm lại một câu hỏi cũ; answer prose không được lưu nên đây là re-run, không
phải replay.
`response_mode: "monograph"` là lối đi song song với hỏi-đáp AI: bỏ qua
generation/grounding, cho người dùng tự chọn section rồi đọc verbatim qua
`GET /v1/rag/sections` + `/section-text`. Hữu ích khi cần đối chiếu nguyên văn
thay vì câu trả lời tổng hợp.
## Output cho UI
Response mang business `trace_id`, `correlation_id`, `otel_trace_id`, decision,
reason, answer, resolved drug, citations, blocks, answer plan, candidate assessments,
quick replies và disclaimer cố định. Citation giữ chunk, printed page, physical page,
source crop/attachment và thông tin drug/section/source document.
## Giới hạn đã biết
Hai năng lực dưới đây **chưa có code path**, đo trực tiếp qua live query (không
suy đoán) và ghi lại làm fixture tại `apps/ai-service/evals/known_gaps.jsonl` để
tái kiểm chứng thay vì chỉ dựa trên tuyên bố:
- **Tính liều theo cân nặng.** `rag/calculators.py::body_surface_area_m2()` tồn
tại nhưng không được `agent.py` gọi trên đường xử lý thật — hỏi liều theo cân
nặng vẫn quay lại hỏi tuổi thay vì tính ra số.
- **So sánh nhiều thuốc.** Không có `turn_type` hay đường xử lý riêng cho so
sánh thuộc tính giữa 2+ thuốc; đường 2-thuốc duy nhất hiện có
(`agent.py::_interaction`) chỉ xử lý tương tác thuốc-thuốc, không tổng quát
hoá được. Hệ thống trả lời trung thực "chưa đủ cơ sở" thay vì bịa bảng so sánh.