在本指南中,您将使用 OpenAI 的文本嵌入(text embeddings)来测量文档属性之间的相似度。然后,通过 LangChain 框架无缝集成 Meilisearch,构建一个具备语义搜索功能的应用程序。
环境要求
本指南假设您已掌握 Python 和 LangChain 的基础知识。LangChain 初学者也能轻松跟随本教程。
创建应用程序
为您的应用程序创建一个文件夹,并添加空的 setup.py
文件。
在编写代码前,请先安装必要的依赖:
pip install langchain openai meilisearch python-dotenv
首先创建 .env 文件存储凭证:
# .env
MEILI_HTTP_ADDR="您的 Meilisearch 主机地址"
MEILI_API_KEY="您的 Meilisearch API 密钥"
OPENAI_API_KEY="您的 OpenAI API 密钥"
配置好环境变量后,创建包含基础代码的 setup.py
文件:
# setup.py
import os
from dotenv import load_dotenv # 如不使用 dotenv 请删除此行
from langchain.vectorstores import Meilisearch
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.document_loaders import JSONLoader
load_dotenv() # 如不使用 dotenv 请删除此行
# 缺少环境变量时退出
if "MEILI_HTTP_ADDR" not in os.environ:
raise Exception("缺少 MEILI_HTTP_ADDR 环境变量")
if "MEILI_API_KEY" not in os.environ:
raise Exception("缺少 MEILI_API_KEY 环境变量")
if "OPENAI_API_KEY" not in os.environ:
raise Exception("缺少 OPENAI_API_KEY 环境变量")
# 后续设置代码将在此处添加 👇
导入文档和向量嵌入
现在项目已准备就绪,可以开始向 Meilisearch 导入文档。首先下载这个小型的电影数据集:
然后更新 setup.py 文件来加载 JSON 数据并存储到 Meilisearch 中。同时您将使用 OpenAI 的文本搜索模型来生成向量嵌入。
要使用向量搜索功能,我们需要设置索引的 embedders 配置。在本例中,您使用的是 userProvided
源,这需要在 dimensions
字段中指定向量的维度大小。OpenAIEmbeddings()
默认使用的模型是 text-embedding-ada-002
,该模型生成的向量有 1,536 个维度。
# setup.py
# 之前的代码
# 加载文档
loader = JSONLoader(
file_path="./movies-lite.json",
jq_schema=".[] | {id: .id, overview: .overview, title: .title}",
text_content=False,
)
documents = loader.load()
print("已加载 {} 个文档".format(len(documents)))
# 将文档存储到 Meilisearch
embeddings = OpenAIEmbeddings()
embedders = {
"custom": {
"source": "userProvided",
"dimensions": 1536
}
}
embedder_name = "custom"
vector_store = Meilisearch.from_documents(documents=documents, embedding=embeddings, embedders=embedders, embedder_name=embedder_name)
print("开始导入文档")
现在您的 Meilisearch 实例中已包含这些文档。Meilisearch 会异步执行文档导入等任务,因此您可能需要稍等片刻文档才会可用。更多关于任务工作原理的信息,请参阅异步操作说明。
执行相似性搜索
您的数据库现已填充了电影数据集的数据。创建一个新的 search.py
文件来进行语义搜索查询:使用相似性搜索查找文档。
# search.py
import os
from dotenv import load_dotenv
from langchain.vectorstores import Meilisearch
from langchain.embeddings.openai import OpenAIEmbeddings
import meilisearch
load_dotenv()
# 可以使用与 `setup.py` 相同的代码来检查缺失的环境变量
# 创建向量存储
client = meilisearch.Client(
url=os.environ.get("MEILI_HTTP_ADDR"),
api_key=os.environ.get("MEILI_API_KEY"),
)
embeddings = OpenAIEmbeddings()
vector_store = Meilisearch(client=client, embedding=embeddings)
# 执行相似性搜索
embedder_name = "custom"
query = "superhero fighting evil in a city at night"
results = vector_store.similarity_search(
query=query,
embedder_name=embedder_name,
k=3,
)
# 显示搜索结果
for result in results:
print(result.page_content)
运行 search.py
。如果一切正常,你将看到类似以下的输出:
{"id": 155, "title": "The Dark Knight", "overview": "Batman raises the stakes in his war on crime. With the help of Lt. Jim Gordon and District Attorney Harvey Dent, Batman sets out to dismantle the remaining criminal organizations that plague the streets. The partnership proves to be effective, but they soon find themselves prey to a reign of chaos unleashed by a rising criminal mastermind known to the terrified citizens of Gotham as the Joker."}
{"id": 314, "title": "Catwoman", "overview": "Liquidated after discovering a corporate conspiracy, mild-mannered graphic artist Patience Phillips washes up on an island, where she's resurrected and endowed with the prowess of a cat -- and she's eager to use her new skills ... as a vigilante. Before you can say \"cat and mouse,\" handsome gumshoe Tom Lone is on her tail."}
{"id": 268, "title": "Batman", "overview": "Batman must face his most ruthless nemesis when a deformed madman calling himself \"The Joker\" seizes control of Gotham's criminal underworld."}
恭喜 🎉 你已成功使用 Meilisearch 作为 LangChain 的向量存储实现了相似性搜索。
深入探索
将 Meilisearch 作为 LangChain 的向量存储使用,您可以采用多种方式加载文档并进行搜索:
如需更多信息,请参考:
Meilisearch Python SDK 文档
最后,如果您希望在不使用 LangChain 或混合搜索功能的情况下体验 Meilisearch 的向量搜索能力,请参阅专门教程。