Elasticsearch:带有自查询检索器的聊天机器人示例

本工作簿演示了 Elasticsearch 的自查询检索器 (self-query retriever) 将问题转换为结构化查询并将结构化查询应用于 Elasticsearch 索引的示例。

在开始之前,我们首先使用 langchain 将文档分割成块,然后使用 ElasticsearchStore.from_documents 创建一个向量存储并将数据索引到 elasticsearch。

然后,我们将看到一些示例查询,展示了由 elasticsearch 驱动的自查询检索器的全部功能。

安装

如果你还没有安装好自己的 Elasticsearch 及 Kibana,请参考文章:

安装 Elasticsearch 及 Kibana

如果你还没有安装好自己的 Elasticsearch 及 Kibana,那么请参考一下的文章来进行安装:

  • 如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch

  • Kibana:如何在 Linux,MacOS 及 Windows 上安装 Elastic 栈中的 Kibana

在安装的时候,请选择 Elastic Stack 8.x 进行安装。在安装的时候,我们可以看到如下的安装信息:

Python 安装包

我们需要安装 Python 版本 3.6 及以上版本。我们还需要安装如下的 Python 安装包:

python3 -m pip install -qU lark elasticsearch langchain openai
$ pwd
/Users/liuxg/python/elser
$ python3 -m pip install -qU lark elasticsearch langchain openai
$ pip3 list | grep elasticsearch
elasticsearch             8.11.1
rag-elasticsearch         0.0.1        /Users/liuxg/python/rag-elasticsearch/my-app/packages/rag-elasticsearch

在本练习中,我们将使用最新的 Elastic Stack 8.11 来进行展示。

环境变量

在启动 Jupyter 之前,我们设置如下的环境变量:

export ES_USER="elastic"
export ES_PASSWORD="yarOjyX5CLqTsKVE3v*d"
export ES_ENDPOINT="localhost"
export OPENAI_API_KEY="YOUR_OPEN_AI_KEY"

请在上面修改相应的变量的值。特别是你需要输入自己的 OPENAI_API_KEY。

拷贝 Elasticsearch 证书

我们把 Elasticsearch 的证书拷贝到当前的目录下:

$ pwd
/Users/liuxg/python/elser
$ cp ~/elastic/elasticsearch-8.11.0/config/certs/http_ca.crt .
overwrite ./http_ca.crt? (y/n [n]) y
$ ls http_ca.crt 
http_ca.crt

创建应用

导入 python 包

我们在当前的目录下创建 jupyter notebook:Chatbot Example with Self Query Retriever.ipynb

from langchain.schema import Document
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import ElasticsearchStore
from langchain.llms import OpenAI
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain.chains.query_constructor.base import AttributeInfo

创建文档

接下来,我们将使用 langchain 模式文档创建包含电影摘要的文档列表,其中包含每个文档的 page_content 和元数据。

docs = [Document(page_content="A bunch of scientists bring back dinosaurs and mayhem breaks loose",metadata={"year": 1993, "rating": 7.7, "genre": "science fiction", "director": "Steven Spielberg", "title": "Jurassic Park"},),Document(page_content="Leo DiCaprio gets lost in a dream within a dream within a dream within a ...",metadata={"year": 2010, "director": "Christopher Nolan", "rating": 8.2, "title": "Inception"},),Document(page_content="A psychologist / detective gets lost in a series of dreams within dreams within dreams and Inception reused the idea",metadata={"year": 2006, "director": "Satoshi Kon", "rating": 8.6, "title": "Paprika"},),Document(page_content="A bunch of normal-sized women are supremely wholesome and some men pine after them",metadata={"year": 2019, "director": "Greta Gerwig", "rating": 8.3, "title": "Little Women"},),Document(page_content="Toys come alive and have a blast doing so",metadata={"year": 1995, "genre": "animated", "director": "John Lasseter", "rating": 8.3, "title": "Toy Story"},),Document(page_content="Three men walk into the Zone, three men walk out of the Zone",metadata={"year": 1979,"rating": 9.9,"director": "Andrei Tarkovsky","genre": "science fiction","rating": 9.9,"title": "Stalker",},),
]

连接到 Elasticsearch

我们将使用我们本地构建的 Elasticsearch 集群进行连接。我们可以参考之前的文章 “Elasticsearch:使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation (三)”。

from dotenv import load_dotenv
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import ElasticKnnSearch
from langchain.text_splitter import CharacterTextSplitter
from urllib.request import urlopen
import os, jsonload_dotenv()openai_api_key=os.getenv('OPENAI_API_KEY')
elastic_user=os.getenv('ES_USER')
elastic_password=os.getenv('ES_PASSWORD')
elastic_endpoint=os.getenv("ES_ENDPOINT")
elastic_index_name='elastic-knn-search'
from elasticsearch import Elasticsearchurl = f"https://{elastic_user}:{elastic_password}@{elastic_endpoint}:9200"
connection = Elasticsearch(url, ca_certs = "./http_ca.crt", verify_certs = True)print(connection.info())embeddings = OpenAIEmbeddings(openai_api_key=openai_api_key)
dims=1536es = ElasticsearchStore.from_documents( docs,embedding = embeddings, es_url = url, es_connection = connection,index_name = elastic_index_name, es_user = elastic_user,es_password = elastic_password)

