SQLBot
dataease/SQLBot项目目录
项目简介
SQLBot 是自然语言数据分析平台,可连接业务数据库,结合表字段说明、人工表关系、术语和 SQL 示例生成查询,并展示结果与图表。Python 后端负责相关表选择、查询上下文组装、执行检查和会话错误反馈。
如何写进简历
仓见 · 仓储库存经营问数平台 | 场景化示例
项目描述:基于 SQLBot,面向仓储主管查询库存快照、出入库流水和商品资料,通过自然语言查看低库存、滞销与库存变化,展示 SQL、明细和图表。
技术栈:Python、FastAPI、SQLModel、PostgreSQL、pgvector
主要工作:
- 表级召回与一跳关联:在表级融合结构向量与关键词得分,保留明确点名的表,再按
table_relation补齐一跳表和连接字段,为库存快照、商品与出入库查询提供结构上下文。 - 库存口径与生成上下文:将快照时点、出库类别与滞销口径写为术语和问题—
SQL示例,与Schema分段注入生成消息;元数据同步后触发表结构向量更新,支持库存结构变化后的查询生成。 - 查询检查与错误反馈:从生成的
SQL提取真实表名核对本次允许范围,执行前检查读取操作;保存数据库执行错误并带入同会话下一轮,辅助定位选表、关联和语句错误。
面试题与回答
如何检索召回数据库的表和字段?
展开收起
核心回答
SQLBot的这条召回链以表级结构为单位:先在当前数据源已选用的表字段范围内,用表结构向量和关键词规则给表排序,保留用户明确点名的表,再补入已配置关系中与候选表直接相连的表,最后把表名、字段类型、说明和连接关系交给模型生成SQL。它的
Python后端负责结构读取与上下文组装,Embedding模型提供语义相似度,关键词规则补充精确名称和业务描述。字段参与表的匹配,并随入选表进入结构上下文;这条实现并没有为每个字段建立独立向量召回分支。选中了业务表,还要确认连接路径及需要的字段是否完整。先准备结构,再做表匹配
构建表向量时,程序把表名、字段名、字段类型及自定义说明组织为结构文本,计算并保存向量。查询阶段先读取已勾选的表和字段,对字段应用列权限过滤;若调用方提供
table_list,还会进一步限制候选表。随后组装各表的
schema_table:表说明优先采用自定义说明,否则使用原表注释;字段结构包含字段名、类型及已配置的自定义说明。关键词评分还能使用字段原注释。由此,向量所依据的结构、关键词信号和最终送给模型的字段列表需要分别核对,修改说明后也要关注表向量是否同步更新。普通内置数据源路径会先抽取问题关键词,再用术语同义词扩展,供表匹配使用。向量分数衡量关键词与表结构的语义接近程度;关键词规则则匹配表名、表说明、字段名和字段说明,并结合匹配质量与覆盖率评分。启用融合时,分数为
α × 向量分数 + (1−α) × 关键词分数,默认α=0.4。它是规则分数与向量分数的线性融合,未使用RRF或独立重排模型。见关键词与向量融合实现。明确点名的表怎样保留,失败时怎样回退
仅按融合分取前几名,可能漏掉问题中明确要求使用的表。
_select_tables()因此会用原始问题匹配完整表名或完整表说明,把这些表保留在前面,再按已有排名填充剩余名额。匹配处理标识符边界、引号包裹名称和重叠名称,减少把短表名误当成长表名中一部分的情况。TABLE_EMBEDDING_COUNT默认是 10,但显式命中的表全部保留,数量可能超过这个值。这一规则只作用于调用方已经筛选过的候选,不会把范围外的表重新引入。见显式表保留规则。当前表匹配按排名和数量选择,没有额外的最低相似度阈值。因此,低相关问题也可能得到若干候选表。关键词为空、关键词功能关闭或融合计算异常时,会改用原问题做纯向量排序;纯向量计算也异常时,则保留全部已过滤候选并把显式命中项置前。这种回退减少了计算失败造成的漏表,但会增加结构上下文,不能把“有候选”当作已经找到正确表。
一跳关联补表能补什么
表匹配后,程序读取数据源维护的
table_relation,找出至少一个端点属于当前候选表的关系边,补入这些边另一端缺失的表结构,再追加相应字段等式。关系来自配置,虽然输出栏目名是Foreign keys,并不表示已经从数据库自动发现并验证全部外键约束。补表也只从此前允许的候选范围中取结构。这个过程只扩展一跳。例如已选
A,关系为A→B→C,能补入与A直接相连的B,但不会再以新补的B为起点递归查找C。它可以补回某些未直接命中的桥表,却没有实现任意多跳路径搜索;长链查询仍可能缺表或缺边。具体流程见结构拼接与一跳关系补全。最终结构上下文包括数据库标识、入选和补入的表结构,以及相关字段连接式;可选的样本数据另行读取。业务术语、示例
SQL和额外提示分别注入生成消息,不由表向量替代。若要进一步支持复杂桥接,应在允许范围内增加路径选择与连接粒度校验,而不是无差别扩展整张关系图。验证时,可以对照纯向量、融合、显式保留和一跳补表,分别检查目标表是否出现、关键字段是否保留、连接路径是否完整,以及最终结果是否符合口径。这样才能区分是选表漏了、关系配置缺了,还是结构已经齐全但生成的连接或聚合有误。
参考资料
- 国内:飞致云:SQLBot 最佳实践:采用表字段说明、手工关系配置、术语与示例分别提供上下文的做法,解释表匹配之后为何仍需连接和业务知识。
- 国外:Wang 等:RAT-SQL:依据问题名称、字段及关系共同对齐的分析,解释显式名称信号与表结构关系各自解决的歧义;项目机制以固定版本源码为准。
Text-to-SQL 如何区分表结构与业务规则知识,并适应表结构变更?
展开收起
核心回答
SQLBot将表字段元数据、人工维护的表关系、业务术语和SQL示例分开管理,生成时再组合成上下文。表字段说明有哪些可用对象、类型和注释,表关系提供连接依据;术语解释业务含义与同义表达,示例则提供“问题—查询写法”的参考。字段类型本身不能说明库存余额采用哪个快照时点、滞销天数按哪类出库计算,这类口径需要补进业务说明或示例。适应结构变化时,先同步真实表字段,再检查人工关系、业务说明和示例是否仍引用正确对象。该版本的结构同步会更新元数据并触发表与数据源的向量更新,但这条同步链没有自动迁移业务术语、改写示例
SQL或清理全部生成依赖的过程。不同知识怎样进入 SQL 上下文
以平台管理的普通数据源问数为例,
get_table_schema()从启用的表与字段构造结构信息,列权限过滤也在构造前处理。选表后,表名、字段名、类型与注释被组织成Schema文本;已有人工配置的table_relation会补充相关表及连接字段。这里的表关系来自维护的关系图,不等于系统自动读取并验证了数据库中的外键约束。表字段范围、结构与表关系组装。业务语义走独立匹配:
filter_terminology_template()根据未扩展的关键词或原问题匹配术语,带上当前数据源等适用范围,返回主词、同义词与解释;filter_training_template()按问题匹配该数据源范围内的SQL示例。开启向量匹配时可补充语义候选,结果随后被格式化为上下文,并非修改数据库结构或训练模型。术语匹配入口、示例匹配入口、术语模板、示例模板。sql_sys_question()分别构造结构、术语和示例模板,init_messages()将这些内容逐项加入生成SQL的消息。结构信息与业务解释因此可以同时约束查询,但前提是对应内容确实被匹配并加入;只维护一条术语,并不代表每次生成都会使用它。模板构造、消息注入。结构同步更新了什么
同步逻辑按表名、字段名匹配记录:已有表更新数据库注释,已有字段更新类型、原始注释和顺序,新表新字段创建记录。已有的
custom_comment不会因此被数据库注释覆盖,所以人工维护的业务说明可以保留,也需要在含义变化时另行检查。表与字段同步。同步结束会提交表和数据源的向量更新任务,这些任务在线程池中运行。触发更新与更新完成需要区分;重新生成时应检查实际选表结果及注入的结构,确认使用的是更新后的内容。单表字段更新、后台向量更新。
字段重命名也不会自动识别为同一业务字段的迁移。旧名称可能仍出现在术语解释、示例查询和人工关系配置中,相关内容需要单独确认和修改。若要实现“字段变化后自动定位并停用受影响的规则、示例与缓存”,还需要额外维护依赖关系与失效机制,不能仅靠同步表结构完成。
怎样验证一次变更
例如业务库把库存数量字段从
stock_qty改成on_hand_qty,且业务含义不变:先同步字段,检查注入结构是否已使用新名称;再检查相关术语、示例及连接配置中是否残留旧引用。用同一批问数问题重新生成查询,对照参考SQL检查库存快照、出入库和日期口径,并核对查询结果与可访问范围。这能分别确认结构刷新、知识匹配与业务结果。查询成功执行只说明表字段和语法可用,不能证明新字段承接了原来的业务含义,也不能证明示例中的统计口径仍然正确。
Text-to-SQL 在 Agent 中如何应用?存在哪些风险和限制?
展开收起
核心回答
SQLBot把自然语言问数拆成相关表选择、结构与业务知识组装、SQL 生成、执行和结果展示。表备注、人工表关系、术语与 SQL 示例帮助模型理解该查什么、怎样关联;生成后仍需由程序检查实际 SQL,并依据数据库返回的数据回答。这里要区分三件事:模型按格式返回了 SQL、SQL 通过现有执行检查、查询结果符合业务口径。前两项成立,也不能证明日期条件、连接粒度和统计公式都正确。
生成结果怎样进入执行?
check_sql()从模型返回中提取 JSON,读取success、sql等字段,并检查 SQL 非空。它负责响应格式和生成结果解析,不是完整的语法、安全或成本审核。随后程序用
sqlglot从 SQL 本身提取真实表名,与本次允许的table_name_list比较,不直接信任模型附带的tables字段。没有成功提取表或出现白名单外表时拒绝继续。这个检查使用裸表名,不能据此推导已经完成任意数据库、Schema、列和行级权限校验。响应解析、真实表提取与白名单。exec_sql()执行前还会调用check_sql_read()。该函数检查允许的首关键字、危险模式、解析出的语句类型和危险函数;默认允许SELECT/WITH,元数据命令另受配置控制。它形成了一层读取操作检查,但现有写类型判断主要针对每条语句的顶层节点,不能直接称为已经证明所有嵌套表达式都安全的完整 AST 沙箱。执行前检查、读取操作检查。查询失败后会自动反复修正吗?
这条对话链路没有同一轮自动重试循环。数据库执行异常会被包装、保存并作为错误返回,本轮随后结束;下一轮初始化时,程序查询同一会话的最新记录,如果它属于
exec-sql-err,才把错误放入<error-msg>供模型参考。连接失败、格式错误等情况不能统一当成这条执行错误反馈。错误保存与结束、下一轮错误上下文。若要增加自动纠错,应限制次数,区分可纠正的语法、结构错误与权限拒绝,并让修正后的 SQL 重新通过执行检查。这是进一步完善方案,不能写成该版本已经具备的行为。
实际落地还要验证什么?
首先核对业务结果。例如一对多连接可能让库存数量重复累加,SQL 却能顺利执行;要用明确的样例数据和参考查询检查粒度、时间及过滤条件。术语和示例是生成依据,不是正确性证明。
其次按数据源核对运行限制。不同连接器的连接、驱动和执行超时配置并不相同,不能统一称为查询的硬截止时间;提示词中的结果行数要求也不等于所有分支都有后端强制上限。生产接入还应配置适当的数据库账号与权限、结果上限和查询资源约束,再验证越权、慢查询与错误反馈。这里的源码审查不替代这些部署测试。