(本文基于 9 月 27 日与阿里云合办的线下沙龙分享整理而成。)
探索的起点
我们在AskTable的探索起点,是一个简单的问题:如何让数据变得更加容易访问?
随着企业中数据量的增长,传统的数据访问方式逐渐难以满足需求,尤其是数据存储在多种数据库中、结构复杂、逻辑多样时,如何让非技术用户直接获取数据成了巨大挑战。
(http://arxiv.org/abs/2408.05109)
大模型的出现,自然语言检索成为了可能。大语言模型(LLM)与数据检索的结合,通过LLM对自然语言的理解能力,使用户能够用自然语言与数据交互,摆脱对SQL等编程语言的依赖,降低了数据访问的门槛,使数据获取更加直观和高效。
NL2SQL
企业大量高价值的数据都是结构化的,而这类数据大部分则用 SQL Database 来存储。NL2SQL 期望解决的问题是,如何将用户的问题,转换为到数据库中查询数据的 SQL。
AI 的仿生学
在希望 AI 来解决问题之前,我们先思考下,人类是如何解决问题的。
为了从数据中获取信息,工程师通常会经历理解问题、分析查表、编写SQL 这三个步骤。
我们举一个例子,来看下人类是如何理解问题的。
示例问题是:“告诉我所有在上个月购买商品的品类超过3种并且消费金额超过200元的客户联系方式”。
步骤 1:理解问题
通常涉及到以下步骤:
提取关键词:例如“上个月”、“3种”、“200元”等。
约束条件的歧义:上个月是一个相对现在的时间描述,联系方式也存在可能的多义性(手机、邮箱等都是联系方式)。
自然语言的多义性:自然语言有其天然的复杂性,包括词法语法的歧义、开放式问题、不明确的定义、拼写或输入错误等。
理解问题的核心是搞明白用户要什么,对自然语言的理解能力。这是大模型的基础能力。
步骤 2:分析和查表
接下来,就是找数据。一般企业的数据表都非常多,只要找对了表,才能查到对的数据。
核心内容包括:
找到关键词和数据库中的字段对应关系:例如“客户”可以对应customers.customerId,而“品类”可能涉及多个字段,如Category和Subcategory。
数据库的复杂性:数据分析过程中,需要考虑数据库的多样性和复杂性,如:
字段的模糊性:例如“Datetime”字段可能表示不同时间含义。
字段之间的关系:单次消费还是累计消费?
专有名词、拼音、字母缩写的处理。
数据类型:例如Gender、Number等。
业务知识的重要性:查找数据表的过程需要理解数据的domain knowledge(领域知识)并且熟知数据库的schema。
对业务数据和表结构的深入理解是正确生成SQL查询的前提。
步骤 3:编写SQL
找到数据之后,就是编写 SQL 来查询的过程。该过程需要将用户的问题精确映射到数据库的结构和内容上。
挑战和复杂性:
复杂的外键关系:表之间可能存在复杂的外键关系,尤其是涉及多表联查的情况。
多种写法:同样的需求可能存在多种SQL写法,具体如何编写取决于数据库结构和查询目标。
schema的定义:需要理解具体数据库的表结构(schema),包括字段和关系。
方言:不同数据库(例如MySQL、PostgreSQL等)有各自的SQL方言,需要针对不同的语法进行调整。
我们的思考和实践
RAG的故事
在讲我们的解决方案之前,不得不提一下 RAG。
RAG(Retrieval-Augmented Generation)是将检索和生成结合来回答用户问题的技术。
工作流程概述:用户提出问题(Question),经过预处理(Preprocess),系统在向量数据库(Vector DB)中进行检索(Retrieve),最后使用大语言模型生成响应(Response)。
用户(User)提问:用户以自然语言提出问题。
预处理(Preprocess):对用户的问题进行预处理,以便更好地理解和格式化该问题。
检索(Retrieve):从向量数据库(Vector DB)中检索相关信息。向量数据库用于存储嵌入(embedding),通过相似度匹配检索与问题相关的文档或数据。
生成响应(Response):将检索到的信息输入到大语言模型中,结合检索结果来生成最终的回答。
RAG通过将外部知识引入LLM,能够有效弥补模型知识的不足。但普通的 RAG 架构对查询结构化数据,比如 SQL 数据库,有明显的不足。因为结构化数据不能像文本内容那样,做切片、 做 Embeding、做召回。
Structured RAG
简单点,是否可以直接将 SQL Database 中的数据,同步到 Vector DB,然后做 RAG?如下图。
很明显,有这些问题:
如何同步:数据同步?向量数据库和关系型数据库
形式问题:结构化数据到更容易被向量数据库处理的自然语言
上下文窗口:在处理大量数据时,如何确保上下文信息能够被有效利用。
聚合操作(aggregate/group by):在复杂查询中,聚合操作(例如求和、分组)如何被正确处理。
权限和数据安全:在处理用户数据时,如何确保数据安全和权限控制。
通用的 RAG无法解决这类问题,我们需要一款专门为结构化数据设计的 Structured RAG。
主要流程如下:
预处理(Preprocess):在用户提出问题后,首先对其进行预处理,以消除问题中的歧义,并尽可能使需求清晰、明确、独立。
SQL生成:结合数据库的schema和相关业务信息,调用大语言模型生成SQL查询。这一步强调了生成SQL是通过理解数据库结构和用户需求实现的。
SQL执行与结果返回:
执行SQL:在向量数据库中检索相关信息并生成SQL。
返回结果:修正并执行生成的SQL,将查询结果返回给用户。
在LLM Structured RAG系统中,SQL仍然是关键部分。SQL生成能力需要结合LLM的自然语言理解和数据库的结构化信息,这对于有效完成数据操作和返回结果是至关重要的。
Pipeline
(http://arxiv.org/abs/2408.07702)
为了让查询结果更准确,从用户问题到SQL查询的典型Pipeline流程,分为检索、生成和纠正三个阶段。
每个阶段都有具体的子任务:
预处理(Preprocessing):
包括对数据库schema的理解,数据库内容的检索,以及对提示词或示例的处理。这一步确保输入的自然语言查询能够被更好地理解和处理。
生成阶段(Generation):
分解(Decomposition):将复杂的问题分解为更简单的子任务。
思维链(Chain-of-Thought, CoT):利用思维链来生成推理过程,使得生成SQL时具有更好的逻辑连续性。
后处理(Post-processing):
纠正(Correction):包括执行导向的解码,通过执行SQL查询的结果来修正SQL。
排序(Ranking):对生成的SQL进行排序以选取最佳的查询版本。
将自然语言转换为SQL查询的复杂过程,包括理解用户意图、生成SQL以及通过执行和结果反馈来优化SQL的准确性。这个多阶段的处理流程确保生成的SQL查询不仅正确,还具有更高的执行效率和业务关联度。
向量数据库存储了embeddings(schemas、examples、values),这些信息可以帮助在自然语言到SQL的转换中更好地理解上下文。
在生成SQL后,模型会再次通过检索阶段从向量数据库中获取相关的schema、示例等,帮助生成更准确的SQL。
关键挑战:
Schema的复杂性:数据库的schema可能非常多,因此需要有足够的上下文长度(context length)来处理这些信息。
示例问题(few shots):示例数据可能和具体的问题不相关,因此需要精心挑选相关的few-shot示例来帮助理解和生成。
描述性的schema和字段名:为了更好地生成有效的SQL,需要提供详细的schema描述和字段名称。
结合向量数据库可以更好地利用数据库内容和结构信息来生成精准的SQL查询,增强LLM的生成能力,并提高查询的准确性和上下文的相关性。
AskTable 架构
(https://docs.asktable.com/docs/chat-database/database-query-via-natural-language)
这个架构图中详细描述了如何通过各种模块完成用户的查询需求。图中有多个部分,下面进行概述:
AskTable Meta Retrival模块:
利用大语言模型(Qwen/GPT等)来生成向量嵌入(Query Embeddings)。
通过查询向量数据库(Meta Brain)来检索与问题相关的信息。
AskTable Meta Brain模块:
支持多种数据库系统,如MySQL、PostgreSQL、TiDB等,处理表结构和字段相关的元数据。
将获取的嵌入与具体数据库信息结合,帮助理解问题中的意图。
AskTable Data Retrieval模块:
使用大语言模型生成具体的SQL查询。
结合权限管理,对生成的SQL进行权限校验,确保查询的合规性。
对SQL进行执行,将查询结果返回给用户。
自动纠错,多路召回/查询等强化技术
查询缓存(Query Cache):
在系统中有查询缓存机制,通过缓存提高重复查询的效率,减少系统负担。
我们结合大语言模型、向量数据库、元数据查询等技术模块,实现从用户问题到SQL生成与执行的全流程。架构中考虑了元数据管理、权限控制以及缓存等机制,以确保系统的高效性和安全性。
NL2SQL easy?
做一个 Demo 很简单,但真正落地并不容易,这篇论文中,详细介绍了需要充分利用预处理、复杂的模型策略和后处理来确保结果的正确性和有效性。
(http://arxiv.org/abs/2408.05109)
仍然要考虑
用户交互和系统设计方面的考量:
提问的艺术:引导用户如何更好地提出问题
角色和授权,权限控制:确保不同用户有不同的数据访问权限,防止未经授权的数据泄漏。
字段描述的设计、业务文档:如何有效地描述字段以帮助模型理解业务含义。
冗余数据和fallback设计:为系统提供fallback机制,以便在查询失败时有替代方案。
SQL注入和数据泄露防护:在SQL生成和执行时防止SQL注入和数据泄露。
SQL的方言适配:针对不同数据库,SQL语法可能存在差异,需要确保生成的SQL适配具体的数据库。
模型和系统实现方面的考量:
模型能力和效率:确保大语言模型在生成SQL时的效率和能力,避免性能瓶颈。
方案成本:考虑实现方案的成本,包括计算资源和数据处理成本。
数据集:使用的训练和评估数据集需具有代表性,以确保模型能够处理多样化的问题。
结果的解释性、可靠性和一致性:生成的SQL不仅需要是正确的,还需要具有解释性和一致性,以便用户理解和信任结果。
这些方面共同确保系统在用户使用时既高效又安全,并能够提供准确和可解释的查询结果。
我们在哪?到哪里?
随着技术的发展,自然语言处理到SQL生成的能力逐步增强,从简单的词汇和规则到对复杂业务的理解与高效的SQL生成。
对于此,我们的选择是:
ALL in LLM:我们是 LLM 虔诚的信徒,不引入复杂的系统设计,尽可能激发LLM的潜能。
业务第一:我们专注于 LLM 在具体业务场景的落地,聚焦上层应用的落地
安全性:我们相信开源模型的能力,寻找最佳的本地部署方案