设置查询检索器

接下来,我们将通过提供有关文档属性的一些信息和有关文档的简短描述来实例化自查询检索器。

然后我们将使用 SelfQueryRetriever.from_llm 实例化检索器 (retriever)

metadata_field_info = [AttributeInfo(name="genre",description="The genre of the movie. Can be either 'science fiction' or 'animated'.",type="string or list[string]",),AttributeInfo(name="year",description="The year the movie was released",type="integer",),AttributeInfo(name="director",description="The name of the movie director",type="string",),AttributeInfo(name="rating", description="A 1-10 rating for the movie", type="float"),
]document_content_description = "Brief summary of a movie"# Set up openAI llm with sampling temperature 0
llm = OpenAI(temperature=0, openai_api_key=openai_api_key)# instantiate retriever
retriever = SelfQueryRetriever.from_llm(llm, es, document_content_description, metadata_field_info, verbose=True
)

使用自查询检索器回答问题

现在我们将演示如何使用 RAG 的自查询检索器。

from langchain.chat_models import ChatOpenAI
from langchain.schema.runnable import RunnableParallel, RunnablePassthrough
from langchain.prompts import ChatPromptTemplate, PromptTemplate
from langchain.schema import format_documentLLM_CONTEXT_PROMPT = ChatPromptTemplate.from_template("""
Use the following context movies that matched the user question. Use the movies below only to answer the user's question.If you don't know the answer, just say that you don't know, don't try to make up an answer.----
{context}
----
Question: {question}
Answer:
""")DOCUMENT_PROMPT = PromptTemplate.from_template("""
---
title: {title}                                                                                   
year: {year}  
director: {director}    
---
""")def _combine_documents(docs, document_prompt=DOCUMENT_PROMPT, document_separator="\n\n"
):doc_strings = [format_document(doc, document_prompt) for doc in docs]return document_separator.join(doc_strings)_context = RunnableParallel(context=retriever | _combine_documents,question=RunnablePassthrough(),
)chain = (_context | LLM_CONTEXT_PROMPT | llm)chain.invoke("What movies are about dreams and it was released after the year 2009 but before the year 2011?")

上面的代码可以在地址:https://github.com/liu-xiao-guo/semantic_search_es/blob/main/Chatbot%20Example%20with%20Self%20Query%20Retriever.ipynb下载。

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

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

相关文章

【微服务】springcloud集成skywalking实现全链路追踪

目录 一、前言 二、环境准备 2.1 软件环境 2.2 微服务模块 2.3 环境搭建 2.3.1 下载安装包 2.3.2 解压并启动服务 2.3.3 访问web界面 三、搭建springcloud微服务 3.1 顶层公共依赖 3.2 用户服务模块 3.2.1 准备测试使用数据库 3.2.2 添加依赖 3.2.3 添加配置文件 …

如何保证本地缓存的一致性(和分布式缓存)

保证本地缓存和分布式缓存的一致性是一个关键的问题,因为这可以确保系统的健壮性和响应速度。以下是一些在Java中实现这一目标的方法: 1.使用一致性哈希:一致性哈希是一种特殊的哈希技术,它能够在节点增减时最小化哈希环上的数据分…

c++基础(对c的扩展)

