`Text2SqlSkill` 赋予了智能体（Agent）直接通过自然语言与结构化数据库对话的能力。它不仅仅是简单的 SQL 生成，更集成了一套从元数据探测到方言适配，再到执行安全拦截的完整闭环。

相关依赖包：[solon-ai-skill-text2sql](/article/1367)


### 1、 核心特性

自适应方言引擎：

* 内置多种 `SqlDialect`，自动识别 MySQL、PostgreSQL、Oracle 等数据库差异，自动处理引号转义、分页语法（Limit/Offset）及系统函数差异。

分级元数据策略：

* FULL 模式（表 `<= 20`）：自动注入全量 DDL 和备注，让 AI 拥有“全局视角”。
* DYNAMIC 模式（表 `> 20`）：仅注入表清单与关系地图，引导 AI 通过 get_table_schema 按需探测，节省 Token。


语义关联引导：


* 自动提取外键关系（Foreign Keys）与表/列备注，为 AI 提供多表 Join 的“语义线索”。


执行安全护栏：

* 强制只读校验（仅限 SELECT）、标识符自动修复（Alias Repairing）以及最大行数（Max Rows）限制。



### 2、应用示例

将数据库变成智能体的知识库，只需几行代码：

```java
// 1. 初始化 Skill，指定数据源及允许 AI 访问的表范围
Text2SqlSkill sqlSkill = new Text2SqlSkill(dataSource, "users", "orders", "order_refunds")
        .maxRows(50)            // 限制单次返回最大行数，防止大表扫描
        .readOnly(true)         // 强制只读模式，拦截任何写操作
        .maxContextLength(8000) // 结果截断长度，保护 AI 上下文
        .schemaMode(SchemaMode.DYNAMIC); // 如果表非常多，建议手动开启动态模式

// 2. 构建 ReAct 智能体
ReActAgent agent = ReActAgent.of(chatModel)
        .role("财务分析专家")
        .instruction("你负责分析订单与退款数据。请结合表备注理解字段含义，金额单位均为元。")
        .defaultSkillAdd(sqlSkill)
        .build();

// 3. 执行任务
// Agent 会经历：Reasoning (分析表名) -> Action (生成/执行 SQL) -> Observation (结果分析)
String response = agent.prompt("张三在 2024 年一共有多少笔退款订单？总金额是多少？")
       .call()
       .getContent();
```


### 3. 工作流程：从意图到结果

环境探测：

* 在 onAttach 阶段，Skill 自动识别数据库产品名并匹配最优方言。

Schema 注入：

* AI 在 System Prompt 中会看到当前数据库的方言类型（如 MySQL）和系统时间。
* 根据 SchemaMode，AI 会获得全量表结构或带有外键线索的“关系地图”。

SQL 修复与执行：

* 当 AI 调用 execute_sql 时，Skill 会通过正则修复 AI 经常遗漏引号的别名（如 SELECT count(*) AS count 修复为符合方言的转义格式）。
* 自动注入分页逻辑（防止 SELECT * 导致的 OOM）。

纠错反馈：

* 如果执行报错，Skill 会利用方言引擎将复杂的 SQL 错误转化为对 AI 友好的 Hint（纠错建议）。



### 4、 内置管理工具



| 工具名称 (Tool) | 触发模式 | 功能说明 |
| -------- | -------- | -------- |
| execute_sql     | 始终开启     | 执行 SELECT 查询。自动进行别名修复、只读检查和分页补全。     |
| get_table_schema     | DYNAMIC 模式     | AI 用来“探测”具体某张表的详细字段定义（DDL）、备注及主键信息。     |

### 5、 最佳实践建议

* 完善注释：在数据库中为表和关键字段添加 COMMENT。Text2SqlSkill 会自动提取这些备注，这是提升 AI 字段识别准确率的最有效手段。
* 权限隔离：虽然 Skill 有 readOnly(true) 护栏，但仍强烈建议在数据库层面为 AI 连接配置只读账号。
* 表范围控制：在构造函数中只传入当前任务相关的表名，减少干扰并显著降低 Token 消耗。
