V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lgc653
V2EX  ›  分享发现

NL2SQL 擂台赛

  •  
  •   lgc653 · 14 天前 · 382 次点击

    NL2SQL 擂台赛

    评测简介

    NL2SQL 核心功能是构建一个基于 AI 的数据库查询助手,它能够理解自然语言的用户查询,并自动生成相应的 SQL 语句进行查询。

    个人觉得目前大模型完成 NL2SQL 的能力都还是蛮强的,甚至用我本地的 3050 乞丐卡驱动 ollama + deepseek-coder-v2 就可以干的不错了。这里做一个实验,比较一下各家大模型的 NL2SQL 能力。

    主要原理是:

    • 提取数据库结构定义 (DDL)
    • 利用向量数据库 (lancedb)和 SQLite 存储 DDL 信息,并建立混合索引(向量化+全文索引)
    • 接收用户以自然语言形式提出的数据库查询请求。
    • 通过之前建立的混合索引查询相关的 DDL
    • 将用户查询和相关的 DDL 语句作为上下文信息,发送给大模型,请求其生成能够满足用户查询需求的 SQL 语句。
    • 执行生成的 SQL 语句,并将查询结果以表格形式展示给用户。
    • 还可以通过大模型生成数据可视化和优化建议。

    评测数据简介

    这是一个很老的卡牌对战游戏。数据库使用的是 PostgreSQL

    • dt_account:用户表
    • dt_account_info:用户的详细信息
    • dt_account_product:用户的道具
    • dt_guild:用户所属社团
    • mt_entry:招募用户的入口
    • mt_exer_type:用户类型
    • mt_product:道具
    • mt_skill:道具的技能

    image-20241129173816161

    评测题目

    这里选 5 道有特色的题目来测试一下,涉及到 PostgreSQL 的专有函数和数据库常用的 JOIN 和 GROUP BY 。

    数据类型与函数

    ❓题目:显示 dt_account 的 last_login_date 是 exer_type 个月( exer_type 作为参数)内的 account_id ,last_login_date 。

    这道题要考研大模型对 PostgreSQL 的时间类型的了解程度

    ❓题目:

    选出 dt_account 中所有 login_id 含有‘-’字符的数据,将‘-’后面的字符显示出来。 注意‘-’字符不一定在第一位,例如 339-339 ,但是一个 login_id 中只有一个‘-’字符。 例如:-carbon 显示 为 carbonzero-3719 显示 为 3719

    这道题要考研大模型对 PostgreSQL 的字符串函数的了解程度

    连接与聚合

    ❓题目:

    显示 mt_product 的所有数据,他关联 mt_skill 的两个字段 skill_id_0,skill_id_1 用对应的 skill_name 表示出来

    这题看似简单,但是有一个坑,就是 mt_skill 需要连接两次,我们需要用别名来应对

    ❓题目:

    计算每一个会员( dt_account)所拥有的商品(mt_product)的总价值(product_price * product_count)。

    这题虽然不难,但是是 JOIN 和 GROUP BY 的组合应用,也是现实工作中常见的业务统计问题。

    ❓题目:

    将 dt_account 与 dt_guild 、mt_entry 和 mt_exer_type 进行连接后。只能得到 299 条数据。而 dt_account 表中一共有 300 条数据。为什么?找到这条数据。

    这题是道应用题,看看大模型解决疑难问题的实战能力

    评测环境

    基于开篇介绍的思路,我自己开发了一套软件,叫做 Local Agents ,里面提供了 NL2SQL 功能,大家有兴趣可以去数据库智能体 | Local Agents详细了解。

    这个项目自己用了一段时间,感觉效果还不错(是不是有点王婆卖瓜😄),这里就通过这个软件来评测一下当前各家的大模型的 NL2SQL 的能力

    数据库智能体详解

    执行 SQL 查询

    参赛选手

    参赛选手基本囊括了国内外主流模型,没选 gpt-4o 是因为 gpt-4o-mini 就是我日常的主力模型,我觉得在 NL2SQL 这件事上 gpt-4o-mini 已经不错了,至于网传很神的 claude 3.5 ,我没 key 就没有测试。

    • gemini-1.5-pro:免费而强大,我日常的主力模型,没免费额度时换 gpt-4o-mini
    • gpt-4o-mini:便宜好用,我日常的主力模型
    • ERNIE-4.0-8K:国产巨头
    • qwen-turbo:国产巨头
    • hunyuan-turbo-latest:国产巨头
    • moonshot-v1-8k:国产新锐
    • deepseek-chat:国产新锐

    评测

    首先大家也知道,大模型回答问题有一定随机性,所以我们评测时,如果在 3 次内,大模型根据 SQL 查询的反馈信息(比如报错信息)或者追加题词能够最终回答正确就算 OK

    大家如果想自己试试看,可以去https://github.com/lgc653/courses的 database 目录下载原始数据自行验证

    问题一

    这题主要考察时间类型

    首先是用我最喜欢的 gemini-1.5-pro ,轻松搞定(这题由于原始数据日期很老,所以应该检索结果是空),但是有些模型对 PostgreSQL 的时间类型不是很熟悉,反复调校也无法成功。

    image-20241201201044449

    我就不每个截图了,直接给出结果

    模型 结果
    gemini-1.5-pro 1 次成功
    gpt-4o-mini 2 次成功,根据反馈的 SQL 错误自行修正
    qwen-turbo 1 次成功
    hunyuan-turbo-latest 1 次成功
    ERNIE-4.0-8K 失败
    moonshot-v1-8k 失败
    deepseek-chat 1 次成功

    问题二

    这题考察的是字符串函数,这个各家都比较厉害,相反我最喜欢的 Google gemini 翻车了,不过他知错能改,提醒了一次搞定了

    image-20241201204255193

    模型 结果
    gemini-1.5-pro 2 次成功(第一次带了“-”,经过题词提醒修正)
    gpt-4o-mini 1 次成功
    qwen-turbo 1 次成功
    hunyuan-turbo-latest 1 次成功,答案思路还和我的一模一样
    ERNIE-4.0-8K 1 次成功
    moonshot-v1-8k 1 次成功,还比较了字符串处理前后的数据
    deepseek-chat 1 次成功

    问题三

    这个如果是人第一次写可能会踩重复 join 一个表的坑,但是大模型没一个踩坑的,都是一次性成功

    image-20241201204439934

    模型 结果
    gemini-1.5-pro 1 次成功
    gpt-4o-mini 1 次成功
    qwen-turbo 1 次成功
    hunyuan-turbo-latest 1 次成功
    ERNIE-4.0-8K 1 次成功
    moonshot-v1-8k 1 次成功
    deepseek-chat 1 次成功

    问题四

    这个是现实工作中常见的统计分析问题,大家也都一次成功了,说明这种统计分析都是各家的强项。

    可以看到文心一言做的很对,就是思考过程太啰嗦了(这都是消耗的小钱钱……)

    image-20241201204837786

    模型 结果
    gemini-1.5-pro 1 次成功
    gpt-4o-mini 1 次成功
    qwen-turbo 1 次成功
    hunyuan-turbo-latest 1 次成功
    ERNIE-4.0-8K 1 次成功
    moonshot-v1-8k 1 次成功
    deepseek-chat 1 次成功

    问题五

    这个我是想一次性给我找出这个因为数据不匹配导致问题的数据。

    各家模型基本都是思路正确,但是都是教你多步完成查询后自己去比较,只有 Google 更换题词后直接命中了异常的数据

    image-20241201205902654

    模型 结果
    gemini-1.5-pro 经过多次尝试,更换了题词后成功
    gpt-4o-mini 思路正确,但需要人多次查询后自行比较
    qwen-turbo 思路正确,但需要人多次查询后自行比较
    hunyuan-turbo-latest 思路正确,但需要人多次查询后自行比较
    ERNIE-4.0-8K 思路正确,但需要人多次查询后自行比较
    moonshot-v1-8k 思路正确,但需要人多次查询后自行比较
    deepseek-chat 思路正确,但需要人多次查询后自行比较

    总结

    NL2SQL 其实还是比较靠谱的,但是有以下几点需要注意:

    • 数据库的 DDL 命名的规范和注释完整度直接影响效果

    • 使用自然语句也要有一定规范,比如我同事喜欢称呼 account 表为顾客,我们实际注释写的是用户,导致效果不佳,统一称谓习惯后取得了很好的效果

    • 需要使用偏门的函数可能效果不佳

    • 因为数据异常导致的问题,想要大模型一次性找到原因很难

    3 条回复    2024-12-02 13:59:30 +08:00
    gammabeta
        1
    gammabeta  
       14 天前 via iPhone
    请问混合索引搜索 ddl ,是向量搜索最相关的 top n 个 ddl 给大模型?还是用的其他什么方法?
    lgc653
        2
    lgc653  
    OP
       14 天前
    我自己写了些逻辑,先分词,根据词性和权重再在全文索引和向量搜索中重排 rank ,不过其实也不用太严谨,尽可能命中更多的有关联性的表即可。
    lgc653
        3
    lgc653  
    OP
       14 天前
    因为 DDL 长度其实也不大,本身具备很强的语义,便于大模型理解,所以即使你添加了一些无用的 DDL 作为上下文,大模型也可以很好的处理。所以尽可能多的命中是关键(即使可能是无效的)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5466 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 02:53 · PVG 10:53 · LAX 18:53 · JFK 21:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.