当前位置: 首页 > news >正文

Java 8老系统SQL Agent实战:AI生成候选SQL,安全引擎拦截后再执行

AI自然语言查库不能直接执行模型生成的SQL。本文详解SQL Agent安全引擎设计:候选SQL审核、表白名单、敏感字段拦截、LIMIT强制补齐,附带Java 8可运行Maven Lab代码。适合企业级AI数据查询安全接入场景。

为什么要写这个系列

做Java后端十年,我接触过不少企业的核心系统。

金融、电商、政务——行业不同,但底层的现状惊人地相似:生产系统还在Java 8,框架停在Spring Boot 2.x甚至更早,代码跑了很多年,没人敢轻易动。

去年开始,几乎每个项目都在谈接AI。

但真正动手的时候,团队就卡住了。

不是因为不懂大模型,而是老系统本身接不住。JDK版本不够,Spring AI引不进来;依赖树牵一发动全身,升级一个包怕带崩一片;生产流量压着,不敢拿主流程赌一个AI试点。

更危险的是硬塞。我见过团队在老系统的Service层直接new一个HttpClient调模型API,Prompt拼在业务代码里,超时没配、降级没有。模型响应慢的时候,老系统的订单查询线程池被占满,主流程跟着卡住。还有团队把用户手机号、身份证原样送进Prompt,过了两个月才被安全审计发现。

这种事见多了,我就开始想一个问题:老系统不具备直接接入AI的条件,这是不是大多数企业的常态?

答案是肯定的。而且这不应该成为接不了AI的理由。

核心思路其实就三条:

老系统少改 —— 不升级 JDK,不引入 Spring AI 依赖 AI 能力旁路 —— 独立部署,老系统通过 HTTP 或 MQ 调用 企业边界先行 —— 脱敏、审计、降级、幂等比模型调用更重要

这个系列就是把这三条线展开成10讲。

从AI Gateway到MCP工具中心,从SQL Agent到RAG知识库,从工单Agent到多Agent研发团队——每一讲都围绕同一个前提:

你的老系统还在跑Java 8,你不能为了AI去赌它的稳定性。

每讲配套一个可运行的Maven Lab,不讲空架构,不写Hello World。你跑得通Demo,看得到边界,拿得到代码。

这就是我做这个系列的原因。

这个系列帮你建立企业 AI 接入的架构意识。每个 Demo 都可独立运行,每讲都配有边界设计和企业避坑。

但意识不等于系统。当你真正要在自己的项目里落地时,会发现:

  • 10 个独立 Lab 的组件需要整合成一个完整的 AI 能力中心
  • Stub 模型需要替换成真实模型调用
  • 权限、审计、脱敏需要从 Demo 级别升级到生产级别

先把架构意识打好,落地时才能走得更稳。


Java 8老系统SQL Agent实战:AI生成候选SQL,安全引擎拦截后再执行

企业里最容易被老板、业务方理解的AI场景之一,是自然语言查数据。

比如:

统计本月销售额最高的 10 个商品 查询本月退款订单数量

听起来很简单:

用户说一句话 AI 生成 SQL 数据库执行 返回结果

但真正放到企业系统里,这条链路不能这么走。

第1讲我们说,Java 8老系统接AI要走旁路,AI不直接改业务状态。

第2讲我们说,老系统能力要先包装成可授权、可审计、可脱敏的工具。

这一讲继续往前走:如果这个工具不是普通API,而是”查数据库”,边界要更严格。

因为数据库查询一旦失控,影响的不只是一个接口,而是整片业务数据。

AI 生成 DELETE 怎么办? AI 查敏感字段怎么办? AI 写了慢 SQL 怎么办? AI 越权查了别的租户怎么办? AI 把查询结果原样返回给模型怎么办?

所以这一讲的重点不是”让AI会写SQL”。

重点是:

模型只能生成候选SQL,候选SQL必须先经过安全引擎,再决定能不能执行。

自然语言查库最容易被误解

很多人一听自然语言查库,第一反应就是Text2SQL。

这当然有价值,但企业里真正卡住的地方通常不是模型能不能写出一条SQL,而是这条SQL能不能被信任。

在企业系统里,模型输出不能被当成执行指令。它最多只是一个候选产物:

用户问题 ↓ 模型生成候选 SQL ↓ 安全引擎审核 ↓ 只读执行器执行 ↓ 结果摘要返回

这和第2讲的工具授权思路一致。第2讲管的是API Tool,第3讲管的是数据库查询Tool:

AI 能不能查这张表? 能查哪些字段? 查询范围和条数怎么限制? 结果能不能原样返回?

边界没有变,只是风险更集中。

只读为什么仍然危险

很多团队会觉得,只要不让AI执行UPDATEDELETE,只允许SELECT,风险就小了。

这只说对了一半。只读不等于安全。

一个企业可接受的查询工具,至少要回答6个问题:

