跳至主要内容

如何使用 OpenAI API 和 Pinecone 构建聊天机器人

分步指南:在您自有数据上构建由大语言模型驱动的聊天机器人,使用 OpenAI 和 Pinecone 在 Python 中实现 RAG 技术。
· 12分钟 阅读

使用 AI 探索

自 2022 年 11 月 ChatGPT 发布以来,LLM 聊天机器人在众多场景中迅速崭露头角。

聊天机器人的概念并不新鲜。我们都见过那些“无用”的机器人,需要进行极其深入的配置,几乎是按 if-else 规则硬编码。它们既难以维护,又无法帮助终端用户,反而只会让用户更加沮丧。

但到了 2024 年,聊天机器人卷土重来,这要归功于大语言模型(LLM)。

在本文中,您将了解:

  • 什么是检索增强生成(RAG)技术
  • 什么是大语言模型
  • 如何使用 OpenAI GPT 及其他 API
  • 什么是向量数据库,以及我们为何需要它
  • 使用 Pinecone 和 OpenAI 在 Python 中构建您自己的聊天机器人

您还可以查看我们的 使用 Pinecone 的向量数据库与嵌入课程,以及使用 OpenAI API 和 Pinecone 构建聊天机器人的代码演练,了解更多内容。 

大语言模型(LLM)

image1.png

图片来源

像 GPT-4 这样的大语言模型(LLM)是先进的机器学习算法,利用深度学习技术,尤其是Transformer 架构,来理解并生成自然语言。

它们在包含万亿级词汇量的海量数据集上进行训练,这些数据来源于互联网上各种各样的文本,如书籍、文章、网站和代码仓库。如此广泛的训练使其能够执行多种复杂的语言处理任务。

LLM 的一大特性是几乎可以围绕任何主题生成文本。这种能力覆盖多种风格和格式,从创意写作到技术文档不一而足。

LLM 擅长摘要生成,能够将长文档提炼为精炼摘要;也能胜任对话式 AI,与用户进行自然、流畅的交流。它们还能在多语言之间进行翻译,甚至能把握俚语和方言等细微差异。

然而,LLM 并非没有挑战。其中一个重要问题是它们可能会“幻觉”,即在遇到超出训练数据或含糊提示时,生成看似合理但实际上错误或无意义的信息。

另一个关键问题是可能出现输出偏见,这种偏见可能源自训练数据,或在模型开发过程中引入。

LLM 代表了 AI 的重大进步,在诸多领域具有巨大的创新和效率潜力,但也需要谨慎管理,以降低偏见和错误信息等风险。

什么是检索增强生成(RAG)?

image2.png

图片来源

LLM 虽然强大,但也存在局限。当查询超出其训练数据范围时,可能给出过时、泛化甚至错误的信息。

它们也可能编造事实错误或无意义的信息,并以貌似真实或合乎逻辑的方式呈现出来,这种现象就是所谓的“幻觉”。

RAG 旨在通过引导 LLM 从预先确定的来源检索相关信息来缓解这些问题。这样做能提升用户信任,因为模型输出更为准确,并且可以追溯到可靠来源。

它也让开发者对 LLM 生成的响应有更强的可控性,从而提升系统的整体质量和适用性。

RAG 流程

您可以在我们的独立教程中进一步了解检索增强生成。下面简要列出了主要步骤。

  1. 创建外部数据:RAG 以准备 LLM 原始训练集之外的外部数据源开始。此类数据(如最新的研究、新闻或统计数据)会被转换为 LLM 能理解和利用的格式(嵌入)。
  2. 存储嵌入:使用某个模型将原始文本数据转换为嵌入后,会将其存入一种名为向量数据库的数据库。它专为高效存储与检索向量数据而设计,非常适合 RAG 应用。Pinecone 是最流行的向量数据库之一。
  3. 检索相关信息:模型随后通过查询向量数据库执行语义搜索。当输入用户查询时,会将其转换为向量表示,并与向量化的外部数据进行匹配,从而确保检索到最相关、最新的信息。
  4. 增强 LLM 提示:将检索到的数据与用户的原始查询组合,用于增强传递给 LLM 的提示词。这个更丰富的提示使模型能够生成更准确、更贴合语境的响应。
  5. 持续更新外部数据:为保持信息的相关性与准确性,需要定期更新外部数据源,确保 LLM 能访问到最新信息。

向量数据库

image10.png

图片来源

向量数据库是一类专门用于处理高维向量的数据库,这些向量是对数据属性或特征的数学表示。根据数据的复杂度与粒度,向量维度可以从几十到上千不等。

这类数据库擅长基于向量距离或相似度进行快速且准确的相似性搜索与检索,从而支持更具语义或上下文的查询方式,而非依赖传统的精确匹配或预设条件。

在实际应用中,向量数据库用途广泛。例如,它们可以基于视觉内容和风格查找与给定图像相似的图片;根据主题和情感,定位与某文档相似的文档;或依据特征和评分,识别与某产品相似的产品。

