在人工智能领域,大型语言模型(LLM)正以前所未有的速度发展,它们不仅改变了我们与机器交互的方式,也在深刻地影响着内容创作、信息检索等多个领域。本文将深入探讨如何利用Langchain和Google Gemini Pro构建一个高效的文档检索系统,并结合实际案例,详细阐述每个步骤的技术细节与应用场景。
一、环境初始化与模型加载
首先,我们需要初始化开发环境,并加载所需的模型。以下是具体的步骤:
- 设置API密钥:为了能够使用Google Gemini Pro,你需要拥有一个有效的Google API密钥。请将你的密钥配置到环境变量中,代码如下:
import os
os.environ["GOOGLE_API_KEY"] = 'YOUR_API_KEY' # 替换成你的API密钥
- 导入必要的库:接下来,导入所有需要的Python库。这些库包括用于展示Markdown文本的
IPython.display
,以及来自langchain_google_genai
和langchain
的各种模块,用于处理LLM、嵌入、向量数据库和提示模板。
from IPython.display import display, Markdown
import google.generativeai as genai
from langchain_google_genai import ChatGoogleGenerativeAI, GoogleGenerativeAIEmbeddings
from langchain.vectorstores import DocArrayInMemorySearch
from langchain.prompts import ChatPromptTemplate
from langchain.schema.output_parser import StrOutputParser
- 加载Gemini Pro模型:使用
ChatGoogleGenerativeAI
类加载Gemini Pro模型。temperature
参数用于控制模型输出的随机性。较高的温度会产生更多样化的输出,而较低的温度则会产生更保守的输出。
model = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0.7)
二、构建向量数据库
向量数据库是构建文档检索系统的核心。它允许我们存储和检索文本的嵌入向量,从而实现语义搜索。
- 创建嵌入模型:使用
GoogleGenerativeAIEmbeddings
类创建一个嵌入模型。这个模型负责将文本转换为向量。
embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
- 初始化向量数据库:使用
DocArrayInMemorySearch
类创建一个内存向量数据库。我们将向其中添加一些示例文本。
vectorstore = DocArrayInMemorySearch.from_texts(
["Gemini Pro 是 外星人 开发的大型语言模型。",
"Gemini 可以是一个星座,也可以是一系列语言模型的名称。",
"人是由龙进化而来的。",
"天才儿童喜欢吃牛肉",
"儿童喜欢吃零食"],
embedding=embeddings # passing in the embedder model
)
这些文本将被嵌入并存储在向量数据库中。这样,我们就可以根据语义相似度检索这些文本。
- 创建检索器:使用
as_retriever
方法创建一个检索器。search_kwargs
参数用于指定检索的参数,例如返回的文档数量。
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
三、构建Langchain Chain
Langchain Chain是将多个组件(如提示模板、LLM和输出解析器)组合在一起,以创建一个完整的pipeline。这使得构建复杂的应用程序变得更加容易。
- 创建提示模板:使用
ChatPromptTemplate
类创建一个提示模板。提示模板定义了如何将用户的问题和检索到的上下文组合成一个提示,传递给LLM。
from langchain.schema.runnable import RunnableMap
template = """Answer the question a a full sentence, based only on the following context:
{context}
Question: {question}
"""
output_parser = StrOutputParser()
prompt = ChatPromptTemplate.from_template(template)
- 创建RunnableMap:
RunnableMap
允许我们并行地执行多个操作,并将它们的结果合并到一个字典中。在这个例子中,我们将使用RunnableMap
来检索相关的文档,并将用户的问题传递给提示模板。
chain = RunnableMap({
"context": lambda x: retriever.get_relevant_documents(x["question"]),
"question": lambda x: x["question"]
}) | prompt | model | output_parser
- 组合组件:我们使用
|
运算符将RunnableMap
、提示模板、LLM和输出解析器组合在一起。这个pipeline将首先检索相关的文档,然后将它们与用户的问题一起传递给LLM。LLM将生成一个答案,然后输出解析器将把答案转换为字符串。
四、实际案例:使用README.md文档
为了演示如何使用Langchain和Gemini Pro构建一个实际的文档检索系统,我们将使用llama.cpp的README.md文档作为我们的知识库。
- 加载文档:使用
UnstructuredMarkdownLoader
类加载README.md文档。
from langchain.document_loaders import UnstructuredMarkdownLoader
loader = UnstructuredMarkdownLoader("./README.md")
text = loader.load()
- 分割文档:由于LLM有输入长度的限制,我们需要将文档分割成更小的块。使用
RecursiveCharacterTextSplitter
类可以将文档分割成多个块,并保持语义的完整性。
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size = 2000,
chunk_overlap = 400,
length_function = len,
is_separator_regex = False
)
all_splits = text_splitter.split_documents(text)
- 创建FAISS向量数据库:使用
FAISS
类创建一个FAISS向量数据库。FAISS是一个高效的向量相似度搜索库,特别适合于大规模的文档检索。
from langchain.vectorstores import FAISS
vectorstore = FAISS.from_documents(all_splits, embeddings)
- 创建Chain:
from langchain.schema.runnable import RunnableMap
from langchain_core.runnables import RunnablePassthrough
template = """Answer the question a a full sentence, based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
query = {"question": "What is --interactive option used for?"}
chain = RunnableMap({
"context": lambda x: retriever.get_relevant_documents(x["question"]),
"question": RunnablePassthrough()
}) | prompt | model | output_parser
chain.invoke(query)
五、结论与展望
本文详细介绍了如何使用Langchain和Google Gemini Pro构建一个文档检索系统。通过向量数据库、提示模板和LLM的组合,我们可以创建一个高效的系统,能够根据用户的问题检索相关的文档,并生成高质量的答案。随着LLM技术的不断发展,我们可以期待更加智能和高效的文档检索系统,它们将会在知识管理、客户服务和教育等领域发挥重要的作用。
未来,我们可以进一步探索以下方向:
- 多模态检索:将文本、图像和音频等多种模态的信息融合到向量数据库中,实现更加全面的检索。
- 个性化检索:根据用户的兴趣和历史行为,定制检索结果,提供更加个性化的服务。
- 主动学习:通过用户的反馈,不断优化检索系统,提高检索的准确性和效率。