Hoàn thành bài "Cơ sở: Cách một AI Agent nhận thức, lập kế hoạch và hành động" trước để mở khoá bài này.Đến bài trước

Giới thiệu

Các tác nhân AI trở nên hữu ích hơn rất nhiều khi chúng có thể tương tác trực tiếp với cơ sở dữ liệu quan hệ thay mặt người dùng — trả lời các câu hỏi như "sản phẩm bán chạy nhất quý trước là gì?" hay "Cập nhật địa chỉ giao hàng của khách hàng này" mà không có người viết SQL bằng tay. Thách thức là trang bị cho tác nhân quyền lực thực sự với cơ sở dữ liệu đồng thời ngăn nó thực thi các truy vấn phá hoại hoặc không an toàn. Bài học đi qua các khối xây dựng thực tế: cho phép tác nhân đọc sơ đồ của bạn, sinh SQL, xác thực SQL, và chỉ sau đó chạy nó trên một cơ sở dữ liệu thực tế.

Cấp quyền nhận thức về sơ đồ cho tác nhân

Một tác nhân không thể viết SQL đúng nếu nó không biết bảng và cột tồn tại. Kỹ thuật chuẩn là cung cấp cho mô hình một mô tả ngắn gọn về sơ đồ cơ sở dữ liệu như một phần của prompt hệ thống hoặc như một khối ngữ cảnh được truy xuất. Với cơ sở dữ liệu PostgreSQL, bạn có thể sao chép các bảng và cột bằng cách dùng information_schema, sau đó rút ngắn đầu ra trước khi chuyển cho mô hình.

sql
SELECT table_name, column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'public'
ORDER BY table_name, ordinal_position;

Các hàng trả về trở thành một bản tóm tắt văn bản mà tác nhân có thể tham chiếu bất cứ khi nào nó xây dựng một câu lệnh truy vấn. Nếu không có phần này, mô hình sẽ tự huyền thoại hóa (hallucinate) tên cột và gặp lỗi liên tục.

sơ đồ luồng cho thấy tác nhân nhận câu hỏi của người dùng, truy xuất ngữ cảnh sơ đồ từ siêu dữ liệu cơ sở dữ liệu, sinh một ứng viên SQL, xác thực SQL, rồi hoặc thực thi hoặc từ chối

Sinh và xác thực SQL

Khi tác nhân đã có ngữ cảnh sơ đồ, bạn yêu cầu nó tạo ra một câu lệnh SQL đơn nhất để đáp ứng yêu cầu của người dùng. Đóng gói đầu ra đó vào một trình phân tích để bạn có thể kiểm tra trước khi thực thi. Một pipeline vững chắc thực hiện ba việc theo thứ tự: (1) từ chối bất cứ thứ gì không phải là một câu lệnh duy nhất, (2) từ chối bất kỳ câu lệnh nào có động từ đầu tiên nằm trong danh sách bị cấm (DROP, TRUNCATE, DELETE mà không có WHERE, UPDATE mà không có WHERE, GRANT, v.v.), và (3) chạy câu lệnh với kết nối chỉ đọc hoặc có giới hạn tham số tùy theo mục đích.

python
import sqlparse
FORBIDDEN = {"drop", "truncate", "grant", "revoke"}
def safe_sql(raw: str) -> str:
parsed = sqlparse.parse(raw)
if len(parsed) != 1:
raise ValueError("Must be exactly one statement")
stmt = parsed[0]
first_token = stmt.get_type().lower()
head = stmt.token_first(skip_cm=True).value.lower()
if head in FORBIDDEN:
raise ValueError(f"Forbidden verb: {head}")
return str(stmt)

Lớp xác thực này được thực thi *trước* khi SQL tiếp xúc với cơ sở dữ liệu của bạn. Đây là hàng rào an toàn quan trọng nhất trong toàn bộ pipeline.

Thực thi thông qua một kết nối bị giới hạn

