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... 下载。

相关推荐
Elastic 中国社区官方博客1 小时前
Elasticsearch:检索增强生成背后的重要思想
大数据·人工智能·elasticsearch·搜索引擎·全文检索
中间件XL1 小时前
搜索引擎onesearch3实现解释和升级到Elasticsearch v8系列(四)-搜索
elasticsearch·搜索引擎·全文检索·elasticsearch8
Fan3 小时前
Elasticsearch 下载安装及使用总结
大数据·elasticsearch·jenkins
Connie14515 小时前
filebeat采集挂载出来的/home/Logs下的日志过程
elasticsearch
周全全7 小时前
Elasticsearch 检索优化:停用词的应用
大数据·elasticsearch·jenkins
码爸8 小时前
flink自定义process,使用状态求历史总和(scala)
大数据·elasticsearch·flink·kafka·scala
小宋10219 小时前
高性能分布式搜索引擎Elasticsearch详解
大数据·elasticsearch·搜索引擎
不是笨小孩i18 小时前
Git常用指令
大数据·git·elasticsearch
+码农快讯+21 小时前
Git入门学习(1)
git·学习·elasticsearch
码爸1 天前
java 执行es中的sql
java·sql·elasticsearch