Một dòng code chạy trơn tru, biên dịch sạch sẽ, và gọi một API không hề tồn tại — đó chính là hallucination, và nó nguy hiểm hơn bất kỳ lỗi cú pháp nào bạn từng gặp.
Code Hallucination Là Gì?
Hallucination (ảo giác) là hiện tượng LLM (large language model — mô hình ngôn ngữ lớn) tạo ra thông tin nghe có vẻ hợp lý, đúng cú pháp, đúng ngữ cảnh — nhưng thực chất sai hoặc không tồn tại. Trong văn bản thông thường, hallucination có thể là một trích dẫn bịa đặt hay một sự kiện lịch sử sai. Trong code, hallucination có hình hài cụ thể hơn nhiều: một method không có trong thư viện, một tham số API đã bị deprecated từ ba năm trước, một behavior của framework mà AI "tưởng tượng" ra dựa trên pattern quen thuộc từ hàng triệu dòng code khác nó từng thấy.
Điều quan trọng cần hiểu: AI không "nói dối" theo nghĩa có chủ đích. Mô hình đang làm đúng việc nó được huấn luyện để làm — dự đoán token tiếp theo có xác suất cao nhất dựa trên pattern đã học. Khi bạn hỏi "viết cho tôi hàm parse date bằng thư viện X", nếu thư viện X có API gần giống với một thư viện phổ biến khác mà model học được nhiều hơn, model có xu hướng "trộn" hai API đó lại — tạo ra một API lai không tồn tại ở đâu cả. Đây không phải bug của model, đây là bản chất thống kê của cách LLM hoạt động.
Với engineer, điều này có nghĩa: hallucination không phải là chuyện "thỉnh thoảng mới xảy ra với model kém". Nó là một rủi ro cấu trúc, luôn hiện diện, ở mọi model, mọi lúc — chỉ khác nhau về tần suất. Nhiệm vụ của bạn không phải là loại bỏ hoàn toàn hallucination (bất khả thi), mà là xây dựng quy trình phát hiện nó trước khi nó đi vào production.
Mẹo: Đừng hỏi "AI có hallucinate không?" — luôn giả định câu trả lời là "có, ở đâu đó trong output này". Tư duy đúng là hỏi "phần nào trong output này có khả năng là hallucination cao nhất, và tôi verify nó bằng cách nào?"
Phân Loại Các Dạng Code Hallucination
Để bắt lỗi hiệu quả, bạn cần biết mình đang tìm cái gì. Dưới đây là các nhóm hallucination phổ biến nhất mà engineer gặp phải khi làm việc với AI coding assistant:
1. API/method không tồn tại (Package hallucination). AI gọi một hàm, method, hoặc class không có trong thư viện thực tế — ví dụ gọi axios.retry() trong khi axios không có method này native, hoặc import một package có tên gần giống package thật (lodash.debounce thay vì lodash/debounce). Đây là dạng nguy hiểm nhất vì nó có thể qua mặt cả compiler trong ngôn ngữ dynamic typing như JavaScript/Python cho đến khi code chạy runtime.
2. Tham số hoặc signature sai. Hàm tồn tại thật, nhưng thứ tự tham số, kiểu dữ liệu, hoặc giá trị mặc định bị AI "đoán" sai — thường do trộn lẫn version cũ và mới của cùng một API.
3. Behavior giả định sai. AI mô tả đúng tên hàm nhưng sai về cách nó hoạt động — ví dụ khẳng định một method là idempotent trong khi thực tế không phải, hoặc giả định một thao tác là synchronous trong khi nó là async.
4. Hallucination về business logic. Đây là dạng tinh vi nhất: AI tự "bổ sung" các nhánh xử lý, edge case, hoặc rule nghiệp vụ mà bạn chưa từng yêu cầu — nghe rất hợp lý, rất "đầy đủ", nhưng hoàn toàn không khớp với spec thực tế của hệ thống.
5. Hallucination về config/infrastructure. AI đưa ra tên biến môi trường, tên service, endpoint URL, hoặc cấu hình deployment nghe rất giống thật nhưng không khớp với hệ thống cụ thể của bạn.
6. Trích dẫn nguồn giả. AI dẫn ra "theo tài liệu chính thức của X" hoặc "best practice được khuyến nghị bởi Y" nhưng không có nguồn thật nào như vậy — chỉ là câu văn tạo cảm giác đáng tin.
Mẹo: Giữ một checklist phân loại này trong đầu khi review. Khi gặp một đoạn code "lạ", tự hỏi nó rơi vào nhóm nào trong 6 nhóm trên — việc phân loại giúp bạn biết cách verify nhanh nhất (check docs, chạy thử, hay hỏi lại chính AI).
Vì Sao Code Hallucination Đặc Biệt Nguy Hiểm
So với hallucination trong văn bản thường, hallucination trong code có ba đặc điểm khiến nó nguy hiểm hơn hẳn.
Thứ nhất, tính thuyết phục cao bất thường. Code hallucination thường được viết với style, indentation, naming convention hoàn toàn nhất quán với phần code còn lại — không có "tín hiệu cảnh báo" về mặt hình thức như văn phong lạ hay lỗi chính tả. Một API bịa đặt trông y hệt một API thật.
Thứ hai, compiler và type checker không phải lá chắn toàn diện. Trong ngôn ngữ static typing, một số hallucination sẽ bị bắt ngay (gọi hàm không tồn tại → lỗi biên dịch). Nhưng rất nhiều hallucination — đặc biệt là về business logic, behavior ngầm định, hay edge case — hoàn toàn hợp lệ về cú pháp và kiểu dữ liệu. Compiler không có khái niệm "đúng về mặt nghiệp vụ".
Thứ ba, chi phí phát hiện muộn rất cao. Một package hallucination trong dependency có thể dẫn tới lỗi supply-chain nghiêm trọng (kẻ tấn công đăng ký một package trùng tên package "ảo" mà AI hay gợi ý — gọi là "slopsquatting", một dạng tấn công lợi dụng chính hallucination của AI để phát tán mã độc). Một hallucination về business rule có thể âm thầm tính sai tiền cho hàng nghìn giao dịch trước khi ai đó phát hiện ra, vì mọi thứ "chạy được" và "trông hợp lý".
Ngoài ra còn có yếu tố tâm lý: con người có xu hướng tin code chạy được là code đúng. Khi AI generate ra một đoạn code compile sạch, test cơ bản pass, review viên rất dễ giảm mức độ hoài nghi xuống — trong khi đây chính là lúc cần tăng cường kiểm tra nhất.
Mẹo: Coi mọi function call, mọi con số "magic", mọi khẳng định về behavior trong code AI-generated là một "claim cần verify" — không phải một "fact đã được chứng minh" — cho tới khi bạn tự kiểm tra.
Kỹ Thuật Phát Hiện Thực Sự Hiệu Quả
Không phải kỹ thuật phát hiện nào cũng đáng thời gian bỏ ra. Dưới đây là những kỹ thuật đã được chứng minh hiệu quả trong thực tế, xếp theo độ ưu tiên:
1. Compile/build ngay, đừng đợi. Với ngôn ngữ compiled hoặc có type checker mạnh (TypeScript, Go, Rust, Java, Kotlin), chạy build ngay sau khi AI generate code là bước rẻ nhất và bắt được nhiều nhất các package/API hallucination. Đừng đọc code trước — build trước, đọc sau.
2. Verify import/dependency tồn tại thật. Với mọi package mới được AI import mà bạn chưa từng dùng, mở registry thật (npm, PyPI, crates.io, Maven Central) và kiểm tra: package có tồn tại không, version có đúng không, method được gọi có trong API docs không. Đây là bước bắt buộc, không phải tùy chọn — đặc biệt quan trọng để phòng slopsquatting.
3. Grep codebase để verify pattern nội bộ. Khi AI khẳng định "project này dùng utility function formatCurrency ở utils/format.ts", đừng tin — grep để xác nhận file, function, và signature đó tồn tại thật trong repo của bạn.
4. Đối chiếu với official docs cho mọi API "lạ". Nếu một đoạn code dùng API bạn chưa quen, mở tài liệu chính thức (không phải blog, không phải Stack Overflow cũ) và đối chiếu từng tham số.
5. Chạy thử với input thật, không chỉ đọc bằng mắt. Nhiều hallucination về behavior chỉ lộ ra khi bạn thực thi — ví dụ một hàm được cho là trả về null khi not-found nhưng thực tế throw exception.
6. Yêu cầu AI trích dẫn nguồn cụ thể. Hỏi thẳng: "Bạn lấy thông tin về method này từ đâu? Link tới docs?" Nếu AI không đưa được nguồn cụ thể hoặc đưa nguồn mơ hồ, đó là tín hiệu cảnh báo mạnh.
7. Second-opinion từ một model/session khác. Dán đoạn code nghi ngờ vào một phiên chat mới (không có context cũ) và hỏi "API này có tồn tại thật không, hoạt động đúng như code mô tả không?" — model không bị "cam kết" với câu trả lời trước đó thường bắt lỗi tốt hơn.
Mẹo: Xây dựng thói quen "build-first, read-second" thành phản xạ. 90% package hallucination bị bắt ngay ở bước build/compile với chi phí gần như bằng không.
Các Pattern Hallucination Cụ Thể Cần Để Ý
Qua thời gian làm việc với AI coding assistant, cộng đồng engineer đã tổng hợp được một số pattern lặp lại rất thường xuyên:
-
Trộn API giữa các version. AI viết code dùng React class component pattern trộn lẫn với hooks, hoặc dùng cú pháp Vue 2 Options API lẫn Vue 3 Composition API trong cùng một file — vì model học từ dữ liệu trải dài nhiều năm, nhiều version.
-
"Ảo giác tiện ích" (convenience hallucination). AI bịa ra một helper method "tiện lợi vừa đủ" mà bạn ước gì thư viện có thật — ví dụ
Array.prototype.groupByAsync()— vì đó là điều "hợp lý" một thư viện tốt nên có. -
Tự thêm error handling không có thật trong spec. AI viết
try/catchbắt một exception cụ thể mà hàm gốc không bao giờ throw, tạo cảm giác code "chắc chắn" hơn thực tế. -
Giả định permission/role không tồn tại trong hệ thống. Ví dụ code check
user.role === 'moderator'trong khi hệ thống của bạn chỉ cóadminvàmember. -
Số liệu benchmark hoặc con số "magic" không có căn cứ. AI khẳng định "cache TTL 300 giây là tối ưu cho use case này" — nghe có vẻ có cơ sở kỹ thuật nhưng thực chất là con số bịa.
-
Giả định database schema/field không có thật. Đặc biệt phổ biến khi AI không được cấp context về schema thật, nó sẽ "đoán" tên cột dựa trên convention phổ biến (
created_atthay vìcreatedAtbạn đang dùng, hoặc fieldemail_verifiedkhông hề tồn tại trong bảngusers). -
Bịa link tài liệu hoặc issue tracker. AI generate comment kiểu
// see https://github.com/org/repo/issues/1234với link hoàn toàn không tồn tại.
Mẹo: Lập một "danh sách đen cá nhân" — ghi lại mỗi khi bạn bắt được một hallucination cụ thể từ AI assistant bạn đang dùng. Theo thời gian, bạn sẽ nhận ra model của mình có xu hướng hallucinate lặp lại ở một số dạng nhất định, và biết trước chỗ nào cần soi kỹ hơn.
Kỹ Thuật Prompt Để Giảm Tần Suất Hallucination
Bạn không thể loại bỏ hallucination bằng prompt, nhưng bạn có thể giảm đáng kể tần suất nó xảy ra bằng cách thiết kế prompt tốt hơn.
Cung cấp context cụ thể thay vì để AI đoán. Thay vì "viết hàm parse ngày tháng", hãy dán trực tiếp version của thư viện đang dùng, đoạn code liên quan trong repo, và ví dụ input/output thực tế.
Ví dụ prompt tốt:
Tôi đang dùng date-fns version 3.6.0 (không phải moment.js hay dayjs).
Đây là type định nghĩa Order hiện có trong project (dán từ types/order.ts):
[dán type thật]
Viết hàm formatOrderDate(order: Order): string trả về định dạng "dd/MM/yyyy HH:mm".
Chỉ dùng function có thật trong date-fns v3 — không tự bịa helper.
Nếu không chắc method nào tồn tại trong date-fns v3, nói rõ bạn không chắc thay vì đoán.
Yêu cầu AI tự đánh giá độ tin cậy. Thêm câu "Nếu bạn không chắc chắn 100% về API này tồn tại, hãy nói rõ thay vì đoán" vào cuối prompt. Kỹ thuật này không hoàn hảo nhưng giảm đáng kể tỷ lệ AI "tự tin bịa".
Giới hạn phạm vi tri thức được phép dùng. Với prompt liên quan tới business logic nội bộ, luôn kèm theo: "Chỉ dùng các function, field, và rule đã được liệt kê trong context này. Không tự thêm rule nào khác."
Yêu cầu liệt kê giả định trước khi viết code. Prompt: "Trước khi viết code, liệt kê tất cả giả định bạn đang đưa ra về API, schema, và business rule liên quan." Điều này buộc hallucination phải "lộ diện" bằng văn bản, dễ verify hơn nhiều so với việc nó ẩn trong code.
Chia nhỏ task phức tạp. Task càng lớn, càng nhiều chỗ để hallucination len vào ngóc ngách. Chia nhỏ thành các bước có thể verify độc lập.
Mẹo: Câu thần chú hữu ích để thêm vào cuối mọi prompt liên quan tới API bên thứ ba: "Chỉ dùng API mà bạn chắc chắn tồn tại trong version được nêu. Nếu không chắc, hãy nói rõ và đề xuất tôi tự kiểm tra docs."
Thực Hành: Bắt Hallucination Trong Một Đoạn Code Thật
Hãy cùng thực hành quy trình bắt hallucination trên một tình huống cụ thể.
Bước 1 — Yêu cầu AI generate code cho một task thực tế. Dùng prompt:
Viết một hàm TypeScript retryWithBackoff(fn, options) dùng thư viện axios
để retry một HTTP request tối đa 3 lần với exponential backoff.
Dự án đang dùng axios 1.7.x.
Bước 2 — Build/compile ngay lập tức. Chạy tsc --noEmit hoặc build command của project. Ghi lại mọi lỗi biên dịch — đây là vòng lọc đầu tiên.
Bước 3 — Liệt kê mọi API được gọi trong output. Ví dụ nếu AI viết axios.retry(config) hay import axios-retry mà bạn không yêu cầu, đánh dấu ngay — axios core không có method retry() native.
Bước 4 — Mở npm registry hoặc docs chính thức, verify từng API. Kiểm tra axios package.json thật, xem method axios.request, axios.interceptors có đúng như AI mô tả không.
Bước 5 — Chạy thử với một mock server trả lỗi 500 liên tục. Verify behavior thật: có đúng 3 lần retry không, thời gian giữa các lần có đúng là exponential không (1s, 2s, 4s hay AI tính sai công thức).
Bước 6 — Hỏi ngược AI để kiểm tra tính nhất quán. Prompt: "Giải thích chi tiết cơ chế exponential backoff bạn vừa dùng, công thức tính delay là gì, và dẫn chứng bạn dựa trên tài liệu nào." So sánh câu trả lời với code thực tế — nếu giải thích không khớp code, đó là dấu hiệu rõ ràng của hallucination hoặc thiếu nhất quán nội bộ.
Bước 7 — Second-opinion. Copy hàm sang một session AI mới, hỏi "Đoạn code này có gọi API nào không tồn tại trong axios 1.7.x không? Logic exponential backoff có đúng không?"
Qua bài thực hành này, bạn sẽ thấy quy trình bắt hallucination không tốn quá nhiều thời gian nếu đã thành thói quen — build trước, verify API bên thứ ba, chạy thử behavior, và luôn giữ thái độ hoài nghi lành mạnh.
Mẹo: Biến 7 bước trên thành một checklist ngắn dán ngay cạnh editor trong vài tuần đầu làm việc với AI assistant, cho tới khi nó trở thành phản xạ tự nhiên.
Những điểm chính
- Hallucination là hệ quả tất yếu của cách LLM hoạt động — không phải lỗi ngẫu nhiên, mà là rủi ro cấu trúc luôn hiện diện.
- Có ít nhất 6 nhóm hallucination phổ biến: API không tồn tại, sai signature, sai behavior, bịa business logic, bịa config/infrastructure, và trích dẫn nguồn giả.
- Code hallucination nguy hiểm hơn hallucination văn bản vì nó thuyết phục về mặt hình thức, không bị compiler bắt hết, và chi phí phát hiện muộn rất cao.
- Kỹ thuật phát hiện hiệu quả nhất: build/compile ngay, verify package trên registry thật, grep để xác nhận pattern nội bộ, chạy thử với input thật, và xin second-opinion từ session khác.
- Prompt tốt (cung cấp context cụ thể, giới hạn phạm vi, yêu cầu liệt kê giả định) giảm đáng kể tần suất hallucination dù không loại bỏ hoàn toàn được nó.
- Xây dựng thói quen hoài nghi lành mạnh: coi mọi function call trong code AI-generated là "claim cần verify", không phải "fact đã chứng minh".