RAG实战篇:将用户输入转换为精确的数据库查询语言

前言

在这篇文章中,围绕查询构建(Query Construction)环节,如下图黄框所示,风叔详细介绍一下如何将用户输入,转换为精准的数据库查询语言。

查询构建主要是为了将用户自然语言的Query,转化为某种特定软件或机器能理解的语言。因为随着大模型在各行各业的渗透,除文本数据外,诸如表格和图形数据等越来越多的结构化数据正被融入RAG系统。

比如在ChatBI的场景下,就需要将用户的Query内容转化为SQL语句,进行数据库查询,这就是Text-to-SQL。如果是在图数据库场景下,那就是Text-to-Cypher。

下面结合源代码,风叔详细介绍下查询构建的三种高级方法,【元数据筛选器】、【Text-to-SQL】和【Text-to-Cypher】。具体的源代码地址可以在文末获取。

1. 元数据筛选器

元数据筛选器是一种通过元数据构建筛选器的查询结构,比如增加内容摘要、时间戳、章节引用、文本关键信息、小节标题、段落标签等附加信息来丰富知识库,用于改进知识检索的准确性。这种方法在构建比如知识库助手、智能问答系统时,非常有效。

有一点需要注意,即元数据是不需要被向量化的。因此可以通过元数据筛选器,从自然语言问题中进行快速过滤,如下图所示。

我们看一下在 YouTube 转录数据库中的一些示例元数据。

from langchain_community.document_loaders import YoutubeLoader``   ``docs = YoutubeLoader.from_youtube_url(`    `"https://www.youtube.com/watch?v=pbAd8O1Lvm4", add_video_info=True``).load()``   ``docs[0].metadata

输出如下所示,将目标数据的元数据全部提取出来,以结构化方式存储。

{'source': 'pbAd8O1Lvm4',` `'title': 'Self-reflective RAG with LangGraph: Self-RAG and CRAG',` `'description': 'Unknown',` `'view_count': 11922,` `'thumbnail_url': 'https://i.ytimg.com/vi/pbAd8O1Lvm4/hq720.jpg',` `'publish_date': '2024-02-07 00:00:00',` `'length': 1058,` `'author': 'LangChain'}

假设我们已经建立了一个索引,通过这个索引我们可以对每个文档的内容和标题进行非结构化搜索,并通过查看次数、发布日期和长度范围进行过滤。我们可以为结构化搜索查询构建一个schema,然后将自然语言转换为结构化搜索查询。

给出Prompt,告诉大模型你是将用户问题转换为数据库查询的专家,给定一个问题,返回一个经过优化的数据库查询,以检索最相关的结果。

system = """You are an expert at converting user questions into database queries. \``You have access to a database of tutorial videos about a software library for building LLM-powered applications. \``Given a question, return a database query optimized to retrieve the most relevant results.``   ``If there are acronyms or words you are not familiar with, do not try to rephrase them."""``   ``prompt = ChatPromptTemplate.from_messages(`    `[`        `("system", system),`        `("human", "{question}"),`    `]``)``   ``llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)``structured_llm = llm.with_structured_output(TutorialSearch)``query_analyzer = prompt | structured_llm

我们来检验一下输出结果,成功地将非结构化的自然语言输入,转化成了结构化的输出。

query_analyzer.invoke(`    `{"question": "videos on chat langchain published in 2023"}``).pretty_print()``   ``"""``result:``content_search: chat langchain``title_search: 2023``earliest_publish_date: 2023-01-01``latest_publish_date: 2024-01-01``"""

2. TEXT-to-SQL

当前AI大模型输出的SQL准确性还远远无法达到人类工程师的输出精度。由于自然语言表达本身的歧义性和模糊性,在实际应用中,可能会出现无法理解或者错误理解的情况,比如“谁是本月最厉害的销售?”,AI可能会理解成订单数量最多,而不是订单金额最大。

虽然我们可以通过Prompt帮助大模型来理解SQL语句,但AI也可能出现对概念不理解导致的错误,比如“分析去年的客户整体流失率?”,AI可能会因为不理解“流失率”这个概念,而无法给出准确的答复。

总之,TEXT-to-SQL是一个非常有挑战性的领域,还存在准确率不高的问题,因此在使用TEXT-to-SQL的场景下,建议一定要加上人工核对。

下面,我们借助一个例子,看看如何通过RAG系统来优化TEXT-to-SQL。

先准备一个ddl.txt,这里面存放的都是业务范围内容的表结构,如下:

CREATE TABLE ai_prj_plan ( duty_party character varying(255) , pipeline_type character varying(255) , ... );``CREATE TABLE dtqjln (  xmbh character varying(100), jgsj integer, ...}

再准备一个documentations.txt ,这里存放的是每个字段的详细说明或者注意事项,如下:

ai_prj_plan 表中的字段 id 表示工程计划的主键 id 。``ai_prj_plan 表中的字段 create_time 表示工程计划的创建时间。``...``dtqjln 表中的字段 jsdw 表示地铁线路或者地铁区间的建设单位名称。``dtqjln 表中的字段 sjdw 表示地铁线路或者地铁区间的设计单位名称。

接下来再准备question-sql.txt,这里存放的是一些代表性的业务可能涉及到的问题-sql 对样本,如下:

已经投运的管线工程计划总长###select SUM(length::numeric) from ai_prj_plan where current_progress=5 and plan_type in (1,2,3)``查10条计划单独施工的工程名字###select project_name as "ai_prj_plan.project_name"  from ai_prj_plan where plan_type=1 limit 10``...

