Files
duocthu/docs-legacy/bao-cao-kiem-ke-tinh-nang-va-trien-khai-2026-08-13.md
T

45 KiB
Raw Blame History

BÁO CÁO KIỂM KÊ TÍNH NĂNG VÀ TRIỂN KHAI

Nền tảng chatbot RAG Dược thư Quốc gia Việt Nam 2018

Thuộc tính Giá trị
Dự án VSF-DUOCTHU
Kỳ báo cáo 30/07/202613/08/2026
Ngày chốt kiểm kê 13/08/2026
Đối tượng trình bày Quản lý kỹ thuật, quản lý sản phẩm, hội đồng đánh giá
Phạm vi Source code, dữ liệu đã xử lý, kiểm thử, CI/CD, hạ tầng và vận hành
Trạng thái Git tại thời điểm kiểm kê 88 commit trong kỳ; 413 file được Git theo dõi
Tác giả commit trong kỳ BaoVu2k4

1. Mục đích báo cáo

Báo cáo này trả lời năm câu hỏi quản trị:

  1. Hệ thống hiện giải quyết bài toán gì và dành cho ai?
  2. Những tính năng nào đã được triển khai trong code và đang nằm trên đường runtime?
  3. Hệ thống được đưa từ PDF nguồn đến chatbot và production bằng cách nào?
  4. Bằng chứng nào cho thấy các thành phần đang hoạt động?
  5. Những giới hạn, rủi ro và hạng mục tiếp theo là gì?

Báo cáo chủ động phân biệt bốn trạng thái để tránh báo cáo vượt quá thực tế:

Nhãn Ý nghĩa
Đang dùng trên runtime Có wiring từ entrypoint tới implementation và có test hoặc bằng chứng vận hành
Đã triển khai trong code Có implementation và test, nhưng có thể cần cấu hình hoặc chưa có bằng chứng production đầy đủ
Deployment kit Có manifest/workflow phục vụ triển khai, nhưng chưa được chứng minh đã áp dụng vào môi trường đích
Chưa hoạt động Mới là scaffold, thử nghiệm, dead code hoặc kế hoạch

Nguồn sự thật ưu tiên theo thứ tự: code tại Git HEAD → workflow/config đang được runtime dùng → test chạy lại tại ngày kiểm kê → handoff/progress log có bằng chứng → tài liệu kế hoạch.


2. Tóm tắt điều hành

Trong hai tuần, dự án được xây dựng lại từ đầu và đi từ monorepo scaffold đến một nền tảng RAG có thể phục vụ tra cứu Dược thư bằng hội thoại. Các kết quả chính:

  • Xây dựng pipeline PDF deterministic cho Dược thư 1.668 trang.
  • Phân đoạn 684 chuyên luận thuộc Part 2 của sách.
  • Tạo và nạp 15.100 chunks vào Qdrant collection duocthu_v1.
  • Xây dựng FastAPI AI service với query understanding, retrieval, generation, grounding, citation, abstention và multi-turn.
  • Xây dựng Next.js web chat với evidence panel, PDF deep-link và feedback.
  • Bổ sung luồng condition/disease → medication dựa riêng trên mục Chỉ định.
  • Container hóa toàn bộ runtime bằng Docker Compose và Caddy HTTPS.
  • Bổ sung Prometheus, Grafana, Tempo và OpenTelemetry.
  • Bổ sung CI, deploy, rollback và Qdrant snapshot migration workflow.
  • Xây dựng Helm chart làm migration kit cho Kubernetes/ArgoCD.

Theo hồ sơ trong repository, hệ thống đã được triển khai trên một EC2 cá nhân tại https://realvuxbaro.me. Báo cáo này không thực hiện kiểm tra trực tiếp website tại thời điểm lập báo cáo, do đó đây là trạng thái được xác nhận từ workflow và handoff đã lưu trong repository, không phải một uptime attestation tại ngày 13/08.

Kết quả kiểm tra lại trên workspace ngày 13/08:

Hạng mục Kết quả
AI service pytest 278 passed, 6 skipped
Ingestion pytest 277 passed, 12 skipped
Tổng Python test pass 555
Frontend ESLint 0 warning, 0 error
Frontend unit/component test Chưa có

3. Bài toán, người dùng và ranh giới sản phẩm

3.1 Bài toán

Dược thư Quốc gia Việt Nam 2018 là tài liệu khoảng 1.668 trang. Nội dung thuốc được tổ chức theo chuyên luận và các mục cố định như chỉ định, chống chỉ định, thận trọng, liều dùng, tương tác và phản ứng có hại. Việc tra cứu thủ công chậm và dễ bỏ sót mục liên quan.

Hệ thống cung cấp giao diện hội thoại tiếng Việt để:

  • Xác định thuốc và mục thông tin người dùng cần tra.
  • Truy xuất đoạn nguồn từ Dược thư.
  • Trình bày lại câu trả lời với citation tới đúng trang và đoạn bằng chứng.
  • Từ chối hoặc yêu cầu đối chiếu PDF nếu bằng chứng không đủ an toàn.

3.2 Người dùng mục tiêu

  • Bác sĩ.
  • Dược sĩ.
  • Nhân sự chuyên môn cần tra cứu nội dung Dược thư.

UI và prompt giữ thuật ngữ chuyên môn, không chủ động đơn giản hóa thành hướng dẫn tự điều trị cho người phổ thông.

3.3 Phạm vi hiện tại

Đang hỗ trợ:

  • 684 chuyên luận thuốc thuộc Part 2, trang in 991496.
  • Tra cứu theo thuốc và theo mục.
  • Tương tác hai thuốc.
  • Một số câu hỏi condition → medication có bằng chứng ở mục Chỉ định.
  • Context bệnh nhân có cấu trúc để cảnh báo hoặc yêu cầu thêm dữ kiện.

Không hỗ trợ hoặc không tuyên bố hỗ trợ:

  • Part 1: chương nguyên tắc, đối tượng đặc biệt, ngộ độc và nội dung tổng quan.
  • Part 3: phụ lục BSA, tương hợp thuốc tiêm, ATC index.
  • Kê đơn, xếp hạng thuốc hoặc khuyến cáo first-line.
  • Reverse lookup “thuốc nào gây X” hoặc “thuốc nào chống chỉ định trong X”.
  • Tính liều tự động.
  • Thú y hoặc chủ thể không phải người.
  • Đọc tự động số liệu từ bảng/công thức 2D đã bị quarantine.

