跳至主要内容

使用 Pinecone 和 OpenAI 的语义搜索

一份使用 OpenAI 和 Pinecone 在 Python 中构建语义搜索应用的分步指南。
· 13分钟 阅读

使用 AI 探索

不断变化的数据格局,加上过去两年生成式 AI 的快速发展,重塑了语义搜索的发展方向,并日益推动语义搜索应用的流行。

搜索与检索是根据查询条件,在更大的数据库或集合中定位并获取特定信息或数据的过程。AI 的进步提升了人们对更精准、具备上下文意识且高效的搜索方法的需求,从而催生了随处可见的语义搜索应用。

语义搜索通过理解查询的意图和上下文含义,超越了传统基于关键词搜索的局限,从而提供更相关、更精确的结果。

要构建端到端的语义搜索应用,您需要理解多个关键概念,如嵌入(Embeddings)、向量数据库、距离度量(Distance Metrics)等,并学习如何使用 Pinecone 和 OpenAI 的 GPT 等产品/服务来构建和部署端到端的语义搜索应用。

阅读完这篇博客,您将全面理解语义搜索、嵌入以及向量数据库的原理,并最终学会如何在 Python 中使用以下工具实现语义搜索:

  • Pinecone(最受欢迎的向量数据库之一)
  • OpenAI 的 GPT 嵌入模型。

如果您想通过实操进一步学习,请查看我们的课程:Vector Databases for Embeddings with Pinecone。

什么是嵌入(Embedding)?

嵌入是机器学习中的核心概念。它弥合了人类语言与理解的复杂细腻世界与将人类世界精确地用数字表示之间的鸿沟。

文本、图像、音频和视频等非结构化数据不遵循特定、有组织的格式,这给传统数据库的存储和处理带来挑战。为了用于机器学习和 AI 应用,通常需要通过向量嵌入将其转换为多维数值表示。将非结构化数据转换为多维数值向量的过程称为嵌入(Embedding)。

嵌入是对文本、图像或任何类型非结构化数据的多维数值表示,使机器能够以计算高效且富含上下文的方式,学习人类交流的复杂性、概念之间的关系或数据中的模式。

展示 OpenAI 文本与代码嵌入模型将文本输入转为向量输出的图片。

OpenAI 的文本与代码嵌入模型(图片来源)

嵌入模型背后的核心思想是,相似的项目可以在高维空间中被表示为彼此接近的点。这个概念使得我们能够捕捉数据中的复杂关系,如同义词、类比,甚至更抽象的联系,将人类语言或其他数据类型的巨大复杂性转化为机器可以处理的形式。

例如,在文本数据中,词会被转换为向量(数字),本质上是数字数组。这些向量封装了词语的含义、用法以及在语言模型理解框架中的上下文。

向量的长度由您使用的嵌入模型决定。比如,如果您使用 OpenAI 的嵌入模型,向量长度将始终为 `1536`。

创建嵌入的过程

在幕后,嵌入模型就是一个巨大的神经网络模型,在极其庞大的语料上进行训练。模型学习为输入数据分配向量,使得这些向量之间的几何关系能够映射数据实例之间的语义或概念关系。

例如,在一个训练良好的嵌入模型中,表示“king”的向量减去“man”的向量再加上“woman”的向量,可能会得到一个非常接近“queen”所代表向量的结果。这种带有语义的算术操作能力,生动展示了嵌入如何捕捉语言的底层语义。

展示经典的 king + woman − man ≈ queen 神经词嵌入示例的图片。

经典的 king + woman − man ≈ queen 神经词嵌入示例(图片来源)

如果您愿意,也可以训练自己的嵌入模型,但这可能需要收集海量数据和资源来训练一个巨型神经网络,成本可能高达数百万美元,并需要数月时间训练。

更实际的替代方案是使用某种预训练的嵌入模型。Hugging Face 上有许多开源嵌入模型可供下载并在本地使用,您也可以使用 OpenAI、Anthropic、Cohere 等公司提供的专有模型。

在这篇博客中,我们将使用 OpenAI 的 `text-embedding-ada-002` 模型,定价适中(每 1K tokens 收费 $0.00010)。这意味着一本 1000 页的书,成本大约不到 $1。