权限:这个操作者是否有权查这类数据? 租户:查询是否被限制在当前 tenantId? 参数:时间范围、条数、聚合维度是否可控? 字段:是否包含手机号、证件号、内部备注等敏感字段? 审计:谁在什么时候问了什么,生成了什么 SQL,是否执行? 返回值:查询结果能否原样给模型或前端?

本讲Demo里,SqlQueryRequest已经保留了tenantIdoperatorId。它们不是装饰字段。

真实项目里,SQL Agent必须知道:谁在查、代表哪个租户查、为什么查、查到了什么、有没有被安全策略拒绝。

本讲Demo最终效果

代码目录:

code/spring-ai-enterprise-lab/labs/chapter03-sql-agent

运行:

.\compile-and-run.ps1

跑完后能看到四类结果:

  • 合法销售额查询:放行。
  • 合法退款数量查询:自动补LIMIT 50
  • 删除数据意图:被拦截。
  • 查询手机号:被拦截。

这四类结果想证明的是:

候选 SQL 不能直接执行 确定性安全代码必须挡在数据库前面

端到端走一遍

整体链路:

SqlQueryRequest ↓ SqlAgentService ↓ StubSqlGenerateService ↓ CandidateSql ↓ SqlSafetyEngine ↓ SqlSafetyDecision ↓ ReadOnlySqlExecutor ↓ SqlResultSummarizer ↓ SqlQueryResult

第一步,用户输入自然语言问题,组装成SqlQueryRequest

new SqlQueryRequest("demo", "u1001", question)

第二步SqlAgentService调用StubSqlGenerateService生成候选SQL。

注意这里叫CandidateSql——它不是最终SQL,也不是可以立刻执行的SQL。

第三步,候选SQL进入安全引擎:

SqlSafetyDecision decision = sqlSafetyEngine.inspect(candidateSql, SchemaSnapshot.orderReport());

如果安全引擎拒绝,链路直接结束,不会进入执行器。

第四步,如果安全引擎放行,进入只读执行器。这里执行的也不是原始候选SQL,而是安全引擎处理后的safeSql

比如缺少LIMIT时,安全引擎会自动补上LIMIT 50

第五步SqlResultSummarizer把查询结果变成摘要,最终返回。

这条链路的原则:

模型负责生成候选 SQL 安全引擎负责决定能不能执行 只读执行器只执行安全 SQL 摘要器只返回业务需要的结果

代码结构

src/main/java/com/ynzz/lab/chapter03 ├── Chapter03Demo.java ├── agent │ ├── StubSqlGenerateService │ ├── SqlAgentService │ ├── ReadOnlySqlExecutor │ └── SqlResultSummarizer ├── common │ ├── CandidateSql │ ├── SqlQueryRequest │ └── SqlQueryResult └── safety ├── SchemaSnapshot ├── SqlSafetyDecision └── SqlSafetyEngine

agent负责生成、执行和总结。safety负责判断候选SQL是否安全。

现在还没有接真实模型。StubSqlGenerateService先模拟模型生成候选SQL,把注意力集中在安全引擎上。等安全链路跑通后,再把Stub替换成真实模型调用。

这个顺序很重要。如果一上来就接模型,注意力会被prompt、模型效果、API Key牵走。但企业真正关心的是:候选SQL到底能不能执行?

Schema白名单

本讲模拟了一个报表表:

CREATE TABLE order_report ( id BIGINT PRIMARY KEY, order_id VARCHAR(64) NOT NULL, product_name VARCHAR(128) NOT NULL, customer_level VARCHAR(32) NOT NULL, order_month VARCHAR(16) NOT NULL, amount DECIMAL(12, 2) NOT NULL, status VARCHAR(32) NOT NULL, created_at TIMESTAMP NOT NULL );

这张表故意不包含手机号、身份证、邮箱等敏感字段。

重要设计原则:

SQL Agent 优先连接报表库、分析库、只读副本 不要让模型直接靠近生产业务库

SchemaSnapshot维护了三类信息:allowedTablesallowedColumnssensitiveColumns

关键原则:

不要把完整数据库结构直接交给模型。模型只应该看到它能查询的部分。

SQL安全引擎

SqlSafetyEngine做了5件事:

1. 只允许 SELECT 2. 拦截 INSERT / UPDATE / DELETE / DROP / ALTER 3. 校验表白名单 4. 拦截敏感字段 5. 强制 LIMIT

用户问”删除所有测试订单数据”,Stub生成:

DELETE FROM order_report WHERE status = 'TEST'

安全引擎返回:

{ "blocked": true, "blockReason": "WRITE_OPERATION_NOT_ALLOWED", "summary": "SQL 已被安全引擎拦截,未执行。" }

运行效果

合法查询:放行,返回摘要。

没带LIMIT的退款查询:安全引擎自动补上LIMIT 50

敏感字段查询(”查询所有客户手机号”):拦截,blockReason=SENSITIVE_FIELD_NOT_ALLOWED