4. Kiến trúc tổng thể

flowchart LR
    U[Người dùng chuyên môn] -->|HTTPS| C[Caddy]
    C --> W[Next.js Web/BFF]
    W -->|POST /v1/rag/query| A[FastAPI AI Service]
    A --> Q[(Qdrant 15.100 chunks)]
    A --> P[(PostgreSQL)]
    A --> B[AWS Bedrock]
    A --> M[Prometheus metrics]
    A --> O[OTel Collector]
    O --> T[Tempo]
    M --> G[Grafana]
    T --> G
    PDF[Dược thư PDF] --> I[Offline ingestion]
    I --> Q

4.1 Thành phần runtime

Thành phần Công nghệ Trạng thái Trách nhiệm
apps/web Next.js 14, React 18, TypeScript Đang dùng Chat UI, BFF, PDF route, feedback route, rate limit
apps/ai-service Python, FastAPI Đang dùng Query understanding, orchestration, retrieval, generation, grounding, traces
Qdrant Qdrant v1.19.0 ở chart Đang dùng Vector và payload corpus
PostgreSQL PostgreSQL 16 Đang dùng Retrieval trace, conversation turn, correlation và feedback
AWS Bedrock Cohere embedding/rerank, Converse model Đang dùng khi provider bật Query embedding, hiểu câu hỏi, sinh và kiểm tra câu trả lời
Caddy Caddy 2 Đang dùng theo production config Reverse proxy và TLS
Prometheus Prometheus Đã triển khai trong config Metrics và PromQL
Tempo Grafana Tempo Đã triển khai trong config Distributed trace
Grafana Grafana Đã triển khai trong config Dashboard và Explore
OTel Collector OpenTelemetry Collector Đã triển khai trong config Nhận và export span

4.2 Thành phần chưa xây dựng

Các thư mục sau chỉ có README.mdpackage.json tối thiểu, không có source runtime:

  • apps/api-gateway.
  • apps/auth-service.
  • apps/user-service.
  • apps/chat-service.
  • apps/mobile.

Vì vậy web hiện gọi trực tiếp AI service và không có authentication/authorization.


5. Kiểm kê pipeline dữ liệu và ingestion

5.1 Nguồn dữ liệu

  • PDF: Dược thư Quốc gia Việt Nam 2018.
  • Số trang vật lý: 1.668.
  • Phạm vi chuyên luận được ingest: Part 2.
  • Số chuyên luận runtime: 684.
  • Artifact verified gồm danh mục thuốc, formula regions và outlined-text transcriptions.

5.2 Luồng xử lý

flowchart TD
    PDF[PDF nguồn] --> PM[Page map]
    PDF --> SP[Extract spans]
    SP --> GO[Glyph/reading-order scan]
    SP --> VT[Merge vector-outlined transcriptions]
    PDF --> TB[Detect/lift table regions]
    PDF --> FR[Verified 2D formula regions]
    VT --> SG[Segment monographs/sections]
    TB --> SG
    FR --> SG
    SG --> CK[Section-aware chunking]
    CK --> RD[Readiness and coverage gates]
    RD --> EM[Embedding]
    EM --> Q[Qdrant upsert]
    Q --> MF[Manifest sidecar]

5.3 Extraction và sửa lỗi PDF

Đang dùng trong pipeline:

  • PyMuPDF span extraction.
  • Page map giữa trang vật lý và trang in.
  • Kiểm tra glyph order và reading order.
  • Merge lại 51 text runs chỉ tồn tại dưới dạng vector outline.
  • Tách table/formula region khỏi prose trước khi phân đoạn.
  • Giữ bbox và page provenance.

Nguyên tắc an toàn:

  • Không tự sửa vùng công thức 2D chỉ dựa trên thứ tự text extraction.
  • Không biến bảng không chắc chắn thành prose giả.
  • Region không thể tái tạo đáng tin được đánh dấu quarantine.
  • Quarantined block vẫn được gắn với chunk để UI chỉ người dùng tới ảnh/PDF gốc.

5.4 Phân đoạn chuyên luận

Pipeline xử lý:

  • Tiêu đề chuyên luận nhiều dòng.
  • Chuyên luận nhóm có nhiều mã ATC.
  • Mã ATC có khoảng trắng hoặc nhầm O/0 từ PDF.
  • Part divider không được coi nhầm thành tên thuốc.
  • Section vocabulary và section order.
  • Đơn vị và chuỗi liều dùng nhạy cảm.
  • Duplicate drug ID là lỗi chặn, không silently overwrite.

5.5 Chunking

  • Chunk theo ranh giới section thay vì chia đều toàn văn bản.
  • Có token estimate và oversized detection.
  • Có chunk kind riêng cho prose và block descriptor.
  • Prose chunk có thể tham chiếu attachment table/formula.
  • Citation giữ trang in, trang vật lý, bbox và block ID.
  • Context header của bảng có thể được gắn khi chunk liên quan.

5.6 Validation gates

Các công cụ validation hiện có:

  • Back-index recall/precision.
  • Span-level coverage ledger.
  • Residual-ink scan.
  • Table/formula region audit.
  • Chunk readiness metrics.
  • Clinical readiness checks.
  • Token and oversized chunk checks.
  • Golden/scaffold utilities ở các mức hoàn thiện khác nhau.

Một số CLI được khai báo nhưng tài liệu trong code vẫn ghi chưa hoàn thiện hoàn toàn; do đó không được mô tả toàn bộ validation CLI là production-complete.

5.7 Embedding và load

  • Adapter Cohere embeddings qua AWS Bedrock.
  • Vector dimension: 1.024.
  • Qdrant collection: duocthu_v1.
  • Số points theo README/handoff: 15.100.
  • Upsert có batch và repository abstraction.
  • Payload index được định nghĩa theo schema corpus.
  • Manifest sidecar lưu corpus hash/model/dimension.
  • AI service kiểm manifest lúc startup và từ chối chạy nếu mismatch.

