AI bịa hàm hoặc thư viện không tồn tại vì nó viết mã bằng cách đoán phần tiếp theo trông hợp lý nhất, chứ không tra cứu xem tên đó có thật hay không. Khi một cái tên nghe đúng khuôn của thư viện, như một phương thức có tên rất "hợp lý", mô hình có thể viết ra với cùng độ tự tin như khi viết tên có thật. Hiện tượng này thường được gọi là ảo giác (hallucination).
Tin tốt là trong lập trình, ảo giác dễ bắt hơn nhiều so với trong văn bản thường: chạy mã là lộ. Bài này giải thích cơ chế, những kiểu bịa hay gặp, quy trình kiểm trong vài phút và cách đặt câu hỏi để giảm bịa ngay từ đầu.
Cơ chế: mô hình viết thứ trông giống thật nhất
Mô hình học từ một lượng mã khổng lồ, nên nó nắm rất chắc khuôn đặt tên của các thư viện phổ biến: phương thức đọc dữ liệu thường bắt đầu bằng get hoặc read, phương thức chuyển đổi thường có to, tham số tuỳ chọn thường có tên như timeout, encoding. Khi được hỏi về một việc mà nó không có ví dụ cụ thể, nó ghép các khuôn đó lại thành một cái tên rất hợp lý. Mô hình không có bước nào kiểm "tên này có trong thư viện không"; nó chỉ có xác suất của chữ tiếp theo.
Vì vậy ảo giác không phải lỗi ngẫu nhiên kiểu gõ nhầm. Nó có xu hướng rơi vào đúng những chỗ mà một người đọc lướt cũng thấy hợp lý. Đó là điều khiến nó nguy hiểm khi bạn không chạy thử, và cũng là lý do kinh nghiệm đọc mã của bạn vẫn quan trọng: người đã dùng thư viện đó nhiều lần thường thấy ngay chỗ lạ.
Các mô hình mới, nhất là khi được cho tra tài liệu hoặc chạy mã, bịa ít hơn hẳn so với vài năm trước. Nhưng chưa có bằng chứng nào cho thấy hiện tượng này biến mất hoàn toàn, nên quy trình kiểm vẫn cần.
Năm kiểu bịa hay gặp trong mã
Không phải mọi chỗ sai đều là ảo giác. Nhưng những kiểu dưới đây có chung dấu hiệu: cái tên nghe đúng mà không có thật, hoặc có thật nhưng ở chỗ khác.
| Kiểu bịa | Ví dụ giả định | Thường lộ ra lúc nào |
|---|---|---|
| Hàm hoặc phương thức không tồn tại | Gọi một phương thức "lọc theo ngày" trên đối tượng mà thư viện chưa từng có | Chạy tới dòng đó thì báo không có thuộc tính hoặc không có hàm |
| Trộn hai thư viện giống nhau | Trong Python, đối tượng phản hồi của thư viện requests có phương thức json, còn get_json là của đối tượng yêu cầu trong Flask; AI có thể viết lẫn hai cái | Báo lỗi không có thuộc tính, hoặc chạy được ở dự án này mà hỏng ở dự án khác |
| Tham số không có hoặc sai tên | Thêm một tham số tuỳ chọn nghe hợp lý vào hàm có sẵn | Báo lỗi tham số không mong đợi, hoặc tệ hơn là bị bỏ qua im lặng |
| Hàm có ở phiên bản khác | Dùng hàm str_contains của PHP trong khi máy chủ chạy PHP 7.4, hàm này chỉ có từ PHP 8.0 | Chạy tốt trên máy cá nhân, hỏng trên máy chủ |
| Gói thư viện không có thật | Gợi ý cài một gói có tên ghép từ hai từ khoá phổ biến | Lệnh cài báo không tìm thấy, hoặc tệ hơn là cài được một gói lạ do người khác đăng |
Kiểu cuối cùng cần chú ý riêng vì nó có thể thành vấn đề an ninh, sẽ nói ở phần dưới. Bốn kiểu đầu chủ yếu làm mất thời gian, và đều lộ ra nếu bạn chạy mã cùng một bộ kiểm thử tử tế.
Khi nào AI dễ bịa nhất
Biết trước những tình huống rủi ro cao giúp bạn tăng mức kiểm đúng chỗ, thay vì nghi ngờ mọi dòng như nhau.
- Thư viện ít người dùng, thư viện nội bộ công ty, hoặc thư viện của một dịch vụ nhỏ ở Việt Nam mà mã công khai về nó rất ít.
- Phiên bản mới ra sau thời điểm dữ liệu huấn luyện của mô hình được chốt, hoặc thư viện vừa đổi tên hàm giữa hai bản lớn.
- Câu hỏi rất cụ thể về tham số cấu hình, cờ dòng lệnh, tên biến môi trường của một công cụ, nơi chi tiết nhỏ quyết định mọi thứ.
- Khi bạn ép AI phải có câu trả lời, kiểu "viết hàm dùng thư viện X để làm Y" trong khi thư viện X không hỗ trợ Y. Mô hình thường cố viết thay vì nói là không có.
- Khi ngữ cảnh thiếu tệp khai báo phụ thuộc, nên AI không biết dự án đang dùng thư viện nào, phiên bản nào.
- Cuối các phiên trò chuyện rất dài, khi thông tin đúng bạn đưa ở đầu phiên đã trôi xa.
Ngược lại, với các hàm chuẩn của ngôn ngữ phổ biến và thư viện lớn lâu năm, tỉ lệ bịa thấp hơn nhiều. Lỗi ở đó thường là lỗi logic chứ không phải tên không có thật.
Bắt lỗi bịa trong vài phút
Quy trình dưới đây áp dụng cho bất kỳ đoạn mã nào AI đưa ra có dùng thư viện. Phần lớn chỉ mất vài giây mỗi bước.
- Đọc lướt và đánh dấu mọi tên hàm, tham số, tên gói mà bạn chưa từng thấy. Đó là danh sách cần kiểm.
- Dùng chức năng nhảy tới định nghĩa của trình soạn thảo. Tên có thật thì trình soạn thảo mở được định nghĩa; tên bịa thì không tìm thấy hoặc bị gạch chân.
- Kiểm nhanh trong môi trường đang chạy. Với Python, có thể chạy một dòng như python -c "import requests; print(hasattr(requests.Response, 'json'))" để biết thuộc tính đó có thật không. Với PHP, lệnh php -r "var_dump(function_exists('str_contains'));" chạy trên đúng máy chủ cho biết hàm có ở phiên bản đó hay không.
- Kiểm tên gói trước khi cài: xem thông tin gói trên kho chính thức của ngôn ngữ, như lệnh npm view tên-gói với JavaScript, hoặc trang của gói trên kho Python. Nhìn tác giả, số phiên bản, ngày phát hành, mức độ được dùng.
- Đối chiếu với tài liệu chính thức đúng phiên bản bạn đang dùng, không phải bài viết trên diễn đàn.
- Chạy kiểm thử hoặc chạy thử đoạn mã với dữ liệu mẫu. Đây là bước quyết định, các bước trên chỉ để lỗi lộ ra sớm hơn.
Nếu dự án dùng trình kiểm kiểu tĩnh như kiểm kiểu cho Python hay TypeScript ở chế độ chặt, nhiều tên bịa sẽ bị báo ngay khi bạn lưu tệp, trước cả khi chạy.
Hỏi thế nào để AI bịa ít hơn ngay từ đầu
Nêu phiên bản. Ghi rõ "Python 3.11, Django 4.2" hay "PHP 7.4" trong câu hỏi. Mô hình biết nhiều phiên bản và sẽ ưu tiên đúng cái bạn nói, thay vì trộn.
Đưa tệp khai báo phụ thuộc. Dán hoặc đính kèm tệp liệt kê thư viện của dự án. AI sẽ không đề xuất thư viện bạn không có, và biết đúng phiên bản.
Dán đoạn tài liệu liên quan. Với thư viện mới hoặc ít người dùng, dán phần tài liệu chính thức mô tả hàm cần dùng. Lúc đó AI viết dựa trên văn bản trước mặt thay vì trí nhớ.
Cho phép nói không biết. Thêm một câu như "Nếu thư viện này không có sẵn chức năng đó thì nói rõ và đề xuất cách khác, đừng tự đặt tên hàm". Câu này không loại bỏ hết ảo giác nhưng giảm rõ kiểu cố viết cho có.
Yêu cầu chỉ ra chỗ không chắc. Đề nghị AI đánh dấu những dòng dùng hàm mà nó không chắc có trong phiên bản bạn nêu. Danh sách đó chính là danh sách bạn cần kiểm trước.
Dùng công cụ có tra cứu hoặc chạy mã. Tác tử chạy được kiểm thử, hoặc trợ lý được phép đọc tài liệu, tự phát hiện nhiều tên bịa trước khi đưa cho bạn. Vẫn cần kiểm lại, nhưng phần việc nhẹ hơn.
Phân biệt ảo giác với lỗi logic thông thường
Không phải mọi mã sai của AI đều là bịa. Có hai loại lỗi khác nhau về bản chất và cách kiểm. Ảo giác là khi mã dựa trên một thứ không tồn tại: hàm, tham số, gói, tuỳ chọn cấu hình. Lỗi logic là khi mọi thứ được gọi đều có thật nhưng cách ghép sai: điều kiện đảo ngược, vòng lặp thiếu phần tử cuối, làm tròn tiền sai chỗ, quên trường hợp danh sách rỗng.
Ảo giác thường lộ ra rất sớm, ngay lần chạy đầu tiên hoặc ngay khi trình soạn thảo phân tích tệp, vì máy không tìm thấy thứ được gọi. Lỗi logic thì nguy hiểm hơn: mã chạy êm, trả về kết quả trông bình thường, chỉ sai với một số dữ liệu. Một đơn hàng có mã giảm giá lớn hơn tổng tiền, một khách có tên chứa dấu phẩy, một ngày cuối tháng hai. Những lỗi này chỉ bị bắt bởi kiểm thử có ca biên, hoặc bởi người đọc mã hiểu nghiệp vụ.
Vì vậy đừng thấy mã đã chạy được, không còn báo lỗi thiếu hàm, mà nghĩ là xong. Vượt qua được ảo giác mới là qua cửa đầu tiên. Phần kiểm thử và rà soát mã AI viết có cả một mục riêng trên trang, với cách viết ca biên và cách đọc mã trông đúng mà sai.
Gói thư viện không có thật: vì sao đáng lo hơn một lỗi chạy
Khi AI bịa một hàm, cái giá thường chỉ là một lỗi chạy và vài phút sửa. Khi AI bịa tên một gói thư viện, câu chuyện khác: kho thư viện công khai cho phép bất kỳ ai đăng gói mới. Nếu một cái tên bịa được AI gợi ý lặp lại cho nhiều người, kẻ xấu có thể đăng một gói đúng tên đó chứa mã độc, chờ ai đó chạy lệnh cài theo gợi ý. Cộng đồng bảo mật đã cảnh báo về kiểu rủi ro này.
Ở mức thói quen, chỉ cần một nguyên tắc: không cài gói nào chỉ vì AI gợi ý mà chưa tự kiểm gói đó trên kho chính thức. Với tác tử được quyền chạy lệnh cài đặt, nên để chế độ hỏi trước với lệnh cài gói. Cách phòng thủ chi tiết hơn, như khoá phiên bản và rà danh sách phụ thuộc, nằm ở mục an toàn mã nguồn và khoá bí mật của trang.
Câu hỏi thường gặp
AI bịa hàm có phải do mình hỏi sai không?
Không hẳn. Câu hỏi thiếu phiên bản hay thiếu ngữ cảnh làm tăng khả năng bịa, nhưng ngay cả câu hỏi tốt vẫn có thể gặp. Cách đúng là coi kiểm tra là một bước cố định, không phải phản ứng khi nghi ngờ.
Hỏi lại AI "hàm này có thật không" có tin được không?
Không nên coi đó là kiểm chứng. Mô hình có thể xác nhận nhầm cái nó vừa bịa, hoặc phủ nhận nhầm cái có thật. Kiểm bằng trình soạn thảo, môi trường chạy hoặc tài liệu chính thức mới đáng tin.
Mô hình đắt hơn có hết bịa không?
Mô hình mạnh hơn thường bịa ít hơn, nhất là với thư viện phổ biến. Nhưng chưa có mô hình nào bảo đảm không bịa, đặc biệt với thư viện mới hoặc ít người dùng, nên quy trình kiểm vẫn giữ nguyên.
Tại sao mã AI chạy trên máy mình mà hỏng trên máy chủ?
Một nguyên nhân hay gặp là khác phiên bản ngôn ngữ hoặc thư viện giữa hai môi trường, và AI viết theo phiên bản mới hơn cái máy chủ đang chạy. Ghi rõ phiên bản máy chủ khi hỏi và kiểm trên môi trường giống máy chủ.
Có công cụ nào tự phát hiện tên hàm bịa không?
Trình kiểm kiểu tĩnh, trình kiểm lỗi cú pháp và tính năng nhảy tới định nghĩa của trình soạn thảo phát hiện được phần lớn trường hợp với ngôn ngữ có kiểu. Với ngôn ngữ động, bộ kiểm thử chạy thật là lưới quan trọng nhất.
AI có bịa cả thông báo lỗi hay kết quả chạy không?
Có thể, khi nó không thật sự chạy mã mà mô tả kết quả "dự kiến". Chỉ tin kết quả chạy do chính bạn hoặc công cụ chạy thật hiển thị, không tin đoạn văn AI kể lại rằng mã đã chạy thành công.