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

相关推荐
-今昭-1 小时前
AnsibleVault加密配置及zabbix部署
大数据·elasticsearch·搜索引擎
Elastic 中国社区官方博客4 小时前
跳过有状态的 OTel Collector:Elasticsearch 9.5 原生存储两种指标时间类型
大数据·人工智能·elasticsearch·搜索引擎·重构·全文检索
PC2005-cloud1 天前
Elasticsearch 学习笔记:集群实战(3 控制节点 + 3 数据节点部署与故障转移)
笔记·学习·elasticsearch
Devin~Y1 天前
从内容社区到AI智能客服:Spring Boot + Spring Cloud + Spring AI 全栈实战面试拆解
java·spring boot·redis·elasticsearch·spring cloud·kafka·mybatis
凤山老林1 天前
复杂检索引擎落地:Spring Boot + Elasticsearch 数据同步与高阶查询实战
spring boot·后端·elasticsearch
Elastic 中国社区官方博客2 天前
你的 AI agent 不需要你的 API 密钥:使用 OAuth 2.1 对 Elasticsearch MCP 服务器进行身份验证
大数据·运维·人工智能·elasticsearch·搜索引擎·全文检索
互联网中的一颗神经元2 天前
ZZ — Git 速查表
大数据·git·elasticsearch
Elasticsearch2 天前
跳过有状态的 OTel Collector:Elasticsearch 9.5 原生存储两种指标时间类型
elasticsearch
C++、Java和Python的菜鸟3 天前
第2章 项目前置课-代码版本控制Git
大数据·elasticsearch·搜索引擎
Elasticsearch3 天前
什么是混合搜索?
elasticsearch