LLM之RAG实战(四十)| 使用LangChain SQL Agent和MySQL搭建多层RAG ChatBot

       在传统的意义上,RAG 主要是从文档中检索用户想要的数据,从而提高大模型的能力,减少幻觉问题。今天,我们从另一个维度介绍RAG,RAG不从文档中获取数据,而是从MySQL数据库检索数据。我们可以使用LangChain SQL Agent结合聊天历史信息构建一个多层RAG聊天机器人。

一、架构

图片

       整体架构,如上图所示。主要层将使用带有基本链的聊天记录来生成一个新的和改进的查询,然后将其传递给第二层。在这里,我们使用 SQL Agent直接在 MySQL 数据库上运行查询并获取所需的数据。最后,这个检索到的上下文与提示一起传递到 LLM , SQL Agent可以查看您的聊天记录。

        主要层的功能允许我们将聊天记录用作上下文,这样当数据传递给 LLM时,就带有与我们的查询相关的背景知识。我们还在初始提示中要求改进查询的整体情况,以便更轻松地为 SQL Agent进行选择。

self.chat_llm = ChatOpenAI(    openai_api_key=settings.get("langchain.openai_api_key"),    model= llm_model_name,    temperature=0.2,    verbose=True,    model_kwargs={"response_format": {"type": "json_object"}},)
self.memory = ConversationBufferMemory(    memory_key = "chat_history",    input_key = "question",    return_messages = True)
template = """You are a query improvement bot that will use the chat_history provided to improved the user's query. Return your response in the following JSON format:{{    "question": "Your response"}}If the user's query lacks context, you will use the chat_history to build it.If the chat_history is not relevant to the question mentioned, forward the same question forwardQuestion: {question}Chat History: {chat_history}Context: {context}"""
self.prompt = PromptTemplate(    template = template,    input_variables = ["question", "chat_history", "context"])

        在上面的代码块中,使用 LangChain 的 ChatOpenAI 函数启动我们的LLM代码块。之后,使用 ConversationBufferMemory 实例化内存。最后,使用 PromptTemplate 设置提示,该提示适配于我们的用例。

def get_improved_query(            self,            query,            chat_history: list[SessionMessageBase]):        self.chain = load_qa_chain(        llm = self.chat_llm,        chain_type = "stuff",        memory = self.memory,        prompt = self.prompt,        verbose = True    )self.memory.clear()
    print("chat_history", chat_history)for message in chat_history:        self.memory.chat_memory.add_user_message(message.query)        self.memory.chat_memory.add_ai_message(str(message.response))                                            response = self.chain.run(        input_documents=[],        question=query    )    print("response", response)return response

        在下一段代码中,将使用上一个代码块中定义的变量创建 QA 链,将消息添加到聊天记录中,然后运行链以获取改进的查询。请注意,input_documents是故意留空的。

二、SQL Agent

        在第二层,SQL Agent首先获取到用户的问题,然后要求 LLM 根据用户的问题创建 SQL 查询,使用内置函数在MySQL数据库上运行查询。最后,将来自数据库的响应数据与原始问题再次发送给LLM。这是一种新型的 RAG 检索器,可以轻松连接到您的数据库,从而在您的数据和聊天机器人之间轻松无缝地连接。​​​​​​​

self.db = SQLDatabase.from_uri(database_url)  self.chat_llm = ChatOpenAI(    openai_api_key="OpenAI-Key",    model= llm_model_name,    temperature=0,    verbose=True,    model_kwargs={"response_format": {"type": "json_object"}},)

        在这里,我们启动了多个变量,从使用 SQLDatabase.from_uri() 开始,它接受数据库 URL。接下来,我们像以前实例化LLM一样,但这次我们添加了一个名为 model_kwargs 的特殊参数,并将响应格式设置为 JSON,以便我们更容易获取数据并解析它。​​​​​​​

