№ 90
Tìm đúng quy định nhưng không biết nó đã hết hiệu lực — đó mới là rủi ro thật của người làm thuế, và người chịu là người ký tên vào tờ khai. DrakeFamtax trả lời câu hỏi thuế kèm trích dẫn tới đúng Điều, gắn tình trạng hiệu lực ngay cạnh trích dẫn, và từ chối khi không đủ căn cứ thay vì đoán.
Rủi ro nghiêm trọng nhất của người tra cứu văn bản thuế không phải là không tìm thấy quy định — mà là tìm thấy một quy định đã hết hiệu lực và tưởng nó còn đúng. Công cụ tìm kiếm thông thường không giải được, vì chúng trả về nội dung mà không trả về tình trạng hiệu lực — hai thứ đó nằm ở hai chỗ khác nhau trong hệ thống văn bản pháp luật Việt Nam. Và các trang tra cứu có ghi trạng thái thì ghi ở cấp văn bản: một văn bản "còn hiệu lực" vẫn có thể chứa một điều khoản đã bị sửa.
Hậu quả, tính bằng chính luật vừa có hiệu lực. Một hồ sơ khai thiếu 100 triệu đồng, bị phát hiện sau ba năm:
| Khoản | Căn cứ | Số tiền |
|---|---|---|
| Truy thu số thuế khai thiếu | — | 100.000.000 |
| Phạt 20% trên số khai thiếu | Điều 44, Luật 108/2025/QH15 | 20.000.000 |
| Tiền chậm nộp 0,03%/ngày × 3 năm | Điều 16, Luật 108/2025/QH15 | 32.850.000 |
| Tổng | 152.850.000 |
Và cơ quan thuế được truy "trong thời hạn 10 năm trở về trước kể từ ngày phát hiện hành vi vi phạm" (Điều 44). Lỗi này vô hình: không ai biết mình đã sai cho tới lúc thanh tra đến.
Vì sao là lúc này. Luật Quản lý thuế 108/2025/QH15 có hiệu lực từ
01/7/2026 — mới hai tháng — với 53 điều sửa đổi diện rộng. Các văn bản hướng
dẫn vẫn đang ra và đã có trong kho: 252/2026/NĐ-CP, 254/2026/NĐ-CP,
89/2026/TT-BTC, 91/2026/TT-BTC. Cả nước đang tra cứu trên một hệ thống vừa
dịch chuyển dưới chân mình.
Người dùng. Kế toán viên và kế toán tổng hợp là nhóm chính — họ ký tên vào tờ khai và chịu trách nhiệm cá nhân về con số trên đó. Chuyên gia thuế / kế toán trưởng là vai trò duyệt trong luồng human-in-the-loop.
| Nỗi đau | Sản phẩm làm gì |
|---|---|
| Không biết điều khoản còn sống không | Mỗi câu trả lời kèm tình trạng hiệu lực ngay cạnh trích dẫn, ở cấp điều khoản |
| Lỗi vô hình — sai mới biết | Thiếu căn cứ thì từ chối và nói ra mình thiếu gì, không đoán |
| Thanh tra hỏi "căn cứ đâu?" | Xuất ra khối căn cứ dán được vào hồ sơ, kèm cả những nguồn đã rà mà không dùng làm căn cứ |
Cộng thêm một khả năng mà tra cứu thông thường gộp làm một: hệ thống phân biệt được văn bản không có trong kho · có tên nhưng chưa có nội dung · có nội dung nhưng đã hết hiệu lực — ba tình huống đòi ba cách trả lời khác nhau.
Kho tri thức: 19.577 văn bản pháp luật · 94.927 điều khoản đã nhúng vector
100%, cộng 2.046 quan hệ vòng đời giữa các văn bản (844 thay thế · 673 sửa
đổi · 467 bãi bỏ · 62 bổ sung). (Đếm trực tiếp trên Neo4j ngày 01/09/2026. Kho
còn 4.450 node dạng stub — chỉ có số hiệu, chưa có nội dung — đã tách khỏi
con số trên; tổng node Document là 24.027.)
Ba đường truy xuất chạy song song rồi hợp nhất:
bm25s) — bắt câu hỏi nêu từ khoá cụ thể.BAAI/bge-m3, 1024 chiều, cosine. Chỉ mục vector nằm trên chính
node Neo4j, không tách ra một vector DB riêng, nên một truy vấn Cypher lấy
được cả điều khoản gần nghĩa lẫn vị trí của nó trong chuỗi vòng đời văn bản.
Đây là điểm kiến trúc khó sao chép nhất, không phải mô hình AI.REPLACED_BY, AMENDED_BY,
ABOLISHED_BY, SUPPLEMENTED_BY) và dẫn chiếu điều khoản.Ba kết quả hợp nhất bằng RRF (k = 60) cộng recency boost α = 0,15, khử trùng
theo provision_id, cắt theo ngân sách 8.000 token, TOP_K_FINAL = 10.
Trên đó là agent LangGraph chạy vòng công cụ ReAct với hai công cụ được nối
vào vòng (search_tax_hybrid, search_document_history), tối đa 6 bước; hụt
bước thì lùi về đường tra cứu một lượt thay vì treo. Trong src/agents/tools/
còn 4 hàm @tool khác dùng ở các đường gọi trực tiếp, không nằm trong vòng ReAct.
Cuối cùng là cổng an toàn fail-closed (src/api/safety.py) — bất biến được
khoá bằng test: mọi kết luận thuế phải có ít nhất một trích dẫn còn hiệu lực;
văn bản đã hết hiệu lực chỉ được xuất hiện trong warnings, không bao giờ nâng
điểm tin cậy và không bao giờ trở thành căn cứ; dưới ngưỡng tin cậy thì trả
insufficient_evidence; lỗi tầng dưới thì trả lỗi HTTP, không bao giờ trả một
câu trả lời giả.
Stack: FastAPI + Python 3.11 · PostgreSQL 16 (state giao dịch) · Neo4j 5 (graph
và vector) · Next.js 16 + React 19 với server proxy giữ JWT trong cookie
httpOnly · Docker multi-stage + GitHub Actions · gemma-4 tự host trên GPU
L40S, có provider dự phòng.
Truy xuất — eval/results/summary.md, 27/08/2026, commit 0917632, chế độ
hybrid, một lệnh cho cả năm bộ:
| Bộ đề | R@1 | R@5 | MRR | Ghi chú |
|---|---|---|---|---|
| golden 35 câu (nhóm tự soạn) | 0,393 | 0,540 | 0,511 | Coverage 0,931 |
| external 16 câu | 0,750 | 0,750 | 0,750 | |
| vlqa 300 câu (người ngoài soạn) | 0,414 | 0,722 | 0,608 | ⚠️ cố ý NGOÀI miền thuế |
| multihop 31 câu | — | — | — | đúng loại quan hệ 0,957 · đúng văn bản đích 0,818 |
⚠️ Bộ VLQA cố ý nằm ngoài miền thuế. Nó đo năng lực truy xuất và trích dẫn, và không kết luận được chất lượng tư vấn thuế. Chúng tôi dùng nó vì nó do người ngoài soạn và có trước hệ thống này — nên nó không thể vô tình chấm điểm cho chính bộ đề của chúng tôi. Đó là lựa chọn phương pháp luận, không phải một con số về thuế.
Độ bền — 57 câu, đo hệ thống có biết lúc nào KHÔNG nên trả lời không:
| Chỉ số | Giá trị |
|---|---|
| báo động giả | 0,000 |
| cảnh báo đúng loại · đánh dấu hết hiệu lực | 1,000 · 1,000 |
| từ chối đúng | 0,850 |
Hành vi — BASELINE_hanh_vi.md, 25/08/2026 (mẫu số ghi rõ từng dòng):
| Chỉ số | đạt/mẫu | Tỷ lệ |
|---|---|---|
| không bịa số hiệu | 60/60 | 1,000 |
| trích dẫn có thật | 42/43 | 0,977 |
| nêu hiệu lực khi buộc phải nêu | 10/10 | 1,000 |
| từ chối đúng · từ chối có nêu lý do | 13/13 · 19/19 | 1,000 · 1,000 |
| từ chối oan (thấp hơn tốt hơn) | 1/42 | 0,024 |
Kỹ thuật: 100 pull request đã merge · 3.939 test tự động. (Lượt chạy đầy đủ gần nhất 01/09/2026: 3.814 pass · 120 skip · 3 fail — hai fail là phép kiểm môi trường của lane phát triển, một đã sửa trong cùng ngày.)
Sản phẩm đang chạy công khai tại p-185.drakefamtax.id.vn, có đăng nhập Google.
Ghi ra để người đọc không phải tự phát hiện:
38/2019/QH14 vẫn mang trạng thái Còn
hiệu lực và không có cạnh REPLACED_BY nào tới 108/2025/QH15, dù câu văn
chứng minh điều đó nằm sẵn trong Điều 52 của luật mới. Đây đúng lớp lỗi mà
sản phẩm này tồn tại để chữa, và nó cho thấy vì sao hiệu lực phải là một
quan hệ suy ra được, không phải một trường do nguồn tự khai. Đang sửa.case_study, 7 câu) đạt R@5 = 0,000, và "đúng văn
bản" chỉ 0,286 — tức chưa tìm ra đúng văn bản, chứ không phải tìm đúng văn
bản mà sai điều khoản. Đây là gap thật của tầng truy xuất.252/2026/NĐ-CP Điều
10), nên con số thứ hai phải nhảy quanh ngày 20 hằng tháng. Nếu nó không
nhảy, luận điểm của chúng tôi sai.| Con số | File nguồn |
|---|---|
| 19.577 văn bản thật · 4.450 stub · 94.927 điều khoản · 2.046 quan hệ vòng đời | Truy vấn Neo4j trực tiếp, 01/09/2026 |
| R@1 / R@5 / MRR / Coverage — cả năm bộ đề | eval/results/summary.md — 27/08/2026, commit 0917632, một lệnh run_eval.py --all |
| Độ bền 57 câu · multi-hop 31 câu | eval/results/summary.md · report_robustness.md · report_multihop.md |
| Hành vi (60/60, 1/42, …) | eval/results/BASELINE_hanh_vi.md — 25/08/2026 |
case_study R@5 0,000 | eval/results/report.md §"ĐO LẠI 22/08/2026" |
| 0,03%/ngày · phạt 20% · 10 năm · phạt 2–5 triệu | Nguyên văn 108/2025/QH15 Điều 16 & 44, 125/2020/NĐ-CP Điều 13 — đối chiếu trên kho 01/09/2026 |
| Hạn nộp tờ khai tháng = ngày thứ 20 | 252/2026/NĐ-CP Điều 10 khoản 2 — không nằm ở Luật 108/2025 |
| 3.939 test · 100 PR | pytest tests --collect-only -q · gh pr list --state merged --limit 300 — chạy 01/09/2026 |
| 859.048 doanh nghiệp · 5,3 triệu cơ sở | docs/business-problem.md §2.2, §10.1 (nguồn công khai ở Phụ lục B) |