文章目录 命令空间引用基本本质引用作为参数引用的使用场景 内联函数引出基本概念 函数补充默认参数函数重载c中函数重载定义条件函数重载的原理 命令空间 定义 namespace是单独的作用域 两者不会相互干涉 namespace 名字 { //变量 函数 等等 }eg namespace nameA {int num;v…

啊哈c语言——逻辑挑战9:水仙花数

有一种三位数特别奇怪,这种数的“个位数的立方”加上“十位数的 立方”再加上“百位数的立方”恰好等于这个数。例如: 153111555333,我们为这种特殊的三位数起了一个很好听的名字——“水仙花数”,那么请你找出所有的“水仙花数”…

Vue2 - Vue.observable 介绍

目录 1,介绍2,使用场景和 Vue 实例的区别 1,介绍 官网参考 可以让一个对象变成响应式数据。在 Vue 内部就是用它来处理传递给 Vue 的 data 对象,或是在单文件组件中 data() 返回的对象。 var vm new Vue({data: {count: 0} })…

MySQL学习笔记2: MySQL的前置知识

目录 1. MySQL是什么?2. 什么是客户端,什么是服务器?3. 服务器的特点4. 安装mysql5. mysql 客户端6. mysql 服务器7. mysql的本体8. MySQL 使用什么来存储数据?9. 数据库的多种含义10. MySQL 存储数据的组织方式 1. MySQL是什么? MySQL 是…

【Unity】 HTFramework框架(四十七)编辑器日志中使用超链接的技巧

更新日期:2024年1月3日。 Github源码:[点我获取源码] Gitee源码:[点我获取源码] 索引 日志中使用超链接超链接-网络地址超链接-本地地址超链接-项目资源文件超链接-脚本对象 日志中使用超链接 在编辑器控制台Console中的日志是支持富文本的&…

K8S集群部署解决工作节点couldn‘t get current server API group list问题

最近在自己电脑上装了VMWare Player,在上面装了两个Ubuntu虚拟机,为了方便学习云原生技术,决定在上面装一个2个节点(一个控制面,一个工作节点)的K8S集群。 参考这篇文章: Ubuntu 22.04 搭建K8…

Linux驱动学习—中断

1、中断基础概念 1.1 什么是中断 CPU在正常运行期间&#xff0c;由外部或者内部引起的时间&#xff0c;让CPU停下当前正在运行的程序&#xff0c;转而去执行触发他的中断所对应的程序&#xff0c;这就是中断。 响应中断的过程&#xff1a; <1>中断请求 <2>中断…

探索网络连接的netstat

文章目录 探索网络连接的netstat基本概述更多信息 探索网络连接的netstat 在Linux系统中&#xff0c;网络是至关重要的部分&#xff0c;而netstat命令是管理和监视网络连接的强大工具之一。 它提供了关于网络接口和路由表的详细信息&#xff0c;有助于了解网络连接状态、统计…

全国计算机等级考试| 二级Python | 真题及解析(10)

一、选择题 1.要实现将实数型变量a的值保留三位小数,以下python可以实现的是( ) A.a%0.001 B.a//0.001 C.round(a,3) D.round(3,a) 2.在Python中要交换变量a和b中的值,应使用的语句组是( )。 A…

通信原理期末复习——基础小题汇总(二)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…

【Docker】容器的相关命令

上一篇&#xff1a;创建&#xff0c;查看&#xff0c;进入容器 https://blog.csdn.net/m0_67930426/article/details/135430093?spm1001.2014.3001.5502 目录 1. 关闭容器 2.启动容器 3.删除容器 4.查看容器的信息 查看容器 1. 关闭容器 从图上来看&#xff0c;容器 aa…

【leetcode】力扣算法之有效的数独【中等难度】

题目描述 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例图&…

监控API的指标

监控服务器已经是常态了&#xff0c;但是监控API的表现是啥意思呢&#xff1f;还有监控指标&#xff1f;今天就来看看如何监控API。 正如监控应用程序以确保高质量性能一样&#xff0c;也必须监控API。 API是应用程序相互通信的管道。更具体地说&#xff0c;API提供了一种方法…

软碟通UltraISO制作U盘安装Ubuntu

清华大学开源软件镜像站https://mirrors.tuna.tsinghua.edu.cn/ 从里面下载ubuntu-22.04-desktop-amd64.iso UltraISO是一款非常不错的U盘启动盘制作工具&#xff0c;一直被许多网友们所喜欢&#xff0c;使用简单、方便。 UltraISO官方下载地址&#xff1a;https://cn.ultrais…

游戏Lua调用01.lua的编译及测试

一、lua库下载与编译 进入lua官网 Lua: version history 找到lua5.1 选择lua5.1是因为大部分游戏使用的都是lua5.1的库&#xff0c;也可以选择高版本&#xff0c;影响不大 下载完了后使用vs建立一个静态库或者动态库的工程 这里以动态库为例子&#xff0c;静态库也是一样的…

用队列实现栈oj题——225

. 个人主页&#xff1a;晓风飞 专栏&#xff1a;LeetCode刷题|数据结构|Linux 路漫漫其修远兮&#xff0c;吾将上下而求索 文章目录 题目要求&#xff1a;实现 MyStack 类&#xff1a;注意&#xff1a;示例&#xff1a;解释&#xff1a;提示&#xff1a; 解题核心数据结构的定义…

Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中

场景 SpringBootVue整合WebSocket实现前后端消息推送&#xff1a; SpringBootVue整合WebSocket实现前后端消息推送_websocket vue3.0 springboot 往客户端推送-CSDN博客 上面实现ws推送数据流程后&#xff0c;需要在windows上使用ws客户端定时记录收到的数据到文件中&#x…

SPRING BOOT发送邮件验证码(Gmail邮箱)

SPRING BOOT邮件发送验证码 一、Gmail邮箱配置 1、进入Gmail(https://mail.google.com) 2、打开谷歌右上角设置 3、启用POP/IMP 4、启用两步验证(https://myaccount.google.com/security) 5、建立应用程式密码 6、复制保存应用程式密码 二、代码 1、引入依赖 <d…