智能问数项目核心是自然语言转 SQL(NL2SQL),通过 LangChain4j 封装大模型能力,结合 Spring Boot 快速开发后端服务,支持用户用自然语言提问业务数据(如 “查询 2024 年 Q3 华北地区销售额 TOP3 的产品”),系统自动生成 SQL 执行并返回结果。以下是完整实现方案,包含技术选型、架构设计、代码实现和部署优化。
一、技术选型
|
技术栈 |
选型说明 |
|
后端框架 |
Spring Boot 3.2.x(轻量、快速集成,支持 RESTful API 和 Spring 生态) |
|
大模型集成 |
LangChain4j 0.25.x(Java 版大模型开发框架,简化 NL2SQL、Prompt 工程、结果解析) |
|
大模型选择 |
支持多模型切换: – 开源本地:Llama 3(70B)、Qwen 2(72B)(需 GPU 部署) – 云服务:通义千问、GPT-4o、智谱清言(API 调用) |
|
数据库连接 |
Spring Data JPA + HikariCP(简化数据库操作,支持多数据源) |
|
SQL 解析 / 校验 |
JSqlParser(解析生成的 SQL,防止注入、校验语法) |
|
结果格式化 |
FastJSON 2(JSON 序列化,支持复杂结果结构转换) |
|
缓存 |
Redis(缓存高频 SQL、表结构元数据,提升响应速度) |
|
日志监控 |
SLF4J + Logback(日志记录)、Spring Boot Actuator(服务监控) |
|
部署方式 |
Docker(容器化部署,适配本地 / 云环境) |

