Che dữ liệu cá nhân trước khi gửi lên LLM: đổi tên thành nhãn vẫn có thể chưa đủ theo luật mới
Bộ lọc PII viết vội vẫn có thể để lọt dữ liệu cá nhân, còn bảng ánh xạ giữ lại cho tiện có thể khiến cả hệ thống khó được coi là đã khử nhận dạng.
- 1Phân loại dữ liệuXác định trường nhạy cảm theo Nghị định 356 và thông tin tác vụ thật sự cần
- 2Phát hiện thực thểRegex cho số điện thoại, mật khẩu; NER cho tên, địa danh, nghề nghiệp
- 3Thay bằng nhãn chungDùng [NGƯỜI_DÙNG], [BÍ_MẬT], không giữ bảng ánh xạ về tên thật
- 4Fail closedBộ lọc lỗi hoặc timeout thì chặn request, không gửi bản gốc
- 5Gọi LLMChỉ văn bản đã che mới được đi ra API bên ngoài
- 6Đo bỏ sótChạy lại bộ test gắn nhãn tay, tính recall theo từng loại thực thể
Dữ liệu chỉ được gửi ra ngoài khi bộ lọc chạy thành công, còn nếu bộ lọc lỗi thì request bị chặn.
Đồ hoạ: FDE Times
Tóm tắt nhanh
- Theo Luật BVDLCN 2025, dữ liệu đã qua khử nhận dạng thì ra khỏi phạm vi dữ liệu cá nhân, còn dữ liệu chỉ được mã hóa thì vẫn là dữ liệu cá nhân.
- Thay tên bằng nhãn PERSON_001 nhưng vẫn giữ bảng ánh xạ để khôi phục thì chỉ giảm được rủi ro lộ dữ liệu. Khi còn đường quay về tên thật, khó coi đó là khử nhận dạng, và người quyết nên là bộ phận pháp chế của khách hàng.
- Bộ lọc phải chặn request khi detector lỗi, và tỷ lệ bỏ sót phải được đo trên dữ liệu tiếng Việt thật.
Tuần đầu ở một khách hàng tài chính, bạn được giao làm tính năng tóm tắt ticket chăm sóc khách hàng bằng LLM. Model tốt nhất lại chạy qua API đặt ở nước ngoài. Đến buổi review, trưởng nhóm pháp chế hỏi: “Tên, số điện thoại, mật khẩu khách hàng đọc cho tổng đài viên có đi ra khỏi Việt Nam không?”
Họ hỏi vậy vì Nghị định 356, có hiệu lực từ 1/1/2026 và thay thế Nghị định 13/2023, đã đổi luật chơi.
Nếu dữ liệu nhạy cảm chưa được khử nhận dạng triệt để mà vẫn đi qua API đặt ở nước ngoài, nghị định này áp thủ tục chuyển dữ liệu xuyên biên giới chặt hơn và đòi hỏi có biện pháp mã hóa, ẩn danh hoặc bảo mật tương đương.
Nhiều kỹ sư sẽ trả lời rằng nhóm đã che hết rồi. Câu trả lời đó chỉ đứng vững khi bạn biết rõ mình đã che đến mức nào, vì luật phân biệt khá rạch ròi giữa “che cho đỡ lộ” và “khử nhận dạng”. Chênh lệch giữa hai mức này quyết định khách hàng còn phải gánh bao nhiêu nghĩa vụ.
Che đến đâu thì dữ liệu hết là dữ liệu cá nhân?
Hãy bắt đầu từ định nghĩa. Luật Bảo vệ dữ liệu cá nhân 2025 định nghĩa dữ liệu cá nhân là thông tin xác định một con người cụ thể hoặc giúp xác định người đó. Vế “giúp xác định” quan trọng nhất: xóa tên rồi mà vẫn giữ “giáo viên, chi nhánh Hội An, sinh năm 1990” thì người đọc vẫn có thể lần ra đúng một người.
Luật cũng mở một lối ra rõ ràng. Dữ liệu đã qua khử nhận dạng thì luật không còn coi là dữ liệu cá nhân, với khử nhận dạng được hiểu là sửa hoặc xóa thông tin để có một bộ dữ liệu mới không còn chỉ ra được ai.
Bản thân Nghị định 356 cũng yêu cầu khử nhận dạng dữ liệu trước khi đem giao dịch trên sàn dữ liệu, tức đây là biện pháp được pháp luật chính thức thừa nhận.
Kỹ sư hay vấp ở hai chỗ. Theo luật, dữ liệu đã mã hóa vẫn là dữ liệu cá nhân, nên mã hóa không phải lối ra.
Còn Điều 14 khoản 6 cấm tái nhận dạng dữ liệu đã khử nhận dạng, tức khử nhận dạng thật phải là đường một chiều. Pipeline nào cần gắn lại tên thật vào câu trả lời của LLM thì khó có thể xếp vào vùng khử nhận dạng ngay từ đầu.
| Cách làm | Ví dụ | Theo luật |
|---|---|---|
| Mã hóa | Gửi bản mã của số điện thoại | Vẫn là dữ liệu cá nhân |
| Thay nhãn, giữ bảng ánh xạ | PERSON_001 ↔ “Nguyễn Thị Lan” |
Giảm rủi ro, nhưng còn đường quay về tên thật nên khó coi là khử nhận dạng |
| Khử nhận dạng thật | Xóa tên và cả các chi tiết giúp suy ra danh tính, không giữ đường quay lại | Không còn là dữ liệu cá nhân |
Bài phân tích của Wavect về GDPR cũng đi đến kết luận tương tự cho hàng giữa: đổi tên thành PERSON_001 giúp giảm rủi ro lộ dữ liệu, nhưng luồng xử lý vẫn nằm trong phạm vi GDPR.
Bạn nên coi đây là tín hiệu để thận trọng, chứ đừng coi là kết luận pháp lý cho Việt Nam. Hàng nào áp dụng được cho hệ thống của khách hàng thì luật sư của họ quyết, còn việc của bạn là giúp họ thấy rõ hệ thống đang nằm ở hàng nào.
Một ticket đi qua bộ lọc
Cùng xem một ticket giả định:
Chị Nguyễn Thị Lan, SĐT 0912345678, giáo viên ở Hội An, báo không đăng nhập được tài khoản định danh điện tử, mật khẩu cũ là Lan@1990.
Ticket này có bốn loại thông tin cần xử lý. Tên và số điện thoại dễ thấy nhất, còn mật khẩu tài khoản định danh điện tử thì Nghị định 356 đã xếp vào nhóm dữ liệu nhạy cảm, nên phải ưu tiên bắt bằng được. Cụm “giáo viên ở Hội An” không trực tiếp chỉ ra ai nhưng có thể giúp xác định người đó.
Muốn tóm tắt ticket, LLM chỉ cần biết loại sự cố. Vì vậy đầu ra mong muốn chỉ cần thế này:
[NGƯỜI_DÙNG], SĐT [ĐIỆN_THOẠI], [NGHỀ_NGHIỆP] ở [ĐỊA_ĐIỂM], báo không đăng nhập được tài khoản định danh điện tử, mật khẩu cũ là [BÍ_MẬT].
Ở đây không có số thứ tự, cũng không có bảng ánh xạ. Hệ thống nội bộ vẫn trả kết quả về đúng người qua ticket ID, còn LLM không thấy ID đó.
Nhưng cần nói thẳng: ticket ID cũng là một đường nối ngược về người dùng. Cách làm này giảm mạnh lượng thông tin đi ra ngoài, chứ chưa biến cả hệ thống thành khử nhận dạng thật, và bạn nên mô tả đúng như vậy với khách hàng.
Dưới đây là phác thảo phần khung; các regex chỉ là ví dụ, bạn phải sửa theo định dạng dữ liệu thật của khách hàng:
import re
RULES = [
("BÍ_MẬT", r"(mật khẩu|password|mk)\s*(cũ|mới)?\s*(là|:)\s*\S+"),
("ĐIỆN_THOẠI", r"\b0\d{9}\b"),
("EMAIL", r"[\w.+-]+@[\w-]+\.[\w.]+"),
]
class PIIFilterError(Exception):
pass
def redact(text: str, ner) -> str:
for label, pattern in RULES:
text = re.sub(pattern, f"[{label}]", text, flags=re.IGNORECASE)
# Tên người, địa danh, nghề nghiệp: cần model NER (vd. Presidio + model tiếng Việt)
for span in sorted(ner(text), key=lambda s: -s.start):
text = text[:span.start] + f"[{span.label}]" + text[span.end:]
return text
def build_prompt(ticket: str, ner) -> str:
try:
clean = redact(ticket, ner)
except Exception as e:
# Fail closed: bộ lọc hỏng thì KHÔNG gửi gì ra ngoài
raise PIIFilterError("PII filter unavailable") from e
return f"Tóm tắt sự cố sau:\n{clean}"
Khối except là chỗ quan trọng nhất. Wavect khuyến cáo bộ lọc không bao giờ được âm thầm “fail open” chỉ vì detector chậm hoặc đang sập. Trong thực tế, chuyện hỏng thường bắt đầu từ một dòng như “nếu timeout thì gửi luôn bản gốc cho khỏi ảnh hưởng người dùng”.
Detector tốt đến đâu thì phải tự đo
Microsoft Presidio là thư viện mã nguồn mở hợp lý để làm lớp phát hiện vì nó nhận diện và ẩn danh được thực thể riêng tư trong cả văn bản lẫn ảnh.
Tuy vậy, chính trang giới thiệu của Presidio cũng ghi rằng không có gì bảo đảm thư viện tìm ra hết thông tin nhạy cảm. Với tên tiếng Việt viết không dấu, viết tắt hay gõ sai chính tả, bạn không thể đoán trước mức bỏ sót.
Vì thế, trước khi lên production, Wavect khuyên đo trên dữ liệu của chính khách hàng: tỷ lệ bỏ sót, chất lượng tác vụ, độ trễ, và cách bộ lọc xử lý văn bản trộn tiếng Việt và tiếng Anh.
Lấy một con số giả định cho dễ hình dung: bạn gắn nhãn tay 200 ticket và đếm được 412 thực thể cần che, còn bộ lọc bắt được 375. Recall là 375/412, khoảng 91%, nghĩa là 37 mẩu dữ liệu cá nhân vẫn đi ra ngoài.
Con số 91% nghe thì cao, nhưng nếu một ngày có hàng nghìn ticket thì mỗi ngày vẫn có rất nhiều mẩu dữ liệu bị lọt. Bạn nên tách kết quả theo loại thực thể, vì bỏ sót mật khẩu nghiêm trọng hơn nhiều so với bỏ sót tên một quận. Mỗi lần bổ sung rule hay đổi model, hãy chạy lại bộ test này như chạy regression test.
Năm bước làm ở khách hàng
Bước một: ngồi với khách hàng để phân loại dữ liệu. Bạn cần biết trường nào thuộc nhóm nhạy cảm theo Nghị định 356 và tác vụ của LLM thực sự cần những gì. Phần lớn tác vụ tóm tắt hay phân loại không cần biết tên người.
Bước hai: dựng bộ lọc nhiều lớp. Regex xử lý những thứ có cấu trúc, NER xử lý tên, địa danh, nghề nghiệp. Bước ba: bọc lời gọi LLM trong cơ chế fail closed và ghi log mỗi lần request bị chặn.
Bước bốn: đo recall trên dữ liệu đã gắn nhãn, tách theo từng loại thực thể. Bước năm: viết một trang mô tả luồng dữ liệu, nói rõ hệ thống đang ở hàng nào trong bảng trên và còn những đường nối ngược nào, rồi đưa cho bộ phận pháp chế quyết định.
Che dữ liệu xong vẫn chưa hết nghĩa vụ. Luật liệt kê cả mã hóa, giải mã lẫn khử nhận dạng là hoạt động xử lý dữ liệu cá nhân, nên bản thân bước che chạy trong hạ tầng của khách hàng vẫn phải tuân thủ như mọi bước xử lý khác.
Những lỗi hay gặp
Lỗi phổ biến nhất là che những định danh trực tiếp mà bỏ qua những chi tiết giúp xác định danh tính. Kế đến là coi mã hóa hay token có thể đảo ngược là đã khử nhận dạng.
Lỗi thứ ba đi liền với lỗi trên: giữ bảng ánh xạ placeholder ↔ tên thật rồi báo với khách hàng rằng dữ liệu đã được khử nhận dạng.
Đọc cùng lúc định nghĩa “giúp xác định”, quy định rằng dữ liệu mã hóa vẫn là dữ liệu cá nhân và lệnh cấm tái nhận dạng, khó coi một thiết lập còn đường quay về tên thật là khử nhận dạng.
Kết luận cuối cùng thuộc về luật sư của khách hàng, nhưng họ phải được biết bảng ánh xạ đó đang tồn tại.
Còn hai lỗi nữa. Một là chỉ thử bộ lọc bằng câu tiếng Anh mẫu trong tài liệu. Hai là mặc định bộ lọc sẽ luôn chạy.
Ghi kỹ năng này vào CV thế nào?
Đừng chỉ ghi “đã dùng Presidio”. Hãy ghi rằng bạn đã đo recall che PII trên dữ liệu tiếng Việt và thiết kế cơ chế fail closed, kèm con số nếu có.
Khi đọc JD của một vị trí FDE, những cụm như “data residency”, “PII” hay “compliance review” là dấu hiệu cho thấy họ cần đúng kỹ năng này.
Bài tập tuần này
Hãy lấy ticket mẫu ở trên, viết thêm 20 biến thể như không dấu, viết tắt, số điện thoại có dấu chấm hay mật khẩu nằm sau chữ “pass”, rồi chạy qua bộ lọc của bạn. Đếm xem có bao nhiêu thực thể lọt qua. Con số đó là thứ bạn cần mang theo vào buổi họp với bộ phận pháp chế.
5 nguồn
- Điều 2 Luật Bảo vệ dữ liệu cá nhân 2025
- Mã hóa dữ liệu cá nhân và khử nhận dạng dữ liệu cá nhân là gì? · 2026-01-10
- EY Vietnam – Nghị định số 356/2025/NĐ-CP quy định chi tiết một số điều và biện pháp thi hành Luật Bảo vệ dữ liệu cá nhân · 2026-03-03
- Presidio – Data Protection and De-identification SDK
- PII Redaction Before LLM Prompts: Presidio, Privacy Filter, and a Production Pipeline · 2026-08-06