环境搭建
下载:https://ollama.com/download
双击安装,一直下一步即可。
启动:
ollama run llama2
在这一步的时候,如果本地没有这个模型,可能会联网下载模型。模型一般都比较大,要根据自己的电脑实际配置去选择模型。
安装依赖
创建虚拟环境
创建虚拟环境:
conda create --name zdppy_langchainx python==3.11.7
激活虚拟环境:
conda activate zdppy_langchainx
安装Langchain
使用conda安装:
conda install langchain -c conda-forge
实现检索链
To properly answer the original question (“how can langsmith help with testing?”), we need to provide additional context to the LLM. We can do this via retrieval. Retrieval is useful when you have too much data to pass to the LLM directly. You can then use a retriever to fetch only the most relevant pieces and pass those in.
为了正确回答最初的问题(“langsmith如何帮助测试?”),我们需要为LLM提供额外的背景。我们可以通过检索来实现。当您有太多的数据需要直接传递给LLM时,检索非常有用。然后,您可以使用检索器只获取最相关的部分并将它们传递进去。
In this process, we will look up relevant documents from a Retriever and then pass them into the prompt. A Retriever can be backed by anything - a SQL table, the internet, etc - but in this instance we will populate a vector store and use that as a retriever. For more information on vectorstores, see this documentation.
在这个过程中,我们将从猎犬中查找相关文档,然后将它们传递给提示符。检索器可以由任何东西支持——SQL表、互联网等——但在本例中,我们将填充一个向量存储并将其用作检索器。有关vectorstores的更多信息,请参阅本文档。
First, we need to load the data that we want to index. To do this, we will use the WebBaseLoader. This requires installing BeautifulSoup:
首先,我们需要加载要建立索引的数据。为此,我们将使用WebBaseLoader。这需要安装BeautifulSoup:
pip install beautifulsoup4
After that, we can import and use WebBaseLoader.
之后,我们可以导入和使用WebBaseLoader。
from langchain_community.document_loaders import WebBaseLoader
loader = WebBaseLoader("https://docs.smith.langchain.com/user_guide")
docs = loader.load()
WebBaseLoader API接口文档:https://api.python.langchain.com/en/latest/document_loaders/langchain_community.document_loaders.web_base.WebBaseLoader.html
Next, we need to index it into a vectorstore. This requires a few components, namely an embedding model and a vectorstore.
接下来,我们需要将其索引到vectorstore中。这需要一些组件,即嵌入模型和vectorstore。
For embedding models, we once again provide examples for accessing via API or by running local models.
对于嵌入模型,我们再次提供了通过API或运行本地模型进行访问的示例。
Make sure you have Ollama running (same set up as with the LLM).
确保Ollama正在运行(与LLM的设置相同)。
from langchain_community.embeddings import OllamaEmbeddings
embeddings = OllamaEmbeddings()
OllamaEmbeddings API接口文档:https://api.python.langchain.com/en/latest/embeddings/langchain_community.embeddings.ollama.OllamaEmbeddings.html
Now, we can use this embedding model to ingest documents into a vectorstore. We will use a simple local vectorstore, FAISS, for simplicity’s sake.
现在,我们可以使用这个嵌入模型将文档摄取到vectorstore中。为了简单起见,我们将使用一个简单的本地向量库FAISS。
First we need to install the required packages for that:
首先,我们需要安装所需的软件包:
pip install faiss-cpu
Then we can build our index:
然后我们可以建立索引:
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter()
documents = text_splitter.split_documents(docs)
vector = FAISS.from_documents(documents, embeddings)
FAISS 接口文档:https://api.python.langchain.com/en/latest/vectorstores/langchain_community.vectorstores.faiss.FAISS.html
RecursiveCharacterTextSplitter 接口文档:https://api.python.langchain.com/en/latest/character/langchain_text_splitters.character.RecursiveCharacterTextSplitter.html
Now that we have this data indexed in a vectorstore, we will create a retrieval chain. This chain will take an incoming question, look up relevant documents, then pass those documents along with the original question into an LLM and ask it to answer the original question.
现在我们已经在vectorstore中为这些数据建立了索引,我们将创建一个检索链。该链将接收传入的问题,查找相关文档,然后将这些文档与原始问题一起传递给LLM,并要求它回答原始问题。
First, let’s set up the chain that takes a question and the retrieved documents and generates an answer.
首先,让我们设置接受问题和检索文档并生成答案的链。
from langchain.chains.combine_documents import create_stuff_documents_chain
prompt = ChatPromptTemplate.from_template("""Answer the following question based only on the provided context:
<context>
{context}
</context>
Question: {input}""")
document_chain = create_stuff_documents_chain(llm, prompt)
If we wanted to, we could run this ourselves by passing in documents directly:
如果我们愿意,我们可以通过直接传入文档来运行它:
from langchain_core.documents import Document
document_chain.invoke({
"input": "how can langsmith help with testing?",
"context": [Document(page_content="langsmith can let you visualize test results")]
})
此时的完整代码如下:
from langchain_core.prompts import ChatPromptTemplate
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.output_parsers import StrOutputParser
from langchain_community.llms import Ollama
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.documents import Document
"""
Github: https://github.com/zhangdapeng520/zdppy_langchainx
file: study/official_doc/c04_retraivel_chain.py
"""
# 创建模型对象
llm = Ollama(model="llama2")
# 构建提示词
prompt = ChatPromptTemplate.from_template("""Answer the following question based only on the provided context:
<context>
{context}
</context>
Question: {input}""")
# 将结果解析为字符串
output_parser = StrOutputParser()
# 构建web加载器对象
loader = WebBaseLoader("https://docs.smith.langchain.com/user_guide")
docs = loader.load()
# 创建嵌入对象
embeddings = OllamaEmbeddings()
# 建立索引
text_splitter = RecursiveCharacterTextSplitter()
documents = text_splitter.split_documents(docs)
vector = FAISS.from_documents(documents, embeddings)
# 构建链条
document_chain = create_stuff_documents_chain(llm, prompt)
# 接着,使用链条和大模型聊天
response = document_chain.invoke({
"input": "how can langsmith help with testing?",
"context": [Document(page_content="langsmith can let you visualize test results")]
})
print(response)
However, we want the documents to first come from the retriever we just set up. That way, we can use the retriever to dynamically select the most relevant documents and pass those in for a given question.
但是,我们希望文档首先来自我们刚刚设置的检索器。这样,我们就可以使用检索器动态地选择最相关的文档,并为给定的问题传递这些文档。
from langchain.chains import create_retrieval_chain
retriever = vector.as_retriever()
retrieval_chain = create_retrieval_chain(retriever, document_chain)
We can now invoke this chain. This returns a dictionary - the response from the LLM is in the answer
key
现在我们可以调用这个链。这将返回一个字典——LLM的响应在’ answer '键中
response = retrieval_chain.invoke({"input": "how can langsmith help with testing?"})
print(response["answer"])
# LangSmith offers several features that can help with testing:...
This answer should be much more accurate!
这个答案应该准确得多!
此时的完整代码如下:
from langchain_core.prompts import ChatPromptTemplate
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains import create_retrieval_chain
from langchain_core.output_parsers import StrOutputParser
from langchain_community.llms import Ollama
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter
"""
Github: https://github.com/zhangdapeng520/zdppy_langchainx
file: study/official_doc/c04_retraivel_chain.py
"""
# 创建模型对象
llm = Ollama(model="llama2")
# 构建提示词
prompt = ChatPromptTemplate.from_template("""Answer the following question based only on the provided context:
<context>
{context}
</context>
Question: {input}""")
# 将结果解析为字符串
output_parser = StrOutputParser()
# 构建web加载器对象
loader = WebBaseLoader("https://docs.smith.langchain.com/user_guide")
docs = loader.load()
# 创建嵌入对象
embeddings = OllamaEmbeddings()
# 建立索引
text_splitter = RecursiveCharacterTextSplitter()
documents = text_splitter.split_documents(docs)
vector = FAISS.from_documents(documents, embeddings)
# 构建链条
document_chain = create_stuff_documents_chain(llm, prompt)
# 设置检索器
retriever = vector.as_retriever()
retrieval_chain = create_retrieval_chain(retriever, document_chain)
# 调用
response = retrieval_chain.invoke({"input": "how can langsmith help with testing?"})
print(response["answer"])