Elasticsearch:使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation (四)

这篇博客是之前文章:

的续篇。在这篇文章中,我们将学习如何把从 Elasticsearch 搜索到的结果传递到大数据模型以得到更好的结果。

如果你还没有创建好自己的环境,请参考第一篇文章进行详细地安装。

创建应用并展示

安装包

bash 复制代码
#!pip3 install langchain

导入包

javascript 复制代码
1.  from dotenv import load_dotenv
2.  from langchain.embeddings import OpenAIEmbeddings
3.  from langchain.vectorstores import ElasticsearchStore
4.  from langchain.text_splitter import CharacterTextSplitter
5.  from langchain.prompts import ChatPromptTemplate
6.  from langchain.prompts import PromptTemplate
7.  from langchain.chat_models import ChatOpenAI
8.  from langchain.schema.output_parser import StrOutputParser
9.  from langchain.schema.runnable import RunnablePassthrough
10.  from langchain.schema.runnable import RunnableLambda
11.  from langchain.schema import HumanMessage
12.  from urllib.request import urlopen
13.  import os, json

15.  load_dotenv()

17.  openai_api_key=os.getenv('OPENAI_API_KEY')
18.  elastic_user=os.getenv('ES_USER')
19.  elastic_password=os.getenv('ES_PASSWORD')
20.  elastic_endpoint=os.getenv("ES_ENDPOINT")
21.  elastic_index_name='langchain-rag'

添加文档并将文档分成段落

python 复制代码
1.  with open('workplace-docs.json') as f:
2.     workplace_docs = json.load(f)

4.  print(f"Successfully loaded {len(workplace_docs)} documents")
css 复制代码
1.  metadata = []
2.  content = []

4.  for doc in workplace_docs:
5.    content.append(doc["content"])
6.    metadata.append({
7.        "name": doc["name"],
8.        "summary": doc["summary"],
9.        "rolePermissions":doc["rolePermissions"]
10.    })

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

Index Documents using ELSER - SparseVectorRetrievalStrategy()

ini 复制代码
1.  from elasticsearch import Elasticsearch

3.  url = f"https://{elastic_user}:{elastic_password}@{elastic_endpoint}:9200"
4.  connection = Elasticsearch(url, ca_certs = "./http_ca.crt", verify_certs = True)

6.  es = ElasticsearchStore.from_documents(
7.      docs,
8.      es_url = url,
9.      es_connection = connection,
10.      es_user=elastic_user,
11.      es_password=elastic_password,
12.      index_name=elastic_index_name,
13.      strategy=ElasticsearchStore.SparseVectorRetrievalStrategy()
14.  )

如果你还没有配置好自己的 ELSER,请参考之前的文章 " Elasticsearch:使用 Open AI 和 Langchain 的 RAG - Retrieval Augmented Generation (三)"。

在执行完上面的命令后,我们可以在 Kibana 中进行查看:

展示结果

lua 复制代码
1.  def showResults(output):
2.    print("Total results: ", len(output))
3.    for index in range(len(output)):
4.      print(output[index])
ini 复制代码
1.  r = es.similarity_search("work from home policy")
2.  showResults(r)

RAG with Elasticsearch - Method 1 (Using Retriever)

ini 复制代码
1.  retriever = es.as_retriever(search_kwargs={"k": 4})

3.  template = """Answer the question based only on the following context:
4.  {context}

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

10.  chain = (
11.      {"context": retriever, "question": RunnablePassthrough()} 
12.      | prompt 
13.      | ChatOpenAI() 
14.      | StrOutputParser()
15.  )

17.  chain.invoke("vacation policy")

RAG with Elasticsearch - Method 2 (Without Retriever)

Add Context

ini 复制代码
1.  def add_context(question: str):
2.      r = es.similarity_search(question)

4.      context = "\n".join(x.page_content for x in r)

6.      return context

Chain

ini 复制代码
1.  template = """Answer the question based only on the following context:
2.  {context}

4.  Question: {question}
5.  """

7.  prompt = ChatPromptTemplate.from_template(template)

9.  chain = (
10.      {"context": RunnableLambda(add_context), "question": RunnablePassthrough()}
11.      | prompt
12.      | ChatOpenAI()
13.      | StrOutputParser()
14.  )

16.  chain.invoke("canada employees guidelines")

Compare with RAG and without RAG

ini 复制代码
1.  q = input("Ask Question: ")

3.  ## Question to OpenAI

5.  chat = ChatOpenAI()

7.  messages = [
8.      HumanMessage(
9.          content=q
10.      )
11.  ]

13.  gpt_res = chat(messages)

15.  # Question with RAG

17.  gpt_rag_res = chain.invoke(q)

20.  # Responses

22.  s = f"""
23.  ChatGPT Response:

25.  {gpt_res}

27.  ChatGPT with RAG Response:

29.  {gpt_rag_res}
30.  """

32.  print(s)

上面的 jupyter notebook 的代码可以在地址 github.com/liu-xiao-gu... 下载。

相关推荐
2301_797604245 小时前
d47:Elasticsearch入门
elasticsearch
勇往直前plus5 小时前
ElasticSearch详解(篇一)
大数据·elasticsearch·jenkins
大哥,带带弟弟5 小时前
ES错误记录
elasticsearch·kubernetes
眠りたいです15 小时前
基于脚手架微服务的视频点播系统-脚手架开发部分(完结)elasticsearch与libcurl的简单使用与二次封装及bug修复
c++·elasticsearch·微服务·云原生·架构·bug
失散1316 小时前
分布式专题——57 如何保证MySQL数据库到ES的数据一致性
java·数据库·分布式·mysql·elasticsearch·架构
liliangcsdn2 天前
如何基于DSL脚本进行elasticsearch向量检索示例
大数据·elasticsearch·搜索引擎
hadage2332 天前
--- git 笔记 ---
笔记·git·elasticsearch
厨 神2 天前
11月10日ES本机
大数据·elasticsearch·搜索引擎
小二·2 天前
Elasticsearch 面试题精编(26题|含答案|分类整理)
java·大数据·elasticsearch
❀͜͡傀儡师2 天前
docker搭建Elasticsearch+Kafka+Logstash+Filebeat日志分析系统
elasticsearch·docker·kafka