Giá trị kỹ thuật: Qdrant có thể trả kết quả bình thường dù corpus được embed bằng model khác; manifest check biến lỗi chất lượng âm thầm thành lỗi startup rõ ràng.


6. Kiểm kê query understanding và orchestration

6.1 Query understanding

Đang dùng trên runtime khi generator được cấu hình:

  • Chuẩn hóa câu hỏi thành structured frame.
  • Xác định subject scope.
  • Xác định intent và turn type.
  • Xác định tên thuốc hoặc condition.
  • Xác định section/facet cần tra.
  • Nhận biết population, route, age, weight và context phụ thuộc turn trước.
  • Tạo standalone query cho follow-up.
  • Sinh clarification khi thiếu dữ kiện.

6.2 Entity resolution và autocomplete

  • Danh mục 684 thuốc và hơn 10.000 alias theo tài liệu hiện tại.
  • Catalog được nạp từ drug_entities.json.
  • Candidate gửi vào LLM được giới hạn deterministic.
  • Canonical name luôn được ưu tiên để tránh danh sách alias toàn biệt dược khó nhận biết.
  • Autocomplete chạy local/deterministic, không gọi model.
  • Autocomplete khớp token đang gõ thay vì toàn bộ câu.

6.3 Multi-turn

  • conversation_id tối đa 128 ký tự.
  • Raw turns được lưu trong PostgreSQL.
  • Structured prior frame và clarify streak hiện vẫn giữ trong memory process.
  • Follow-up có thể kế thừa thuốc hoặc field đã trả lời ở turn trước.
  • Clarify loop circuit breaker dừng vòng hỏi lặp vô hạn.

Giới hạn: structured frame không được chia sẻ giữa nhiều replica; scale ngang có thể làm chất lượng multi-turn không ổn định.

6.4 Routing

Các nhóm routing chính:

  • Drug overview.
  • Drug attribute/section lookup.
  • Dosage-related query.
  • Two-drug interaction.
  • Condition → drug indication lookup.
  • Condition relation không được hỗ trợ.
  • Out-of-scope hoặc non-human.
  • Clarification khi thiếu thuốc hoặc dữ kiện lâm sàng.

6.5 Request budget

  • Mặc định tối đa 40.000 ms wall-clock ở backend.
  • Mặc định tối đa 8 LLM calls/turn.
  • Provider timeout/retry được kiểm soát.
  • Bedrock read timeout riêng có retry cho lỗi đọc cô lập.
  • Reason code phân biệt hết budget, provider outage, malformed output và lỗi nội dung.

7. Kiểm kê retrieval

7.1 Section retrieval

  • Khi biết đúng thuốc và section, retrieval dùng Qdrant payload filter.
  • Không phụ thuộc hoàn toàn vào vector similarity cho câu hỏi section rõ ràng.
  • Section resolver chuẩn hóa các cách hỏi tiếng Việt.
  • Rerank không chạy trên section route vì section route đã deterministic.

7.2 Similarity/overview retrieval

  • Query embedding bằng Cohere qua Bedrock.
  • Dense vector search trên Qdrant.
  • Rerank tùy cấu hình bằng Cohere reranker.
  • Token-budget packing chọn evidence vừa context.
  • Có fallback overview/rerank.

7.3 Lexical retrieval

  • Có lexical search dùng token match và Python re-scoring.
  • Đây không phải BM25 hoàn chỉnh: chưa có IDF, term frequency hoặc length normalization chuẩn.
  • Hiệu lực của MatchText phụ thuộc full-text index của payload field; cần tiếp tục xác minh collection đang deploy.

7.4 Parent/child và neighbour pooling

  • Có parent store/hydration abstraction.
  • Corpus hiện không phát parent_id, nên parent hydration hầu như không tạo năng lực thực tế.
  • Section-neighbour pooling hiện chỉ được mở có giới hạn cho một số trường hợp như thận trọng.

7.5 Module có code nhưng chưa nối runtime

  • rag/fusion.py: Reciprocal Rank Fusion.
  • rag/expansion.py: query/sibling expansion.
  • rag/calculators.py: DuBois body-surface-area calculator.

Các module này có test nhưng không có runtime caller; không được báo cáo là tính năng người dùng đang sử dụng.


8. Kiểm kê generation, grounding và guardrails

8.1 Provider modes

AI service hỗ trợ các cấu hình:

  • disabled: không có conversational agent/generation.
  • stub: local test không gọi cloud.
  • bedrock-claude.
  • bedrock-converse.

Model ID là cấu hình; code default hiện là deepseek.v3.2, nhưng model production thực tế phụ thuộc environment ngoài Git.

8.2 Structured answer contract

Thay vì model trả prose tự do có marker [n], response nội bộ gồm:

  • Answer plan.
  • Answer blocks.
  • Claims.
  • source_ids theo từng claim.
  • Candidate assessments khi là condition → medication.

UI hiển thị cấu trúc đã được backend xác minh; không tự parse semantics từ prose.

8.3 Numeric grounding

  • Mọi số trong claim phải có trong evidence thực.
  • Không dùng “global number pool” để cho phép số từ evidence không được citation.
  • Số phải thuộc evidence mà claim tham chiếu.
  • Sai số liệu dẫn tới ungrounded_number và câu trả lời bị hủy.

8.4 Citation validation

  • Citation index/chunk ID phải tồn tại.
  • Claim không có citation bị hủy.
  • Citation phải trỏ tới đúng evidence.
  • Với condition → medication, citation phải thuộc đúng thuốc của claim.
  • Thuốc ngoài candidate set retrieval bị hủy bằng unsupported_drug.

8.5 Entailment và completeness

  • Có một LLM entailment pass kiểm ngữ nghĩa phi số.
  • Có completeness check/repair cho câu trả lời thiếu dữ kiện liên quan.
  • Provider outage không còn bị báo nhầm thành “nội dung không được nguồn hỗ trợ”.
  • Một entailment pass không phải bằng chứng hoàn hảo; accuracy của judge chưa có benchmark committed đầy đủ.

8.6 Abstention