在向量数据库中进行查询时,会使用一个代表目标信息或条件的查询向量,并应用相似度度量来判断向量空间中各向量的接近程度。最终返回与查询向量相似度最高的向量列表,并可访问与每个向量相关联的原始数据。

向量数据库由多种算法驱动,如 k 近邻(k-NN)索引,并采用层次化可导航小世界图(HNSW)与倒排文件索引(IVF)等方法构建。

向量数据库是检索增强生成(RAG)应用的核心组件。它们提供高效的相似性搜索、内容扩展、多样性以及动态的多模态数据检索能力。在生成式 AI 中,这一点至关重要,因为访问大规模、多样化的数据集对于减少模型偏见与幻觉尤为关键。

Pinecone 是广受欢迎的向量数据库,尤其在处理大规模数据场景时,以高效与易用见长。它面向希望在各类应用中实现向量搜索功能的开发者与数据科学家。

Pinecone 采用了产品量化与局部敏感哈希等先进索引技术,能够在高维向量空间中实现高效且准确的相似性搜索,这使其特别适用于 RAG 应用。您可以在我们的独立教程中进一步了解使用 Pinecone 精通向量数据库。

在本教程中,我们将使用 Pinecone 作为向量数据库。

OpenAI API

OpenAI 的 API 平台提供对所有面向公众开放的 OpenAI 训练模型的访问权限,包括 GPT、DALL-E、Whisper 等。

该 API 通过 HTTP 请求访问,因此您可以使用任何支持发起 HTTP 请求的编程语言进行集成。不过,在 Python 中,有一个名为 openai 的库,您可以通过 pip install openai 安装它,从而更轻松地使用这些 API。

在 Python 中使用 OpenAI API 与 openai 库,仅需寥寥数行代码。

Python 示例:

import os
os.environ["OPENAI_API_KEY"] = " "


from openai import OpenAI
client = OpenAI()


completion = client.chat.completions.create(
  model="gpt-4",
  messages=[
    {"role": "system", "content": "You are expert in Machine Learning."},
    {"role": "user", "content": "Explain how does random forest works?."}
  ]
)


print(completion.choices[0].message)

LangChain

LangChain 是一个用于开发由语言模型驱动的应用的框架。它提供了一定层次的抽象,使得原型开发更简单、更快速,也能更快地从原型走向生产。该框架的增长与流行,从其 Github 页面上的星标数量可见一斑。

这是一个出色的框架。但需要注意的是,它目前仍不稳定。API 仍在不断变化,甚至当您阅读下一节代码时,可能已经无法运行。这在所难免,因为该库仍处于 pre-release 阶段。撰写本文时,LangChain 的最新版本为 0.1.4。

Python 端到端示例:使用 OpenAI GPT-4 API 与 Pinecone 向量存储构建 LLM 聊天机器人应用的分步指南

要实现一个 RAG 后端,我们需要外部数据的嵌入。如果从原始数据开始,则需要使用 OpenAI 的嵌入 API 或其他开源嵌入模型来生成嵌入。

为原始数据生成嵌入并不复杂。不过,如果您使用 OpenAI 的 API,将按 token 计费。

出于本教程的目的,本节的大部分代码来自官方Pinecone 的 LangChain 指南。Pinecone 文档质量极高且始终保持最新。

1. 注册 OpenAI 和 Pinecone

注册 OpenAI 账户后,请前往 https://platform.openai.com/api-keys

生成密钥时您必须立即复制,因为之后将无法再次查看或复制该密钥。

image7.png

对于 Pinecone,登录您的账户并点击 API Keys。您可以点击右上角的 “Click API Key” 按钮。

与 OpenAI 不同,在 Pinecone 中生成 API key 后不必立刻复制,因为您可以随时通过“Actions”列下的复制图标来复制。

image3.png

从 OpenAI 和 Pinecone 获取 API 密钥后,请在 Notebook 中将它们设置为变量。或者,您也可以使用 Python 的 `os` 模块将这些密钥设置为环境变量。如选择该方式,请相应修改下方代码。

OPENAI_API_KEY = '...'
PINECONE_API_KEY = '...'

2. 安装 Python 库

要实现本教程,您需要使用 pip 安装以下库。

!pip install -qU \
  langchain==0.1.1 \
  langchain-community==0.0.13 \
  openai==0.27.7 \
  tiktoken==0.4.0 \
  pinecone-client==3.0.0 \
  pinecone-datasets==0.7.0

3. 示例数据集

pinecone-datasets 库提供了一些已经使用 OpenAI 的 embedding-ada-002 模型生成嵌入的示例数据集。我们将使用名为 wikipedia-simple-text-embedding-ada-002-100K 的数据集。

顾名思义,该数据集中有 100,000 篇文档。但在本教程中,我们只抽样前 30,000 条记录。尽管所有 100,000 篇文档都已提供嵌入,抽样并不会影响成本,这么做只是为了加快处理速度。

import pinecone_datasets
dataset = pinecone_datasets.load_dataset('wikipedia-simple-text-embedding-ada-002-100K')