嵌入的应用场景

嵌入在各个领域的众多应用中至关重要。在语义搜索中,嵌入使系统能够超越简单的关键词匹配,检索与查询在上下文上相关的结果,即使内容中并未使用完全相同的词。这一能力显著提升搜索结果的相关性和准确性,使信息发现更直观、更高效。

文本、音频、视频与各类数据

嵌入并不局限于文本。以图像嵌入为例,它们在计算机视觉领域也带来了类似的进步,使机器能够在高维向量空间中理解图像和视频中的物体、场景与活动。这种理解不仅仅是识别像素,而是把握像素所代表的本质。

嵌入模型不仅具有变革性,而且极其实用,因为它们将真实世界数据的复杂性转换为机器能够理解和执行的语言(数值向量),从而支持广泛依赖深层语义理解和智能数据处理的应用。

想进一步了解嵌入,请查看Introduction to Text Embeddings with the OpenAI API 博客。

什么是向量数据库?

向量数据库是相对较新的非关系型数据存储类别,因生成式 AI 与大语言模型的最新进展而日益流行。

不同于以行列组织数据的传统关系型数据库,或将数据组织为 json/xml 对象的文档数据库等其他非关系型存储,向量数据库被设计为高效存储与处理多维向量数据。

向量数据库是一种针对存储与查询向量而优化的专用数据库。向量本质上是代表多维空间中数据点的数字数组。

展示原始数据如何被嵌入并存入向量数据库的工作流程图片

图片来源

向量数据库的关键优势在于其高效执行相似度搜索的能力。这意味着它们可以根据某种距离或相似度度量,快速找出数据库中与给定查询项“最接近”的项目。

这一能力对于推荐系统(例如找出与用户喜好相似的商品)或语义搜索应用(目标是找到与查询短语在语义上相关的文档)至关重要。

向量数据库使用多种用于索引和搜索向量的算法,通常依赖近似最近邻(ANN)搜索技术。

语义搜索及其应用场景

语义搜索在提升搜索引擎理解与处理用户查询的方式上迈出了重要一步。不同于关注查询文本与文档内容字面匹配的传统搜索方法,语义搜索深入挖掘查询背后的意图和上下文含义。

以谷歌搜索为例展示词法搜索与语义搜索差异的图片。

词法搜索 vs. 语义搜索(图片来源)

过去十年来,搜索技术向语义搜索演进的推动因素有很多。由 Siri、Alexa、Google Assistant 等虚拟助手驱动的语音搜索,严重依赖自然语言处理来理解并执行用户命令。

语音搜索的对话式特性要求理解上下文,促使搜索引擎需要把握整句甚至更长短语背后的含义。

人类语言的复杂性与搜索的局限

人类语言的复杂性对传统基于词法的搜索应用是巨大障碍,而语义搜索正快速克服这一难题。英语中有成千上万个一词多义的词语,其实际含义取决于使用的上下文。这些词被称为多义词(polysemous words)。

例如,“table”一词,依据上下文,可能指一件家具,也可能指一种数据排列。

多模态大语言模型(LLMs)的崛起

多模态大语言模型(LLMs)的崛起,是语义搜索应用爆炸式流行的主要推手。旨在理解搜索者意图以及术语在可检索数据空间中出现时的上下文含义的语义搜索,正在被多模态 LLM 的能力显著增强。

随着这些模型不断演进,它们不仅能理解和生成文本,还能解读并生成包括图像、音频、视频在内的多种形式内容。这些进步意味着搜索已能超越简单的关键词匹配,理解语言的细微差别、不同媒介的微妙之处,以及概念之间的复杂关系。

例如,您可以用自然语言发出搜索查询,系统不仅返回基于文本的结果,还会包括相关的图片、视频片段或音频片段,所有这些均由 AI 理解并策划,以匹配查询的意图。

应用场景