Các nhóm lý do từ chối:

  • Không resolve được thuốc.
  • Câu hỏi mơ hồ.
  • Ngoài phạm vi hoặc non-human.
  • Xin khuyến nghị điều trị.
  • Retrieval score không đủ.
  • Thiếu provenance.
  • Bảng/công thức cần kiểm tra PDF.
  • Provider unavailable.
  • Hết request budget.
  • Invalid citation/uncited claim.
  • Unsupported claim/drug.
  • Incomplete answer.

BFF có bản đồ thông báo tiếng Việt riêng cho reason code, tránh biến mọi lỗi thành “không có dữ liệu trong Dược thư”.

8.7 Prompt injection và disclaimer

  • User text được đặt trong fenced region.
  • Marker có thể bị người dùng chèn vào được loại bỏ trước khi tạo prompt.
  • System prompt quy định vùng này là dữ liệu, không phải chỉ thị.
  • Output grounding vẫn là lớp bảo vệ chính.
  • Disclaimer là chuỗi cố định từ backend, không do model tạo.
  • BFF có fallback disclaimer để version skew không làm response y khoa mất cảnh báo.

9. Condition/disease → medication

9.1 Mục tiêu

Mở rộng chatbot từ “biết tên thuốc rồi tra thông tin” sang “condition nào có thuốc được Dược thư ghi chỉ định”. Đây là factual evidence lookup, không phải recommendation engine.

9.2 Luồng retrieval

flowchart TD
    Q[Condition query] --> N[Normalize condition/relation]
    N --> A{Mơ hồ đáng kể?}
    A -->|Có| C[Clarify subtype]
    A -->|Không| L[Lexical search trong chi_dinh]
    L -->|Không đủ| D[Dense fallback trong chi_dinh]
    L --> GR[Group theo drug_id]
    D --> GR
    GR --> CAP[Rank/cap drug candidates]
    CAP --> PC{Có patient context?}
    PC -->|Không| G[Grounded list]
    PC -->|Có| S[Safety second stage]
    S --> G

9.3 Safety second stage

Khi query có dữ kiện bệnh nhân, hệ thống có thể kiểm top candidates theo:

  • Thuốc đang dùng và interaction evidence.
  • Contraindication/precaution.
  • Renal/hepatic context.
  • Thai kỳ/cho con bú.
  • Tuổi và cân nặng.
  • Dị ứng/ADR trước đó.

Status có thể gồm:

  • Supported.
  • Supported with caution.
  • Requires additional information.
  • Insufficient evidence.

Hệ thống không tự kết luận “contraindicated” chỉ từ lexical hit và không tự tạo dose adjustment không có trong corpus.

9.4 Evaluation status

  • condition_to_drug_v1.jsonl: 20 case trọng tâm.
  • production_manual_60.jsonl: 60 case manual battery.
  • Theo handoff, 20/20 case unique đầu tiên đã pass sau fix.
  • 40 case còn lại chưa được chạy ở thời điểm handoff.
  • Có deploy smoke hỏi về đợt gout cấp và yêu cầu decision=answerable cùng citation section_key=chi_dinh.

Không nên tuyên bố feature đạt production-quality toàn diện trước khi chạy đủ battery và có baseline lưu được.


10. Kiểm kê API

10.1 FastAPI endpoints

Method Endpoint Chức năng Trạng thái
GET /health Liveness Đang dùng
GET /ready Readiness Đang dùng
GET /metrics OpenMetrics, bearer token tùy chọn Đang dùng khi metrics bật
POST /v1/rag/query Query RAG/conversation Đang dùng
GET /v1/rag/suggest Drug autocomplete Đang dùng
POST /v1/rag/feedback Lưu rating/comment theo trace Đang dùng

10.2 Query request contract

  • query: 14.000 ký tự.
  • subject_scope: enum.
  • intent: enum.
  • conversation_id: tùy chọn, tối đa 128 ký tự.

10.3 Query response contract

Response có:

  • trace_id, correlation_id, otel_trace_id.
  • decision, reason.
  • answer, resolved_drug_id.
  • citations với chunk/page/bbox/evidence/drug/section.
  • generated phân biệt paraphrase đã verify và extractive.
  • quick_replies.
  • Structured blocksanswer_plan.
  • candidate_assessments.
  • disclaimer trên mọi decision.

10.4 Web BFF routes

Method Route Chức năng
POST /api/chat Validate input, correlation, gọi AI service và map DTO
GET /api/suggest Proxy autocomplete
POST /api/feedback Proxy feedback
GET /api/pdf Phục vụ PDF nguồn cho citation viewer

11. Kiểm kê frontend

11.1 Màn hình

  • /: chat workspace.
  • /tra-cuu: split view chat/PDF phục vụ đối chiếu nguồn.

11.2 Thành phần chính

  • Sidebar phiên tra cứu.
  • Chat panel.
  • Composer.
  • Prompt/quick-reply chips.
  • Evidence panel.
  • Citation cards.
  • Citation beam overlay.
  • Disclaimer banner.
  • Answer feedback.
  • Theme context/selector.

11.3 Citation experience

  • Citation được group theo chunk để không hiện trùng prose và attachment ref.
  • Evidence card hiển thị thuốc, section, trang và exact retrieved text.
  • Attachment giữ trang vật lý riêng khi bảng nằm ở trang khác prose.
  • Quarantined content có cảnh báo và link tới PDF gốc.
  • Click citation của message cũ dùng đúng citation array của message đó.

11.4 Reliability fixes

  • Không mất message khi đổi session.
  • Abort/disconnect từ browser được propagate lên BFF fetch.
  • Client timeout được điều chỉnh để không hủy response tốt khi backend còn trong budget.
  • Refusal messages ánh xạ reason code cụ thể.
  • Version skew vẫn giữ disclaimer.

11.5 Rate limiting

Route Giới hạn hiện tại
/api/chat 12/phút và 120/giờ/IP
/api/suggest 120/phút/IP
/api/pdf 30/phút/IP
/api/feedback 60/phút/IP

Rate limit lưu trong memory của một web process. Đây là cost/abuse guard, không phải security control; scale nhiều replica cần Redis hoặc gateway.


12. Persistence và audit trail

12.1 PostgreSQL migrations

