创建你自己的 AI RAG 聊天机器人:Python 指南(使用 LangChain)
谁不想从文档中立即获得答案呢?RAG聊天机器人正是如此——将检索与人工智能生成相结合,提供快速、准确的回复!
在本指南中,我将向您展示如何使用LangChain和Streamlit ,通过检索增强生成 (RAG)技术创建一个聊天机器人。该聊天机器人将从知识库中提取相关信息,并使用语言模型生成回复。
我将带您完成每个步骤,提供多种响应生成选项,无论您使用OpenAI、Gemini还是Fireworks,都能确保灵活且经济高效的解决方案。
什么是检索增强生成(RAG)?
RAG(响应生成算法)是一种结合检索和生成的方法,旨在提供更准确、更具上下文感知能力的聊天机器人回复。检索过程从知识库中提取相关文档,而生成过程则使用语言模型,根据检索到的内容生成连贯的回复。这确保了即使语言模型本身没有针对特定信息进行训练,聊天机器人也能使用最新数据回答问题。
想象一下,你的私人助理并非总能回答你的问题。所以,当你提问时,他们会查阅书籍,找到相关信息(检索),然后总结这些信息,并用自己的语言复述给你(生成)。这基本上就是 RAG 的工作原理,它结合了两种方法的优势。
在流程图中,RAG流程大致如下所示:
现在,让我们开始吧,打造我们自己的聊天机器人!
搭建项目环境
本教程主要使用 Python,如果您是 JS 高手,可以参考langchain js 的文档并进行讲解。
首先,我们需要搭建项目环境。这包括创建项目目录、安装依赖项以及为不同的语言模型设置 API 密钥。
1. 创建项目文件夹和虚拟环境
首先创建项目文件夹和虚拟环境:
mkdir rag-chatbot
cd rag-chatbot
python -m venv venv
source venv/bin/activate
2. 安装依赖项
接下来,创建一个requirements.txt文件来列出所有必要的依赖项:
langchain==0.0.329
streamlit==1.27.2
faiss-cpu==1.7.4
python-dotenv==1.0.0
tiktoken==0.5.1
openai==0.27.10
gemini==0.3.1
fireworks==0.4.0
sentence_transformers==2.2.2
现在,安装以下依赖项:
pip install -r requirements.txt
3. 设置 API 密钥
我们将使用OpenAI、Gemini或Fireworks来生成聊天机器人的回复。您可以根据自己的喜好选择其中任何一个。
如果您正在尝试使用,请不要担心,Fireworks 会免费提供价值 1 美元的 API 密钥,而且
gemini-1.5-flash模型本身也有一定的免费性!
设置一个.env文件来存储您首选型号的 API 密钥:
# Uncomment your API key
# OPENAI_API_KEY=your_openai_api_key_here
# GEMINI_API_KEY=your_gemini_api_key_here
# FIREWORKS_API_KEY=your_fireworks_api_key_here
请务必注册这些服务并获取您的 API 密钥。Gemini和Fireworks都提供免费套餐,而OpenAI则按使用量收费。
文档处理和分块
为了给聊天机器人提供上下文信息,我们需要处理文档并将其拆分成易于管理的小块。这一点至关重要,因为大型文本需要被分解才能进行嵌入和索引。
1. 创建document_processor.py
创建一个名为document_processor.py“处理文档”的新Python脚本:
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
class DocumentProcessor:
def __init__(self, file_path):
self.file_path = file_path
def load_and_split(self):
loader = TextLoader(self.file_path)
documents = loader.load()
splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
texts = splitter.split_documents(documents)
return texts
if __name__ == "__main__":
processor = DocumentProcessor("data/sample_text.txt")
texts = processor.load_and_split()
print(f"Processed {len(texts)} text chunks")
该脚本加载一个文本文件,并将其分割成约 1000 个字符的小块,小块之间略有重叠,以确保块与块之间不会丢失上下文信息。处理完成后,文档即可进行嵌入和索引。
创建嵌入和索引
现在我们已经将文档分块,下一步是将它们转换为词嵌入(文本的数值表示)并建立索引以便快速检索。(因为机器更容易理解数字而不是文字)
1. 创建embedding_indexer.py
创建另一个名为embedding_indexer.py:的脚本
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
class EmbeddingIndexer:
def __init__(self):
self.embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
def create_vectorstore(self, texts):
vectorstore = FAISS.from_documents(texts, self.embeddings)
return vectorstore
if __name__ == "__main__":
from document_processor import DocumentProcessor
processor = DocumentProcessor("data/sample_text.txt")
texts = processor.load_and_split()
indexer = EmbeddingIndexer()
vectorstore = indexer.create_vectorstore(texts)
print("Vector store created successfully")
在本脚本中,我们使用Hugging Face模型( )创建词嵌入all-MiniLM-L6-v2。然后,我们将这些词嵌入存储在FAISS向量存储库中,这样我们就可以根据查询快速检索相似的文本块。
实现检索和响应生成
接下来是激动人心的部分:将检索与语言生成结合起来!现在,您将创建一个RAG 链,该链从向量存储库中获取相关数据块,并使用语言模型生成响应。(向量存储库是一个数据库,我们将其存储为转换为数字向量的数据。)
1. 创建rag_chain.py
让我们创建文件rag_chain.py:
from langchain.chains import RetrievalQA
from langchain.llms import OpenAI, Gemini, Fireworks
from dotenv import load_dotenv
import os
load_dotenv()
class RAGChain:
def __init__(self, vectorstore):
self.vectorstore = vectorstore
self.llm = self.get_llm()
def get_llm(self):
if os.getenv("OPENAI_API_KEY"):
return OpenAI(api_key=os.getenv("OPENAI_API_KEY"), temperature=0)
elif os.getenv("GEMINI_API_KEY"):
return Gemini(api_key=os.getenv("GEMINI_API_KEY"), temperature=0)
elif os.getenv("FIREWORKS_API_KEY"):
return Fireworks(api_key=os.getenv("FIREWORKS_API_KEY"), temperature=0)
else:
raise ValueError("No valid API key found! Please set one in .env file.")
def create_chain(self):
retriever = self.vectorstore.as_retriever(search_kwargs={"k": 3})
qa_chain = RetrievalQA.from_chain_type(
llm=self.llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True
)
return qa_chain
if __name__ == "__main__":
from document_processor import DocumentProcessor
from embedding_indexer import EmbeddingIndexer
processor = DocumentProcessor("data/sample_text.txt")
texts = processor.load_and_split()
indexer = EmbeddingIndexer()
vectorstore = indexer.create_vectorstore(texts)
rag_chain = RAGChain(vectorstore)
qa_chain = rag_chain.create_chain()
query = "What is the capital of France?"
result = qa_chain({"query": query})
print(f"Answer: {result['result']}")
在这里,您可以根据提供的 API 密钥,在OpenAI、Gemini或Fireworks中进行选择。RAG 链将检索出最相关的 3 个文档,并使用语言模型生成响应。
您可以根据预算或使用偏好在不同模型之间切换——Gemini和Fireworks是免费的,而OpenAI则根据使用量收费。
构建聊天机器人界面
现在,我们将构建一个简单的聊天机器人界面,以接收用户输入并使用我们的 RAG 链生成回复。
1. 创建chatbot.py
创建一个名为chatbot.py“
class Chatbot:
def __init__(self, qa_chain):
self.qa_chain = qa_chain
def get_response(self, user_input):
try:
response = self.qa_chain({"query": user_input})
return response['result']
except Exception as e:
return f"An error occurred: {str(e)}"
if __name__ == "__main__":
from rag_chain import RAGChain
from document_processor import DocumentProcessor
from embedding_indexer import EmbeddingIndexer
processor = DocumentProcessor("data/sample_text.txt")
texts = processor.load_and_split()
indexer = EmbeddingIndexer()
vectorstore = indexer.create_vectorstore(texts)
rag_chain = RAGChain(vectorstore)
qa_chain = rag_chain.create_chain()
chatbot = Chatbot(qa_chain)
while True:
user_input = input("You: ")
if user_input.lower() in ['exit', 'quit', 'bye']:
print("Chatbot: Goodbye!")
break
response = chatbot.get_response(user_input)
print(f"Chatbot: {response}")
该脚本创建了一个命令行聊天机器人界面,该界面会持续监听用户输入,通过 RAG 链处理输入,并返回生成的响应。
创建 Streamlit 用户界面
现在是时候使用Streamlit构建一个 Web 界面,让你的聊天机器人更加用户友好。这样用户就可以通过浏览器与你的聊天机器人进行交互。
1. 创建app.py
创造app.py:
import streamlit as st
from document_processor import DocumentProcessor
from embedding_indexer import EmbeddingIndexer
from rag_chain import RAGChain
from chatbot import Chatbot
@st.cache_resource
def initialize_chatbot(file_path):
processor = DocumentProcessor(file_path)
texts = processor.load_and_split()
indexer = EmbeddingIndexer()
vectorstore = indexer.create_vectorstore(texts)
rag_chain = RAGChain(vectorstore)
return Chatbot(rag_chain.create_chain())
st.title("RAG Chatbot")
uploaded_file = st.file_uploader("Upload a text file for the knowledge base", type="txt")
if uploaded_file:
with open("temp_knowledge_base.txt", "wb") as f:
f.write(uploaded_file.getbuffer())
chatbot = initialize_chatbot("temp_knowledge_base.txt")
if "messages" not in st.session_state:
st.session_state.messages = []
for message in st.session_state.messages:
st.chat_message(message["role"]).markdown(message["content"])
if prompt := st.chat_input("Ask a question"):
st.chat_message("user").markdown(prompt)
st.session_state.messages.append({"role": "user", "content": prompt})
response = chatbot.get_response(prompt)
st.chat_message("assistant").markdown(response)
st.session_state.messages.append({"role": "assistant", "content": response})
else:
st.write("Please upload a text file to start chatting!")
2. 运行 Streamlit 应用程序
要运行 Streamlit 应用,只需使用:
streamlit run app.py
这将启动一个网页界面,您可以在其中上传文本文件、提出问题并从聊天机器人处获得答案。
优化性能
为了获得更佳性能,您可以在分割文本时尝试不同的块大小和重叠度。较大的块可以提供更多上下文信息,而较小的块可能加快检索速度。您还可以使用Streamlit 缓存来避免重复执行诸如生成嵌入之类的耗时操作。
如果要优化成本,可以根据查询的复杂程度在OpenAI、Gemini或Fireworks之间切换——对于复杂的问题使用OpenAI ,对于较简单的问题使用Gemini或Fireworks,以降低成本。
总结
恭喜!您已成功创建了自己的基于红黄绿(RAG)算法的聊天机器人。现在,您可以尽情发挥想象,创造无限可能:
- 创建你专属的个性化学习伙伴。
- 无需再查阅冗长的文档——只需“RAG it out”即可快速获得准确的答案!
旅程由此开始,潜力无限!
你可以在GitHub上关注我的工作。欢迎随时联系我——我在X和LinkedIn上的私信一直都开放。
文章来源:https://dev.to/shreshthgoyal/create-your-own-ai-rag-chatbot-a-python-guide-with-langchain-dfi
