使用个性化代理构建食谱推荐器
Weaviate 个性化代理将用户画像和交互数据存储在您的 Weaviate 实例中,与您的主要数据集合一起存储。在实施此代理时,请注意数据隐私法规。
在本教程中,我们将使用 Weaviate 个性化代理 构建一个简单的食品推荐服务。该代理将根据用户定义的画像(persona)和过去的交互(例如,食谱评论)来了解用户偏好,从而从食谱集合中提供个性化推荐。
我们准备了一个公共数据集,您可以使用它来探索个性化代理:它在 HuggingFace 上可用
- 食谱: 一个数据集,列出了食谱名称、简短描述和菜系类型。
简介:什么是个性化代理?
Weaviate 个性化代理是一种预构建的代理服务,旨在以针对个人用户量身定制的方式从 Weaviate 集合中检索对象。它通过考虑用户的定义画像(profile)及其与集合中项目的交互历史来实现这一点。

个性化代理
- 接收针对特定用户的推荐请求(persona)。
- 检索用户的画像资料(例如,喜欢、不喜欢、喜欢的菜系)和 交互历史记录(例如,带有相关权重的喜欢/不喜欢的食谱)。
- 查询参考集合(例如,“食谱”)以查找候选项目。
- (可选)使用适当的生成模型(例如,大型语言模型)根据 persona、交互以及潜在的特定指令重新排序候选项目,并提供排名的理由。
- 向用户返回个性化、排序的对象列表。
先决条件
要使用 Weaviate 代理和 Weaviate Embedding 服务,您需要拥有一个 Weaviate Cloud 帐户。
步骤 1:设置 Weaviate
现在,让我们开始通过设置一个 Weaviate Cloud 实例来完成本教程,并将其连接到 Python 客户端。
1.1 创建 Weaviate Cloud 集群
- 在 Weaviate Cloud 中创建一个 免费的 Sandbox 集群。
- 请注意
REST Endpoint和AdminAPI 密钥,以便连接到您的集群。(有关更多信息,请查看 快速入门)
在本教程中,我们使用 Weaviate Embeddings 服务作为向量化器,因此您无需为外部嵌入提供程序提供任何额外的密钥。Weaviate Embeddings 使用 Snowflake/snowflake-arctic-embed-l-v2.0 作为默认嵌入模型。
如果您想使用另一个向量化器,请查看支持的 模型提供程序列表。
1.2 安装 Python 库
为了安装 Weaviate Python 客户端以及 agents 组件,请运行
pip install "weaviate-client[agents]"
您还需要 datasets,这是一个轻量级库,可提供对 HuggingFace 上托管的公共数据集的访问权限。
pip install datasets
故障排除:强制 pip 安装最新版本
对于现有安装,即使 pip install -U "weaviate-client[agents]" 也可能无法将 weaviate-agents 升级到 最新版本。如果发生这种情况,请尝试显式升级 weaviate-agents 包
1.3 连接到您的实例
现在,您终于可以使用第一步中的参数连接到您的 Weaviate Cloud 实例了
如果某个片段无法工作或您有任何反馈,请打开一个 GitHub issue。
import os
import weaviate
from weaviate.auth import Auth
# Best practice: store your credentials in environment variables
weaviate_url = os.environ["WEAVIATE_URL"]
weaviate_api_key = os.environ["WEAVIATE_API_KEY"]
client = weaviate.connect_to_weaviate_cloud(
cluster_url=weaviate_url,
auth_credentials=Auth.api_key(weaviate_api_key),
)
print(client.is_ready()) # Should print: `True`
# Your work goes here!
client.close() # Free up resources
运行此代码段后,您应该看到消息 True 打印出来,这意味着您已成功连接到您的实例。
步骤 2:准备集合
在以下代码块中,我们将从 Hugging Face 拉取我们的演示食谱数据集,并将其写入 Weaviate Sandbox 集群中的新集合。在导入数据之前,我们需要 定义集合,设置其模式并选择向量化器。
2.1 定义集合
下面可以看到 Recipes 数据集中的对象的样子。

