我们都知道Chatgpt有一个严重的问题,就是幻觉,一部分原因是因为ChatGPT缺少该领域的专业知识。借助大型语言模型 (LLM),我们可以集成特定领域的数据来回答用户请求,一定程度缓解这个问题。这对于模型在初始训练期间无法使用的数据特别有用,例如公司的内部文档或知识库。不过我们这里使用的Google PaLM模型,chatgpt同理。
该架构称为检索增强生成(Retrieval Augmentation Generation)或生成式问答(Generative Question Answering)。
本文帮助您了解如何使用 LLM 和向量数据库来实现此架构。来显着减少通常与LLM相关的幻觉。
它可用于广泛的用例。它减少了我们与文档交互所需的时间。我们不再需要在搜索结果中寻找答案。LLM负责精确查找最相关的文档,并使用它们从您的文档中生成答案。
代码实现:
Langchain:
我们这里使用 LangChain,这是一个开源软件开发框架,旨在简化使用大型语言模型 (LLM) 的应用程序的创建。
在本文中,它用于数据加载、文档分块、向量存储以及文本和嵌入模型交互等任务。
文件:
作为本示例的文档,我们使用完整的
这样,我们的法学硕士就能够回答有关 Vertex AI 的特定领域问题。任何类型的文档都是可以的。
结合LLM模型和向量数据集增强问答系统:
让我们来看看如何结合LLM和向量数据库的优势来创建强大的文档检索和问答系统。
完整的代码可以查看上面的在线colab。这里我们介绍涉及的步骤。
获取文档并进行预处理
LangChain支持多种数据加载选项。我们使用 Langchains 站点地图文档加载器加载基于站点地图的数据。
文档可能非常大并且包含大量文本。因此我们需要将文档分割成更小的块。它减少了发送给法学硕士的文本大小。
这有两个主要优点:
- 为该文档块创建的嵌入更准确地表示了我们问题的信息。
- 在检索过程中,我们收到较小的文档,并且可以保持 LLM 上下文较小。这会导致更快的延迟和更低的成本。
经过这个过程后,我们就有了一个包含一堆块文档的文件夹。这些块文档将在后续步骤中使用
- 创建文档嵌入
- 回答我们的问题
文档嵌入
嵌入步骤将我们的文档转换为称为嵌入的向量表示。我们可以使用 LLM 将每个文档块编码为高维向量。该过程以向量的形式捕获文档的语义信息。
我再次使用 LangChain 来使用 Vertex AI PaLM 2 Embedding 模型。正如已经说过的,langchain绝对不是必须的。对于此任务,您还可以依赖 Google 的 Vertex AI SDK。
from langchain.embeddings import VertexAIEmbeddings
embeddings = VertexAIEmbeddings()
text = "DoiT is a great company"
doc_result = embeddings.embed_documents([text])
在此过程之后,我们为每个文档块提供了一个向量表示(嵌入)。
存储在矢量数据库中
一旦我们有了文档向量,我们就把它们存储在向量数据库中。该数据库可以在向量之间进行高效的相似性搜索,帮助我们检索与给定查询最相关的文档。
查询处理
当提出问题时,我们使用 LLM(在我们的例子中是 Google 的 Vertex AI Embedding PaLM 2 模型)将问题转换为向量,就像我们在上一步中处理文档一样
文件检索:
基于上一步的查询,我们在向量数据库中搜索与问题向量语义最相似的文档向量。与这些向量相关的文档与我们的查询最相关,并将作为我们法学硕士的上下文。
向量数据库仅包含embedding和标识符,没有实际文本。
为了将向量结果与实际文档进行匹配,我再次使用 LangChain,它使用标识符并将它们与文档块进行匹配。
答案生成:
最后,检索到的文档作为上下文反馈到法学硕士中。法学硕士根据提供的信息生成答案。重要的部分是提示结构。
prompt=f"""
Follow exactly those 3 steps:
1. Read the context below and aggregrate this data
Context : {matching_engine_response}
2. Answer the question using only this context
3. Show the source for your answers
User Question: {question}
If you don't have any context and are unsure of the answer, reply that you don't know about this topic and are always learning.
"""
调优与索引:
为了让 LLM 根据我们特定领域的知识回答问题,我们可以微调模型,或者让我们的 LLM 使用可以在运行时查询的外部索引。
与调优相比,索引有一些优点:
- 与可能需要几个小时的调整相比,新文档是实时可用的。
- 规避了上下文大小限制。大多数 LLM 允许每个请求使用大约 4000 个token。这使得无法提供大量数据。通过索引方法,我们的法学硕士可以依赖无限的数据,因为我们只发送相关的类似文档的检索。
- 微调不知道哪些信息应该限制部分人的访问。使用索引,可以限制文档,不应该给所有人使用。
- 更便宜,因为不需要LLM微调。
- 由于基础数据是可解释的,这有助于在需要时验证答案是否正确。我们知道真相。
- 结合及时的工程,我们可以避免幻觉。