1. AI Agent 直连数据库为什么总是翻车:先看清问题的本质
先说一个我亲眼见过的场景。某个团队的 AI Agent 刚上线时,设了一个自然语言查数的入口,让业务同事直接在对话里问"上个月华东区销售额 TOP10 的客户分别是谁"。模型很聪明,SQL 生成得也像模像样。结果这条 SQL 在一个几亿行的订单明细表上做全表扫描,把整个数据库连接池打满,核心交易链路直接卡死。更要命的是,这个 Agent 用的还是 DBA 的账号,理论上它不仅能查,还能删。
这个场景暴露了 AI Agent 访问数据库时最核心的矛盾:模型的能力越强,破坏半径越大。它能理解你的自然语言,能自己写 SQL,但它并不真正理解"哪些数据能碰、哪些操作会出大事、数据库当前的负载能不能扛得住"。这不是模型智商的问题,而是架构层面根本没有给它设定边界。
我当时跟那个团队的负责人聊,他说了一句话让我印象很深:"我们以为给 Agent 接上数据库它就变聪明了,结果它是先把我司的数据库搞挂了。"
所以我写这篇文章,核心就是想把这几年在 AI Agent 接入数据库这件事上攒下的经验梳理清楚,重点聊一聊安全的访问方案怎么做,NineData 这套带 Skill 机制的方案和 ChatDBA 这类 AI 数据库管理工具各自解决了什么问题,以及从 0 到 1 落地时哪些细节是教科书写不到、实战里一定会踩的。
先花点篇幅把"为什么翻车"讲透,因为不理解根源,后面所有安全措施都只是堆砌。
1.1 自然语言转 SQL 的不确定性,是风险的第一来源
大模型生成 SQL 不是一个"查表映射"的过程,而是一个概率生成的过程。同样的问法,换一次模型版本,或者换一种 prompt 措辞,生成的 SQL 可能完全不同。大多数情况下它是对的,但只要有一次生成出DELETE FROM orders WHERE status = 'pending'而实际你想的是"查一下有多少待处理订单",事故就发生了。
我见过不止一个团队在测试环境跑得好好的,一上生产就出事。原因很简单,测试数据量小、表结构简单、没有并发压力,模型怎么生成 SQL 都不会出大问题。生产环境的表动辄几千万行,一个不带索引条件的查询、一个忘记加 LIMIT 的联表查询、一个笛卡尔积,都是灾难。
这里有个关键认知:你没有办法通过 prompt 彻底消除这种不确定性。你可以约束"必须带 WHERE 条件""禁止 DELETE 操作",但模型在某些边界情况下还是会漏。真正可靠的做法是在数据库访问层做强制约束,让"模型想犯错也犯不了"。
1.2 权限过大是比 SQL 写错更隐蔽的问题
很多时候 Agent 接入数据库用的都是现成的连接信息,尤其常见的是拿 DBA 账号或者应用管理员的账号直接配置进去。这么做从研发效率上当然是最快的,但从安全角度说,等于把"神"级别的权限交给了一个"偶尔会犯迷糊"的司机。
数据库本身的权限体系其实设计得很完善,GRANT SELECT ON dbx.* TO 'agent_user'@'%'这种粒度完全够用。但问题在于很多 AI Agent 框架在设计时根本没有考虑"最小权限"这件事,文档里只教你填连接串,不教你建账号、分权限。于是大家默认就用最强的那个账号。
这里的情况有点像:你请了一个帮手来家里帮忙,本来只需要让他进客厅拿个快递,结果你直接把整套房子的钥匙、保险柜密码都交给他了。大多数时候他确实只是在客厅活动,但万一哪次他走错了房间呢?
1.3 上下文缺失与状态失控
人写 SQL 的时候脑子里是有上下文的:我知道当前数据库是哪个、这个表的字段代表什么含义、上一条查询跑出来多少行、事务有没有提交。AI Agent 默认情况下是没有这套状态感的。
典型的表现有几种:
- 连接池里几百个连接,Agent 每个请求都新建连接,用完不释放,池子耗尽。
- 生成了跨多表的复杂查询,没估算数据量就直接跑,把 IO 打满。
- 执行了写操作没有及时提交事务,锁一直持有,阻塞了其他业务。
- 问了上一句"查一下用户表结构",下一句"帮我查这个表的全部数据",模型没有意识到这条 SQL 会返回全表几百万行。
这些都是"状态"问题。解决思路不是让模型更聪明,而是让架构层帮它兜住底,把它不该有的自由度收走。
2. 四条安全防线:查、改、限、审的权限模型设计
聊完了问题根源,我们来看方案。我自己的实践中,把 AI Agent 访问数据库的安全模型归纳成四个字:查、改、限、审。无论你用什么工具、什么框架,最终都是在落实这四件事。
这四件事不是各管各的,而是一个层层递进的关系。查是基础能力,改是受控能力,限是兜底机制,审是复盘保障。缺任何一个,整个体系都有漏洞。
2.1 查:让 Agent 默认只能做查询
先说查。绝大部分 AI Agent 访问数据库的需求,本质上都是"查数"。业务人员想知道某个指标、某个榜单、某条订单的状态,这些都是读操作。所以最基础的安全策略,就是让 Agent 默认只能查询,所有写操作默认禁止。
具体落到数据库层,就一句话的事:
CREATE USER 'ai_agent'@'%' IDENTIFIED BY '强密码'; GRANT SELECT ON business_db.* TO 'ai_agent'@'%'; FLUSH PRIVILEGES;这样配完之后,哪怕模型哪天真生成了DELETE FROM users,数据库也会直接拒绝。这是最后一道物理屏障,比任何 prompt 约束都可靠。
这里有个细节容易被忽略:GRANT SELECT并不会自动限制某些敏感列。如果你有一张用户表里面有手机号、身份证号,而业务只是需要看姓名和城市,那么更精细的做法是建一个视图,只暴露业务需要的列,然后只给 Agent 授予视图的查询权限。
CREATE VIEW v_user_basic AS SELECT id, name, city FROM users; GRANT SELECT ON business_db.v_user_basic TO 'ai_agent'@'%';这个做法在银行、医疗这类强监管行业里几乎是标配,叫"按列授权"。AI 时代的数据库访问,建议大家都养成这个习惯,反正成本不高。
2.2 改:如果实在要写,请走审批流
有些场景确实避不开写操作。比如 Agent 要帮运营新建一条活动配置、要更新一批商品的状态。这种需求是合理的,但不能让 Agent 直接执行任意写操作,必须引入"审批+白名单"机制。
我的建议是把写操作收口成一个个"预定义模板"。什么意思呢?Agent 不允许自由生成 UPDATE、DELETE,但它可以说"我想创建一个新活动",然后代码里调用一个已经写好的create_campaign(params)函数。这个函数的执行,就是一次加了权限校验、参数校验、日志记录的受控操作。
用代码来表达大概是这个样子:
# 不安全的做法:让模型自由生成 UPDATE # agent.execute("UPDATE campaigns SET status = 'active' WHERE id = ?") # 安全的做法:只暴露预定义的操作函数 OPERATIONS = { "create_campaign": create_campaign, "update_campaign_status": update_campaign_status, } def create_campaign(campaign_name, start_time, end_time): # 参数校验、权限校验、操作日志 # 必要条件下进入待审批队列 ...模型只能从OPERATIONS字典里选函数来调用,函数内部的逻辑是开发人员写死的。这样即使模型犯迷糊,它能造成的破坏面也就是参数范围内的,不会有"自由发挥"的空间。
2.3 限:行数、超时、连接池的强制限制
限这道防线,对应的就是文章开头那个"几亿行表全表扫描"的痛点。无论读操作还是写操作,都必须加物理层面的兜底限制。
我把常用的限制手段列一张表:
| 限制维度 | 推荐做法 | 作用 |
|---|---|---|
| 查询行数 | 自动追加LIMIT 5000,或使用 SQL Rewrite 工具强制注入 | 防止一次返回太多数据 |
| 执行超时 | 设置max_execution_time(MySQL)/statement_timeout(PostgreSQL) | 防止慢查询拖垮数据库 |
| 连接数 | 为 Agent 创建独立连接账号,限制max_user_connections | 防止 Agent 耗尽连接池 |
| 资源组 | 低优先级账户绑定pg_terminate_backend控制策略 | 保障核心业务优先 |
以 MySQL 为例,直接在会话层做限制:
SET SESSION max_execution_time = 5000; -- 5秒超时 SET SESSION max_join_size = 1000000; -- 限制大JOIN SET SESSION sql_select_limit = 5000; -- 限制返回行数不要小看这几个SET SESSION,我在实践中发现很多 AI Agent 事故其实就是超时失控造成的。一条 SQL 跑 30 秒返回超时,Agent 又自动重试一次,相当于把负载加倍。设了超时之后,至少能把"模型犯错"的影响控制在一个可接受的范围内。
连接池这块也值得单独说。AI Agent 的调用模式和传统应用很不一样,用户在上面多轮对话,每一轮都可能触发一次数据库访问,而且访问是突发的、短连接式的。如果直接用传统的连接池配置,很容易出现"池子里全是空闲连接,但新请求拿不到连接"的诡异现象。
一个比较实用的配置思路:Agent 的数据库账号单独用一个连接池,大小控制在业务高峰期所需连接数的 1/3 到 1/2,超出的请求排队而不是新建连接。宁可让 Agent 等一两秒,也别让它把数据库连接打满。
2.4 审:所有 SQL 都留痕,事故才能复盘
最后是审。AI Agent 访问数据库最大的特点就是不可预测性强,所以审计日志不是可选项,而是必选项。每一句由 Agent 执行的 SQL,都应该记录下完整信息:执行时间、执行用户、SQL 全文、影响行数、来源会话/对话 ID。
审计日志的价值在平时体现不出来,一旦出事故,它就是复原现场的唯一手段。我自己排查过好几次 AI Agent 相关的数据库问题,几乎全是靠审计日志定位的:发现某个时刻有个异常的全表查询,追踪到是模型在某个对话上下文里"自作主张"生成的,然后才知道要优化 prompt 还是收紧权限。
审计日志的存储建议单独放一个库或者直接用日志系统,别跟业务库混在一起,否则排查问题时还要担心日志查询影响到在线业务。另外,日志里如果可能包含敏感数据(比如 SQL 里带手机号、身份证查询条件),建议对关键字段做脱敏处理再落库。这个细节很多人没想到,但合规审计时会卡人。
3. NineData Skill 的接入机制:把数据库能力封装成可复用的"技能"
前面聊的是一些通用的安全框架,接下来我们落到具体工具。NineData 这套方案里有个核心概念叫 Skill,我的理解是:Skill 本身不是一个数据库,而是把"数据库访问能力"封装成 Agent 可以安全调用的标准化接口层。
3.1 Skill 机制到底解决什么问题
如果你上手过 AI Agent 开发,应该会遇到一个很别扭的情况:Agent 框架本身跟数据库是分离的。Agent 需要数据,就得自己去连库、写 SQL、处理结果。这个过程中,每一步都有可能出错,也都有可能越权。
NineData Skill 做的事情,说白了就是把中间这层"从自然语言到数据库操作"的过程抽出来,变成 Agent 侧的"一个工具"。Agent 不再关心数据库地址、账号密码、表结构,它只需要知道自己有一个 skill 可以"查订单数据""创建数据源""同步表结构",至于这个 skill 内部怎么连库、怎么生成 SQL、怎么做权限控制,都是 NineData 这一侧统一处理的。
相当于你从"给 Agent 一把数据库钥匙"变成了"给 Agent 一部对讲机,它只能通过对讲机向接线员提需求"。
这个设计的好处很明显:数据库连接信息不用暴露给 Agent 侧,Agent 无法直接构造任意 SQL,所有数据库操作都经过一个中间控制层。
3.2 配置一个 Skill 的完整步骤
实操层面,在 NineData 里创建一个 Skill 大致走这几个流程:
第一步,先接入数据源。NineData 支持 MySQL、PostgreSQL、Oracle、SQL Server 等主流数据库,你先在控制台里把数据库连接配置好。这里的连接信息是存在 NineData 侧的,不是存在 Agent 侧。
第二步,创建自定义技能。技能名称建议起得像"人话",因为在 Agent 对话里,模型要根据技能名字来判断什么时候调用它。比如一个技能叫"查询订单数据",那么用户问"最近订单量怎么样"时,模型就会倾向于调用这个技能;如果技能叫"orders_api",模型在理解上就多了一层障碍,容易选错。
第三步,配置技能内部的规则和约束。这是安全的核心环节,你需要告诉 NineData 这个技能可以执行哪些操作、不可以执行哪些操作。例如:
- 允许执行:SELECT 查询
- 禁止执行:DELETE、UPDATE、DROP
- 默认注入:
LIMIT 1000 - 敏感语句:需要二次确认才能放行
这些规则配好之后,Agent 调用技能时,NineData 会按规则对模型生成的 SQL 做检查,不合规的直接拦截。
第四步,发布技能并绑定到 Agent。Skill 发布后,Agent 的应用代码里只需要声明"我有这个技能"就可以开始用了。具体调用细节对 Agent 透明,Agent 侧不用写任何 SQL 生成逻辑。
3.3 为什么说 Skill 比直连数据库更符合 AI 时代的安全模型
直连数据库的方案也可以做很好,能配权限、能加审计,但有一个本质问题是绕不开的:它把"数据访问能力"和"数据访问意图"耦合在了一起。Agent 每次访问数据库,都是自己生成 SQL、自己执行,安全规则是分散在数据库层和应用层的。
Skill 模式则把意图与执行做了物理隔离。Agent 只需要表达"我要查订单数据"这个意图,技能的内部实现与 Agent 无关。因此:
- Agent 侧代码可以保持纯净,不需要在代码库里维护数据库连接信息。
- 数据团队可以在 NineData 侧集中管理所有 Agent 的技能权限,谁有权限用哪个技能一目了然。
- 技能内部可以用自然语言规则加上硬性拦截双管齐下,实用性比只有数据库层权限要高不少。
这个设计在 MCP(Model Context Protocol)生态成熟之前,算是把工具层做得很完整的一个方案。如果你是在一个团队里做 AI Agent 项目,需要同时管理多个 Agent 的数据库访问权,NineData 这套技能治理的思路值得参考。
4. ChatDBA 的实操流程:建账号、配权限、让 Agent 自动查数
说完了 NineData,再来看看 ChatDBA 这类 AI 数据库管理方案。ChatDBA 更侧重于"用 AI 对话来管理数据库本身",它解决的问题不完全等同于 Agent 访问数据,而是让人和 Agent 都能通过自然语言去操作数据库——查状态、看性能、分析慢查询、甚至做变更。
这两个东西其实是个组合关系:NineData Skill 解决的是"Agent 怎么访问数据"的通道问题,ChatDBA 解决的是"数据库怎么被 AI 管理"的入口问题。如果你既要让 Agent 查数,又要让 DBA 用 AI 辅助运维,那这两者是互补的。
4.1 ChatDBA 一类工具的核心执行链路
ChatDBA 类型的工具工作链路大致是这样的:
用户输入自然语言 → 模型理解意图 → 映射到具体的数据库操作 → 执行并返回结果。
关键在于第二步到第三步的映射过程,好的工具会在这一层加一个"安全校验层"。比如用户问"把测试库的 users 表删了",模型能理解这个意图,但执行层会拒绝,原因可能是"检测到高危操作,需要管理员确认"。
实操里我建议把使用场景分成两类:
一类是查询类,类似"最近数据库 CPU 为什么高""这个慢查询什么情况"。这类操作一般是只读权限,安全风险低,可以直接交给 ChatDBA 跑。
另一类是变更类,类似"给 users 表加一个字段"“调整这条 SQL 的索引”。这类操作影响面大,一定要在设计上走审批流程。很多 ChatDBA 工具本身带工作流,可以配置"变更需要审批"的规则,命令先生成并冻结,确认后才真正执行。
4.2 从 0 到 1 搭建一个"AI 能查数、不能闯祸"的环境
如果你现在想在自己的环境里搭一套类似的能力,不想引入太多平台依赖,可以按下面的思路自己实现。这个思路本身也可以作为理解 ChatDBA 类方案的最小实现版本。
第一步,做数据源抽象。把你所有允许 AI 访问的数据源统一成一个接口,不要出现多个入口。
第二步,给模型配工具说明。在 Agent 的工具注册表里,写清楚每个工具是干什么的、参数是什么、参数有哪些约束。这一步非常关键,一个好的工具描述能把模型选错工具的概率大幅降低。
第三步,在工具执行入口统一鉴权和审计。不管 Agent 内部怎么调度,每个工具的最终执行都走同一个入口函数,在这个函数里做权限检查、SQL 改写、日志记录。
简单示意:
def execute_tool(tool_name, params, session): # 1. 权限校验 if not check_permission(session.user, tool_name): raise PermissionDenied(...) # 2. SQL/参数改写 safe_sql = apply_limits(params.get("sql", ""), max_rows=5000) # 3. 审计日志 log_action(session, tool_name, safe_sql, params) # 4. 执行 result = db_execute(safe_sql) return result这样不管是接入 Cursor 这类 IDE 工具,还是自己在 Spring AI 技术栈里做 Agent 开发,都能把安全逻辑收敛到一个点上。
4.3 自然语言查数的典型场景复现
说个我在生产环境里实际调通的场景。业务同事问 Agent:"帮我查下上周每天的新增注册用户数。"
这个需求如果让 Agent 自由发挥,它需要知道:用户表叫什么名字、注册时间字段是哪个、日期怎么格式化、要不要按天分组、时区怎么处理。看似简单,但任何一个环节猜错,结果都是错的。
在 NineData Skill 的框架下,做法是这样的:先做一个"查询新增用户趋势"的技能,技能内部配置好表名、字段名、默认聚合方式。Agent 接到用户提问后,判断"这个需求匹配查询用户趋势技能",然后调用技能,技能内部自动拼出正确的 SQL:
SELECT DATE(created_at) AS day, COUNT(*) AS new_users FROM users WHERE created_at >= [起始日期] AND created_at < [终止日期] GROUP BY DATE(created_at) ORDER BY day;用户不需要懂表结构,Agent 也不需要猜表结构。整个过程安全、稳定、可重复。这才是 AI 查数的正确打开方式。
5. 落地过程中踩过的坑与排查思路
最后这部分,我打算把实操中最容易踩的坑拿出来摆一摆。这些坑不是我编的,是真实环境中一遍遍踩出来的。
5.1 权限设置正确,但连接走错了库
有个很有意思的坑:权限配置完全正确,GRANT SELECT没漏,但 Agent 查出来的数据总是对不上。查了半天才发现,问题是同一个用户名在多个数据库实例上存在,Agent 配置的连接地址指向了测试库,而业务数据在正式库。AI Agent 项目里这种"配置到一半,环境切错了"的低级错误其实特别常见,因为 Agent 的配置文件常常是几个人轮流改的。
排查思路很简单但很有效:先用一个只读账号手动连一下配置的地址,SELECT DATABASE()确认实例和库名都对。再在审计日志里看 Agent 实际执行的 SQL,确认它查的是哪个库。这一步做完,大多数环境问题都能暴露。
5.2 连接池配置的"隐形杀手"
之前提到过,AI Agent 的访问模式是突发的、多轮对话式的,对连接池的消耗方式和传统应用完全不同。我见过一个项目,Agent 服务上线后,数据库连接数每隔几分钟就暴涨一次,顶到数据库最大连接上限,然后所有业务跟着遭殃。
事后分析发现原因:Agent 框架里每轮对话都新建了好几个数据库客户端实例,用完也没有正确关闭。再加上模型生成 SQL 的耗时较长,客户端等待期间连接一直持着不放,连接数自然就堆上去了。
正确的做法是:给 Agent 侧配置一个独立的数据库连接池,设置最大连接数和空闲回收时间,并且把 Agent 客户端设为单例复用。如果你用的是 Spring AI 或 LangChain 这类框架,注意别在每次请求时 new 客户端。这个细节文档里经常提,但实战中太容易因为追求快速跑通而忽略。
5.3 模型生成的 SQL 超出数据权限
还有一个更隐蔽的场景。权限层面你给 Agent 只开了查询权限,但模型生成的 SQL 里带了一个视图。视图在 MySQL 里默认是DEFINER权限的,也就是说,如果视图的定义者权限更高,Agent 虽然只有SELECT权限,却能通过视图访问到底层更宽范围的数据。
这不是模型的问题,是数据库视图机制在低权限账号下的一种"权限绕过"。排查方法是对 Agent 能访问的每个视图做权限审视,确保视图定义者不是高权限账号,或者干脆使用SQL SECURITY INVOKER模式创建视图。这个坑有一定隐蔽性,我也是在一次数据越权事故复盘时才发现。
CREATE SQL SECURITY INVOKER VIEW v_safe_user_data AS SELECT id, name FROM users;用INVOKER模式后,查询视图时走的是调用者权限,Agent 的只读边界就不会被意外扩大。
5.4 设置超时之后,注意"半成品"查询
给 Agent 的 SQL 都设了max_execution_time后,确实能防止慢查询拖垮数据库,但新的问题来了:某些复杂查询跑到一半被强制终止,可能在数据库里留下大事务、临时表或者未提交的写操作。
尤其是在写操作场景下,一条UPDATE跑到一半超时被杀,事务回滚不一定及时执行,后续的 Agent 对话再发起相同的更新操作,就可能撞上锁等待。对这种问题,我的建议是:写操作尽量让 Agent 走"提交—确认—幂等"模式,同一条写指令不要自动重试,重试前人工确认。读操作超时被杀一般没大问题,但客户端要做好超时异常的处理,别让模型擅自再发一次同样的请求。
5.5 别忽略数据库账号的密码管理
最后聊一个"听起来像小事"但是坑很深的问题。AI Agent 的数据库账号密码,很多团队直接写在配置文件里,甚至传到代码仓库里。一旦代码仓库是共享的,这个账号就等于是公开的。
建议的做法:
- 账号密码用专门的密钥管理服务存放,Agent 侧动态读取。
- 给 Agent 账号设置定期轮换。
- 使用独立于人工 DBA 的账号体系,这样审计日志里能明确分辨哪些操作来自 Agent,哪些操作来自人类。
这一步不复杂,但在整体安全方案里属于"地基"级别。基地方了,上面做的权限模型、SQL 改写、审计日志才有意义。
6. 对几个常见问题的补充说明
写到这里,我想把读者可能会纠结的几个问题一并回答了,省得大家再走弯路。
6.1 有了 Skill 还需要做数据库层权限控制吗
需要。Skill 只是把"数据库访问的入口"收口了,但数据库本身的权限体系依然是最后一道防线。理想状态是双层防护:Skill 层做语义理解和规则校验,数据库层做物理权限限制。两层都配置正确的情况下,即使某一层出现逻辑漏洞,另一层还能兜住。
6.2 Agent 开发框架跟这些方案怎么配合
如果你用 Spring AI 或者 LangChain 开发 Agent,NineData Skill 可以作为 Agent 的工具(Tool)注册进去。相当于你给 Agent 配了一个"数据库专家"的工具,这个工具的底层实现由 NineData 接管。代码层面不需要额外引入复杂的东西,就是标准工具调用。
这也回答了很多人的疑问:"我已经在一个 Agent 框架里了,怎么接入这些安全能力?"答案是:引入一个工具,而不是改造框架。把数据库访问从"框架原生能力"降级为"一个受控工具",本身就是一种安全收敛。
6.3 企业里应该谁负责配置这些安全策略
我的建议是:数据库访问策略必须由 DBA 或数据平台团队来配置和维护,不要让算法工程师自己定。原因很简单,算法工程师关注的是模型能不能理解用户意图,DBA 关注的是数据库扛不扛得住、权限边界在哪里。这两个关注点需要的知识完全不一样,而且数据库安全的坑只有天天跟数据库打交道的人才熟悉。
实际操作中,我见过很多团队让算法同学自己去开数据库账号、配权限,结果把GRANT ALL PRIVILEGES ON *.* TO 'agent'@'%'配上去了。这不能怪他们,他们只是没受过数据库权限管理的训练。所以,配置权和管理权要分开,这是团队协作层面的一条安全红线。
6.4 关于数据库同步和备份
最后补充一个和 AI Agent 不那么直接、但经常被一起提起的话题:数据库同步工具。有段时间热词里关于数据库同步的问题不少,我在这里多说一句。如果你给 Agent 提供的是分析查询,建议优先考虑从从库或者只读副本读取数据。这样 Agent 的任何查询行为都不会影响主库的写入性能。数据库同步工具在这里的价值,就是保证从库数据的新鲜度足够支撑 AI 查询的时效要求。
这个思路本质上也是安全模型的一部分:让 Agent 远离主库,从物理层面隔离风险。别嫌麻烦,生产环境上,Agent 直接读主库的代价早晚会体现在事故报告里。
我自己的经验是,AI Agent 访问数据库这个题目,技术难度不算特别高,难的是把"安全"这件事做到位。安全不是某一个单一的配置项,而是从账号体系、权限模型、SQL 约束、超时兜底、审计追踪一直到团队职责划分这套完整链条。链条里每一环都不能断,断了,模型再聪明也白搭。
最后分享一个我一直在坚持的习惯:任何 Agent 接入新数据源之前,先让它在只读权限下跑一个星期的对话,每天定时看一眼审计日志里有没有异常的 SQL 生成。如果一周都没有问题,再考虑逐步放开更多操作权限。这个习惯帮我躲掉了不少潜在的雷,大家可以试试。