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


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


接下来将用 Nebula(https://symbl.ai/platform/nebula/llm/)替代 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(https://zilliz.com.cn/what-is-milvus)存储对话。


  • Hugging Face


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


02.

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


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


  • 设置技术栈

  • 创建对话

  • 向应用提问


  • 设置技术栈


我们需要安装 LangChain、Milvus (Lite)(https://milvus.io/docs/milvus_lite.md)、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 VectorStoreRetrieverMemory
from langchain.chains import ConversationChain
from langchain.prompts import PromptTemplate
import osfrom dotenv import load_dotenv
load_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_server
default_server.start()

from langchain_community.embeddings import HuggingFaceEmbeddings
is this model by default: sentence-transformers/all-mpnet-base-v2
embeddings = HuggingFaceEmbeddings()

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


from pymilvus import utility, connections
connections.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 Milvus
vectordb = 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 Nebula
llm = 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(Zilliztech)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

“Linux 中国” 开源社区宣布停止运营 JetBrain 捆绑 AI 助手引起用户不满 Tauri v2 支持 Android 和 iOS,跨平台开发新选择 VS Code 1.86 会导致远程开发功能无法使用 FastGateway:一个可以用于代替 Nginx 的网关 Visual Studio Code 1.86 发布 PostgreSQL 90% 的新代码仅由 50 人完成,拓数派荣占一席 联想 2024 年将发布全新 AI OS 操作系统 Redox OS 计划移植更多 Linux 软件 微软为 Windows 11 引入原生 Sudo 命令支持
{{o.name}}
{{m.name}}

猜你喜欢

转载自my.oschina.net/u/4209276/blog/10946656