self.system = """You are an agent designed to interact with a SQL database.Given an input question, create a syntactically correct MySQL query to run, then look at the results of the query and return the answer.Unless the user specifies a specific number of examples they wish to obtain, always limit your query to at most 3 results.You can order the results by a relevant column to return the most interesting examples in the database.Never query for all the columns from a specific table, only ask for the relevant columns given the question.You have access to tools for interacting with the database.Only use the given tools. Only use the information returned by the tools to construct your final answer.Only use the results of the given SQL query to generate your final answer and return that.You MUST double check your query before executing it. If you get an error while executing a query then you should stop!DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the database.Only create an SQL statement ONCE!"""self.prompt = ChatPromptTemplate.from_messages([("system", self.system), ("human", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad")])

       SQL Agent的提示略有不同。在这里,我们使用的是 ChatPromptTemplate,如果你真的研究它,你会看到它是如何专门编写的,用于创建和运行 SQL 查询。​​​​​​​

def create_sql_agent(self):      return create_sql_agent(          llm=self.chat_llm,          db=self.db,          prompt=self.prompt,          agent_type="openai-tools",          verbose=True,      )

       create_sql_agent函数创建了SQL 代理,它包含了LLM、数据库、提示,agent_type必须是“openai-tools”。​​​​​​​

improved_query = json.loads(BaseAgent.get_improved_query(query, chat_history))response = self.agent.invoke({"input": improved_query.get("question")})

        这是代码的最后一部分,它将首先运行第一层以获取改进的查询,然后我们使用该改进的查询来获得最终响应。

三、总结

         这个解决方案的关键要点是,它是根据我的用例DIY 构建的。我相信LangChain社区迟早会找到一个解决方案,他们可以满足与SQL代理的聊天记录。就目前而言,如果您希望将聊天记录与您自己的聊天机器人合并,可以直接查询到您的数据库中,这对您非常有帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/721253.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTML学习和JAVAScript学习

HTML 标签 <!DOCTYPE html> <!-- 文档类型为html --> <html lang"en"> <head><meta charset"UTF-8"> <!-- 使用字符集UTF-8 --> <!-- 设置浏览器兼容性 --><meta name"viewpo…

H6901B升压恒流调光芯片3.7V 7.4V升压 12V 24V 36V 48V 100V高端调光 太阳能照明 锂电池升压

惠海H6902B升压恒流驱动芯片是一款专为LED照明应用设计的驱动方案。该芯片具有多项产品特征&#xff0c;能够满足多种LED照明需求。 适用于多种电压输入范围&#xff08;2.7V-80V&#xff09;并具备效率&#xff08;达95%以上&#xff09;和工作频率&#xff08;1MHz&#xff…

异步爬虫:aiohttp 异步请求库使用:

使用requests 请求库虽然可以完成爬虫业务&#xff0c;但是对于异步任务来说&#xff0c;它是做不到的&#xff0c; 这时候我们需要借助 aiohttp 异步请求库来完成异步爬虫的编写&#xff1a; 话不多说&#xff0c;直接看示例&#xff1a; 注意&#xff1a;楼主使用的python版…

什么是数字化,什么是数智化?数字化与数智化的区别和联系

什么是数字化&#xff1f;什么是数智化&#xff1f;以及数字化与数智化的区别&#xff0c;下面分为三块跟大家详细讲解。 一、什么是数字化&#xff1f; 1、概念&#xff1a; 数字化&#xff08;Digitalization&#xff09;是将信息转换为数字&#xff08;即计算机可读&#…

[14] CUDA_使用Opencv处理图像

CUDA_使用Opencv处理图像 1. Opencv中的图像表示 Opencv 提供了Mat 类来存储图像&#xff0c;如下&#xff1a; cv::Mat img; imgcv::imread("cameraman.tif);定义图像的示例&#xff1a; //定义单通道图像 cv::Mat img(6,6,CV_8UC1); //32位浮点型 Mat img2(256,256,…

【进阶篇-Day3:JAVA接口新特性、代码块、内部类、Lambda表达式、组件等的介绍】

目录 1、接口新特性1.1 JDK8的新特性1.2 JDK9的新特性 2、代码块2.1 代码块的定义2.2 代码块的分类 3、内部类3.1 内部类的定义3.2 内部类成员访问3.3 学习内部类的原因3.4 内部类的分类3.4.1 成员内部类3.4.2 静态内部类3.4.3 局部内部类3.4.4 匿名内部类&#xff08;1&#x…

分布式技术导论 — 探索分析从起源到现今的巅峰之旅(流式处理到微批处理)

探索分析从起源到现今的巅峰之旅 流式计算回顾流式服务结合分布式特性 流式计算组成部分监控数据处理进度流式分析案例流转数据的衍生存储确认器采取高效策略确认器异常应对策略工作节点故障的处理&#xff08;精确一次处理&#xff09;确认器故障的处理&#xff08;恰好一次处…

Druid未授权访问漏洞修复

前言 安全组针对系统漏扫发现系统存在Druid未授权访问&#xff0c;会引发泄露系统敏感信息&#xff0c;漏洞链接为ip:端口/druid/index.html&#xff0c;可以清楚的查看数据库的相关连接信息&#xff0c;如下图所示&#xff1a; 漏洞修复 1、关闭Druid监控页面 在Druid的配…

2-9 基于matlab的传递矩阵计算轴的模态

基于matlab的传递矩阵计算轴的模态&#xff0c;包括模态频率和模态振型&#xff0c;可设置轴的结构参数。程序已调通&#xff0c;可直接运行。 2-9 传递矩阵计算轴的模态 模态频率 - 小红书 (xiaohongshu.com)

Chromium 开发指南2024 Mac篇-安装和配置depot_tools工具(三)

1.引言 在前两篇指南中&#xff0c;我们详细介绍了在 macOS 环境下编译 Chromium 所需的硬件要求和系统依赖&#xff0c;并具体讲解了如何正确安装和配置 Xcode。通过这些步骤&#xff0c;您已经为编译 Chromium 打下了坚实的基础。然而&#xff0c;编译 Chromium 还需要配置一…

网络编程---Java飞机大战联机

解析服务器端代码 代码是放在app/lib下的src下的main/java&#xff0c;而与之前放在app/src/main下路径不同 Main函数 Main函数里只放着创建MyServer类的一行 public static void main(String args[]){new MyServer();} MyServer构造函数 1.获取本机IP地址 //获取本机IP地…

处理耗时任务

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 namespace 处理耗时任务 {public partial class Form1 : Form{public Form1(){InitializeComponent();}bool IsRun false;private string path Directory.GetCurrentDirectory() "\\古诗词.txt";private…

技术点梳理0618

ann建库&#xff0c;分布式建库&#xff0c;性能优化&#xff0c;precision recall参数优化 hnsw&#xff0c;图索引 1. build a&#xff09;确定层&#xff1a;类似跳表思路建立多层&#xff0c;对每一个插入的节点&#xff0c;random层号l&#xff0c;从图的起始点search_…

第十二章:会话控制

会话控制 文章目录 会话控制一、介绍二、cookie2.1 cookie 是什么2.2 cookie 的特点2.3 cookie 的运行流程2.4 浏览器操作 cookie2.5 cookie 的代码操作&#xff08;1&#xff09;设置 cookie&#xff08;2&#xff09;读取 cookie&#xff08;3&#xff09;删除 cookie 三、se…

python+unity手势控制地球大小

效果图如下 具体操作如下 1 在unity窗口添加一个球体 2 给球体添加材质,材质图片使用地球图片 地球图片如下 unity材质设置截图如下 3 编写地球控制脚本 using System.Collections; using System.Collections.Generic; using UnityEngine;public class test : MonoBehavio…

餐饮业应该购置精酿啤酒设备吗?

近几年&#xff0c;啤酒行业刮起了一股“精酿风”&#xff0c;它不只是一种饮品口味上的变化&#xff0c;更像是一个生活方式的升级。精酿啤酒的兴起&#xff0c;不仅体现在味道的多样性和层次感上&#xff0c;更重要的是它代表了一种生活态度&#xff0c;是对品质生活的追求。…

shell脚本中的变量

关于Linux操作系统中当前shell进程与子shell进程的详细解释 如上图所示&#xff0c;使用ps -f可以当前查看Linux操作系统中当前正在运行的进程。 然后敲bash后&#xff0c;相当于在当前的bash shell环境下又创建了一个子bash shell的进程&#xff0c; 如上图所示&#xff0c;…

代码随想录-Day35

134. 加油站 在一条环路上有 n 个加油站&#xff0c;其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车&#xff0c;从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发&#xff0c;开始时油箱为空。 给定两个整数数组 …

使用 AST语法树分析与修改Javascript 代码

1、AST语法树简介 当编写代码分析工具、代码美化工具、网站逆向分析等场景时&#xff0c;通常需要使用AST语法树技术。 比如项目开发过程中常遇到的场景&#xff1a;某个公共函数名需要更改&#xff0c;但被很多文件多处代码调用&#xff0c;手工修改非常容易漏改、改错等&…

微服务开发与实战Day11 - 微服务面试篇

一、分布式事务 1. CAP定理 1998年&#xff0c;加州大学的计算机科学及Eric Brewer提出&#xff0c;分布式系统有三个指标&#xff1a; Consistency&#xff08;一致性&#xff09;Availability&#xff08;可用性&#xff09;Partition tolerance&#xff08;分区容错性&am…