
先把结论甩前面:让智能体把人话翻成SQL去查库,最该防的不是它写不对查询,是它在你没盯着的时候,把一句帮我清理下过期数据执行成了真的DELETE。下面这几个坑,我都是踩过血才知道要拦在哪一层。起因是上个月,运营那帮人天天来找我跑数。看看上周华东区退款单多少把昨天注册没下单的用户拉给我——一天七八次,我SQL写到手软。后来我花了俩晚上,拿一个零代码就能配智能体的工具,搭了个查数小助手:挂个大模型,把库表结构喂进去当知识,运营直接打字问,它生成SQL、跑、把结果用大白话回出来。第一版上线那天我挺得意的。然后第三天,差点出事。坑1:它真的会写出 DELETE / DROP我以为模型只会SELECT。天真。有个运营手抖打了句删掉这些测试订单,小助手就老老实实生成了DELETE FROM orders WHERE ...,还准备执行。幸好我连的是只读账号,它报权限错了才被我发现。解法,按优先级排:数据库层给只读账号。这是底线,别的全失效时它还在。建个只有SELECT权限的account,智能体只能用这个连。GRANT SELECT ON db.* TO agent_ro%;——就这一句,挡掉八成事故。SQL执行前做语句类型白名单。解析出来不是SELECT开头的,直接拒,连库都不连。别嫌两层重复,数据库权限是兜底,白名单是早拦,两个都要。坑2:运营的话里能藏注入这个更阴。有人问:查一下用户名等于 a OR 11 的记录。模型很听话,把那串原样拼进了SQL。虽然是查询,但条件被撑开了,返回了全表。防法只有一个真管用的:别让模型直接生成带值的完整SQL。让它生成带占位符的模板 一组参数,你这边用参数化查询(prepared statement)去填。WHERE name ?,值单独走绑定。模型负责结构,值永远不进SQL字符串。我后来还顺手加了条:生成的SQL里要是出现明文常量值而不是占位符,打回重生成。坑3:一句全量能把库拖垮SELECT * FROM orders,八百万行,没LIMIT。智能体不懂什么叫慢查询,运营也不懂,库懂——直接卡给你看。强制给生成的SQL尾部塞LIMIT 1000(没有就补上);给这个只读账号单独设查询超时,MySQL里max_execution_time几秒就够,跑超了自己断;复杂JOIN我干脆加了层校验,扫到三张表以上的关联先人工过一眼。坑4:表结构全喂进去 把家底亮给模型为了让它生成准,我一开始把整库schema全塞知识库了,包括user_password_hash、id_card那些字段。后来反应过来,模型生成时完全可能把敏感列写进SELECT。只喂业务真用得上的表和字段,敏感列在那层零代码工具里直接不进知识库,它看不见就查不到。一点不吹的实话搭这玩意儿没编程,拖拖配配两小时,但调prompt和这几道防护卡,我前后弄了快两天,中间还跑题去研究了半天怎么让它把结果排成表格——后来发现纯属多余,运营要的是数,不是好看。它也就只能干查数这种杂活,真复杂的分析还得我自己上。响应也不算快,一句问下去得等个三五秒。但说真的,运营现在不找我了,这点就值。防注入防删库这事,核心就一句:别信模型的输出,信你卡的那几道关。只读账号、参数化、LIMIT、敏感列不外露,四道叠上,出事概率低到能睡着觉。你们让Agent查库踩过啥更野的坑?评论区聊聊,我想看看还有哪个角度我没堵上。(模型这块我直接调的讯飞星辰MaaS,现成大模型API,没自己搭算力,省了部署那摊事)