写点什么

手把手系列!无需 OpenAI 即可搭建 RAG 应用

作者:Zilliz
  • 2024-01-25
    北京
  • 本文字数:3341 字

    阅读完需:约 11 分钟

OpenAI 是时下最火爆的大语言模型(LLM),不过除了 OpenAI 以外,还有许多不同的 LLM。此前,我们发布的许多篇文章中都介绍了如何使用 LangChain、Milvus 和 OpenAI 搭建众多 RAG 应用,这次我们来试试不一样的 LLM。


接下来我将用 Nebula 替代 OpenAI,Hugging Face 上的 Embedding 向量模型代替 OpenAI 模型。

01.对话式 RAG 应用技术栈

对话式 RAG 是最常见的 RAG 应用,也就是我们常说的 RAG 聊天机器人。在之前的文章中,我们介绍了 RAG 应用典型的技术栈——CVP(注:CVP 全称为 ChatGPT + Vector Database + Prompt as code,即 ”以 ChatGPT 为代表的 LLM + 向量数据库 + Prompt”)。本文搭建的 RAG 应用将在此技术栈基础上进行微调,将 ChatGPT 的 LLM 替换为 Hugging Face 上的 Embedding 模型,将 LangChain 用于管理 Prompt,并使用 Milvus 作为向量数据库。此外,我们会用 SymbI AI 提供的 LLM。

LangChain

LangChain 框架,提供了一套工具、组件和接口,是开发大语言模型应用的利器,帮助我们简化 LLM 应用开发的过程。我们之前讲过如何用 LangChain 和 OpenAI 搭建带有记忆缓存的问答机器人,本文将依然使用 LangChain 开发 RAG 应用。

Symbl AI

Symbl AI 提供基于对话数据训练的对话式 LLM——Nebula。Nebula 可与 LangChain 集成。本文中,我们就将使用 Nebula 模型,用于替代此前教程中使用过的 OpenAI GPT-3.5。

Milvus

本文所搭建的应用中最核心的部分便是向量数据库。向量数据库用于处理由非结构化数据转化而来的 Embedding 向量,接下来我们将用 Milvus 存储对话。

Hugging Face

Hugging Face 是一个庞大的模型库,可与 LangChain 集成。本文将用到 Hugging Face 中的 Embedding 模型,用于替代此前教程中使用的 OpenAI 模型。

02.如何快速搭建一个对话式 RAG 应用

本次搭建过程主要包含以下三个环节:


  • 设置技术栈

  • 创建对话

  • 向应用提问

设置技术栈

我们需要安装 LangChain、Milvus (Lite)、PyMilvus、python-dotenv、Sentence Transformers。在代码前半部分中,通过 LangChain 导入 Vector Store Retriever Memory、 Conversation Chain 和 Prompt Template 对象,用这些导入创建对话,并存入 RAG 应用的“记忆”中。


此外,还需要导入 osload_dotenv,用于加载环境变量。与此前的教程不同,本次不再导入 OpenAI 的 API 密钥,而是 Nebula 的 API 密钥。


! pip install langchain milvus pymilvus python-dotenv sentence_transformers
from langchain.memory import VectorStoreRetrieverMemoryfrom langchain.chains import ConversationChainfrom langchain.prompts import PromptTemplateimport osfrom dotenv import load_dotenvload_dotenv()api_key = os.getenv("NEBULA_KEY")
复制代码


从 Milvus Lite 中导入 default_server 并启动 Milvus 向量数据库。接着继续从 LangChain 导入 Hugging Face Embedding 模型,默认导入的模型为 all-mpnet-base-v2,该模型生成 768 维向量。


from milvus import default_serverdefault_server.start()
from langchain_community.embeddings import HuggingFaceEmbeddingsis this model by default: sentence-transformers/all-mpnet-base-v2embeddings = HuggingFaceEmbeddings()
复制代码


以下主要用于“清理”此前创建的 LangChain Collection,如果之前没有同时使用过 LangChain 和 Milvus,请忽略以下代码。


from pymilvus import utility, connectionsconnections.connect(host="127.0.0.1", port=default_server.listen_port)utility.drop_collection('LangChainCollection')
复制代码

创建对话

现在,让我们创建并存储对话。


首先从 LangChain 导入一个 Milvus 向量数据库用于存储向量数据,传入创建的 Hugging Face Embedding 函数以及 Milvus Lite 实例的 server 和 endpoint 用于连接至 Milvus。最后,传入 consistency_level 参数,从而设置数据一致性等级,参数值为 Strong,即最高级别的数据一致性。


