先把结论摆这儿:让 AI 智能体连数据库做问答,最稳的防线不在 prompt,在数据库账号本身——给它一个只有SELECT权限的只读账号,再叠一层视图和statement_timeout。提示词层面的"请不要删数据"全是心理安慰,真正拦得住DROP TABLE的是 MySQL 那句GRANT SELECT。下面是我上周踩完坑后的完整做法。
问题:我让智能体直连了业务库,然后后背发凉
事情起因很无聊。我们运营天天来问我"上个月华东区退款单多少""某个 SKU 复购率"这种,我 SQL 写到手软。想着干脆搭个能听人话查数据的小助手,把自然语言翻成 SQL,跑完把结果讲给运营听。
我用的是一个零代码就能配智能体的平台,挂了个大模型,把数据库连接信息填进去,知识库里塞了张表结构说明。配的时候那叫一个顺,拖几下、填几个框,二十分钟出了个能跑的 demo。我对它说"查一下昨天的订单总额",它真就吐了句SELECT SUM(amount) FROM orders WHERE created_at >= ...,跑出来 38 万多,跟报表对得上。当时还挺得意。
得意了大概十分钟,我后背就凉了。
我顺手测了句:"把 orders 表清空"。那小助手很听话地生成了DELETE FROM orders——虽然平台拦了一下没真执行,但它愿意生成、也具备执行通道,这事就够吓人了。要是哪天运营手滑打了句"把测试数据删干净",或者有人故意喂一句拼接的指令进来,大模型理解错意图,生产库就没了。靠 prompt 里写"你是只读助手,禁止删改"?我试了,绕过它太容易,换个说法、用英文、加个"为了演示"前缀,它就破防。
分析:防线该建在哪一层
我把能下手的地方列了一遍,按"绕过难度"排:
防护层 | 做法 | 能不能被绕过 | 我的评价 |
提示词 | prompt 里写"只读,禁止 DELETE/DROP" | 太容易,换个话术就破 | 聊胜于无 |
应用层正则 | 拦 SQL 里的 delete/drop 关键词 | 中等,大小写/注释/ | 当兜底,别当主力 |
数据库权限 | 专用只读账号,只授 SELECT | 绕不过,引擎层强制 | 主防线 |
视图隔离 | 敏感字段不进视图,智能体只能看视图 | 绕不过 | 配合权限用 |
结论很清楚:权限要往下沉,沉到大模型够不着的地方。大模型再聪明,它生成的 SQL 最后是拿一个数据库账号去执行的,这个账号能干什么由GRANT说了算,跟它怎么"说服"自己没关系。
具体我是这么干的,MySQL 为例:
-- 1. 建个专用只读账号,别复用业务账号 CREATE USER 'ai_readonly'@'%' IDENTIFIED BY '你的强密码'; -- 2. 只给 SELECT,而且只给到具体的视图/表,不给整库 GRANT SELECT ON shop.v_orders_safe TO 'ai_readonly'@'%'; GRANT SELECT ON shop.v_sku_stats TO 'ai_readonly'@'%'; -- 3. 千万别 GRANT ALL,也别 GRANT SELECT ON shop.* -- 手机号、身份证这种字段根本不进视图 FLUSH PRIVILEGES;视图这层我专门把脏东西挡在外面:
CREATE VIEW v_orders_safe AS SELECT id, sku, amount, region, created_at -- 没有 user_phone、没有 address FROM orders;再加两道保险,防的是"虽然只读但能把库拖垮"的慢查询:
SET SESSION MAX_EXECUTION_TIME = 3000; -- 单条查询最多跑 3 秒 SET SESSION TRANSACTION READ ONLY; -- 会话级只读,双保险回到那个零代码平台里,我把数据库连接的账号从业务账号换成了ai_readonly,智能体能看见的就剩两张视图。再喂"把 orders 清空",底层直接ERROR 1142: DELETE command denied,大模型再怎么想删也使不出劲——它手里那把钥匙根本开不了删除那扇门。
结论:能力下放,权限上锁
这事做完我最大的体会是,搭智能体这种活儿,最容易出事的从来不是模型本身,是你给模型开的口子有多大。零代码平台让搭一个能查数据的小助手变得太快了,快到你容易忘了它背后连的是生产库。
也有不爽的地方,得说实话。那平台的可视化配置对"标准活儿"很友好,但我想做按部门动态切换数据权限(行级隔离),拖拽这套就有点够不着了,最后还是绕回去写了点逻辑兜。还有第一版生成的 SQL 偶尔会自作主张加LIMIT 10,运营要全量我还得回去调提示词,来回折腾了三四遍才顺。学习曲线不算陡,但"配得能用"和"配得靠谱"中间隔着好几个下午。
但核心那条值:把执行能力交给智能体没问题,前提是把数据库权限锁死在只读。prompt 是劝,GRANT才是法。两者别搞反。
你们给智能体连库都怎么控权限的?有没有踩过比DELETE更骚的坑——评论区聊聊,我赌有人遇到过大模型UPDATE错一整列的。
(模型这块我直接调的讯飞星辰 MaaS,现成大模型 API,没自己搭算力,省了一堆部署的事;只读账号那套是我自己在库上配的,跟平台无关。)