二、核心架构设计
项目采用分层架构,核心流程为:自然语言提问 → 元数据加载 → Prompt 构造 → 大模型生成 SQL → SQL 校验 → 数据库执行 → 结果格式化返回。
1. 架构分层
┌─────────────────────────────────────────────────────────┐
│ 接入层:REST API(接收用户提问、返回结果) │
├─────────────────────────────────────────────────────────┤
│ 业务层:核心流程编排(元数据加载、Prompt构造、结果处理) │
├─────────────────────────────────────────────────────────┤
│ 能力层: │
│ - LangChain4j:大模型调用、NL2SQL链、Prompt模板 │
│ - SQL工具:语法校验、注入防护、执行结果解析 │
│ - 缓存工具:Redis缓存表结构、高频SQL │
├─────────────────────────────────────────────────────────┤
│ 数据层:业务数据库(MySQL/Oracle)、元数据库(表结构) │
└─────────────────────────────────────────────────────────┘
2. 核心流程
- 用户提问:用户通过 API 提交自然语言问题(如 “2024 年各部门离职人数”)。
- 元数据加载:从缓存 / 数据库获取业务表结构(表名、字段名、字段注释、关联关系)。
- Prompt 构造:将用户问题、表结构元数据、SQL 生成规则(禁止删改、只查指定表)封装为 Prompt。
- 大模型生成 SQL:LangChain4j 调用大模型,基于 Prompt 生成目标 SQL。
- SQL 校验:校验 SQL 语法、是否包含危险操作(DELETE/UPDATE/DROP)、是否只操作白名单表。
- SQL 执行:通过 JPA 执行合法 SQL,获取原始结果。
- 结果格式化:将数据库结果转换为自然语言描述 + 结构化数据(JSON),返回给用户。
三、项目实现步骤
1. 初始化 Spring Boot 项目
1.1 依赖配置(pom.xml)
核心依赖如下,需引入 LangChain4j、数据库、缓存相关依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<relativePath/>
</parent>
<dependencies>
<!-- Spring Boot核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- LangChain4j(大模型集成) -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>0.25.0</version>
</dependency>
<!-- 大模型适配器(以通义千问为例,其他模型替换对应依赖) -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-alibaba-tongyi</artifactId>
<version>0.25.0</version>
</dependency>
<!-- 本地模型支持(如Llama 3,需额外部署模型) -->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-ollama</artifactId>
<version>0.25.0</version>
</dependency>
<!-- 数据库 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- SQL解析 -->
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>4.8</version>
</dependency>
<!-- 缓存 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.50</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
1.2 配置文件(application.yml)
配置数据库、Redis、大模型参数:
spring:
# 数据库配置(业务库)
datasource:
url: jdbc:mysql://localhost:3306/business_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# JPA配置
jpa:
hibernate:
ddl-auto: none
show-sql: true
properties:
hibernate:
format_sql: true
# Redis缓存配置
redis:
host: localhost
port: 6379
password:
database: 0
# LangChain4j大模型配置(通义千问为例,支持动态切换)
langchain4j:
alibaba-tongyi:
api-key: 你的通义千问API密钥
model: qwen-turbo # 模型版本(qwen-turbo/qwen-plus)
# 本地模型配置(Ollama部署Llama 3)
ollama:
base-url: http://localhost:11434
model: llama3:70b-instruct
temperature: 0.1 # 越低越稳定,适合SQL生成
# 应用配置
app:
# 数据库表结构白名单(只允许查询这些表)
sql:
table-whitelist: employee, department, sales, order_info
# 缓存配置(表结构缓存1小时)
cache:
table-meta-ttl: 3600
2. 核心模块开发
2.1 表结构元数据模块(加载数据库表信息)
用于获取表名、字段名、字段注释、数据类型,提供给大模型生成 SQL 时参考。
表元数据实体类:
import lombok.Data;
import java.util.List;
@Data
public class TableMetadata {
private String tableName; // 表名(数据库实际表名)
private String tableComment; // 表注释(业务含义)
private List<ColumnMetadata> columns; // 字段列表
}
@Data
public class ColumnMetadata {
private String columnName; // 字段名
private String columnComment; // 字段注释(核心,协助大模型理解业务)
private String dataType; // 数据类型(如varchar、int、datetime)
private boolean isPrimaryKey; // 是否主键
}
表元数据 DAO(查询数据库元信息):
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Repository
public class TableMetadataDao {
@Resource
private JdbcTemplate jdbcTemplate;
/**
* 查询指定表的元数据(MySQL为例)
*/
public List<TableMetadata> queryTableMetadata(List<String> tableNames) {
return tableNames.stream().map(tableName -> {
TableMetadata tableMeta = new TableMetadata();
tableMeta.setTableName(tableName);
// 1. 查询表注释
String tableCommentSql = "SELECT TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES " +
"WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?";
String tableComment = jdbcTemplate.queryForObject(tableCommentSql, String.class, tableName);
tableMeta.setTableComment(tableComment);
// 2. 查询字段信息(字段名、注释、类型、主键)
String columnSql = "SELECT COLUMN_NAME, COLUMN_COMMENT, DATA_TYPE, " +
"CASE WHEN COLUMN_KEY = 'PRI' THEN 1 ELSE 0 END AS IS_PRIMARY_KEY " +
"FROM INFORMATION_SCHEMA.COLUMNS " +
"WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? " +
"ORDER BY ORDINAL_POSITION";
List<Map<String, Object>> columnMaps = jdbcTemplate.queryForList(columnSql, tableName);
List<ColumnMetadata> columns = columnMaps.stream().map(map -> {
ColumnMetadata columnMeta = new ColumnMetadata();
columnMeta.setColumnName(map.get("COLUMN_NAME").toString());
columnMeta.setColumnComment(map.get("COLUMN_COMMENT") != null ? map.get("COLUMN_COMMENT").toString() : "");
columnMeta.setDataType(map.get("DATA_TYPE").toString());
columnMeta.setPrimaryKey(Boolean.parseBoolean(map.get("IS_PRIMARY_KEY").toString()));
return columnMeta;
}).collect(Collectors.toList());
tableMeta.setColumns(columns);
return tableMeta;
}).collect(Collectors.toList());
}
}
表元数据服务(缓存 + 业务逻辑):
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class TableMetadataService {
@Resource
private TableMetadataDao tableMetadataDao;
@Resource
private List<String> tableWhitelist; // 从配置文件注入表白名单
/**
* 获取表元数据(缓存优先)
*/
@Cacheable(value = "tableMetadataCache", key = "'all'", ttl = "${app.cache.table-meta-ttl}")
public List<TableMetadata> getTableMetadata() {
// 查询白名单中的所有表元数据
return tableMetadataDao.queryTableMetadata(tableWhitelist);
}
}
2.2 LangChain4j NL2SQL 模块(核心:自然语言转 SQL)
通过 LangChain4j 的PromptTemplate构造提示词,调用大模型生成 SQL,同时添加结果解析逻辑。
1. 大模型配置类:
import dev.langchain4j.model.ollama.OllamaChatModel;
import dev.langchain4j.model.alibaba.tongyi.TongyiChatModel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class LangChain4jConfig {
// 通义千问配置
@Value("${langchain4j.alibaba-tongyi.api-key}")
private String tongyiApiKey;
@Value("${langchain4j.alibaba-tongyi.model}")
private String tongyiModel;
// 本地Ollama配置(Llama 3)
@Value("${langchain4j.ollama.base-url}")
private String ollamaBaseUrl;
@Value("${langchain4j.ollama.model}")
private String ollamaModel;
@Value("${langchain4j.ollama.temperature}")
private float temperature;
/**
* 通义千问模型Bean(云服务)
*/
@Bean(name = "tongyiChatModel")
public TongyiChatModel tongyiChatModel() {
return TongyiChatModel.builder()
.apiKey(tongyiApiKey)
.model(tongyiModel)
.temperature(temperature)
.build();
}
/**
* 本地Ollama模型Bean(开源模型)
*/
@Bean(name = "ollamaChatModel")
public OllamaChatModel ollamaChatModel() {
return OllamaChatModel.builder()
.baseUrl(ollamaBaseUrl)
.model(ollamaModel)
.temperature(temperature)
.build();
}
}
2. NL2SQL 服务(核心逻辑):
import dev.langchain4j.chain.ConversationalChain;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.prompt.PromptTemplate;
import dev.langchain4j.data.message.SystemMessage;
import dev.langchain4j.data.message.UserMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
public class Nl2SqlService {
// 注入大模型(可通过配置动态切换,这里以通义千问为例)
@Resource(name = "tongyiChatModel")
private ChatLanguageModel chatModel;
@Resource
private TableMetadataService tableMetadataService;
@Resource
private List<String> tableWhitelist;
/**
* 自然语言转SQL核心方法
*/
public String convertNlToSql(String userQuestion) {
// 1. 加载表元数据
List<TableMetadata> tableMetas = tableMetadataService.getTableMetadata();
String tableMetaStr = formatTableMetadata(tableMetas);
// 2. 构造Prompt(关键:明确SQL生成规则)
String systemPrompt = """
你是一个专业的SQL生成工程师,需要根据用户的自然语言问题和提供的数据库表结构,生成正确的MySQL SQL语句。
必须遵守以下规则:
1. 只允许查询白名单中的表:{tableWhitelist},禁止操作其他表。
2. 只能生成SELECT查询语句,禁止DELETE、UPDATE、DROP、ALTER等危险操作。
3. 严格按照表结构中的字段名和表名编写SQL,字段名必须与提供的一致(区分大小写)。
4. 处理时间范围时,使用正确的日期格式(如'2024-01-01'),避免语法错误。
5. 生成的SQL必须可以直接执行,不需要额外修改,不要包含任何解释性文字。
6. 若用户问题不明确或无法生成SQL,返回"ERROR: 无法生成合法SQL,请补充问题细节"。
数据库表结构:
{tableMetadata}
""";
// 填充Prompt参数
String filledSystemPrompt = PromptTemplate.from(systemPrompt)
.replace("tableWhitelist", String.join(",", tableWhitelist))
.replace("tableMetadata", tableMetaStr)
.toString();
// 3. 调用大模型生成SQL
ConversationalChain chain = ConversationalChain.builder()
.chatLanguageModel(chatModel)
.systemMessage(SystemMessage.from(filledSystemPrompt))
.build();
String sql = chain.execute(userQuestion);
log.info("用户问题:{},生成SQL:{}", userQuestion, sql);
return sql;
}
/**
* 格式化表元数据为大模型易理解的字符串
*/
private String formatTableMetadata(List<TableMetadata> tableMetas) {
return tableMetas.stream().map(tableMeta -> {
String columnsStr = tableMeta.getColumns().stream().map(column ->
String.format("字段名:%s,注释:%s,类型:%s,是否主键:%s",
column.getColumnName(),
column.getColumnComment(),
column.getDataType(),
column.isPrimaryKey() ? "是" : "否")
).collect(Collectors.joining("
"));
return String.format("表名:%s,表注释:%s
字段列表:
%s",
tableMeta.getTableName(),
tableMeta.getTableComment(),
columnsStr);
}).collect(Collectors.joining("
"));
}
}
2.3 SQL 校验模块(安全防护)
防止大模型生成危险 SQL(如删改操作)或语法错误 SQL,保障数据库安全。
import com.alibaba.fastjson2.JSON;
import com.github.jsqlparser.JSQLParserException;
import com.github.jsqlparser.parser.CCJSqlParserUtil;
import com.github.jsqlparser.statement.Statement;
import com.github.jsqlparser.statement.select.Select;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.regex.Pattern;
@Slf4j
@Component
public class SqlValidator {
@Resource
private List<String> tableWhitelist;
// 禁止的SQL关键字(正则匹配,忽略大小写)
private static final Pattern FORBIDDEN_KEYWORDS = Pattern.compile(
"b(DELETE|UPDATE|INSERT|DROP|ALTER|TRUNCATE|CREATE|REPLACE)b",
Pattern.CASE_INSENSITIVE
);
/**
* 校验SQL合法性
* @return 合法返回true,非法抛出异常
*/
public boolean validateSql(String sql) {
// 1. 检查是否包含错误标记
if (sql.startsWith("ERROR:")) {
throw new IllegalArgumentException(sql);
}
// 2. 检查禁止关键字
if (FORBIDDEN_KEYWORDS.matcher(sql).find()) {
throw new IllegalArgumentException("SQL包含危险操作,禁止执行");
}
// 3. 校验SQL语法
try {
Statement statement = CCJSqlParserUtil.parse(sql);
// 4. 校验是否为SELECT语句
if (!(statement instanceof Select)) {
throw new IllegalArgumentException("仅支持SELECT查询语句");
}
// 5. 校验操作的表是否在白名单(简化版:解析FROM后的表名)
Select select = (Select) statement;
String fromClause = select.getSelectBody().toString().toLowerCase();
for (String table : tableWhitelist) {
fromClause = fromClause.replace(table.toLowerCase(), "");
}
// 若还有剩余表名,说明操作了非白名单表
if (fromClause.contains("from") || fromClause.contains("join")) {
throw new IllegalArgumentException("SQL操作了非白名单表");
}
} catch (JSQLParserException e) {
log.error("SQL语法错误:{}", sql, e);
throw new IllegalArgumentException("SQL语法错误:" + e.getMessage());
}
return true;
}
}
2.4 数据查询与结果格式化模块
执行合法 SQL,将数据库返回的原始结果转换为 “自然语言描述 + 结构化数据” 的格式。
import com.alibaba.fastjson2.JSON;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@Service
public class DataQueryService {
@Resource
private JdbcTemplate jdbcTemplate;
/**
* 执行SQL查询
*/
public List<Map<String, Object>> executeQuery(String sql) {
return jdbcTemplate.queryForList(sql);
}
/**
* 格式化结果(自然语言描述+JSON结构化数据)
*/
public QueryResult formatResult(String userQuestion, String sql, List<Map<String, Object>> rawResult) {
QueryResult result = new QueryResult();
result.setUserQuestion(userQuestion);
result.setGeneratedSql(sql);
result.setData(rawResult);
// 生成自然语言描述(简化版:根据结果数量和字段名生成)
if (rawResult.isEmpty()) {
result.setNaturalLanguageAnswer("未查询到符合条件的数据");
} else {
String fields = String.join("、", rawResult.get(0).keySet());
result.setNaturalLanguageAnswer(
String.format("查询到%d条数据,包含字段:%s", rawResult.size(), fields)
);
}
return result;
}
}
// 结果返回实体类
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class QueryResult {
private String userQuestion; // 用户原始问题
private String generatedSql; // 生成的SQL
private String naturalLanguageAnswer; // 自然语言回答
private List<Map<String, Object>> data; // 结构化数据(JSON格式)
}
2.5 控制器(API 接入层)
提供 RESTful API 供前端调用,接收用户提问并返回结果。
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("/api/query")
public class QueryController {
@Resource
private Nl2SqlService nl2SqlService;
@Resource
private SqlValidator sqlValidator;
@Resource
private DataQueryService dataQueryService;
// 请求参数实体
@lombok.Data
public static class QueryRequest {
@NotBlank(message = "提问内容不能为空")
private String question; // 用户自然语言问题
}
/**
* 智能问数核心接口
*/
@PostMapping("/nl2sql")
public Result<QueryResult> nl2sql(@Valid @RequestBody QueryRequest request) {
String userQuestion = request.getQuestion();
try {
// 1. 自然语言转SQL
String sql = nl2SqlService.convertNlToSql(userQuestion);
// 2. SQL校验
sqlValidator.validateSql(sql);
// 3. 执行查询
List<Map<String, Object>> rawResult = dataQueryService.executeQuery(sql);
// 4. 格式化结果
QueryResult queryResult = dataQueryService.formatResult(userQuestion, sql, rawResult);
return Result.success(queryResult);
} catch (IllegalArgumentException e) {
log.error("问数失败:{}", e.getMessage(), e);
return Result.error(400, e.getMessage());
} catch (Exception e) {
log.error("问数系统异常:{}", e.getMessage(), e);
return Result.error(500, "系统异常,请稍后重试");
}
}
}
// 统一返回结果类
import lombok.Data;
@Data
public class Result<T> {
private int code; // 状态码(200成功,其他失败)
private String msg; // 提示信息
private T data; // 业务数据
public static <T> Result<T> success(T data) {
return new Result<>(200, "操作成功", data);
}
public static <T> Result<T> error(int code, String msg) {
return new Result<>(code, msg, null);
}
}

3. 关键优化点
3.1 Prompt 优化(提升 SQL 生成准确率)
- 明确表结构的业务含义(字段注释必须详细,如 “sales_amount:销售额(单位:元)”)。
- 限制 SQL 语法(如 “只支持 MySQL,使用 LEFT JOIN 而非 JOIN”)。
- 提供示例(如 “用户问‘2024 年 1 月销售额’,生成 SQL:SELECT SUM (sales_amount) FROM sales WHERE sale_date BETWEEN '2024-01-01' AND '2024-01-31'”)。
3.2 缓存优化
- 缓存表结构元数据(避免频繁查询 INFORMATION_SCHEMA)。
- 缓存高频问题的 SQL(如 “近 7 天销售额”,直接复用已生成的 SQL)。
3.3 安全优化
- 严格的 SQL 校验(禁止危险操作、白名单表限制)。
- 数据库账号权限最小化(仅授予 SELECT 权限)。
- 防止 SQL 注入(通过 JdbcTemplate 参数化查询,避免字符串拼接)。
3.4 多模型适配
通过 LangChain4j 的统一接口,支持动态切换大模型:
// 切换为本地Ollama模型(Llama 3)
@Resource(name = "ollamaChatModel")
private ChatLanguageModel chatModel;

四、部署与测试
1. 本地测试
- 启动 MySQL、Redis 服务,创建业务数据库和测试表(如sales表包含sale_date、product_id、sales_amount字段)。
- 配置大模型参数(通义千问 API 密钥或本地 Ollama 服务)。
- 启动 Spring Boot 应用,通过 Postman 调用接口:请求 URL:http://localhost:8080/api/query/nl2sql请求体:{“question”: “查询2024年Q3销售额大于10万的产品ID和销售额”}响应示例:
- json
- { “code”: 200, “msg”: “操作成功”, “data”: { “userQuestion”: “查询2024年Q3销售额大于10万的产品ID和销售额”, “generatedSql”: “SELECT product_id, SUM(sales_amount) AS total_sales FROM sales WHERE sale_date BETWEEN '2024-07-01' AND '2024-09-30' GROUP BY product_id HAVING SUM(sales_amount) > 100000”, “naturalLanguageAnswer”: “查询到2条数据,包含字段:product_id、total_sales”, “data”: [ {“product_id”: “P001”, “total_sales”: 156000}, {“product_id”: “P002”, “total_sales”: 123000} ] } }
2. 部署方案
- 容器化:使用 Docker 打包应用,配置Dockerfile:
- dockerfile
- FROM openjdk:17-jdk-slim VOLUME /tmp COPY target/intelligent-query-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT [“java”,”-jar”,”/app.jar”]
- 生产环境提议:大模型:若使用开源模型,部署在 GPU 服务器(如 A10、A100),通过 Ollama 或 vLLM 提供 API 服务。数据库:使用主从分离,查询走从库,避免影响业务库。缓存:Redis 集群,提升缓存可用性。监控:集成 Prometheus + Grafana,监控接口响应时间、SQL 执行效率。
五、扩展方向
- 复杂查询支持:优化 Prompt 支持多表关联、子查询、聚合函数(SUM/COUNT/GROUP BY)。
- 问题澄清:当用户问题不明确时(如 “查询最近的销售额”),大模型自动反问用户(“请问‘最近’指的是近 7 天、近 30 天还是近 90 天?”)。
- SQL 优化:大模型生成 SQL 后,通过工具类自动优化(如添加索引提示、简化查询)。
- 前端可视化:开发 Vue/React 前端,支持用户输入问题、展示 SQL 和结果表格、导出数据。
- 多数据源支持:适配 MySQL、Oracle、ClickHouse 等多种数据库,动态切换数据源。
通过以上方案,可快速实现一个高可用、安全的智能问数系统,降低业务人员的数据分析门槛,提升数据查询效率。核心在于 LangChain4j 对大模型的封装和 Prompt 工程的优化,确保 SQL 生成的准确性和安全性。






![[C++探索之旅] 第一部分第十一课:小练习,猜单词 - 鹿快](https://img.lukuai.com/blogimg/20251015/da217e2245754101b3d2ef80869e9de2.jpg)










- 最新
- 最热
只看作者