语义搜索在各领域拥有广泛应用,在提升搜索结果的相关性与精确性方面提供了显著价值:

  • 电商:线上零售商使用语义搜索改进商品发现。通过理解搜索查询背后的意图,电商平台即使在查询含糊或使用了商品描述中未出现的同义词时,也能展示最契合消费者需求的商品。
  • 内容发现:内容平台利用语义搜索推荐与用户兴趣和过往互动高度契合的文章、视频及其他内容形式,即使内容中未出现完全相同的检索词。
  • 客户支持:语义搜索通过使聊天机器人与支持系统更准确地理解并响应客户咨询,提供与用户问题上下文相关的答案,从而提升其有效性。
  • 知识管理:在组织内部,语义搜索通过理解查询上下文,帮助员工更高效地查找信息与文档,减少检索时间并提升生产力。
  • 语音搜索优化:随着语音搜索日益普及,语义搜索在解读此类查询中自然、对话式语言方面发挥关键作用,使虚拟助手能够提供准确答案。

想进一步了解向量数据库?请查看这篇最佳向量数据库综合指南。

Pinecone 概览

展示向量数据库生态全景的图片。

向量数据库生态(图片来源)

Pinecone 是专为处理复杂高维数据而设计的向量数据库。它提供先进的搜索与索引能力,使数据工程师和科学家能够高效构建与运行大规模机器学习项目。

Pinecone 的关键特性

  • 全托管:Pinecone 负责所有基础设施与维护,让开发者专注于构建与部署应用,而无需操心后端管理。
  • 可扩展性:可轻松管理数十亿向量,横向扩展以满足高强度机器学习任务的需求。
  • 实时数据写入:支持立刻添加与索引新数据,确保无停机或延迟。
  • 高速搜索:利用先进算法快速返回搜索结果,对需要即时响应的应用至关重要。
  • 易于集成:API 设计易用,便于与现有机器学习管道与工作流集成。

如果您想更深入了解 Pinecone,请查看 Datacamp 上的Mastering Vector Databases with Pinecone Tutorial: A Comprehensive Guide。

OpenAI 概览

OpenAI 通过其平台 API 提供对所有模型的访问。这包括广受欢迎的 GPT、DALL-E 和 Whisper 模型,以及三种嵌入模型。

OpenAI 网站上所有可用嵌入模型的截图。

来源

这些 API 可通过 HTTP 请求进行对接,因而兼容任何能够进行 HTTP 通信的编程语言。

Python 用户也可以使用 openai 库来与这些 API 交互,使用起来更为简单便捷。该库可通过 pip install openai 安装。

在 Python 中结合 openai 库调用 OpenAI API,仅需极少量代码。

在 Python 中使用 OpenAI 库的示例

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 Fitness & Health."},
    {"role": "user", "content": "Explain what is Keto diet?"}
  ]
)


print(completion.choices[0].message)

输出:(已截断)

ChatCompletionMessage(content="The ketogenic diet, commonly known as the keto diet, is a low-carbohydrate, high-fat diet. The diet is named after ketosis, a metabolic state where your body starts burning fat for energy instead of carbohydrates. This is accomplished by drastically reducing your intake of carbohydrates and increasing your intake of fats….", role='assistant', function_call=None, tool_calls=None)

探索 ChatGPT 和大语言模型如何重塑数字世界!查看 Datacamp 的速查表,掌握使用最强大 AI API 之一——OpenAI API 的要点。

使用 OpenAI 和 Pinecone API 在 Python 中实现端到端语义搜索

1. 注册 OpenAI 与 Pinecone

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

展示在 platform.openai.com 上创建 API key 的截图

API Keys platform.openai.com

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

与 OpenAI 不同,Pinecone 在您生成密钥时不一定需要立即复制,因为在 Actions 列下有复制图标,您可随时使用。

展示在 pinecone 平台账号中创建 API 的截图。

API Keys - Pinecone

获得 OpenAI 和 Pinecone 的 API key 后,将其赋值给 Notebook 中的变量,或使用 Python 的 os 模块设置为环境变量。

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

2. 安装 Python 库

要实现本教程,您需要通过 pip 安装以下库。必须使用完全一致的版本,否则下方代码将无法运行。

!pip install pinecone-client==3.0.0
!pip install pinecone-datasets==0.7.0
!pip install openai==0.28

3. 示例数据集

pinecone-datasets 库包含若干使用 OpenAI 的 embedding-ada-002 模型预嵌入的数据集。