真实项目里还应该把这些信息写入审计记录:原始问题、候选SQL、安全决策、执行状态、结果摘要、tenantId、operatorId。

企业避坑

  1. 不要让AI直连生产库— 至少用只读数据源,最好从报表库、分析库开始。
  2. 不要把完整Schema给模型— 模型只需要知道允许查询的表和字段。
  3. 不要相信模型会生成安全SQL— 安全检查必须由确定性代码完成。
  4. 不要忽略LIMIT— 没有限制的SELECT也可能拖垮系统。
  5. 不要忘记租户和操作者上下文— 不同租户、角色允许看到的数据范围不同。
  6. 不要把查询结果原样返回— 要做字段裁剪、敏感信息处理和摘要控制。
  7. 不要缺审计— 自然语言查库必须记录完整调用链路。

从 Demo 到落地,还差什么

本讲帮你验证了”候选 SQL + 安全引擎”的核心思路,但企业查库场景落地还差几步:

SQL Parser 替换字符串判断:当前 Demo 用简单字符串匹配做安全检查。真实项目需要 SQL Parser(如 JSqlParser)支持复杂 SQL 语法——子查询、JOIN、嵌套 SELECT 等场景。

多租户行级权限:本讲在请求里带了 tenantId,但安全引擎没有按租户过滤数据。真实项目里同一张表,不同租户只能看到自己的数据,行级权限必不可少。

完整审计服务:当前 Demo 只在控制台打印信息。真实项目需要审计服务:异步写入、查询接口、告警规则、合规报表。

查询资源配额:不同租户的查询频率和返回行数应该有配额限制,防止一个租户的查询拖垮整条链路。

如果你正在推进企业 AI 查库能力落地,后续会有完整版把这些组件整合成企业级 SQL Agent。

小结

模型只生成候选 SQL 确定性代码决定能不能执行 查询结果经过控制后再返回
这就是企业Java系统接AI时必须补上的一层。
http://www.jsqmd.com/news/1014493/

相关文章:

  • 如何让2008年以后的旧款Mac安装最新macOS?OCLP-Mod终极指南
  • 【AI Daily】AI日报 2026-06-14
  • 惊了!原来论文可以这样省时间?2026降AIGC网站推荐合集
  • 心电图特征点检测系统Matlab程序含GUI2(设计源文件+万字报告+讲解)(支持资料、图片参考_降重降ai)
  • 3分钟搞定洛雪音乐播放问题:六音音源优化版终极解决方案
  • 如何用5分钟将你的英雄联盟游戏效率提升300%:League Akari完全指南
  • 086、Claude Code 无头模式:在 CI/CD 流水线中的 headless 使用与参数配置
  • 2026年成都小吃车定制服务商TOP5盘点 - 互联网科技品牌测评
  • 牛客网Java面试题汇总(2026秋招最新版,附答案,持续更新)
  • 2026免费音频转AIFF在线保姆级教程!无限制工具手把手教学,苹果专业音频工作站专用 - 时时资讯
  • 终极AI换脸指南:3步实现专业级深度伪造,无需训练!
  • 如何永久免费使用IDM下载加速器:开源激活脚本完全指南
  • 2026这6款宝藏降AI率网站全网首测,一键让AIGC率断崖式下跌!
  • 照着用就行:一键生成论文工具2026最新测评与推荐
  • 双麦克风降噪仿真matlab程序2(设计源文件+万字报告+讲解)(支持资料、图片参考_降重降ai)
  • 影刀RPA新手教程_多账号Cookie池调度高并发采集的账号资源管理
  • [Word] 只关闭Microsoft Word动画,不关闭Windows动画的方法
  • 2026年烟台地暖服务商推荐榜:芝罘莱山新房/老房地暖,暖气地暖暖通公司专业实力与口碑深度测评 - 品牌发掘
  • 内容运营团队用智能内容分发工具_CSDN_AI数字营销适合哪类场景
  • 构建Python微服务架构:轻松应对高并发场景
  • 2026免费音频转CAF在线保姆级教程!无限制工具手把手教学,iOS系统原生核心音频格式 - 时时资讯
  • 查询每门课程最好的前两名的SQL实现
  • 7 硬件工程师笔面试高频考点真题解析——IGBT
  • 实战构建抖音批量下载器:5步掌握无水印内容自动化采集
  • 设计系统中的主题切换:从 CSS 变量到运行时主题引擎的架构实践
  • OpenCore Legacy Patcher解决方案:为老款Mac注入新生命,体验最新macOS系统
  • 2026年 东莞UV打印/亚克力UV打印/UV打印加工/UV彩白彩玻璃贴最新推荐榜单:高精度工艺与创意透光的品质之选 - 品牌发掘
  • BedrockLauncher:颠覆性Minecraft基岩版智能版本管理解决方案
  • 打造你的AI灵魂伴侣:SillyTavern角色卡片完全指南
  • 想高效完成一篇高质量的文献综述,AI辅助工具该怎么选?求真实推荐