Building Local RAG Chatbots Without Coding Using LangFlow and Ollama
在这个项目中,我们将构建一个 AI 聊天机器人,让我们称它为"Dinnerly – Your Healthy Dish Planner"。它旨在通过检索增强生成(RAG)技术,从食谱 PDF 文件中推荐健康菜肴食谱。在深入探讨我们将如何实现它之前,让我们快速回顾一下我们将在项目中使用的主要成分。
记得那些构建智能聊天机器人需要数月编码的日子吗?
像 LangChain 这样的框架无疑简化了开发过程,但对于不是程序员的人来说,数百行代码仍然是一个障碍。
有没有更简单的方法?(如果你还不是 Medium 会员,请在这里找到朋友链接阅读完整故事,并请考虑订阅 Medium 会员以支持作者)。
图片由Ravi Palwe在Unsplash提供
那是我发现了"Lang Flow",这是一个基于 LangChain Python 版本的开放源代码包。它允许你创建一个 AI 应用程序,而无需编写任何代码。它提供了一个画布,你可以在这里拖动组件并将它们链接起来以构建你的聊天机器人。
在这篇文章中,我们将使用LangFlow在几分钟内构建一个智能 AI 聊天机器人原型。对于后端,我们将使用Ollama进行嵌入模型和大型语言模型,这意味着应用程序可以在本地免费运行!最后,我们将把这个流程转换成一个Streamlit应用程序,而无需编写大量代码。
Retrieval-Augmented Generation Pipeline、LangChain、LangFlow 和 Ollama 简介
在这个项目中,我们将构建一个 AI 聊天机器人,让我们称它为"Dinnerly – Your Healthy Dish Planner"。它旨在通过检索增强生成(RAG)技术,从食谱 PDF 文件中推荐健康菜肴食谱。
在深入探讨我们将如何实现它之前,让我们快速回顾一下我们将在项目中使用的主要成分。
Retrieval-Augmented Generation (RAG)
RAG(检索增强生成)通过向大型语言模型(LLMs)提供来自外部来源的相关信息来帮助 LLMs。这使得 LLMs 在生成响应时考虑这个上下文,使它们更加准确和及时。
RAG 管道通常包括以下步骤,如A Guide to Retrieval Augmented Generation中所述:
"
-
**加载文档:首先加载文档或数据源。
-
**分割成块:将文档分割成可管理的部分。
-
**创建嵌入:使用嵌入将这些块转换为向量表示。
-
***存储在向量数据库中:将这些向量存储在数据库中以实现高效的检索。
-
***用户交互:接收用户的查询或输入并将其转换为嵌入。
-
***在 VectorDB 中进行语义搜索:根据用户的查询连接到向量数据库以执行语义搜索。
-
***检索和处理响应:检索相关响应,通过 LLM 传递,并生成答案。
-
***向用户交付答案:将 LLM 生成的最终输出呈现给用户。
"
由 Han HELOIR, Ph.D. ☕️ 提供的 RAG 工作流程概述
Langchain
一个围绕大型语言模型(LLM)构建的开源框架,LangChain 促进了各种通用人工智能(GenAI)应用的设计和开发,包括聊天机器人、摘要等。
该库的核心思想是将不同的组件“连接”起来,以简化复杂的 AI 任务,并在 LLM 周围创建更高级的使用案例。
![Langchain 框架。来源
Langchain 框架。来源
LangFlow
LangFlow 是一个专门为 LangChain 设计的 Web 工具。它提供了一个用户界面,用户可以简单地拖放组件来构建和测试 LangChain 应用程序,而无需任何编码。
然而,您首先需要了解 LangChain 的工作原理及其不同组件,以便使用 LangFlow 设计您的 AI 应用程序流程。
LangFlow 界面
Ollama
Ollama对我来说,是最佳且最简单的方式,也是开始使用开源 LLM 的最佳途径。它支持包括 Llama 2 和 Mistral 在内的一些最强大的 LLM,您可以在 ollama.ai/library 上找到可用模型的列表。
Ollama ollama.ai/
设置 Ollama
安装 Ollama
首先,前往 Ollama 下载页面,选择与您的操作系统匹配的版本,下载并安装它。
安装 Ollama 后,打开您的命令终端并输入以下命令。这些命令将在您的机器上下载模型并本地运行。
对于这个项目,我们将使用 Llama2 作为我们的大型语言模型(LLM)和 “nomic-embed-text” 作为嵌入模型。“Nomic-embed-text” 是一个功能强大的开源嵌入模型,具有很大的上下文窗口。这使得我们可以在本地运行整个应用程序,而无需任何云服务!
ollama serve
ollama pull llama2
ollama pull nomic-embed-text
ollama run llama2
设置 LangFlow
预先条件
在我们开始使用 LangFlow 之前,重要的是要检查您的计算机上已安装 Python。您的 Python 版本应高于 3.9 但低于 3.12。
安装 LangFlow
接下来,让我们继续安装 LangFlow。我建议在虚拟环境中进行此操作。这种方法有助于在其自己的空间内整洁地管理依赖项。在我的 Mac 上,我使用 Conda 来设置。只需在命令行终端中输入以下命令,以创建一个名为 “langflow” 的 Python 3.11 虚拟环境。
conda create -n langflow python=3.11
conda activate langflow
pip install langflow
如果你没有 Conda,你也可以直接使用 Python 设置虚拟环境,以下是一些命令。
python -m venv langflow
source langflow/bin/activate
pip install langflow
安装完成后,启动 LangFlow 就像在终端中输入 “langflow run” 那么简单。
Langflow 后端控制台。图片由作者提供。
然后,取回它提供的 URL(例如,上面的示例中是 127.0.0.1: 7860),将其粘贴到你的网页浏览器中,哇!你应该会看到一个类似这样的界面。此页面显示所有项目。
Langflow UI 项目页面。图片由作者提供。
设计你的聊天机器人流程
是时候制作你的第一个流程了!
首先点击 “新建项目”,这将为你打开一个空白画布。在左侧面板中,你会注意到各种组件,可以拖放到你的工作区中。
LangFlow 画布。图片由作者提供。
对于我们的项目,我们正在构建一个能够从 PDF 文件中回答问题的聊天机器人。还记得我们之前提到的 RAG 管道吗?我们需要某些元素来构建这个组合:
-
PDF 加载器:我们将使用 “PyPDFLoader”。你需要输入你的 PDF 文档的文件路径。
-
文本分割器:我们将选择 “RecursiveCharacterTextSplitter”,默认设置将足够好。
-
文本嵌入模型:选择 “OllamaEmbeddings” 以利用免费的、开源的嵌入。
-
向量数据库:我们将选择 “FAISS” 来存储嵌入并促进向量搜索。
-
用于生成响应的 LLM:选择 “ChatOllama” 并指定模型为 “llama2”。
-
对话记忆:这允许我们的聊天机器人保留聊天历史,有助于后续问题的提问。我们将使用 “ConversationBufferMemory”。
-
对话检索链:这连接了 LLM、记忆和检索到的文本等各个组件以生成响应。“ConversationRetrievalChain” 是我们的选择。
将所有这些组件拖放到画布上,并设置所需的字段,如 PDF 文件路径和 LLM 模型名称。其他设置保留默认值即可。
接下来,将这些组件连接起来形成你的流程。
一切连接好之后,点击右下角的 “闪电” 按钮,以编译流程。如果一切顺利,按钮应该变成绿色,表示成功。
在成功编译流程后,点击“聊天机器人”图标以测试您的创作。
Langflow 聊天机器人演示。图片由作者提供。
几个提示:
-
一旦您的流程完成,您可以将其保存为 JSON 文件,或在未来访问或编辑时在“我的收藏”中找到它。
-
使用预构建示例深入了解 LangFlow 可以提供极大的灵感,并帮助您开始。以下是方法:
-
"LangFlow 存储"包含示例,但您需要 API 密钥才能访问。
-
LangFlow GitHub 页面允许您下载示例,然后您可以使用“上传”按钮将其上传到 LangFlow UI。
-
-
如果在本地设置不适合您,您还可以选择 OpenAI 来构建您的 RAG 管道。只需确保您有用于设置的 OpenAI API 密钥。
将流程转换为 Streamlit 聊天机器人
现在,如果流程设置得当,是时候将其集成到您的应用程序中了。在构建您的流程后,LangFlow 通过提供必要的代码片段使这变得简单。只需点击侧边栏中的“代码”按钮即可。
让我们继续将此流程集成到 Streamlit 聊天机器人中。
- 设置依赖项:首先,我们必须安装依赖项。
pip install streamlit
pip install langflow
pip install langchain-community
- 获取 Lang Flow 代码片段:创建一个新的 Python 文件 “app.py”。返回 LangFlow UI 并再次找到那个“代码”按钮。导航到“Python API”选项卡,复制代码片段并将其粘贴到“app.py”中。
import requests
from typing import Optional
BASE_API_URL = "http://127.0.0.1:7860/api/v1/process"
FLOW_ID = "d9392262-a912-42b4-8582-cc9e48894a00"
# You can tweak the flow by adding a tweaks dictionary
# e.g {"OpenAI-XXXXX": {"model_name": "gpt-4"}}
TWEAKS = {
"VectorStoreAgent-brRPx": {},
"VectorStoreInfo-BS24v": {},
"OpenAIEmbeddings-lnfRZ": {},
"RecursiveCharacterTextSplitter-bErPe": {},
"WebBaseLoader-HLOqm": {},
"ChatOpenAI-aQOv0": {},
"FAISS-o0WIf": {}
}
def run_flow(inputs: dict, flow_id: str, tweaks: Optional[dict] = None) -> dict:
"""
Run a flow with a given message and optional tweaks.
:param message: The message to send to the flow
:param flow_id: The ID of the flow to run
:param tweaks: Optional tweaks to customize the flow
:return: The JSON response from the flow
"""
api_url = f"{BASE_API_URL}/{flow_id}"
payload = {"inputs": inputs}
headers = None
if tweaks:
payload["tweaks"] = tweaks
response = requests.post(api_url, json=payload, headers=headers)
return response.json()
3. 构建聊天功能:在同一个 Python 文件中,我们将定义一个专门用于聊天的函数。此函数运行流程以从用户的新查询中获取响应。然后,它在界面上流式传输此响应。
def chat(prompt: str):
with current_chat_message:
# Block input to prevent sending messages whilst AI is responding
st.session_state.disabled = True
# Add user message to chat history
st.session_state.messages.append(("human", prompt))
# Display user message in chat message container
with st.chat_message("human"):
st.markdown(prompt)
# Display assistant response in chat message container
with st.chat_message("ai"):
# Get complete chat history, including latest question as last message
history = "n".join(
[f"{role}: {msg}" for role, msg in st.session_state.messages]
)
query = f"{history}nAI:"
# Setup any tweaks you want to apply to the flow
inputs = {"input": query}
output = run_flow(inputs, flow_id=FLOW_ID, tweaks=TWEAKS)
print(output)
try:
output = output['result']['output']
except Exception :
output = f"Application error : {output}"
placeholder = st.empty()
response = ""
for tokens in output:
response += tokens
# write response with "▌" to indicate streaming.
with placeholder:
st.markdown(response + "▌")
# write response without "▌" to indicate completed message.
with placeholder:
st.markdown(response)
# Log AI response to chat history
st.session_state.messages.append(("ai", response))
# Unblock chat input
st.session_state.disabled = False
st.rerun()
4. 构建界面:现在我们将使用以下代码在同一 Python 文件中构建一个简单的 Streamlit 用户界面。
st.set_page_config(page_title="Dinnerly")
st.title("Welcome to Dinnerly : Your Healthy Dish Planner")
system_prompt = "You´re a helpful assistant to suggest and provide healthy dishes recipes to users"
if "messages" not in st.session_state:
st.session_state.messages = [("system", system_prompt)]
if "disabled" not in st.session_state:
# `disable` flag to prevent user from sending messages whilst the AI is responding
st.session_state.disabled = False
with st.chat_message("ai"):
st.markdown(
f"Hi! I'm your healthy dish planner. Happy to help you prepare healthy and yummy dishes!"
)
# Display chat messages from history on app rerun
for role, message in st.session_state.messages:
if role == "system":
continue
with st.chat_message(role):
st.markdown(message)
current_chat_message = st.container()
prompt = st.chat_input("Ask your question here...", disabled=st.session_state.disabled)
if prompt:
chat(prompt)
一旦运行 Streamlit 应用程序,您将能够与您自己的食谱规划师进行聊天!它将帮助您创建美味健康的餐点。
Streamlit 应用程序演示。图片由作者提供。
提示:
您可以使用相同的代码和界面为不同的流程。只需更改 FLOW_ID 以测试并集成新的流程到您的应用程序中。
收尾语
在这篇文章中,我们构建了一个基于 RAG 的智能聊天机器人。我们利用 LangFlow 建立了 RAG 管道,无需编写代码,利用开源模型进行嵌入和 LLM 处理,以使我们的应用程序在本地运行且无需推理成本,最后,我们将此设置转换为 Streamlit 应用程序。
我特别欣赏 LangFlow 的无代码方式,并且我相信它可能会在构建和原型化 AI 应用程序的方式上产生变革。
然而,值得注意的是,一些组件仍在开发中,有时它们可能不会按预期工作。在这些时刻出现时,缺乏对问题的可见性或故障排除的指导。另一个改进可能是直接提供底层 Python 代码,以提供更大的定制性。
总体来说,我发现 LangFlow 是一个快速原型设计的宝贵工具。
在你离开之前!🦸🏻♀️
如果你喜欢我的故事,并且想要支持我:
-
给 Medium 一些爱💕(点赞、评论和突出显示),你的支持对我来说意义重大。👏
-
在 Medium 上关注我 并订阅以获取我的最新文章🫶
参考文献
-
美味健康的晚餐(演示中使用的 pdf 文件):
healthyeating.nhlbi.nih.gov/pdfs/dinners_cookbook_508-compliant.pdf
更多推荐


所有评论(0)