Cơ sở dữ liệu không được thiết kế cho AI Agent: Cách xây dựng lớp phòng thủ hiệu quả

24 tháng 4, 2026·8 phút đọc

Các hệ thống AI Agent đang phá vỡ những giả định nền tảng trong thiết kế cơ sở dữ liệu suốt 40 năm qua. Bài viết này phân tích các rủi ro và đưa ra các mẫu thiết kế phòng thủ như soft delete, idempotency key và connection pool chuyên biệt để bảo vệ dữ liệu trước các tác nhân tự động.

Cơ sở dữ liệu không được thiết kế cho AI Agent: Cách xây dựng lớp phòng thủ hiệu quả

Trong suốt 40 năm qua, kiến trúc cơ sở dữ liệu được xây dựng dựa trên một "hợp đồng ngầm" giữa ứng dụng và hạ tầng dữ liệu. Chúng ta luôn mặc định rằng: người gọi là một ứng dụng do con người viết, chạy các mã code xác định, đưa ra các truy vấn có thể dự đoán và được xem xét kỹ lưỡng trước khi triển khai. Các thao tác ghi (write) đều có chủ đích, kết nối ngắn gọn và khi có sự cố, con người sẽ nhận ra.

Kiến trúc cơ sở dữ liệu truyền thốngKiến trúc cơ sở dữ liệu truyền thống

Nhờ hợp đồng này, cơ sở dữ liệu có thể "ngu ngơ" nhưng cực nhanh, bởi vì lớp ứng dụng đủ thông minh và cẩn thận. Tuy nhiên, sự trỗi dậy của Agentic AI (Hệ thống AI tác nhân) đang phá vỡ hoàn toàn hợp đồng này ở mọi tầng. Các tác nhân AI tự chủ, suy luận và đưa ra quyết định đã biến những giả định an toàn trước đây thành những lỗ hổng bảo mật nghiêm trọng.

Dưới đây là phân tích chi tiết về cách các giả định này bị phá vỡ và cách chúng ta thiết kế lại cơ sở dữ liệu để phòng thủ.

Giả định 1: Người gọi là con người và truy vấn có thể dự đoán được

Trước đây, các truy vấn đánh vào cơ sở dữ liệu đều do con người viết ra. Do đó, công cụ tối ưu hóa query, bộ nhớ đệm (cache) và pool kết nối đều được tinh chỉnh cho các mẫu truy vấn lặp lại và đã biết trước.

AI Agent hoạt động khác biệt hoàn toàn. Chúng "suy luận" để tạo ra truy vấn. Các đường dẫn suy luận khác nhau tạo ra các truy vấn hoàn toàn khác nhau trên cùng một bảng dữ liệu. Một Agent có thể thực hiện phép join qua 5 bảng chưa từng thấy trước đó, giữ kết nối trong khi nó "nghĩ" về kết quả, rồi sau đó đưa ra một truy vấn tiếp theo hoàn toàn khác biệt.

Giải pháp phòng thủ:

  • Thiết lập thời gian chờ (Timeouts): Đặt timeout ở cấp độ role (vai trò), không chỉ ở cấp độ ứng dụng. Một truy vấn của con người mất 30 giây là một lỗi cần sửa, nhưng một truy vấn của Agent mất 30 giây có thể là một vòng lặp suy luận không ai giám sát.
  • idle_in_transaction_session_timeout: Đây là thiết lập quan trọng. Các Agent có thể tạm dừng giữa chừng để suy luận trong khi vẫn giữ một giao dịch mở, dẫn đến khóa tài nguyên.

Giả định 2: Các thao tác ghi (Write) đều có chủ đích và được xem xét

Giả định nguy hiểm nhất là mọi lệnh ghi đều đã được con người xem xét. Agent viết dữ liệu tự chủ dựa trên sự hiểu biết hiện tại của chúng, mà sự hiểu biết này có thể sai. Chúng viết trong các vòng lặp khi công cụ trả về kết quả bất ngờ, hoặc thử lại (retry) khi gặp lỗi mạng tạm thời.

Một trường hợp thất bại thực tế đã được ghi nhận: một Agent gọi một API cũ nhận được HTTP 200 với tập kết quả rỗng. API thất bại âm thầm vì pool kết nối cơ sở dữ liệu bị cạn kiệt. Agent hiểu "không có dữ liệu" là "không có vấn đề gì" và tiếp tục xử lý 500 giao dịch với dữ liệu không đầy đủ.

Giải pháp phòng thủ:

  • Không bao giờ cho phép xóa cứng (Hard Delete): Luôn sử dụng Soft Delete (xóa mềm) làm mặc định cho mọi bảng Agent có quyền ghi.
  • Cột deleted_by: Cột này quan trọng hơn bạn nghĩ. Khi gỡ lỗi, câu lệnh "hiển thị mọi thứ mà Agent X đã xóa" sẽ cực kỳ hữu ích.
  • Bảng chỉ thêm (Append-only): Với các dữ liệu nhạy cảm như tài chính, kho hàng, hãy biến bảng thành append-only. Agent không bao giờ issued UPDATE hay DELETE, mà chỉ issued INSERT với trạng thái mới và lý do thay đổi. Đây là mô hình Event Sourcing áp dụng ở cấp bảng.
  • Khóa Idempotency: Agent thường thử lại tác vụ. Hãy sử dụng khóa idempotency để cơ sở dữ liệu từ chối các bản ghi trùng lặp một cách âm thầm, đảm bảo chạy thao tác 10 lần cũng cho kết quả giống như chạy 1 lần.