在本例中,我们将使用 `wikipedia-simple-text-embedding-ada-002-100K` 数据集,从其中 100,000 篇文档及其嵌入中抽样 5,000 条。

import pinecone_datasets

# load dataset from pinecone
dataset = pinecone_datasets.load_dataset('wikipedia-simple-text-embedding-ada-002-100K')

# 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 5k documents
dataset.documents.drop(dataset.documents.index[5_000:], inplace=True)
dataset.head()

来自 pinecone-datasets 库的示例数据集 `wikipedia-simple-text-embedding-ada-002-100K` 的截图。

示例数据集

3. 创建 Pinecone 索引

在 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')

# set index name
index_name = 'semantic-search-demo'

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

上述代码初始化了 Pinecone 实例,并创建名为 semantic-search-demo 的索引。此时,您也能在 UI 中看到该索引。

pinecone UI 的索引页面截图,显示 semantic-search-demo 索引已成功创建

4. 插入数据

由于我们的数据已包含嵌入表示,因此可以跳过嵌入过程,直接将数据插入到新创建的索引中。

对于不含嵌入表示的数据集,需先使用 OpenAI API 对原始数据进行嵌入(见下方第 5 步的说明)。

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

代码成功运行后,您也可以在用户界面中查看到这些数据。

Pinecone UI 的截图,显示我们刚插入的数据。

5. 使用 OpenAI API 嵌入新数据

新数据或查询需要使用同一模型进行嵌入,以确保向量维度匹配。由于我们的数据集使用 text-embedding-ada-002,我们将创建一个函数,使用相同模型通过 OpenAI API 对新查询进行嵌入。

import openai
openai.api_key = OPENAI_API_KEY


def get_embedding(text_to_embed):
  # Embed a line of text
  response = openai.Embedding.create(
      model= "text-embedding-ada-002",
      input=[text_to_embed]
  )
  # Extract the AI output embedding as a list of floats
  embedding = response['data'][0]['embedding']
   
  return embedding

6. 使用新数据查询向量数据库

query = "What are some easter related events in Western Christianity?"

result = get_embedding(query)
print(len(result))
print(result)

输出:

1536

[0.014745471067726612, -0.03282099589705467, -0.006603493355214596, -0.0025058642495423555,.........]

result 的长度为 1536,与创建索引时设定的 dimension 一致。

发送搜索查询非常直接:

query_result = index.query(vector=result, top_k=3, include_metadata=True)
print(query_result)

输出:

设置 top_k=3 的查询输出截图。

query_result 返回一个包含与用户查询最匹配的前 3 个结果的字典。这些 Top N 匹配结果现可用于下游任务,例如在检索增强生成(RAG)场景中为提示提供上下文,或用于构建聊天机器人。

总结

在本教程中,我们介绍了理解语义搜索应用完整机制所需的多个关键基础概念,如嵌入与向量数据库。

随着生成式 AI 的到来以及多模态 LLM 的持续演进,语义搜索的能力不断扩展,在理解非结构化数据的复杂性与细微差别方面,提供了前所未有的精度与洞察。

借助前沿的向量数据库 Pinecone 与 OpenAI 提供的先进嵌入模型,开发者与数据科学家如今拥有构建语义搜索应用的工具,使之超越传统的基于关键词的搜索方法。

通过本指南,我们还探讨了嵌入在弥合人类语言复杂性与机器学习所需数值表示之间差距方面的重要性,揭示了这些表示如何使机器把握上下文与意图的细微之处。

显而易见,搜索的未来在于由 AI 驱动的对语言及其他非结构化数据形式的理解。无论是电商、内容发现、客户支持还是知识管理,本博客中阐述的原则与实践都为利用语义搜索的力量,打造更智能、更灵活、更以用户为中心的搜索体验提供了基础蓝图。

如果您想进一步学习如何使用 Pinecone 构建语义搜索应用,请查看 Semantic Search with Pinecone code-along;如果您对支撑 ChatGPT 等流行 AI 应用的功能感兴趣,请查看课程 Working with the OpenAI API。另外,别忘了查看我们的课程:Vector Databases for Embeddings with Pinecone。

Moez Ali

作者

Moez Ali

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

主题