from langchain.vectorstores import Milvusvectordb = Milvus.from_documents(   {},   embeddings,   connection_args={"host": "127.0.0.1", "port": default_server.listen_port},   consistency_level="Strong")
复制代码


用 LangChain 设置 Vector store retriever,传入 Milvus Collection 和搜索参数。本教程中,我们只希望获取 Top-K(K=1) 个结果。


接下来需要准备一些对话内容,本例中,我将在对话中给出一些我的个人信息。大家在搭建的过程中可以随意输入自己想要输入的对话内容。随机输入一些对话内容后,我们就需要将这些对话存入应用的“记忆”中,用作后续对话的上下文。


在保存对话上下文时,我们向记忆对象传入两个 dictionary。本例中分别为 inputoutput,大家可以灵活探索 save_context 函数。


retriever = Milvus.as_retriever(vectordb, search_kwargs=dict(k=1))memory = VectorStoreRetrieverMemory(retriever=retriever)about_me = [   {"input": "My favorite snack is chocolate","output": "Nice"},   {"input": "My favorite sport is swimming","output": "Cool"},   {"input": "My favorite beer is Guinness","output": "Great"},   {"input": "My favorite dessert is cheesecake","output": "Good to know"},   {"input": "My favorite musician is Taylor Swift","output": "I also love Taylor Swift"}]for example in about_me:   memory.save_context({"input": example["input"]}, {"output": example["output"]})
复制代码

输入问题

一切准备就绪,就可以开始向 RAG 应用提问了。本文的 RAG 应用借助 Milvus 向量数据库而有了记忆——能够记住我们迄今为止的所有对话内容。开始提问前,先检查一下,确保 RAG 应用已经记住了我们的对话内容。


我问 RAG 应用是否还记得我最喜欢的歌手是谁(答案:Taylor Swift)。收到提问后,RAG 应用的记忆缓存部分就开始工作了。我们的提问(即 Prompt)会通过 Embedding 模型被转化为向量,随后应用会搜索对话记录。


print(memory.load_memory_variables({"prompt": "who is my favorite musician?"})["history"])
复制代码


响应如下所示:



接着,我们来创建 Prompt 模板。此时需要用到 LLM,只需导入 Nebula 并传入其 API 密钥即可,Prompt 可以看作是多条字符串,用括号注释来传入变量。


我们向 LangChain prompt 模版中传入 Prompt 字符串和变量名称。准备好 Prompt 模版、LLM 和应用“记忆”后,就可以使用对话链(Conversation Chain)进行对话。


from langchain_community.llms.symblai_nebula import Nebulallm = Nebula(nebula_api_key=api_key)_DEFAULT_TEMPLATE = """The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.Relevant pieces of previous conversation:{history}(You do not need to use these pieces of information if not relevant)Current conversation:Human: {input}AI:"""PROMPT = PromptTemplate(   input_variables=["history", "input"], template=_DEFAULT_TEMPLATE)conversation_with_summary = ConversationChain(   llm=llm,   prompt=PROMPT,   memory=memory,verbose=True)
复制代码


先输入第一个问题:


conversation_with_summary.predict(input="Hi Nebula, what's up?")
复制代码


响应如下所示:



基于 Nebula 的训练数据以及刚才提供的对话示例数据,可以从响应中看出,LLM 判断我们“人类”会继续进行对话。


现在,我们试试向应用提问“Who did I say was my favorite musician?”,看看它能否回答出我最喜欢的歌手。(敲黑板!此前我们已经在对话中提及我最喜欢的歌手是 Taylor Swift,这个信息应该已经存储在应用的“记忆”里了。)


conversation_with_summary.predict(input="Who did I say was my favorite musician?")
复制代码


问答式 RAG 应用的响应如下所示:


03.总结

至此,我们已经尝试了用 Symbl AI 的 Nebula 大语言模型替代常用的 OpenAI 模型,并搭建了一个对话式 RAG 应用。在后续的文章中,我们将继续用其他 LLM 搭建更多 RAG 应用,敬请期待!

用户头像

Zilliz

关注

Data Infrastructure for AI Made Easy 2021-10-09 加入

还未添加个人简介

评论

发布
暂无评论
手把手系列!无需 OpenAI 即可搭建 RAG 应用_Milvus_Zilliz_InfoQ写作社区