news 2026/9/8 7:27:41

AI Agent写SQL时代,数据库选型与查询治理指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI Agent写SQL时代,数据库选型与查询治理指南

最近和一个团队聊到他们准备给内部系统接入 AI Agents 的需求。第一轮技术评审时,大家花了很长时间争论 MySQL 和 PostgreSQL 的差异,但从我的角度看,这个问题可能被带偏了。当数据库查询语句不再由程序员手写,而是由 LLM 动态生成时,选数据库本质上是在挑一套查询治理机制。这比比较单个 SQL 的写法差异重要得多。

简单说,LLM 生成 SQL 的技术难点早就不是“模型能不能把自然语言翻译成数据库方言”,而是生成之后,这条 SQL 是否安全、是否可控、是否能在生产环境里稳定执行。数据库选型,决定了这些问题好不好解决。

1. 先想清楚一个问题:Agent 写 SQL,为什么不是一个“翻译问题”

很多人以为,LLM 生成 SQL 就是“自然语言 → 数据库方言”的翻译。模型学过的 SQL 语法很多,常见表结构也能猜个大概。可真正到了落地阶段,问题并不是语法,而是 Agent 和数据库之间的协作方式。

传统应用查询,是程序员写 SQL,经过 code review,输入用参数绑定,查询范围固定。AI Agent 不一样。它面对的是开放输入,用户想问什么,模型就动态生成一条查询。字段、JOIN、WHERE、GROUP BY 都可能由模型自由发挥。数据库在这种情况下,面对的是一类全新的查询模式:范围不可预测、组合不可控、频率不可估算。

1.1 传统查询是有边界的,Agent 查询是边界打开的

传统查询的边界有三层:

  • 访问边界:程序员知道用户可能访问哪些表,SQL 是枚举出来的。
  • 资源边界:查询经过预审,复杂 JOIN 会被优化或拦截。
  • 安全边界:参数化查询降低了注入风险,权限固定。

Agent 查询打破了这三层边界。用户可能问出任何一个和业务相关的问题,模型会临时组合查询条件;如果 Prompt 或上下文没约束好,它可能访问不相关的表;如果结果集过大,资源占用也难以预判。

所以我说,选数据库不是选“谁生成 SQL 更快”,而是选“谁的治理机制更适合承接这类边界打开的查询”。这才是 LLM 生成 SQL 场景下数据库选型的真实问题。

1.2 选数据库,其实是在选“查询治理方式”

数据库能不能承接 Agent 查询,主要体现在几个能力上:

  • 是否容易创建只读账号和行级权限。
  • 是否有成熟的 statement timeout。
  • 是否能通过监控视图看到慢查询和锁等待。
  • 是否方便把 schema 导出成 LLM 能理解的 JSON 或 Markdown。
  • 是否有审计日志,能追溯“是谁通过 Agent 查走了什么数据”。

这些能力决定了 LLM 生成的 SQL 是“裸奔式查询”,还是“可管理的生产流量”。

宁可选择一个支持精细控制的普通数据库,也不要让 Agent 直连一个没有限制的“快数据库”。

2. 从 SQLite 到 PostgreSQL:不同阶段,数据库承载的任务不一样

数据库选型不是一步到位,而是跟着项目成熟度走的。Chat with your data 类的 Agent 项目,通常会经历三个典型阶段:原型验证、内部工具、生产服务。每个阶段适合的数据库并不相同。

2.1 原型阶段:SQLite 的低门槛和它的明显局限

SQLite 在本地数据测试、Prompt 调优、快速跑通流程时非常顺手。单文件、零配置、用一个 Python 脚本就能验证“LLM 生成的 SQL 是否正确执行”。如果你只是想验证某个模型生成 SQL 的能力,SQLite 是成本最低的起点。

但它的局限也很明显。第一,并发能力弱,几个查询同时进来就可能出现数据库锁等待。第二,权限控制约等于没有,没有多用户、行级权限、语句超时这些生产级概念。第三,网络访问能力有限,很难给多个 Agent 客户端共用。

所以,SQLite 适合个人桌面、本地试验、百行以内的演示数据。同时接入多个用户和 Agent 服务时,它很快就会变成瓶颈。

2.2 生产阶段:PostgreSQL 是更稳妥的默认起点

如果不想在选型初期纠结太久,我更建议直接选 PostgreSQL。理由不是它比 MySQL 快多少,而是它更适合“治理”Agent 查询:

  • 可以用CREATE ROLE+GRANT SELECT快速构建只读账号。
  • 支持行级安全策略(Row Level Security),可以做租户级数据隔离。
  • pg_stat_statements观察慢查询和锁等待。
  • statement_timeout兜底,防止单条 SQL 把数据库拖垮。
  • 扩展生态里有pgvector,可以把业务表向量索引放在同一个库。
  • 对 JSON、数组、全文检索、数据库函数支持较好,适合多类型数据源。

