Elasticsearch:使用 Gemini、Langchain 和 Elasticsearch 进行问答

本教程演示如何使用 Gemini API创建 embeddings 并将其存储在 Elasticsearch 中。 我们将学习如何将 Gemini 连接到 Elasticsearch 中存储的私有数据,并使用 Langchian 构建问答功能。

准备

Elasticsearch 及 Kibana

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

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

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

在安装的时候,请参照 Elastic Stack 8.x 的文章来进行安装。

Gemini 开发者 key

你可以参考文章 来申请一个免费的 key 供下面的开发。你也可以直接去地址进行申请。

设置环境变量

我们在 termnial 中打入如下的命令来设置环境变量:

export ES_USER=elastic
export ES_PASSWORD=-M3aD_m3MHCZNYyJi_V2
export GOOGLE_API_KEY=YourGoogleAPIkey

拷贝 Elasticsearch 证书

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

$ pwd
/Users/liuxg/python/elser
$ cp ~/elastic/elasticsearch-8.12.0/config/certs/http_ca.crt .

安装 Python 依赖包

pip3 install -q -U google-generativeai elasticsearch langchain langchain_google_genai

应用设计

我们在当前的工作目录下打入命令:

jupyter notebook

导入包

import google.generativeai as genai
import google.ai.generativelanguage as glm
from elasticsearch import Elasticsearch, helpers
from langchain.vectorstores import ElasticsearchStore
from langchain.text_splitter import CharacterTextSplitter
from langchain_google_genai import GoogleGenerativeAIEmbeddings
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain.prompts import ChatPromptTemplate
from langchain.prompts import PromptTemplate
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough
from langchain.schema.runnable import RunnableLambda
from langchain.schema import HumanMessage
from urllib.request import urlopen
from dotenv import load_dotenv
import json, os

读取环境变量

load_dotenv()

GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
ES_USER = os.getenv("ES_USER")
ES_PASSWORD = os.getenv("ES_PASSWORD")
elastic_index_name='gemini-qa'

写入文档

让我们下载示例数据集并反序列化文档

我们首先在地址下载示例数据集:

wget https://raw.githubusercontent.com/liu-xiao-guo/semantic_search_es/main/datasets/data.json

其中的一个文档的内容如下:

$ pwd
/Users/liuxg/python/elser
$ ls datasets/
data.json
# Load data into a JSON object
with open('./datasets/data.json') as f:
   workplace_docs = json.load(f)

print(f"Successfully loaded {len(workplace_docs)} documents")

将文档拆分为段落

metadata = []
content = []

for doc in workplace_docs:
  content.append(doc["content"])
  metadata.append({
      "name": doc["name"],
      "summary": doc["summary"],
      "rolePermissions":doc["rolePermissions"]
  })

text_splitter = CharacterTextSplitter(chunk_size=50, chunk_overlap=0)
docs = text_splitter.create_documents(content, metadatas=metadata)

使用 Gemini Embeddings 将文档索引到 Elasticsearch

url = f"https://{ES_USER}:{ES_PASSWORD}@192.168.0.3:9200"

connection = Elasticsearch(
        hosts=[url], 
        ca_certs = "./http_ca.crt", 
        verify_certs = True
)
print(connection.info())

embeddings = GoogleGenerativeAIEmbeddings(
    model="models/embedding-001", task_type="retrieval_document"
)

es = ElasticsearchStore.from_documents( 
                            docs,
                            embedding = embeddings, 
                            es_url = url, 
                            es_connection = connection,
                            index_name = elastic_index_name, 
                            es_user = ES_USER,
                            es_password = ES_PASSWORD)

运行完上面的代码后,我们可以去 Kibana 中进行查看:

创建 retriever

更多搜索的方法可以参考 “Elasticsearch:使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation (四)”。

embeddings = GoogleGenerativeAIEmbeddings(
    model="models/embedding-001", task_type="retrieval_query"
)