Giả định 3: Kết nối ngắn gọn

Kích thước pool kết nối truyền thống dựa trên mô hình: ứng dụng xử lý N yêu cầu đồng thời, mỗi yêu cầu cần một kết nối trong thời gian ngắn.

Tuy nhiên, một tác vụ suy luận đa bước của Agent có thể đưa ra truy vấn, tạm dừng để xử lý kết quả với LLM, đưa ra truy vấn khác, rồi lại tạm dừng. Mỗi lần tạm dừng đều giữ kết nối mở. Thời gian kết nối không còn là "thời gian thực thi truy vấn" mà là "thời gian thực thi + thời gian suy luận của LLM".

Giải pháp phòng thủ:

  • Pool kết nối chuyên biệt: Tạo một pool riêng cho workload của Agent, tách biệt với lưu lượng truy cập giao dịch của người dùng.
  • Pool_timeout ngắn: Ví dụ pool_timeout=3. Nếu Agent không lấy được kết nối trong 3 giây, nó nên thất bại nhanh và thử lại sau, thay vì xếp hàng vô tận.
  • Sử dụng PgBouncer: Chạy PgBouncer ở chế độ Transaction Pooling. Trong chế độ này, kết nối được trả về pool ngay sau mỗi giao dịch thay vì giữ cho toàn bộ phiên. 20 kết nối Postgres thực tế có thể phục vụ 500 kết nối Agent nhờ cơ chế này.

Giả định 4: Lỗi sẽ được phát hiện ngay lập tức

Trong hệ thống do con người vận hành, truy vấn chậm hoặc sai sẽ nhanh chóng được phát hiện qua dashboard chậm, timeout API. Nhưng Agent lại đóng vòng phản hồi này. Một Agent nhận kết quả chậm vẫn dùng kết quả đó. Một Agent nhận tập kết quả rỗng không biết là do dữ liệu thực sự không tồn tại hay do truy vấn sai, và nó tiếp tục viết quyết định dựa trên dữ liệu đọc bị lỗi.

Giải pháp phòng thủ:

  • Quan sát khả năng (Observability) chuyên biệt: Bạn cần biết Agent nào, tác vụ nào và bước suy luận nào tạo ra truy vấn.
  • Query Comments: Sử dụng comment trong truy vấn Postgres. Ví dụ: /* agent_id=fulfillment-v3, task_id=task-abc-123, step=check-inventory */ SELECT .... Những comment này xuất hiện trong pg_stat_activity và log truy vấn chậm, giúp bạn nhanh chóng tìm ra nguyên nhân.

Giả định 5: Schema là dành cho lập trình viên

Schema của bạn thường được đặt tên để thuận tiện cho kỹ sư, với các cột nullable mà "có ý nghĩa" chỉ khi đọc comment trong file migration. Khi Agent nhìn thấy schema thông qua Text-to-SQL, schema trở thành hợp đồng với mô hình ngôn ngữ (LLM). Tên cột và cấu trúc bảng ảnh hưởng trực tiếp đến việc LLM tạo ra truy vấn đúng hay "nhảm nhí".

Giải pháp phòng thủ:

  • Đặt tên rõ nghĩa: Đặt tên cột để LLM hiểu được ngữ cảnh.
  • Lớp View (View Layer): Xây dựng một lớp view hướng tới Agent để dịch các tên cột cũ kỹ thành tên có ý nghĩa.
  • Comment như Docstring: Viết comment cho cột như thể nó là tài liệu hướng dẫn, vì đối với Text-to-SQL, chúng thực sự là tài liệu.

Giả định 6: Ứng dụng là lớp bảo vệ chính

Các ứng dụng truyền thống chia sẻ role cơ sở dữ liệu, với giả định mã ứng dụng là rào chắn. Nhưng Agent là một "người suy luận tổng quát" với quyền truy cập kết nối cơ sở dữ liệu, không bị ràng buộc bởi các đường dẫn mã code xác định. Các rào chắn ở lớp ứng dụng không thể kiểm soát nó.

Giải pháp phòng thủ:

  • Quyền truy cập tối thiểu (Least-privilege): Thiết lập quyền truy cập riêng cho từng loại Agent ở cấp độ cơ sở dữ liệu. Câu hỏi không phải là "Agent này cần gì?", mà là "Trường hợp xấu nhất nếu Agent này suy luận sai hoặc bị lộ thông tin đăng nhập là gì?".

Kết luận

Không có công nghệ nào ở đây là mới. Soft delete, bảng append-only, role quyền tối thiểu, idempotency key, query tagging là những mô hình đã tồn tại nhiều năm. Sự thay đổi mà Agent mang lại là chuyển các mô hình này từ "thực hành tốt nhất nên triển khai" thành "hạ tầng chịu lực bắt buộc".

Cơ sở dữ liệu không được thiết kế cho người gọi này. Nhưng các công cụ để làm cho nó an toàn đã có sẵn ở đó. Chúng ta cần coi cơ sở dữ liệu như một lớp phòng thủ, luôn giả định rằng người gọi có thể sai, có thể thử lại vô hạn và có thể không giám sát kết quả.

Bài viết được tổng hợp và biên soạn bằng AI từ các nguồn tin tức công nghệ. Nội dung mang tính tham khảo. Xem bài gốc ↗