对于 Recipes 集合,我们将手动定义属性并包含描述。虽然使用 auto-schema 是一个选项,但提供明确的描述有助于个性化代理(尤其是底层 LLM,在用于重新排序时)更好地理解数据的上下文。
如果某个片段无法工作或您有任何反馈,请打开一个 GitHub issue。
from weaviate.classes.config import Configure, DataType, Property
client.collections.create(
"Recipes",
description="A dataset that lists recipes with titles, descriptions, and labels indicating cuisine",
vector_config=Configure.Vectors.text2vec_weaviate(),
properties=[
Property(
name="title", data_type=DataType.TEXT, description="title of the recipe"
),
Property(
name="labels",
data_type=DataType.TEXT,
description="the cuisine the recipe belongs to",
),
Property(
name="description",
data_type=DataType.TEXT,
description="short description of the recipe",
),
],
)
2.2 填充数据库
现在,我们可以将食谱数据 (Recipes) 导入到我们的 Weaviate Cloud 实例中
如果某个片段无法工作或您有任何反馈,请打开一个 GitHub issue。
from datasets import load_dataset
# Ensure datasets library is installed: pip install datasets
dataset = load_dataset(
"weaviate/agents",
"personalization-agent-recipes",
split="train",
streaming=True,
)
recipes_collection = client.collections.use("Recipes")
with recipes_collection.batch.fixed_size(batch_size=200) as batch:
for item in dataset:
batch.add_object(properties=item["properties"])
failed_objects = recipes_collection.batch.failed_objects
if failed_objects:
print(f"Number of failed imports: {len(failed_objects)}")
print(f"First failed object: {failed_objects[0]}")
通过调用 len() 来获取我们的集合,我们可以检查导入是否已成功完成,并查看我们的集合的大小。
如果某个片段无法工作或您有任何反馈,请打开一个 GitHub issue。
print(f"Size of the Recipes dataset: {len(recipes_collection)}")
Size of the Recipes dataset: 5117
步骤 3:设置个性化代理
现在,让我们创建与我们的“食谱”集合关联的 PersonalizationAgent 实例。
首次创建新的 PersonalizationAgent 时,我们定义 user_properties。这些字段将构成每个用户画像资料。对于我们的食品推荐器,诸如喜欢的菜系、一般的食物喜好和不喜欢之类的信息是相关的。
如果集合的代理已经存在(例如,来自之前的运行),我们可以简单地使用 PersonalizationAgent.connect() 连接到它。下面的代码处理这两种情况。
如果某个片段无法工作或您有任何反馈,请打开一个 GitHub issue。
from weaviate.agents.personalization import PersonalizationAgent
from weaviate.classes.config import DataType
agent_exists = PersonalizationAgent.exists(client, "Recipes")
if agent_exists:
print("Connecting to existing Personalization Agent for 'Recipes' collection...")
agent = PersonalizationAgent.connect(
client=client,
reference_collection="Recipes",
vector_name="default"
)
print("Connected to existing agent.")
else:
print("Creating new Personalization Agent for 'Recipes' collection...")
agent = PersonalizationAgent.create(
client=client,
reference_collection="Recipes",
vector_name="default",
user_properties={
"favorite_cuisines": DataType.TEXT_ARRAY,
"likes": DataType.TEXT_ARRAY,
"dislikes": DataType.TEXT_ARRAY,
},
)
print("New agent created.")
您应该会看到一条消息,指示是否创建了新的代理或连接到现有的代理。
步骤 4:使用个性化代理
设置好代理后,现在我们可以添加用户数据并检索推荐信息。
4.1 添加新的 persona
“persona”代表用户资料。我们使用 agent.add_persona() 方法,提供唯一的 persona_id(建议使用 UUID)和我们在创建代理期间定义的 properties。
请随意修改下面的示例,以代表您自己的食物偏好!
如果某个片段无法工作或您有任何反馈,请打开一个 GitHub issue。
from uuid import uuid4
from weaviate.agents.classes import Persona
persona_id = uuid4()
print(f"Adding persona with ID: {persona_id}")
agent.add_persona(
Persona(
persona_id=persona_id,
properties={
"favorite_cuisines": ["Italian", "Thai"],
"likes": ["chocolate", "salmon", "pasta", "most veggies"],
"dislikes": ["okra", "mushroom"],
},
)
)
4.2 添加交互
“交互”代表用户与集合中项目的互动方式。对于我们的推荐器,这些可以是明确的评论、评分或隐式信号,例如查看食谱页面。
每个 PersonaInteraction 将 persona_id 链接到 item_id(“食谱”集合中对象的 UUID),并包含一个从 -1.0(强烈不喜欢)到 1.0(强烈喜欢)的 weight。