retriever = es.as_retriever(search_kwargs={"k": 3})

如果你不用去写入文档(没有上一步的 es),那么你可以使用如下的方法创建 es:

es = ElasticsearchStore(
    es_connection=connection,
    embedding=embedding,
    index_name=elastic_index_name
)

格式化文档

def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

使用 Prompt Template+gemini-pro 模型创建一条链

template = """Answer the question based only on the following context:\n

{context}

Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)


chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()} 
    | prompt 
    | ChatGoogleGenerativeAI(model="gemini-pro", temperature=0.7) 
    | StrOutputParser()
)

chain.invoke("what is our sales goals?")

最终的的 notebook 可以在地址找到:https://github.com/liu-xiao-guo/semantic_search_es/blob/main/QA_using_Gemini_Langchain_Elasticsearch.ipynb

跟多阅读: 快速入门:使用 Gemini Embeddings 和 Elasticsearch 进行向量搜索

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

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

相关文章

小游戏选型(二):第三方社交小游戏厂家对比,即构/声网/融云/云信等

前言: 上一篇文章我们主要介绍社交游戏化趋势,并分析了直播平台面临的买量贵、变现难等问题,探讨了小游戏作为新的运营变现玩法的优势。同时还列举了各大直播平台TOP5的小游戏。今天我们继续介绍小游戏系列内容,本文是该系列的第…

力扣算法-Day20

541. 反转字符串II 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。 如果剩余字符少于 k 个,则将剩余字符全部反转。如果剩余字符小于 2k 但大于或等于 k 个&#xff0c…

确定软件项目范围基准 5个重点

软件项目范围基准明确了项目的边界、目标和主要交付成果,有助于提高项目成本、进度和资源估算的准确性,便于实施项目控制,而且还可以帮助我们清楚分派责任,防止范围蔓延,从而提升项目的成功率。 如果没有明确确定范围基…

Java复习系列之阶段二:数据库

1. 基础语法 1.1 DQL(数据查询语句) 执行顺序: from、join 、on、where、group by、having、select、distinct、order by、limit 1.2 DML(数据修改语言) 对数据表的增删改 insert into update set delete form 1.…

数模.聚类模型

一、前言 二、K-means聚类算法 下面是针对量纲不同进行的操作 三、系统聚类 spass操作 spass操作 总结:最好使用系统聚类算法,在论文上写的的内容更加充实,图片也较多 四、DBSCAN算法 适用于这种比较有规律的。 这种算法使用很少。不建议使用…

喝酒筛子小游戏集合源码微信小程序喝酒骰子程序带流量主版本源码酒桌玩筛子源码

2023新版酒桌小游戏喝酒小程序源码-(流量主版本) 修改增加了广告位 根据文档直接替换,原版本没有广告位 直接上传源码到开发者端即可 通过后改广告代码,然后关闭广告展示提交,通过后打开即可 无广告引流 流量主版…

签到业务流程

1.技术选型 Redis主写入查询,Mysql辅助查询,传统签到多数都是直接采用mysql为存储DB,在大数据的情况下数据库的压力较大.查询速率也会随着数据量增大而增加.所以在需求定稿以后查阅了很多签到实现方式,发现用redis做签到会有很大的优势.本功能主要用到r…

git:使用git rebase合并多次commit为一个

git log:找到需要合并的最早 commit 的父级 git rebase -i 73a5cd8597除第一个 pick 外,将其它改成 s,改完后保存退出 保存完后弹出 commit message 合并提示,根据这次合并的目的,重写commit message,改完后…

计算机中丢失mfc100u.dll怎么解决,详细解析mfc100u.dll丢失的解决方法

遭遇“无法找到mfc100u.dll”的错误不必过分担忧,这是一个普遍现象。许多用户在启动某些软件或游戏的时候可能会碰到这样的情况。通常,这个错误信息表明你的计算机系统中缺失了一个关键的动态链接库(DLL)文件,它可能会妨碍应用程序的顺利启动…

Android读写文件,适配Q以上

Android Q升级了文件系统,访问文件不仅仅是说动态权限了,有各种限制。权限什么的就不赘述了,下面介绍一下在10以上的系统中访问文件。 首先是打开文件管理器 /*** 打开文件管理器 存储卡和外接U盘都可以访问*/public void openFileManager()…

没指定spring-boot-maven-plugin版本导致编译失败,这坑你踩过没

文章目录 1. 前言2. 组件版本信息3. 事件经过3.1 本地通过maven命令打包3.2 定位问题步骤3.2.1 核对spring-boot-maven-plugin版本信息3.2.2 spring-boot-maven-plugin版本错误原因 3.3 解决方案 4.结论 1. 前言 我们在平时开发过程中关注的比较多的是项目开发时依赖包的版本以…

为什么选择快速应用开发:提高业务响应速度与竞争力的关键

如今,企业想要持续蓬勃发展,就需要具备快速满足客户期望的能力。无论是十几年历史的重要市场占有者推出新的APP,还是在疫情期间从线下转向线上电商营销,企业都需要主动适应市场。随着为客户提供新的服务方式,员工也需要…

【LUA】mac状态栏添加天气

基于网络上的版本修改的,找不到出处了。第一个摸索的lua脚本,调了很久。 主要修改:如果风速不大,就默认不显示,以及调整为了一些格式 local urlApi http://.. --这个urlApi去申请个免费的就可以了 然后打开对应的json…

Scratch:启蒙少儿编程的图形化魔法

在当今这个数字化时代,编程已经成为了一项重要的基础技能。就像学习阅读和写作一样,掌握编程能够打开通往未来世界的大门。对于孩子们来说,Scratch作为一种图形化编程语言,不仅简单有趣,而且非常适合作为编程学习的入门…

Vue3 Suspense 优雅地处理异步组件加载

✨ 专栏介绍 在当今Web开发领域中,构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架,正是为了满足这些需求而诞生。它采用了MVVM架构模式,并通过数据驱动和组件化的方式,使…

基于51单片机智能电子秤

实物显示效果: https://www.bilibili.com/video/BV1Wb4y1A7Aw/?vd_source6ff7cd03af95cd504b60511ef9373a1d 功能介绍: (1)用键盘设计单价; (2)称重后同时显示该物品的重量、单价和总额&…

JAVA编程题之用户登录,用户信息存储在本地文件

实现用户登录:键盘输入要登录的用户名与密码 properties类型文件常在框架内用作配置文件. public static void main(String[] args) throws Exception {FileInputStream fis new FileInputStream("user.properties");Properties properties new Prope…

Hive3.1.3基础(续)

参考B站尚硅谷 分区表和分桶表 分区表 Hive中的分区就是把一张大表的数据按照业务需要分散的存储到多个目录,每个目录就称为该表的一个分区。在查询时通过where子句中的表达式选择查询所需要的分区,这样的查询效率会提高很多。 分区表基本语法 分区表…

一、对人工智能大模型了解与认知

黑8说 月黑风高,乌云密布,树木低垂,黯淡沉闷。这黎明前的风暴,预示着新时代的变革即将到来。 在一个8线小城市的办公室中 黑8对主任说: 世界上有男人、女人、人妖,米国有1/3男,2/3女…&#xff…

HCIP实验7-三层架构实验

搭建实验拓扑图 实验开始 配置r1,r2的IP地址及环回 r1 [r1]interface LoopBack 0 [r1-LoopBack0]ip address 1.1.1.1 32 [r1]interface g0/0/0 [r1-GigabitEthernet0/0/0]ip address 23.1.1.1 24 [r1]interface g0/0/1 [r1-GigabitEthernet0/0/1]ip address 34.1.1.1 24 [r1…