Tháng trước, một trợ lý AI đã tạo ra một đoạn mã Python cho một dự án thực tế. Kết quả chạy mà không gặp lỗi nào. Dữ liệu trông có vẻ rất ổn. Nhưng một đợt kiểm tra thủ công đã phát hiện ra mô hình truy vấn N+1 nằm ẩn sâu trong các lệnh gọi cơ sở dữ liệu. Với một tập dữ liệu nhỏ, mã nguồn hoạt động tốt. Nhưng khi mở rộng lên hàng nghìn bản ghi, ứng dụng sẽ thực hiện một truy vấn cho các đối tượng cha, sau đó là hàng nghìn truy vấn tiếp theo cho các dữ liệu liên quan. Kết quả sẽ là một sự sụt giảm hiệu năng đột ngột và nghiêm trọng mà không một bài kiểm tra đơn vị (unit test) nào có thể phát hiện được.
Đây chính là thực tế của phát triển phần mềm hiện đại. Các công cụ AI hiện nay có thể xử lý việc viết mã, gỡ lỗi và đưa ra các gợi ý kiến trúc với tốc độ mà không con người nào có thể theo kịp. Tốc độ đó là có thật. Tuy nhiên, nó thay đổi căn bản bản chất công việc của bạn. Bạn không còn được trả lương chủ yếu để gõ cú pháp nữa. Bạn được trả lương để kiểm định, để thiết kế kiến trúc và để bắt chính xác những loại bẫy vô hình như thế này.
Nguy hiểm thầm lặng của những thứ "Logic nhưng sai"
Mã do AI tạo ra thường trông có vẻ chính xác vì nó biên dịch được, chạy được và trả về giá trị mong đợi. Về mặt bề nổi, logic trông có vẻ hợp lý. Nhưng ẩn sâu bên dưới, nó có thể đã bị hỏng một cách âm thầm.
Hãy lấy ví dụ về biểu thức chính quy (regular expressions). Một AI có thể đưa cho bạn một mẫu khớp hoàn hảo với địa chỉ email hoặc các mã định danh trong tiếng Anh. Nhưng nếu chạy cùng biểu thức đó với các ký tự umlaut tiếng Đức, chữ viết tiếng Ả Rập hoặc các trường hợp biên của chuẩn hóa Unicode, nó sẽ thất bại một cách âm thầm. Mã nguồn không sai theo kiểu gây ra ngoại lệ (exception). Nó chỉ đơn giản là loại bỏ các dữ liệu thực tế hợp lệ.
Các truy vấn cơ sở dữ liệu cũng mang rủi ro tương tự. Một AI có thể viết một truy vấn PostgreSQL trả về đúng các hàng trong quá trình thử nghiệm, nhưng vẫn có thể làm phình to các bảng của bạn với các tuple chết (dead tuples), bỏ qua việc sử dụng index, hoặc buộc phải quét tuần tự (sequential scans) làm tê liệt các tác vụ thực tế trên môi trường production. Những gì hoạt động tốt trong một tập dữ liệu demo và những gì hoạt động tốt dưới tải thực tế là hai thứ hoàn toàn khác nhau. Máy móc không cảm nhận được độ trễ. Nó cũng không phải trả hóa đơn dịch vụ đám mây.
Từ Viết mã sang Xác minh
Sự chuyển dịch thiết yếu là chuyển từ câu hỏi "làm thế nào để tôi viết cái này?" sang "làm thế nào để tôi xác minh cái này?". Khi AI đảm nhận bản thảo đầu tiên, tải nhận thức của bạn nên chuyển xuống các bước sau đó. Bạn cần đọc mã theo cách một kiểm toán viên bảo mật đọc nó, chứ không phải theo cách một tác giả đang mệt mỏi đọc lướt qua tác phẩm của chính mình.
Điều này đòi hỏi một loại kỷ luật khác. Định kiến tự động hóa (Automation bias) là có thật. Khi một công cụ tạo ra kết quả trôi chảy, cú pháp hoàn hảo, não bộ con người sẽ có xu hướng thả lỏng. Bạn mặc định nó đúng vì cách trình bày trông rất chỉn chu. Kháng cự lại xung lực đó chính là kỹ năng cốt lõi hiện nay. Bạn phải coi mọi gợi ý đều là một giả thuyết cho đến khi nó được chứng minh là đúng.
Làm việc với Máy móc
Để nhận được kết quả hữu ích từ một trợ lý lập trình AI không phải là về việc gõ nhanh hơn. Đó là về việc rút ngắn khoảng cách giữa dữ liệu đào tạo của máy móc và thực tế cụ thể của bạn. Bạn có thể thu hẹp khoảng cách đó bằng một vài phương pháp thực hành cụ thể.
Hãy chính xác trong các câu lệnh (prompt). Sự mơ hồ không tạo ra thơ ca ở đây; nó tạo ra lỗi. Một câu lệnh như "tối ưu hóa hàm này" sẽ chỉ nhận được những lời khuyên chung chung. Thay vào đó, hãy viết "refactor vòng lặp Python này để sử dụng một lệnh cập nhật cơ sở dữ liệu hàng loạt (bulk update) duy nhất thay vì lưu từng lần lặp." Sự cụ thể giúp thu hẹp không gian khả năng.
Cung cấp ngữ cảnh thực tế. AI sẽ không biết bạn đang chạy Django 4.2 trên PostgreSQL 15 bên trong một cụm Kubernetes với giới hạn thời gian yêu cầu (request timeout) nghiêm ngặt là 30 giây trừ khi bạn nói cho nó biết. Hãy cung cấp cho nó các phiên bản phụ thuộc (dependency), các thư viện nội bộ và các ràng buộc không thể thương lượng của bạn. Ngữ cảnh không phải là vật trang trí; nó là rào chắn bảo vệ.
Dựa trên các tài liệu của chính bạn để làm căn cứ cho câu trả lời. Retrieval-Augmented Generation, hay RAG, không chỉ là một thuật ngữ thời thượng cho chatbot. Hãy hướng trợ lý của bạn vào các đặc tả API thực tế, các hồ sơ quyết định kiến trúc (architecture decision records) và các quy ước mã nguồn của bạn. Khi mô hình truy xuất các sự thật từ tài liệu của bạn thay vì đoán mò từ dữ liệu đào tạo, khoảng cách giữa lời khuyên chung chung và mã nguồn có thể sử dụng được sẽ được thu hẹp đáng kể.
Chia nhỏ công việc phức tạp thành các tác vụ riêng biệt. Các mô hình tác nhân (agent patterns) hoạt động tốt nhất khi mỗi bước có một phạm vi hẹp. Đừng yêu cầu refactor toàn bộ một microservice trong một lần duy nhất. Hãy yêu cầu sơ đồ dữ liệu (data schema) trước. Xác thực nó. Sau đó yêu cầu kịch bản di chuyển dữ liệu (migration script). Xác thực nó. Rồi mới chuyển sang lớp dịch vụ (service layer).