image5.png

# drop metadata column and renamed blob to metadata
dataset.documents.drop(['metadata'], axis=1, inplace=True)
dataset.documents.rename(columns={'blob': 'metadata'}, inplace=True)


# sample 30k documents
dataset.documents.drop(dataset.documents.index[30_000:], inplace=True)

4. 设置 Pinecone 索引

from pinecone import Pinecone, ServerlessSpec


# configure client
pc = Pinecone(api_key=PINECONE_API_KEY)


# configure serverless spec
spec = ServerlessSpec(cloud='aws', region='us-west-2')


# check for and delete index if already exists
index_name = 'langchain-retrieval-augmentation-fast'
if index_name in pc.list_indexes().names():
    pc.delete_index(index_name)


# we create a new index
pc.create_index(
        index_name,
        dimension=1536,  # dimensionality of text-embedding-ada-002
        metric='dotproduct',
        spec=spec
    )

连接到索引并查看索引统计信息:

index = pc.Index(index_name)
index.describe_index_stats()

输出如下:

{'dimension': 1536,
 'index_fullness': 0.0,
 'namespaces': {},
 'total_vector_count': 0}

1536 是 ada-002 模型嵌入的维度。您可以看到向量数量为 0,因为我们尚未导入任何数据(向量)。

5. 插入数据

将数据插入到索引 langchain-retrieval-augmentation-fast 的过程非常直接:

for batch in dataset.iter_documents(batch_size=100):
    index.upsert(batch)

该命令将需要几分钟完成。

插入数据后,您也可以在 Pinecone 的界面上看到:

image4.png

6. LangChain

现在我们已经使用 Pinecone API 创建了索引并插入了数据,接下来将切换到 LangChain。下一步是使用 LangChain 初始化一个向量存储,并复用我们创建的同一个索引。

from langchain.embeddings.openai import OpenAIEmbeddings
model_name = 'text-embedding-ada-002'
embed = OpenAIEmbeddings(model=model_name, openai_api_key=OPENAI_API_KEY)

初始化向量存储:

from langchain.vectorstores import Pinecone
vectorstore = Pinecone(index, embed.embed_query, "text")

7. 查询向量存储

您现在可以使用 vectorstore 对象查询数据,并查看 Top N 结果:

query = "What is Schizophrenia?"


vectorstore.similarity_search(query, k=3)

输出是一个文档对象,您可以轻松解析其中的字符串。本质上,它展示了基于我们在步骤 4 中选择的度量(此处为 dotmatrix)得到的 Top 3 匹配文档。

image8.png

8. 最后一步——接入 LLM🚀

这是我们应用的最后一步。我们现在要把 LLM 包装进来。为此,您需要从 LangChain 中导入 ChatOpenAI 和 RetrievalQA 类。

from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA


# completion llm
llm = ChatOpenAI(
    openai_api_key=OPENAI_API_KEY,
    model_name='gpt-4',
    temperature=0.0
)


qa = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=vectorstore.as_retriever()
)


qa.run(query)

qa.run(query) 的输出即为语言模型的回答。

Schizophrenia is a mental illness where people may see, hear or believe things that are not real. It often first appears in teenage years and is a chronic condition....

这个答案来自 `dataset` 中的某个文档。如果您还想获取来源(这在 RAG 应用中很常见),只需对上面的代码做一个小改动。

from langchain.chains import RetrievalQAWithSourcesChain


qa_with_sources = RetrievalQAWithSourcesChain.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=vectorstore.as_retriever()
)


qa_with_sources(query)

输出:

{'question': 'What is Schizophrenia?',
 'answer': 'Schizophrenia is a mental illness where people may see, hear or believe things that are not real. It is a relatively common condition ...',
 'sources': 'https://simple.wikipedia.org/wiki/Schizophrenia'}

请注意,这次的输出是一个字典,您可以在其中找到 `source`。

总结

在本文中,我们探讨了 LLM 最受欢迎的应用——检索增强生成(RAG)技术,深入解读了它如何基于 GPT-4 等大语言模型提升聊天机器人回答的可靠性与相关性。

聊天机器人从简单的规则系统演进为复杂的、由 AI 驱动的对话代理,标志着技术上的重大飞跃。LLM 为聊天机器人带来了更高的通用性与智能,能够展开更加自然、具备上下文意识的对话。

我们还介绍了向量数据库在 RAG 中的作用,重点关注 Pinecone 在存储与检索高维向量方面的能力。这类数据库是实现 RAG 的关键。

我们通过代码示例展示了这些概念的实操实现,利用 OpenAI 与 Pinecone 的 API 以及 Python 中的 LangChain 框架。这些工具简化了开发流程,使开发者能够更快速、高效地构建适用于广泛应用的 AI 聊天机器人。

若想进一步学习 使用 Pinecone 的向量数据库与嵌入或使用 OpenAI API,欢迎查看我们的课程,帮助您在这些领域持续进阶。

Moez Ali

作者

Moez Ali

数据科学家,PyCaret 的创始人兼作者

主题