这里的三个文件,每一行都作为一个 doc ,然后将每一行使用预先准备的 acge_text_embedding 嵌入模型转化成1024 向量,也就是三个文件一共有多少行,就会有多少个 1024 的向量,然后都存入ChromaDB 向量数据库。

用户提问“2023年入廊管线中前期项目的计划有多少”,会使用预先准备的 acge_text_embedding嵌入模型,将问题转化为一个 1024 向量,将其与ChromaDB 向量数据库 中的所有1024向量进行相似性召回,分别从三个文件中找出最相关的内容,至于召回策略可以自己定义。

根据自定义召回策略,然后将召回的内容和问题进行拼接组成下面的完整的 prompt ,从完整的 prompt 我们可以看到召回了将要使用的表结构 ai_prj_plan 以及相关字段 plan_type 、annual_aim_json 、plan_category 的使用说明,最后找出了两个可能对模型有用的 question-sql对供模型参考。

[`   `{'role': 'system', 'content': '您是一名精通 SQL 的专家,用户会提出业务相关的问题,请根据相关信息回答合适的 SQL ,您将仅使用 SQL 代码进行回答,不进行任何解释。`        `您可以使用以下展示出的表结构作为参考:\n\nCREATE TABLE ai_prj_plan\n(\n    id character varying(64)  NOT NULL,\n    create_time timestamp(6) without time zone,\n    update_time timestamp(6) without time zone,\n    remark character varying(255) ,\n    plan_type integer,\n    duty_party character varying(255) ,\n    pipeline_type character varying(255) ,\n    project_name character varying(255) ,\n    dlmc character varying(255) ,\n    start_end_point character varying(255) ,\n    ssqx character varying(100) ,\n    total_invest real,\n    length real,\n    plan_code character varying(255) ,\n    plan_category integer,\n    version integer,\n    accept integer,\n    verify_status integer,\n    refuse_reason character varying(255) ,\n    geom geometry(Geometry,4326), -- 几何使用 4326 坐标系\n    years character varying(255) ,\n    current_progress integer,\n    annual_aim_json text ,\n)\n\n`        `您可以使用以下展示出的 documentation 作为参考,每个 documentation 解释了每个表的字段的名字和用法,使用他们以指导您有效准确地回答用户的问题,请务必遵循每个字段的使用方法和注意事项:\n\nai_prj_plan 表中的字段 plan_type 表示工程计划中涵盖的工程类型,我们规定只能枚举整数 1 、 2 、 3 、 4 、 5 ,整数 1 表示单独施工管线计划,整数 2 表示随道路施工管线工程计划,整数 3 表示入廊管线工程计划,整数 4 表示管廊工程计划,整数 5 表示互联互通工程计划,其中将整数 1 、 2 、 3 代表的三种工程计划合并起来统称为“管线工程计划”或者"管线计划"。\n\nai_prj_plan 表中的字段 plan_category 表示工程计划的计划分类,我们规定只能枚举整数 1 和 2 ,整数 1 表示工程计划在计划内,整数 2 表示工程计划在计划外。\n\nai_prj_plan 表中的字段 annual_aim_json 表示工程计划的每年详细计划列表,虽然该字段是字符串内容,但是存储格式是 json 列表。每个 json 中有三个字段 year、planProgress、 planInvest,表示打算计划在某年(year)给该项目一定的投资(planInvest),要将该项目推进到计划的进度(planProgress)。},`    `{'role': 'user', 'content': '2024年入廊管线中前期项目的计划有多少'},`    `{'role': 'assistant', 'content': "SELECT COUNT(*) FROM ai_prj_plan, jsonb_array_elements(annual_aim_json::jsonb) AS aim  WHERE (aim->>'planProgress')::integer = 1 AND plan_category = 1 AND plan_type = 3 AND (aim->>'year')::integer = 2024;"},`    `{'role': 'user', 'content': '2024年入廊管线中已完成的前期项目有多少'},`    `{'role': 'assistant', 'content': "SELECT COUNT(1) AS cnt FROM ai_prj_plan, jsonb_array_elements(annual_aim_json::jsonb) AS aim WHERE (aim->>'year')::int = 2024  and (aim->>'planProgress')::int <= current_progress and (aim->>'planProgress') is not null  and plan_type  = 3 and current_progress = 1    and plan_category = 1"},`    `{'role': 'user', 'content': '2023年入廊管线中前期项目的计划有多少'}` `]

最终模型也给我们生成了符合要求的 SQL,初步实现了既定的目标。

Sql:SELECT COUNT(*) FROM ai_prj_plan, jsonb_array_elements(annual_aim_json::jsonb) AS aim  WHERE (aim->>'planProgress')::integer = 1 AND plan_category = 1 AND plan_type = 3 AND (aim->>'year')::integer = 2023;

还有一些开源的方案大家也可以参考,比如vanna和chat2DB。vanna的源码可以参考 https://github.com/vanna-ai/vanna

3. TEXT-to-Cypher

Text-to-Cipher的实现原理和Text-to-SQL类似,只是将SQL执行语句替换图数据库的查询语句。

所以,其Prompt基本上如下所示:

你是一位 GraphDB Cypher 专家,请根据给定的图 Schema 和问题,写出查询语句。``schema 如下:``---``{schema}``---``问题如下:``---``{question}``---``下面写出查询语句:

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值