Ngay cả khi có xác thực, sự phòng thủ sâu vẫn quan trọng. Kết nối tới cơ sở dữ liệu với người dùng có quyền hạn chế sẵn: một vai trò chỉ đọc cho các câu hỏi phân tích, và một vai trò riêng chỉ có quyền INSERT/UPDATE cụ thể mà ứng dụng của bạn cần. Đặt thời gian bỏ qua câu lệnh (statement timeout) ở cấp phiên làm việc sao cho các truy vấn vượt quá mức không thể khóa một bảng trong vài phút.

sql
SET statement_timeout = '3s';
SET idle_in_transaction_session_timeout = '5s';

Ghép các thời gian chờ này với một giới hạn hàng được bổ sung vào các câu lệnh SELECT được sinh ra (ví dụ, luôn thêm LIMIT 100 trừ khi người dùng chủ động bỏ lựa chọn) để đại lý không thể kéo một bảng hàng triệu into memory và làm chậm hệ thống.

sơ đồ khối so sánh hai vai trò kết nối database — vai trò analytics chỉ đọc và vai trò ghi được giới hạn — cho thấy câu lệnh SQL nào mỗi vai trò được cho phép thực thi

Các bẫy phổ biến

Lỗi phổ biến nhất là để đại lý phản hồi lại SQL thô vào chat mà không bao giờ thực thi — người dùng sau đó sao chép và tự chạy, khiến bạn mất các ghi chú audit. Một lỗi khác là tin tưởng mô hình để “quyết định xem truy vấn có an toàn hay không” ngay trong cùng một prompt; tự kiểm soát là không đáng tin cậy, vì vậy luôn thực thi xác thực trong mã. Cuối cùng, tránh truyền đầy đủ lược đồ của một cơ sở dữ liệu khổng lồ: mô hình sẽ hao tổn ngữ cảnh vào các bảng nó không cần, vì vậy hãy lọc tới những bảng liên quan theo yêu cầu hoặc dùng embeddings để chỉ lấy các bảng phù hợp.

Tóm tắt

Kết nối một agent tới SQL là một vấn đề được phân lớp. Bắt đầu bằng cách phơi bày metadata schema để mô hình có thể viết SQL thực tế, sau đó sinh, phân tích và xác thực mọi câu lệnh trong mã trước khi thực thi. Hỗ trợ trình xác thực bằng quyền theo vai trò và thời gian chờ ở cấp kết nối để một sai sót hoặc prompt ác ý không thể xóa sạch một bảng. Với bốn lớp đó — ngữ cảnh schema, xác thực ở cấp mã, các vai trò hạn chế, và thời gian chờ — một agent có thể trả lời các câu hỏi dữ liệu và thực hiện các thao tác an toàn mà không đặt database của bạn vào rủi ro.

Luyện tập sau buổi học

Bài kiểm tra cuối bài

Ôn lại kiến thức, thử sức và nhận góp ý cho bài làm.

0/8
01Tại sao cung cấp metadata schema cho agent lại là điều kiện tiên quyết để sinh SQL chính xác?
02Động từ SQL nào nên bị từ chối một cách rõ ràng bởi lớp xác thực bất kể ngữ cảnh?
03Trong hàm Python safe_sql, mục đích của việc kiểm tra len(parsed) != 1 là gì?
04Tại sao áp dụng statement_timeout ở cấp độ phiên làm việc thay vì chỉ validate SQL trong mã?
05Vấn đề gì xảy ra khi bạn truyền toàn bộ schema của một cơ sở dữ liệu lớn vào prompt của agent?
06Tại sao việc để agent "tự kiểm tra" SQL của nó trong prompt được coi là không đáng tin cậy?
07Vai trò của người dùng cơ sở dữ liệu chỉ đọc trong thiết lập này là gì?
08Sắp xếp nào mô tả tốt nhất hàng lớp phòng thủ cho SQL do đại lý điều khiển?
Đã trả lời · 0/8
Kết nối AI Agents với Cơ sở dữ liệu SQL