这些能力并不全是 MySQL 做不到,但它们更集中地出现在 PostgreSQL 里。Agent 场景最缺的就是这种“集中治理能力”,而不是某一个特性。

2.3 如果一定需要向量检索,先不要单独引入向量库

很多 Agent 项目一上来就引入向量数据库,理由是“要做知识库”“要做语义检索”。但如果你的核心链路还是要对业务数据进行结构化查询,那向量部分应该只是辅助检索,而不是主数据库。

我见过一个项目,前期把用户提问向量化后存进专用向量库,业务数据放在 PostgreSQL。结果 Agent 每次回答都要跨库调用,先查向量库拿到相关记录 ID,再去 PostgreSQL 查业务明细,调试链路非常长。后来把向量直接放进 PostgreSQL 的pgvector字段,查询从跨服务调用变成同一个库里的 SQL 调用,整体复杂度下降很多。

当然,如果你的数据量到了上亿级,且高并发相似度搜索是主路径,专用向量库更有优势。这个临界点取决于数据规模、并发、延迟预算。不要在几十万条数据时提前做这种优化。

目标阶段方案优点主要限制
原型验证SQLite零配置、单机快速权限、并发、网络能力弱
内部工具 / 小规模生产PostgreSQL + Schema + 只读账号治理能力强、可观察性高需要基本运维能力
知识库 / 语义检索辅助PostgreSQL + pgvector 起步统一存储、减少跨库调用高并发向量检索需要压测
超大规模向量检索专用向量数据库检索性能强、扩展性好需要处理数据同步和一致性

这个表更多是通用经验,不是绝对结论。真实选型时,还是要根据你的数据量、团队维护能力和查询模式来判断。

3. 选型不是终点:把数据库改造成一个能安全交给 Agent 的查询系统

有了合适的数据库只是第一步。真正决定 LLM 生成 SQL 能不能落地的,是你能不能把数据库改造成一个适合 Agent 使用的查询系统。

这里有一个很好的类比:把数据库开放给 AI Agent,类似于把公司数据库开放给一位新来的数据分析师。你不会直接把管理员密码给他,而是给他一个只读账号,外加一份表格说明。LLM 也一样,它比人类更需要结构化上下文和边界约束。

3.1 第一步:让模型看到 schema,而不是看到所有数据

给 LLM 的上下文里,不建议放真实数据样本。这样既容易泄露隐私,也会占用大量 token。更合理的做法,是把表结构、字段注释、枚举值说明、表关系说明都结构化地放进 Prompt 里。

常见做法是把 schema 转成 JSON 或 Markdown 再交给模型。比如:

{ "table": "orders", "description": "订单主表,每行一个订单", "columns": [ {"name": "id", "type": "integer", "description": "订单 ID,主键"}, {"name": "created_at", "type": "timestamp", "description": "下单时间"}, {"name": "customer_id", "type": "integer", "description": "下单客户,关联 customers.id"}, {"name": "amount", "type": "numeric", "description": "订单金额,单位元"} ] }

这样做有两个好处。一是减少模型因为猜表名、猜字段含义而生成错误 SQL 的概率;二是把模型的“可见范围”放在受控的 schema 内,避免它去访问不相干的业务表。

3.2 第二步:用权限和只读账号锁住边界

不要把数据库管理账号直接给 Agent。常见做法是创建一个单独的只读角色,只开SELECT,限制连接数,必要时只允许访问特定 schema。

-- 通用示例结构,具体参数请根据实际环境调整 CREATE ROLE agent_reader WITH LOGIN PASSWORD 'replace-with-strong-password'; GRANT CONNECT ON DATABASE appdb TO agent_reader; GRANT USAGE ON SCHEMA public TO agent_reader; GRANT SELECT ON ALL TABLES IN SCHEMA public TO agent_reader; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO agent_reader;

但注意,只读账号只限制写操作,不限制“坏查询”。某些复杂 JOIN 可能让数据库占用大量资源,所以还必须有超时和并发限制。

3.3 第三步:用超时和资源配额兜底

每条 Agent 生成的 SQL,都应该在事务层和语句层加限制。以 PostgreSQL 为例,可以在会话开始时执行:

SET statement_timeout = '10s'; SET default_transaction_read_only = on;

同时,连接池层面也要限制 Agent 专用连接数,避免某次任务并发生成大量查询,把连接池打满。