Migration Nội dung
001_rag_retrieval_trace.sql Retrieval trace
002_rag_conversation_turn.sql Conversation history
003_rag_trace_correlation.sql Correlation và OTel trace ID
004_rag_answer_feedback.sql Answer feedback

12.2 Retrieval trace

Trace lưu các trường phục vụ audit như:

  • Query.
  • Resolved drug.
  • Decision/reason.
  • Citation/evidence.
  • Correlation ID.
  • OpenTelemetry trace ID.

12.3 Conversation history

  • Lưu raw turn trong PostgreSQL.
  • Query understanding có thể đọc recent turns.
  • Trace/history persistence fail-open: lỗi DB không nhất thiết chặn câu trả lời.

12.4 Feedback

  • Rating: helpful hoặc not_helpful.
  • Comment tối đa 2.000 ký tự.
  • Upsert theo trace.
  • Theo handoff, production feedback smoke đã lưu thành công một bản ghi.

12.5 Giới hạn dữ liệu

  • Chưa có retention/deletion policy.
  • Chưa có redaction PII/patient context.
  • Chưa có conversation ownership.
  • PostgreSQL connection mở theo call, chưa có pool.

13. Observability

13.1 Metrics

Prometheus exporter theo dõi:

  • Request count và latency.
  • Duration từng RAG stage.
  • Routing decisions/reasons.
  • Provider failures.
  • Trace write failures.
  • Grounding/answer domain counters.

13.2 Tracing

OpenTelemetry trace bao phủ:

  • Receive.
  • Understanding.
  • Routing.
  • Retrieval.
  • Rerank/evidence.
  • Generation.
  • Grounding/entailment.
  • Persistence.
  • Response.

Correlation và trace ID đi từ BFF tới AI service và PostgreSQL.

13.3 Grafana/Tempo

  • Prometheus datasource được provision.
  • Tempo datasource được provision.
  • Dashboard duocthu-observability được provision.
  • Grafana có thể truy cập theo đường /grafana/ trong Caddy config production.
  • Prometheus không được expose public theo thiết kế.

13.4 Ba lớp provenance

  1. UI citation/evidence panel: người dùng thấy nguồn đã chọn.
  2. Tempo trace: kỹ sư thấy stage nào đã chạy và mất bao lâu.
  3. PostgreSQL trace: audit record bền và có thể join theo trace ID.

Hệ thống không lưu chain-of-thought; không đưa patient text vào metric labels/span names.

13.5 Khoảng trống observability

  • Chưa Alertmanager/alert rules.
  • Chưa log aggregation.
  • Web chưa được instrument đầy đủ.
  • Chưa có SLO/error budget.
  • Một số metric cũ được đăng ký nhưng không increment.

14. Security và safety

14.1 Đã có

  • HTTPS qua Caddy.
  • Bedrock dùng EC2 IAM instance role, không cần long-lived AWS key trên host.
  • Input length validation.
  • Rate limit tại web middleware.
  • Prompt injection fencing.
  • Numeric/citation/entailment guardrails.
  • Optional bearer token cho /metrics.
  • Grafana anonymous access tắt ở production overlay.
  • Prometheus/Grafana native ports có thể chỉ bind loopback.
  • Secret có thể lấy từ GitHub Actions/Kubernetes Secret.

14.2 Chưa có

  • Authentication.
  • Authorization/RBAC.
  • Per-user session ownership.
  • API gateway thực.
  • NetworkPolicy cho Kubernetes.
  • Container securityContext/runAsNonRoot trong chart.
  • Dependency scanning/SBOM.
  • Security headers đầy đủ.
  • Secret rotation/retention runbook hoàn chỉnh.
  • Patient-data retention/redaction policy.

14.3 Rủi ro ưu tiên

  • Endpoint công khai có thể bị bất kỳ ai gọi.
  • conversation_id do client tự chọn và không có ownership check.
  • Một số default password trong Compose/Helm không phù hợp production mới.
  • Container image hiện chạy root.
  • In-memory rate limiting không bảo vệ khi scale nhiều replica.

15. Local development

15.1 Prerequisites

  • Python 3.11+.
  • Node.js 20 và pnpm.
  • Docker.
  • AWS credentials/IAM có quyền Bedrock nếu cần generation.
  • Corpus Qdrant đã load hoặc snapshot restore.

15.2 Khởi động datastore

docker compose -f infra\docker\docker-compose.yml up -d postgres qdrant

15.3 AI service

cd apps\ai-service
python -m migrate
python -m uvicorn main:app --port 8079

Không khuyến nghị --reload trên Windows trong dự án này vì đã quan sát trường hợp reloader phục vụ code cũ.

15.4 Web

corepack enable
pnpm install
pnpm --filter @duoc-thu/web dev

15.5 Observability local

