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


    这篇博客是之前文章:

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

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

    针对大文本的文档,我们可以采用如下的架构:

    创建应用并展示

    安装包

    #!pip3 install langchain

    导入包

    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
    14. load_dotenv()
    15. openai_api_key=os.getenv('OPENAI_API_KEY')
    16. elastic_user=os.getenv('ES_USER')
    17. elastic_password=os.getenv('ES_PASSWORD')
    18. elastic_endpoint=os.getenv("ES_ENDPOINT")
    19. elastic_index_name='langchain-rag'

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

    1. with open('workplace-docs.json') as f:
    2. workplace_docs = json.load(f)
    3. print(f"Successfully loaded {len(workplace_docs)} documents")

    1. metadata = []
    2. content = []
    3. for doc in workplace_docs:
    4. content.append(doc["content"])
    5. metadata.append({
    6. "name": doc["name"],
    7. "summary": doc["summary"],
    8. "rolePermissions":doc["rolePermissions"]
    9. })
    10. text_splitter = CharacterTextSplitter(chunk_size=50, chunk_overlap=0)
    11. docs = text_splitter.create_documents(content, metadatas=metadata)

    Index Documents using ELSER - SparseVectorRetrievalStrategy()

    1. from elasticsearch import Elasticsearch
    2. url = f"https://{elastic_user}:{elastic_password}@{elastic_endpoint}:9200"
    3. connection = Elasticsearch(url, ca_certs = "./http_ca.crt", verify_certs = True)
    4. es = ElasticsearchStore.from_documents(
    5. docs,
    6. es_url = url,
    7. es_connection = connection,
    8. es_user=elastic_user,
    9. es_password=elastic_password,
    10. index_name=elastic_index_name,
    11. strategy=ElasticsearchStore.SparseVectorRetrievalStrategy()
    12. )

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

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

    展示结果

    1. def showResults(output):
    2. print("Total results: ", len(output))
    3. for index in range(len(output)):
    4. print(output[index])

    1. r = es.similarity_search("work from home policy")
    2. showResults(r)

    RAG with Elasticsearch - Method 1 (Using Retriever)

    1. retriever = es.as_retriever(search_kwargs={"k": 4})
    2. template = """Answer the question based only on the following context:
    3. {context}
    4. Question: {question}
    5. """
    6. prompt = ChatPromptTemplate.from_template(template)
    7. chain = (
    8. {"context": retriever, "question": RunnablePassthrough()}
    9. | prompt
    10. | ChatOpenAI()
    11. | StrOutputParser()
    12. )
    13. chain.invoke("vacation policy")

    RAG with Elasticsearch - Method 2 (Without Retriever)

    Add Context

    1. def add_context(question: str):
    2. r = es.similarity_search(question)
    3. context = "\n".join(x.page_content for x in r)
    4. return context

    Chain

    1. template = """Answer the question based only on the following context:
    2. {context}
    3. Question: {question}
    4. """
    5. prompt = ChatPromptTemplate.from_template(template)
    6. chain = (
    7. {"context": RunnableLambda(add_context), "question": RunnablePassthrough()}
    8. | prompt
    9. | ChatOpenAI()
    10. | StrOutputParser()
    11. )
    12. chain.invoke("canada employees guidelines")

    Compare with RAG and without RAG

    1. q = input("Ask Question: ")
    2. ## Question to OpenAI
    3. chat = ChatOpenAI()
    4. messages = [
    5. HumanMessage(
    6. content=q
    7. )
    8. ]
    9. gpt_res = chat(messages)
    10. # Question with RAG
    11. gpt_rag_res = chain.invoke(q)
    12. # Responses
    13. s = f"""
    14. ChatGPT Response:
    15. {gpt_res}
    16. ChatGPT with RAG Response:
    17. {gpt_rag_res}
    18. """
    19. print(s)

    上面的 jupyter notebook 的代码可以在地址 https://github.com/liu-xiao-guo/semantic_search_es/blob/main/RAG-langchain-elasticsearch.ipynb 下载。

  • 相关阅读:
    【鸿蒙软件开发】ArkUI容器组件之Grid(网格布局)
    专访阿里云 RocketMQ 团队:现代微服务架构需要新的消息系统
    转以太网通过CHNet-S7200在纺机设备控制系统联网中的应用
    数据可视化之大数据可视化
    用selenium和xpath定位元素并获取属性值以及str字符型转json型
    postman 自动升级后恢复collection数据
    服务器正文23:定时器设计与实现(8/7)
    SOC-hello world
    大模型系统和应用——神经网络基础
    OPTEE Gprof(GNU profile)
  • 原文地址:https://blog.csdn.net/UbuntuTouch/article/details/134043106