这一步看起来是配置问题,但在生产环境里,它比模型 Prompt 更关键。因为模型生成 SQL 一定会有超出预期的时候,数据库层兜底才是最后一道防线。

单次跑通,只能说明流程没有断。真正麻烦的是批量任务、异常重试和长期维护。

4. 从“能生成”到“能稳定用”:LLM 生成 SQL 的执行链路设计

很多人把“模型能生成正确 SQL”当成目标,但在生产环境里,这只是起点。真正要做的是把一条生成的 SQL 放进一个有校验、有约束、有反馈的执行链路里。

4.1 查询生成前:把自由输入变成受限意图

我比较推荐的做法是:用户问题进来之后,先做意图分类或改写,再做 SQL 生成。而不是让模型直接从“用户问题”跳到“SQL 语句”。

比如先把问题映射到“查询订单”“查询库存”“统计数据”等几个业务意图,每个意图对应一组允许访问的表和字段。LLM 只需要在给定意图范围内生成条件,自由度被约束在业务允许的路径中。

这样做的好处是,即使模型偶尔写错过滤条件,也不太可能越过业务边界。它生成的 SQL 可能不完美,但大概率是“安全的错误”。

4.2 查询生成后:SQL 静态校验和“是否只读”检查

SQL 生成之后,不建议直接执行。至少要做一个轻量校验:

  • 是否包含INSERTUPDATEDELETEDDL等语句。如果当前任务不是写操作,直接拦截。
  • 是否包含多条语句拼接。防止一次提交里混入额外命令。
  • 是否只访问了允许的 schema 和表。可以通过简单文本规则或 AST 解析判断。
  • 是否包含明显可疑的注释、复杂函数、网络请求等特征。

有些人觉得这层校验“鸡肋”,说 LLM 可能用等价变形绕过规则。确实,静态校验不能做到绝对安全。但它能减少大量无效查询,权限隔离才是最后一道防线。两者是配合关系,不是替代关系。

4.3 查询返回时:行数裁剪和结果二次确认

LLM 生成 SQL 时,容易默认不加LIMIT,导致一次查询返回几十万行。这既浪费资源,也会让模型回答变慢。

建议在执行层强制限制返回行数,同时在自然语言回复中说明:“我取了前 100 条数据,如果你需要更多,我可以换个条件再查。”这样用户体验更好,数据库压力也小。

这个细节看起来小,实际上非常重要。很多 Agent 项目上线后遇到“慢、卡、内存爆掉”,问题往往不是模型能力,而是没有限制返回行数。

5. 当 Agent 报错“数据库无法访问”,问题往往不在 SQL

在日常实践里,我看到很多团队遇到一种情况:Agent 突然报“数据库无法访问”,第一反应是改 Prompt,或者换一个大模型。但顺着调用链路查下来,往往发现问题出在数据库侧。

比如在 SQL Server 场景下,如果报错信息里出现“the master database cannot be accessed”这类字样,通常不是模型生成的 SQL 有问题,而是数据库实例本身异常,比如服务没有启动、连接字符串指向的系统库状态异常、或者数据目录权限不对。这时候再调整提示词,也不可能生效。

5.1 先从现象和输入开始排查

遇到 Agent 连接数据库出错,我一般会按下面的顺序排查:

  1. 先看现象:是连接失败、执行超时、结果异常,还是返回语法错误?
  2. 再看输入:用户问题是否明确,schema 上下文是否完整,模型有没有把表名或字段名猜错。
  3. 再看环境:数据库服务是否在线,连接串对不对,网络策略有没有拦截。
  4. 再看权限:Agent 账号是否真的有对应 schema 的SELECT权限。
  5. 再看参数:statement_timeout、连接数、返回行数限制是否过小。
  6. 最后看工具边界:当前数据库版本是否支持模型使用的语法,中间件是否有限制。

很多问题在第一步和第三步就能定位。如果你一上来就改 Prompt,等于把数据库侧的问题拿模型层来背锅。

5.2 按环境、权限、参数、工具边界逐层确认

下面这个表格是我在常见问题排查中总结的对应关系:

报错现象优先检查项常见原因
连接拒绝服务状态、端口、网络策略数据库没启动,连接串错误
权限不足角色授权、schema 归属Agent 账号只开了 CONNECT,没开 SELECT
执行超时statement_timeout、慢查询LLM 生成的 JOIN 或过滤条件异常
返回空结果schema 描述、字段类型模型把字段名或枚举值猜错了
数据库实例初始化失败数据目录、日志、磁盘空间数据库侧故障,需要 DBA 介入