docker compose -f infra\docker\docker-compose.yml up -d `
  prometheus tempo otel-collector grafana

15.6 Test

cd apps\ai-service
python -m pytest tests -q

cd ..\..\ingestion
python -m pytest tests -q

cd ..
corepack pnpm --filter @duoc-thu/web lint
corepack pnpm --filter @duoc-thu/web build

Integration tests cần datastore/provider live có thể skip theo điều kiện.


16. Production deployment hiện tại

16.1 Topology theo repository

  • Một EC2 t3.large tại us-east-1 theo handoff.
  • Docker Compose.
  • PostgreSQL named volume.
  • Qdrant named volume.
  • AI service container.
  • Web container.
  • Caddy reverse proxy/TLS.
  • Observability overlay.
  • AWS Bedrock qua instance role.

16.2 Deploy workflow

Trigger:

  • Push vào master với path thuộc runtime/deploy scope.
  • Manual workflow_dispatch.

Path filter bao gồm:

  • apps/ai-service/**.
  • apps/web/**.
  • packages/**.
  • ingestion/data/verified/drug_entities.json.
  • infra/docker/**.
  • Chính deploy.yml.

Docs-only push không còn tự redeploy production.

16.3 Các bước deploy

flowchart TD
    P[Push master] --> F[Path filter]
    F --> SSH[SSH EC2]
    SSH --> R[git fetch/reset target]
    R --> D[Docker Compose up -d --build]
    D --> C[Caddy validate/reload]
    C --> MIG[Run migrations]
    MIG --> H[Health/ready/web checks]
    H --> CS[Condition retrieval smoke]
    CS --> OBS[Prometheus/Tempo/Grafana checks]
    OBS --> TR[Generate and verify exact trace]

16.4 Post-deploy verification

  • AI service /health.
  • AI service /ready.
  • Web root.
  • Condition query phải answerable.
  • Citation phải có section_key=chi_dinh.
  • Prometheus ready.
  • Tempo ready với retry.
  • Grafana health/datasources/dashboard.
  • Public Grafana login route.
  • Tạo request có correlation ID.
  • Kiểm tra X-Trace-ID đúng 32 hex characters.
  • Xác minh metric xuất hiện trong Prometheus.
  • Xác minh trace đọc được trong Tempo.

16.5 Rollback

  • Workflow manual nhận target_sha.
  • Verify target là commit.
  • Reset/rebuild về target.
  • Chạy lại migrations idempotent hiện có.
  • Verify health và Grafana.

Giới hạn: rollback không tự động khi deploy fail; image được build lại trên host, không phải immutable artifact. Migration chưa có down migration.

16.6 Qdrant snapshot migration

  • Workflow one-off tạo snapshot production.
  • Download qua Qdrant HTTP API.
  • Chuyển snapshot thành GitHub artifact/thực hiện bridge sang practice environment.
  • Ghi nhận Qdrant version trước snapshot.
  • Tránh re-embed và chi phí Bedrock.

17. CI/CD

17.1 CI workflow

Chạy trên mọi push và pull request:

Job Checks
AI service Ruff + pytest
Ingestion Pytest
Web Install lockfile + lint + production build

CI dùng concurrency cancel-in-progress theo branch/ref.

17.2 Điểm cần lưu ý

deploy.yml trigger độc lập với ci.yml; không có needs: nối deploy với CI. Vì vậy một push master có thể khởi chạy CI và deploy song song. Đây chưa phải “test gate trước production” theo nghĩa chặt.

Khuyến nghị ưu tiên cao:

  • Dùng reusable workflow hoặc workflow_run.
  • Chỉ deploy commit có CI success.
  • Build immutable images trong CI.
  • Tag theo commit SHA.
  • Push registry.
  • Rollback bằng image đã biết tốt thay vì rebuild.

18. Helm/Kubernetes/ArgoCD

18.1 Helm chart hiện có

Chart infra/helm/medical-chatbot chứa:

  • AI service Deployment/Service.
  • Web Deployment/Service.
  • PostgreSQL workload/storage.
  • Qdrant workload/storage.
  • Ingress.
  • Secret hoặc existing Secret.
  • ServiceAccount.
  • Prometheus, Tempo, OTel Collector, Grafana.
  • ServiceMonitor tùy chọn.

18.2 Khả năng cấu hình

  • Bật/tắt aiServiceweb.
  • Bật/tắt PostgreSQL, Qdrant và observability.
  • Dùng PostgreSQL ngoài release qua secret.postgresHost.
  • Dùng external Qdrant URL.
  • Cấu hình ENTITIES_PATH trong image.
  • Image/tag/pull policy theo môi trường.
  • Resource requests/limits.
  • Ingress/TLS.
  • Existing Kubernetes Secret cho staging/prod.

18.3 Trạng thái thật

Helm chart là deployment/migration kit, chưa có bằng chứng đã được apply thành công lên k3s/ArgoCD trong repository hiện tại.

Chart mặc định cũng chưa tự tạo corpus. Qdrant mới sẽ rỗng và AI service manifest check sẽ từ chối startup. Cần snapshot restore hoặc corpus-load Job trước khi chart có thể vận hành end-to-end.

18.4 Hạng mục trước khi apply

  • Registry và immutable image tags.
  • Corpus restore/load Job.
  • Secret management chuẩn.
  • Security context.
  • NetworkPolicy.
  • PodDisruptionBudget/HPA nếu cần.
  • Backup strategy.
  • Helm lint/template trong CI.
  • ArgoCD Application values và image promotion flow.

19. So sánh với dự án cũ D:\AITT_VSF

19.1 Những cải tiến thực sự

Lĩnh vực Dự án cũ Dự án mới
Ingestion Nhiều lỗi bảng/công thức/heading phát hiện muộn Rebuild với full-document survey, quarantine và readiness gates
Data safety Một số lỗi extraction có thể lọt vào corpus Residual-ink scan, vector transcription và VERIFY_PDF
Query experience Chủ yếu drug-centric Structured conversational understanding và multi-turn
Condition lookup Primitive/chưa tạo UX hoàn chỉnh Indication-only condition→drug với patient-context second stage
Answer contract Extractive/summary với validator Structured claimcitation, candidate-set guard, entailment/completeness
Production proof Workflow/Compose có nhưng trạng thái tài liệu không nhất quán Có handoff deploy, smoke, trace và observability production
Observability Chưa có stack end-to-end tương đương Metrics + tracing + dashboard + DB audit
Feedback Chưa có Feedback theo trace
Python tests Khoảng 197 test definitions ở HEAD cũ 555 test pass khi kiểm kê mới

19.2 Những điểm dự án cũ đang tốt hơn

  • Hybrid dense+sparse và RRF đã nằm trên đường retrieval cũ; dự án mới chưa nối RRF runtime.
  • BSA calculator cũ được route; calculator mới hiện là dead code.
  • Dự án cũ có frontend Vitest; dự án mới không có frontend tests.
  • CI cũ khai báo deploy needs backend/frontend; CI mới chưa gate deploy.
  • Dự án cũ có uv.lock; dự án mới chưa có Python lockfile.
  • Dự án cũ hướng đến corpus rộng hơn; dự án mới chủ động giới hạn Part 2.

19.3 Kết luận so sánh

Dự án mới phát triển hơn ở ba trục cốt lõi:

  1. Độ tin cậy dữ liệu: phát hiện và quarantine thay vì serialize sai.
  2. An toàn câu trả lời: structured grounding và fail-closed sâu hơn.
  3. Vận hành: production traceability và observability tốt hơn.

Tuy nhiên cần mang lại ba năng lực tốt từ dự án cũ: hybrid retrieval thật, frontend tests và CI bắt buộc xanh trước deploy.


20. Chất lượng và bằng chứng kiểm thử

20.1 Test inventory

  • AI service: unit, API, agent, routing, policy, grounding, generation, Qdrant adapter, condition flow, observability và prompt injection.
  • Ingestion: extraction, glyph order, formula, segmentation, tables, chunking, validation, embed adapters và Qdrant load.
  • Web: lint/build trong CI, chưa có test runner.

20.2 Kết quả ngày kiểm kê

AI service: 278 passed, 6 skipped
Ingestion: 277 passed, 12 skipped
Web lint: no warnings or errors

20.3 Ý nghĩa của skipped tests

Skipped tests không được coi là pass. Chúng thường yêu cầu:

  • Qdrant live.
  • PostgreSQL live.
  • Provider/cloud access.
  • Integration flag.

Kết quả 555 pass chứng minh unit/offline suite hiện xanh; không chứng minh toàn bộ production integrations hoặc chất lượng lâm sàng.

20.4 Evaluation assets

  • Golden CSVs cho entity, intent, summary, multi-turn và E2E.
  • JSONL manual/adversarial/condition cases.
  • Condition evaluation summarizer.
  • Manual battery script.

Khoảng trống: chưa có một evaluation runner duy nhất chạy mọi dataset trên runtime thật, lưu baseline và fail CI khi chất lượng giảm.


21. Known limitations và technical debt

21.1 P0 cần xử lý trước khi mở rộng người dùng

  1. Authentication/authorization chưa có.
  2. CI chưa chặn deploy production.
  3. Chưa có backup tự động cho PostgreSQL và Qdrant.
  4. Default credentials trong config mẫu cần loại bỏ khỏi mọi production path.
  5. Chưa có ownership và retention cho conversation data.

21.2 P1 ảnh hưởng reliability/scale

  1. Structured multi-turn state nằm trong memory process.
  2. PostgreSQL chưa có connection pool.
  3. Python dependencies chưa có lockfile.
  4. Frontend không có test.
  5. Evaluation chưa thành regression gate.
  6. Rate limit không chia sẻ giữa replicas.
  7. No streaming và latency có thể cao.

21.3 P2 chất lượng và completeness

  1. Hybrid retrieval/RRF chưa nối runtime.
  2. Query expansion chưa nối runtime.
  3. BSA calculator chưa nối runtime.
  4. Part 1/Part 3 chưa ingest.
  5. Quarantined tables/formulas chưa được reconstruct.
  6. Web chưa có telemetry.
  7. Chưa có alerts/SLO.

21.4 Rủi ro claim sản phẩm

Không nên nói:

  • “Chatbot biết toàn bộ Dược thư” — hiện chỉ Part 2.
  • “Chatbot tư vấn thuốc” — hệ thống chỉ factual lookup.
  • “Kubernetes đã production” — mới là deployment kit.
  • “Hybrid search đang chạy” — chưa nối runtime mới.
  • “Tính được liều/BSA” — calculator chưa được gọi.
  • “Condition-to-drug đã eval đủ” — mới ghi nhận 20/60 manual cases.
  • “Mọi test đều chạy” — có integration tests skipped.

22. Đề xuất roadmap

Giai đoạn 1 Production safety gate

  • Nối CI success vào deploy.
  • Build/push immutable images.
  • Backup PostgreSQL/Qdrant và restore drill.
  • Chuyển toàn bộ credential sang secret store.
  • Bổ sung frontend tests cho BFF mapping, middleware và citation state.

Giai đoạn 2 Product access và data governance

  • Xây API gateway/auth hoặc access gate tối thiểu.
  • Conversation ownership.
  • Retention/deletion/redaction.
  • Audit roles và rate limit chia sẻ.

Giai đoạn 3 Quality regression

  • Hợp nhất eval runner.
  • Chạy đủ condition manual 60.
  • Baseline retrieval, grounding, abstention và latency.
  • Gate theo nhóm critical sections.
  • Human clinical review sampling.

Giai đoạn 4 Retrieval and performance

  • Xác minh full-text payload index.
  • Nối native sparse/BM25 và RRF.
  • Cache safe deterministic routes.
  • PostgreSQL pool.
  • Streaming hoặc staged response.

Giai đoạn 5 Kubernetes migration

  • Registry và image promotion.
  • Snapshot restore Job.
  • Helm CI.
  • Security hardening.
  • Staging deploy.
  • ArgoCD rollout và rollback drill.

Giai đoạn 6 Corpus expansion

  • Thiết kế riêng cho Part 1 và Part 3.
  • Không ép appendix/table vào cùng schema prose của Part 2.
  • Bổ sung source-grounded eval trước khi mở query surface.

23. Bộ chỉ số đề xuất báo cáo định kỳ

23.1 Product

  • Số queries/ngày.
  • Tỷ lệ answerable/clarify/abstain/verify_pdf.
  • Feedback helpful rate.
  • Clarification turns/query.
  • Citation click-through.

23.2 Quality

  • Retrieval hit@k/MRR theo section.
  • Citation validity.
  • Numeric grounding pass rate.
  • Entailment pass/reject rate.
  • Condition-to-drug candidate precision.
  • Regression theo critical section.

23.3 Reliability

  • Availability.
  • P50/P95/P99 latency.
  • Provider failure rate.
  • Request budget exhaustion rate.
  • Trace write failure rate.
  • Qdrant/PostgreSQL error rate.

23.4 Cost

  • LLM calls/turn.
  • Embedding/rerank calls.
  • Bedrock cost/query.
  • EC2/storage cost.
  • Re-embedding avoided qua snapshot/reuse.

23.5 Data

  • Corpus points và manifest version.
  • Quarantined blocks.
  • Coverage/monograph count.
  • Unclassified residual-ink regions.
  • Failed ingestion gates.

24. Kịch bản trình bày 10 phút

Phút 01: Bài toán

“Dược thư dài 1.668 trang và thông tin được chia theo chuyên luận, section và bảng. Mục tiêu không chỉ là tìm gần đúng mà là trả lời có thể truy ngược tới đúng nguồn.”

Phút 13: Điểm khó nhất dữ liệu

Trình bày:

  • Hai cột, bảng nối trang, công thức 2D, vector-outlined text.
  • Vì sao hệ thống quarantine thay vì đoán.
  • Manifest mismatch protection.

Phút 35: RAG và safety

Trình bày pipeline:

understand → route → retrieve → generate → ground → entail → cite/abstain

Nhấn mạnh mỗi claim có citation, số phải có trong evidence và unsupported drug bị chặn.

Phút 56: Tính năng người dùng

  • Multi-turn.
  • Evidence panel/PDF.
  • Condition → medication.
  • Feedback.

Phút 68: Production và observability

  • Docker/Caddy/EC2.
  • CI/deploy/rollback.
  • Prometheus/Tempo/Grafana/PostgreSQL trace.

Phút 89: Bằng chứng

  • 15.100 Qdrant points.
  • 555 Python tests pass.
  • Frontend lint sạch.
  • Production smoke và trace workflow.

Phút 910: Trung thực về khoảng trống

  • Chưa auth.
  • Chưa CI gate deploy.
  • Chưa frontend tests.
  • Chưa hybrid runtime mới.
  • K8s chưa apply.

Kết thúc bằng roadmap ba ưu tiên: production gate, access control và quality regression.


25. Câu hỏi quản lý có thể hỏi và câu trả lời đề xuất

“Có đang tư vấn điều trị không?”

Không. Sản phẩm tra cứu factual content trong Dược thư. Prompt cấm first-line/treatment-of-choice; câu xin recommendation bị từ chối.

“Làm sao biết model không bịa số?”

Mỗi số phải xuất hiện trong evidence mà claim citation. Nếu không, response bị hủy với ungrounded_number trước khi tới người dùng.

“Nếu bảng PDF bị đọc sai thì sao?”

Bảng/công thức 2D không đủ tin cậy được quarantine. Hệ thống trả VERIFY_PDF hoặc cảnh báo và dẫn tới đúng trang nguồn, không tự rút số.

“Có thể audit một câu trả lời production không?”

Có ba lớp: citation UI, Tempo trace và PostgreSQL retrieval trace, liên kết qua trace/correlation ID.

“Hệ thống đã sẵn sàng scale chưa?”

Chưa hoàn toàn. Runtime hiện phù hợp single-host/single-replica. Structured multi-turn state và rate limit còn in-memory; Postgres chưa pool.

“Kubernetes chạy chưa?”

Chưa có bằng chứng apply. Helm chart là migration kit; cần image registry, corpus restore Job và hardening trước staging.

“Điểm hơn dự án cũ là gì?”

Data safety, structured grounding và production observability. Điểm cần học lại từ dự án cũ là hybrid retrieval, frontend test và gated deploy.

“Rủi ro lớn nhất hiện nay?”

Không có auth/ownership trên endpoint công khai, CI chưa chặn deploy và chưa có backup/restore automation.


26. Kết luận

Trong kỳ 30/0713/08/2026, dự án đã hoàn thành một vòng xây dựng end-to-end từ PDF đến giao diện chat và hạ tầng production. Giá trị nổi bật không chỉ nằm ở khả năng sinh câu trả lời, mà ở việc thiết kế hệ thống có thể từ chối, truy nguồn và điều tra khi câu trả lời không đủ an toàn.

Trạng thái phù hợp nhất để báo cáo là:

Một nền tảng RAG Dược thư Part 2 đã có runtime, kiểm thử, deployment và observability; đang ở giai đoạn hardening trước khi mở rộng người dùng, scale hoặc chuyển sang Kubernetes/GitOps chính thức.

Ba ưu tiên tiếp theo:

  1. Bắt buộc CI xanh trước deploy và tạo rollback artifact bất biến.
  2. Thêm access control, ownership và data governance.
  3. Biến golden/manual evaluation thành quality regression gate.

Phụ lục A File/source quan trọng

Phạm vi File/thư mục
Runtime assembly apps/ai-service/bootstrap.py
FastAPI entrypoint apps/ai-service/main.py
RAG API apps/ai-service/routers/rag.py
Agent apps/ai-service/rag/agent.py
Retrieval apps/ai-service/rag/service.py
Generation/verification apps/ai-service/rag/answer.py
Grounding apps/ai-service/rag/grounding.py
Query understanding apps/ai-service/rag/understanding.py
Condition contracts apps/ai-service/rag/clinical.py
Qdrant adapter apps/ai-service/adapters/qdrant.py
PostgreSQL adapter apps/ai-service/adapters/postgres.py
Ingestion CLI ingestion/ingestion/cli.py
Web chat page apps/web/app/page.tsx
Web BFF apps/web/app/api/chat/route.ts
Rate limit apps/web/middleware.ts
Production Compose infra/docker/docker-compose.prod.yml
Observability overlay infra/docker/docker-compose.observability.yml
Deploy .github/workflows/deploy.yml
CI .github/workflows/ci.yml
Rollback .github/workflows/rollback.yml
Snapshot migration .github/workflows/migrate-qdrant-snapshot.yml
Helm chart infra/helm/medical-chatbot/

Phụ lục B Quy ước quyết định trả lời

Decision Ý nghĩa
answerable Có evidence và answer vượt guardrails
clarify Cần người dùng bổ sung dữ kiện
abstain Không đủ điều kiện an toàn/phạm vi/provider
verify_pdf Nguồn có bảng/công thức cần đối chiếu bản gốc

Phụ lục C Checklist trước khi demo

  • Xác nhận production URL đang reachable.
  • Xác nhận /health/ready.
  • Xác nhận Grafana login và datasource.
  • Chọn trước ba câu hỏi demo: drug section, multi-turn, condition lookup.
  • Chọn một case VERIFY_PDF để thể hiện safety.
  • Chuẩn bị trace ID để mở trong Tempo.
  • Không demo câu hỏi đang nằm trong known flaky/unsupported scope.
  • Không trình chiếu secrets, environment file hoặc patient data thật.
  • Nêu rõ Part 2 scope và disclaimer.
  • Chốt roadmap/đề nghị nguồn lực ở slide cuối.