本教程将详细介绍如何使用Langchain、Tair作为知识库和OpenAI嵌入来实现一个问题回答系统。如果您不熟悉Tair,请先查看“Getting_started_with_Tair_and_OpenAI.ipynb”笔记。
本教程将全面介绍以下过程:
- 使用OpenAI API计算嵌入。
- 将嵌入存储在Tair实例中以构建知识库。
- 将原始文本查询转换为OpenAI API的嵌入。
- 使用Tair在创建的集合中执行最近邻搜索以查找一些上下文。
- 请求LLM在给定上下文中查找答案。
所有这些步骤将简化为调用一些对应的Langchain方法。
先决条件
为了完成本教程,我们需要准备以下几项内容:
- Tair云实例。
- Langchain作为框架。
- OpenAI API密钥。
安装要求
本教程需要以下Python包:openai、tiktoken、langchain和tair。
- openai 提供了方便的访问OpenAI API的方式。
- tiktoken 是用于OpenAI模型的快速BPE标记化工具。
- langchain 帮助我们更轻松地构建具有LLM的应用程序。
- tair库用于与tair向量数据库交互。
!pip install openai tiktoken langchain tair
准备您的OpenAI API密钥
OpenAI API密钥用于文档和查询的矢量化。
如果您没有OpenAI API密钥,可以从 https://platform.openai.com/account/api-keys 获取一个。
获取密钥后,请通过getpass将其添加。
import getpass
openai_api_key = getpass.getpass("输入您的OpenAI API密钥:")
准备您的Tair URL
要建立Tair连接,您需要TAIR_URL。
URL的格式为:redis://[[用户名]:[密码]]@localhost:6379/0
TAIR_URL = getpass.getpass("输入您的Tair URL:")
载入数据
在这一部分,我们将加载包含一些自然问题和它们的答案的数据。所有这些数据将用于创建具有Tair作为知识库的Langchain应用程序。
import wget
import json
# 所有示例均来自https://ai.google.com/research/NaturalQuestions
# 这是我们下载并提取以进行进一步处理的训练集的示例。
wget.download("https://storage.googleapis.com/dataset-natural-questions/questions.json")
wget.download("https://storage.googleapis.com/dataset-natural-questions/answers.json")
with open("questions.json", "r") as fp:
questions = json.load(fp)
with open("answers.json", "r") as fp:
answers = json.load(fp)
链定义
Langchain已经与Tair集成,并执行给定文档列表的所有索引。在我们的案例中,我们将存储答案集。
from langchain.vectorstores import Tair
from langchain.embeddings import OpenAIEmbeddings
from langchain import VectorDBQA, OpenAI
embeddings = OpenAIEmbeddings(openai_api_key=openai_api_key)
doc_store = Tair.from_texts(
texts=answers, embedding=embeddings, tair_url=TAIR_URL,
)
此时,所有可能的答案都已存储在Tair中,因此我们可以定义整个QA链。
llm = OpenAI(openai_api_key=openai_api_key)
qa = VectorDBQA.from_chain_type(
llm=llm,
chain_type="stuff",
vectorstore=doc_store,
return_source_documents=False,
)
搜索数据
一旦数据放入Tair中,我们就可以开始提出一些问题。问题将由OpenAI模型自动向量化,并创建的向量将用于在Tair中找到一些可能匹配的答案。一旦检索到,最相似的答案将被合并到发送给OpenAI Large Language Model的提示中。
import random
import time
random.seed(52)
selected_questions = random.choices(questions, k=5)
for question in selected_questions:
print(">", question)
print(qa.run(question), end="\n\n")
# 等待20秒以处理速率限制
time.sleep(20)
自定义提示模板
Langchain的“stuff”链类型使用具有问题和上下文文档的特定
提示。以下是默认提示的样式:
使用以下上下文部分来回答最后的问题。如果您不知道答案,只需说您不知道,不要试图编造一个答案。
{context}
问题:{question}
有帮助的答案:
然而,我们可以提供我们自己的提示模板,并更改OpenAI LLM的行为,同时仍然使用“stuff”链类型。保持{context}和{question}作为占位符是重要的。
实验自定义提示
我们可以尝试使用不同的提示模板,以便模型:
- 如果它知道答案,就提供一个单句回答。
- 如果不知道问题的答案,建议一个随机歌曲标题。
from langchain.prompts import PromptTemplate
custom_prompt = """
使用以下上下文部分来回答最后的问题。请只提供简短的单句摘要回答。如果您不知道答案或上下文中没有答案,请不要试图编造一个答案,而是建议我听一首随机无关的歌曲。
上下文:{context}
问题:{question}
有帮助的答案:
"""
custom_prompt_template = PromptTemplate(
template=custom_prompt, input_variables=["context", "question"]
)
custom_qa = VectorDBQA.from_chain_type(
llm=llm,
chain_type="stuff",
vectorstore=doc_store,
return_source_documents=False,
chain_type_kwargs={"prompt": custom_prompt_template},
)
random.seed(41)
for question in random.choices(questions, k=5):
print(">", question)
print(custom_qa.run(question), end="\n\n")
# 等待20秒以处理速率限制
time.sleep(20)
结论
通过本教程,您已经学会了如何使用Langchain、Tair和OpenAI来创建一个强大的问题回答系统。这种系统可以用于各种应用,从搜索引擎到智能助手。希望本教程对您有所帮助,使您能够更好地理解和应用这些技术。