在应用开发中,最常见的需求就是数据查询类的需求,一般都是提供一个查询页面

但是查询页面的查询条件比较固定,可能刚好不能满足用户的新需求

比如提供2种查询——近1年、近半年,但是用户刚好想查3个月的;优化后提供了时间范围可自定义,但是用户又想按地点筛选;再次优化后将全表字段都可以设为查询条件,但用户又想按关联表的一个字段进行筛选。。。

那有没有一种一劳永逸的方案能覆盖所有这些变化呢?

答案当然是有,直接允许用户自行编写sql并执行就可以,但是这要求用户有sql基础,且熟悉数据库表机构,这通常并不现实。

而spring-ai-alibaba的nl2sql包就是为了解决这个问题出现的,用户只需输入自然语言,nl2sql即可将其转化为对应的sql。

简单样例

同样还是老三步,添加依赖,添加配置,代码调用

依赖:spring-ai-alibaba-starter-nl2sql

配置:向量数据库(目前支持analyticdb)、业务数据库(目前支持mysql、postgresql)、向量大模型、聊天大模型

代码调用:主要就是3个方法,VectorStoreService中的schema方法用来将数据库表结构初始化进向量数据库,addEvidence添加一些转换时的参考证据,和Nl2SqlService中的nl2sql方法,将自然语音转换为sql。

ps:注意区分VectorStoreService,spring-ai-alibaba-nl2sql-management包和spring-ai-alibaba-nl2sql-chat有同名VectorStoreService

术语——参考证据:转换sql时可能用到的一些术语或知识,例如"计算销量时只统计收货状态为已收货的订单"、"冬天指的是今年11月到第二年的3月"等。

原理分析

nl2sql整体流程其实有些类似RAG,通过外挂知识库(表结构和参考证据),来增强大模型回答专业问题的能力(生成sql),具体流程为:

数据预处理:将数据库表结构初始化进vectorStore;将一些参考证据也初始化进VectorStore

查询:

1. 根据用户查询获取相关参考证据
2.根据用户查询和参考证据获取相关表结构
3.将用户请求、参考证据、表结构组合为提示词
4.将组合提示词发给大模型,要求生成sql

以上就是主体流程,当然这之外还有很多其他扩展内容,比如sql结果评估、执行sql等。

关于源码的思考

这次我没有罗列相关接口及实现类,是因为nl2sql和之前学习的源码结构差异有些大,给人的感觉并不像一个可插拔的开源组件,更像是一个企业项目去掉了controller层然后打成了jar包

而且存在同名类VectorStoreService,这更不像是一个成熟开源组件应该出现的问题

底层对Analyticdb的使用也没有复用spring-ai-alibaba-starter-store-analyticdb包,存在重复造轮子和jar包功能不单一的问题

所以我大胆猜测后面可能会有较大的重构和升级,所以就没有对代码进行详细说明

升级优化设想

基于后续升级的猜想,我不禁在想,如果是我,如何对其进行优化改造

1.Advisor:既然是RAG类的功能组件,那类比QuestionAnswerAdvisor,可以将流程中1-3步封装进一个Advisor中提供服务,用户使用也很简单,使用ChatClient的advisors注册即可。

advisor中包含可选配的QueryExpander、QueryTransformer等等组件,允许用户通过这些预留组件介入nl2sql的内部流程。

2.将属性类、bean自动配置类剥离为autoconfigure包,保持核心包干净,仅包含核心逻辑代码

3.核心包剥离可变或可自行选型部分

1)向量数据库:保留nl2sql所需要的功能接口,如保存参考证据,保存表结构、查询参考证据、查询表结构等,剥离具体向量数据库实现,与向量数据库类型解耦,具体实现放到对应数据库的自动配置包中。

2)业务数据库:同上,仅保留查询表结构接口及执行sql等接口,不关心具体数据库型号及其实现,一切放到其对应的自动配置包中。

3)聊天大模型及向量大模型:同上,仅声明基础模型,不涉及具体型号。

可以提供一个common包,包含一个上述可选型部分的简单教学实现,如SimpleVectorStore、内存数据库等。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