首先,我们获取用户交互过的一些特定食谱的 UUID。然后,我们定义具有适当权重的交互。最后,我们使用 agent.add_interactions() 将它们添加到代理中。
如果某个片段无法工作或您有任何反馈,请打开一个 GitHub issue。
from weaviate.agents.classes import PersonaInteraction
from weaviate.collections.classes.filters import Filter
reviewed_foods = [
"Coq au Vin",
"Chicken Tikka Masala",
"Gnocchi alla Sorrentina",
"Matcha Ice Cream",
"Fiorentina Steak",
"Nabe",
"Duck Confit",
"Pappardelle with Porcini",
]
# Fetch the recipe objects to get their UUIDs
reviews_dict = {
recipe.properties["title"]: recipe
for recipe in recipes_collection.query.fetch_objects(
filters=Filter.by_property("title").contains_any(reviewed_foods),
limit=len(reviewed_foods), # Use len for limit
).objects
}
# Define the mapping of food titles to interaction weights
interaction_map = {
"Coq au Vin": 0.8,
"Chicken Tikka Masala": 0.8,
"Matcha Ice Cream": 0.8,
"Gnocchi alla Sorrentina": 0.5,
"Fiorentina Steak": 0.8,
"Nabe": 0.5,
"Duck Confit": 1.0,
"Pappardelle with Porcini": -1.0,
}
interactions = []
for food_title, weight in interaction_map.items():
if food_title in reviews_dict:
# If the recipe was found, create the interaction object
interaction = PersonaInteraction(
persona_id=persona_id,
item_id=reviews_dict[food_title].uuid, # Get UUID from fetched recipe
weight=weight,
)
interactions.append(interaction)
# Add the created interactions list to the agent
agent.add_interactions(interactions=interactions)
此块准备交互数据并将其发送到代理。
4.3 获取推荐
现在是核心功能:使用 agent.get_objects() 检索个性化推荐。我们提供我们想要推荐信息的 persona_id。
我们可以设置 use_agent_ranking=True 以启用基于 LLM 的重新排序。这将利用 persona 资料和交互历史记录来提供更细致的排名,并生成 ranking_rationale,解释 为什么 推荐某些项目。
如果某个片段无法工作或您有任何反馈,请打开一个 GitHub issue。
print(f"\nGetting recommendations for persona {persona_id}...")
response = agent.get_objects(persona_id, limit=10, use_agent_ranking=True)
print("\nRanking Rationale:")
print(
response.ranking_rationale
if response.ranking_rationale
else "No rationale provided."
)
print("\nRecommended Recipes:")
if response.objects:
for i, obj in enumerate(response.objects):
print(f"----- Recommendation {i+1} -----")
print(f" Title: {obj.properties.get('title', 'N/A')}")
print(f" Cuisine: {obj.properties.get('labels', 'N/A')}")
print(f" UUID: {obj.uuid}")
else:
print("No recommendations found.")
输出将首先显示代理的 LLM 生成的 ranking_rationale,然后显示推荐的食谱列表,包括它们的标题、描述和菜系标签。
示例响应(将根据 persona/交互和 LLM 而变化)
Getting recommendations for persona e7239e3f-97f5-41b3-939a-5fbf3e0c7f16...
Ranking Rationale:
Because you love Italian dishes and have shown an interest in different cuisines, we've prioritized dishes with Italian, Japanese, and Indian labels, reflecting your preferences for Italian and Thai cuisines and prior positive interactions. We avoided items with mushroom content.
Recommended Recipes:
----- Recommendation 1 -----
Title: Chicken Tikka Masala
Cuisine: Indian
UUID: 5785f023-5ab2-49d8-bb43-0ab047083e16
----- Recommendation 2 -----
Title: Spicy Indian Tikka Masala
Cuisine: Indian
UUID: 753a036f-ec83-4efa-8a1a-5afa021acbc2
----- Recommendation 3 -----
Title: Paneer Tikka
Cuisine: Indian
UUID: 323b6f11-c026-4367-801b-b21f40e6591b
----- Recommendation 4 -----
Title: Paneer Butter Masala
Cuisine: Indian
UUID: 3bd11bc9-d329-4039-9f4a-205f1719048d
----- Recommendation 5 -----
Title: Butter Chicken
Cuisine: Indian
UUID: 4e056c59-e843-419a-8129-b6633fb8c2d3
----- Recommendation 6 -----
Title: Shabu-Shabu
Cuisine: Japanese
UUID: df0ae465-f724-42ed-9876-2c9b91516c13
----- Recommendation 7 -----
Title: Oden
Cuisine: Japanese
UUID: eb6088c1-05a6-46ed-9adc-477313c051d2
----- Recommendation 8 -----
Title: Tempura
Cuisine: Japanese
UUID: 625a5164-e150-4966-a3c6-0aed406db416
----- Recommendation 9 -----
Title: Ramen
Cuisine: Japanese
UUID: 708824b3-fc4a-4927-82bb-a8a4dbd5ee89
----- Recommendation 10 -----
Title: Udon Noodles
Cuisine: Japanese
UUID: 8d6a94b7-c9ae-4d1c-b29a-885717b9a55a
总结
本指南演示了如何使用 Weaviate 的个性化代理构建个性化的食品推荐服务。我们涵盖了
- 使用 Python 客户端设置 Weaviate Cloud 实例。
- 定义具有描述性属性的“食谱”集合。
- 将数据导入到集合中。
- 创建与集合关联的个性化代理,并定义用户资料属性(
user_properties)。 - 添加具有特定偏好的用户资料(
personas)。 - 记录用户与项目的交互,使用加权分数。
- 使用
get_objects检索个性化推荐,利用基于 LLM 的重新排序(use_agent_ranking=True)获得定制的结果和解释(ranking_rationale)。
个性化代理允许您轻松地为基于 Weaviate 构建的应用程序添加复杂、个性化的检索功能。
更多资源
问题和反馈
如果您有任何问题或反馈,请在 用户论坛 中告诉我们。