这条排查链路的核心是:先判断问题出在哪一层,再决定修哪里。不要让模型层承担数据库层的错误。

6. 长期看,LLM 生成 SQL 真正改变的是什么

拉长时间来看,LLM 生成 SQL 不会淘汰数据库,也不会消灭 DBA。它真正改变的,是数据库被访问的方式。

过去,数据库通常面向固定的应用查询,SQL 是程序员写好后固定下来的。未来,数据库会越来越多地面向 AI Agent 开放,查询是动态生成的。这意味着数据库要有更好的自我描述能力,更清晰的权限模型,更完善的可观测性和审计能力。数据库选型逻辑会从“性能最强”慢慢转向“治理最方便”。

6.1 它会重塑数据库选型逻辑,但不会消灭 DBA

DBA 的角色会从“写慢查询优化 SQL”,转向“设计数据库如何安全地向 Agent 暴露能力”。比如哪些表可以放开给模型,哪些字段需要脱敏,哪些时段允许查询,出现资源争抢时怎么限流,这些都是新的职责。

AI Agent 省掉的是“从业务需求到 SQL”的重复翻译过程,而不是“数据库如何稳定运行”的判断过程。模型可以帮你生成查询,但一个查询能不能放行、会不会拖垮库、数据字段是否可以暴露给某个角色,这些决策仍然需要人来完成。

6.2 判断一个方案是否适合你:四条标准

如果你正在为一个 Agent 项目选数据库,可以参考下面四条标准:

  • 数据类型:如果是强结构化业务数据,关系数据库仍是默认选择。
  • 错误容忍度:Agent 查询允许出错吗?如果查错会造成严重后果,就必须加校验层和人工确认。
  • 团队维护成本:有后端或 DBA 同学能维护 PostgreSQL,就不要引入团队没有经验的专用向量库。
  • 数据安全等级:数据越敏感,越要把权限、审计、脱敏做在数据库层,而不是依赖 Prompt 约束。

所以,当你下次要为一个 AI Agent 选数据库时,不要先问“哪款数据库最快”,而要先问:如果模型写出一条不完美的 SQL,我的数据库能不能安全地接住它?

这个问题的答案,比很多选型对比都重要。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 7:27:09

NEU-DET实战解析:钢材表面缺陷检测数据集与YOLOv8训练指南

简介:NEU-DET钢材表面缺陷数据集围绕钢铁生产中的质量检测需求构建,专注于裂纹、腐蚀、氧化皮、凹坑、划痕等常见缺陷的识别,适合计算机视觉、深度学习方向的科研人员、算法工程师及相关专业学生使用。资源共2000个文件,其中JPG图…

作者头像 李华
网站建设 2026/9/8 7:26:31

室内大棚物联网监测系统实战:从ESP32硬件到MQTT云端链路

开篇先聊点实在的。看到一个毕业设计或实训项目标题叫“基于物联网的室内大棚监测系统的设计与实现”,很多人的第一反应是“又是一个老掉牙的选题”。说实话,这类题目确实是物联网方向里最经典的入门实战之一,但经典不代表简单。恰恰是这种“…

作者头像 李华
网站建设 2026/9/8 7:26:11

校园快递代拿系统设计:从订单状态机到运力运营实战

简介:一套面向高校校园场景的快递代拿管理系统,基于Eclipse IDE与MySQL数据库开发,采用JSP/Servlet技术构建,分为学生前台操作与管理员后台维护两个端,涵盖快递信息录入、取件申请、订单状态更新、用户管理等基础增删改…

作者头像 李华
网站建设 2026/9/8 7:22:18

Linux内核MFD子系统与syscon机制详解:高效管理共享寄存器

1. 从一场“多驱动抢寄存器”的混乱说起先说说我为什么会去认真研究MFD子系统。之前拿到一款新平台的开发板,芯片内部同时集成了PMU控制、时钟门控、IO扩展和复位管理。按照普通驱动开发的惯性,我肯定是为每个功能各写一个独立的platform驱动&#xff0c…

作者头像 李华
网站建设 2026/9/8 7:21:47

ESP32上电不启动?Strapping引脚避坑指南,从原理到排查流程全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/8 7:21:05

大一参加电赛的完整通关攻略:从STM32到四天三夜实战复盘

我大一那年稀里糊涂报了电赛,纯属被室友拉去凑人头。现在回头看,那是整个大学阶段让我成长最快的一件事,没有之一。很多新生一听“电子设计竞赛”就觉得那是大三学长才配碰的东西,其实真不是这样。大一参赛有劣势,但优…

作者头像 李华