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代理的聊天记录。就目前而言,如果您希望将聊天记录与您自己的聊天机器人合并,可以直接查询到您的数据库中,这对您非常有帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

web前端技术推荐:构建卓越用户体验的必备工具与策略

web前端技术推荐:构建卓越用户体验的必备工具与策略 在日新月异的互联网时代,Web前端技术扮演着至关重要的角色。它们不仅影响着网站的外观和交互性,还直接关系到用户体验和业务成果。本文将从四个方面、五个方面、六个方面和七个方面&#…

Vue40-vueComponent构造函数

一、组件的本质:VueComponent构造函数 组件的本质是:构造函数 二、每一次调用vue.extend,返回的事一个全新的 VueComponent VueComponent的源码如下: 三、组件中的this 组件中的this是VueComponent实例对象,结构和vm…

如果给电商系统颜值搞排名,我觉得淘宝千牛系统是天花板了。

淘宝的商家操作界面-千牛系统经过多年的迭代,无论从颜值上、功能上还是用户体验上都是行业天花板的存在,我截图软件上的一些图给大家分享下。

快速提高MySQL查询效率的实用方法

快速提高MySQL查询效率的实用方法包括以下几个方面,下面将详细列举并解释: 使用合适的索引 索引可以大大提高查询的速度,允许数据库系统快速定位和访问特定的数据行。在经常用于WHERE子句、JOIN操作和ORDER BY排序的列上创建索引。避免创建过…

网络编程之XDP和TC

一、TC之于XDP 在前面分析过XDP,今天简单分析一下与其相关的TC,即traffic control,流量控制。在分析XDP时知道其只能用于ingress方向触发,而TC却可以在两个方向即ingress和egress方向触发。也可以简单理解成它可以同时钩住进出两个方向的数据…

C 语言实例 - 输出数组

使用 for 循环输出数组 #include <stdio.h>int main() {int array[10] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};int loop;for(loop 0; loop < 10; loop)printf("%d ", array[loop]);return 0; }输出结果为&#xff1a; 1 2 3 4 5 6 7 8 9 0使用 for 循环逆向输…

foxmai邮箱使用技巧图文板简单容易,服务器配置密钥配置

本人详解 作者&#xff1a;王文峰&#xff0c;参加过 CSDN 2020年度博客之星&#xff0c;《Java王大师王天师》 公众号&#xff1a;JAVA开发王大师&#xff0c;专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生&#xff0c;期待你的关注和支持&#xf…

手把手教你实现条纹结构光三维重建(2)——条纹解码

在第一讲中&#xff0c;我们讲到了条纹的生成&#xff0c;这一讲&#xff0c;我们将实现条纹的解码。我们这里的解码技术很简单&#xff0c;即高低频倍数解码&#xff0c;详细的论文可以参考&#xff1a;《Temporal phase unwrapping algorithms for fringe projection profilo…

基于 Transformer 的大语言模型

语言建模作为语言模型&#xff08;LMs&#xff09;的基本功能&#xff0c;涉及对单词序列的建模以及预测后续单词的分布。 近年来&#xff0c;研究人员发现&#xff0c;扩大语言模型的规模不仅增强了它们的语言建模能力&#xff0c;而且还产生了处理传统NLP任务之外更复杂任务…

RAC11G修改监听默认端口

大多数现场集群都采用的是默认端口&#xff0c;现XX现场客户领导要求不使用默认端口&#xff0c;以下是修改监听端口的步骤&#xff0c;配置过程中若有疑问可添加文末公众号发私信一对一答疑解惑。 一.修改SCAN listener port 1.1 修改SCAN listener port 1.1.1.crs配置中修…

C++11中的类型推演工具decltype

decltype是根据表达式的实际类型推演出定义变量时所用的类型 auto和decltype的区别 auto类型用编译器计算变量的初始值来推断其类型, decltype虽然也让编译器分析表达式并得到它的类型&#xff0c;但是不实际计算表达式的值。 推演表达式类型作为变量的定义类型 int main()…

4-字符串-11-反转字符串-LeetCode344

4-字符串-11-反转字符串-LeetCode344 LeetCode: 题目序号344 更多内容欢迎关注我&#xff08;持续更新中&#xff0c;欢迎Star✨&#xff09; Github&#xff1a;CodeZeng1998/Java-Developer-Work-Note 技术公众号&#xff1a;CodeZeng1998&#xff08;纯纯技术文&#xff0…

认识一些分布函数-Frechet分布及其应用

1. 何为Frechet分布 Frechet分布也称为极值分布(EVD)类型II,用于对数据集中的最大值进行建模。它是四种常用极值分布之一。另外三种是古贝尔分布、威布尔分布和广义极值分布(Gumbel Distribution, the Weibull Distribution and the Generalized Extreme Value Distributi…

MyBatis-PageHelper 源码解说

归档 GitHub: MyBatis-PageHelper-源码解说 总说明 源码仓库&#xff1a; https://github.com/pagehelper/Mybatis-PageHelper克隆&#xff1a;git clone https://github.com/pagehelper/Mybatis-PageHelper.git切分支&#xff08;tag&#xff09;&#xff1a;git checkout m…

亿达中国武汉园区入选“武汉市科技金融工作站”及“武汉市线下首贷服务站”

近日&#xff0c;武汉市2024科技金融早春行活动在深交所湖北资本市场培育基地举行。会上&#xff0c;第四批武汉市科技金融工作站试点单位名单及第五批武汉地区金融系统线下首贷服务站名单正式公布&#xff0c;武汉软件新城成功入选上述两个名单。 为缓解科技型企业融资难题&a…

vue2+echarts实现简易的2d地图效果

背景 公司的一个可视化数据大屏里面&#xff0c;有一个使用echarts实现的2d地图。不是我开发的&#xff0c;在此记录一下实现过程以及一些扩展解构。应该是从哪个航空航线图改动了一下&#xff0c;效果看起来还是可以的。 效果预览 版本 vue版本使用的是"^2.6.12"…

TypeScript中的数组类型

数组类型 目录 数组类型 目录自动推断类型配置只读数组多维数组 自动推断 不定义类型&#xff0c;推断为never let array []; //never推断为字符串数组 const akun [akun.com, akun001] //const akun : string[] hd.push(100) //因为类型不允许&#xff0c;所以报错推断…

我要成为算法高手-双指针篇

目录 什么是双指针?问题1&#xff1a;移动零问题2&#xff1a;复写零问题3&#xff1a;快乐数问题4&#xff1a;盛最多水的容器问题5&#xff1a;有效三角形个数问题6&#xff1a;查找总价格和为目标值的两个商品(两数之和)问题7&#xff1a;三数之和问题8&#xff1a;四数之和…

Linux中“计划任务”设置以及补充

目录 一、关闭防火墙 &#xff08;1&#xff09;关闭防火墙 &#xff08;2&#xff09;关闭防火墙2 &#xff08;3&#xff09;关闭selinux 二、安装 php 第一步&#xff1a;yum源 第二步&#xff1a;下载php 第三步&#xff1a;启动php 第四步&#xff1a; 检查php是…

web前端开发前途:探索、挑战与无限可能

web前端开发前途&#xff1a;探索、挑战与无限可能 在数字化浪潮席卷全球的今天&#xff0c;Web前端开发作为连接技术与用户的桥梁&#xff0c;其前途无疑充满了探索、挑战与无限可能。本文将从四个方面、五个方面、六个方面和七个方面&#xff0c;深入剖析Web前端开发的前途&…