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

相关推荐
liuhl09108 小时前
【无标题】
大数据·elasticsearch·搜索引擎
xbgRS9 小时前
Elasticsearch的查询
elasticsearch
Elasticsearch13 小时前
使用 Lucene 搜索你的 Bean —— Highlighting
elasticsearch
Elasticsearch13 小时前
使用 Lucene 搜索你的 Bean —— Elasticsearch
elasticsearch
Elasticsearch18 小时前
最好的 LLM 只有 59% 的时间能写出正确的 Elasticsearch ES|QL。以下是另外 41% 出错的原因
elasticsearch
垚垚学技术_聚焦云原生18 小时前
Ansible Role 生产环境标准目录结构与规范化实践
java·elasticsearch·ansible
小林ixn18 小时前
从 MySQL 的 LIKE 到 ES 倒排索引:一次把全文检索和混合检索讲透
sql·elasticsearch·全文检索·agent·关键词
MayBaymax19 小时前
ES 基础总结
大数据·elasticsearch·搜索引擎
Elastic 中国社区官方博客19 小时前
两个依赖和一个配置块:通过 Prometheus 远程写入将 Spring Boot 指标发送到 Elasticsearch
大数据·数据库·spring boot·elasticsearch·搜索引擎·全文检索·prometheus
SelectDB技术团队19 小时前
ELK 太占磁盘、ES 总报写入拒绝:从归因到可执行的优化清单
大数据·clickhouse·elk·elasticsearch·全文检索·复杂查询·实时更新