S3 Vectors 如何工作:AWS 新向量存储的友好指南
Source: Dev.to
为什么使用向量?
我们都知道 AWS S3 是什么,对吧?它是那种众所周知、便宜且持久的对象存储,已经使用了数十年。当你第一次听到 S3 向量 时,可能会出现几个问题:
- 什么是向量?
- 向量只适用于数学家吗?
- 它们与 AI 有什么关系?
- 为什么它们带有 S3 前缀?
下面我们将回答这些问题,并展示 S3 向量是如何工作的。
什么是向量存储,为什么在 AI 中需要它?
向量 是一种既有大小(幅度)又有方向的数学对象,通常表示为有序数字列表,例如 ["tell"] = [0, 2, 1, 10, …, 3]。
这些数字并非随机,它们编码了语义意义。例如,单词 Espresso 和 Latte 的向量会非常相似,因为它们指的是相似类型的咖啡。
向量数据库
向量数据库(vector DB)专为使用近似最近邻(ANN)算法进行相似性搜索而构建。关系型数据库也能进行相似性搜索,但在大规模时效率不高。
典型工作流:
- 你的应用查询向量存储。
- 存储返回最近的向量(块)。
- 将这些块作为上下文提供给大型语言模型(LLM)。
示例:如果聊天机器人 LLM 收到问题 “Are there any discounts for students on your website?”,且向量数据库中包含相关信息,LLM 可以检索、补充并回答该查询。
向量存储充当 增强知识库,让你在不进行昂贵模型训练的情况下注入任意信息。这种方法被称为 检索增强生成(Retrieval‑Augmented Generation,RAG)。向量可以表示文本、图像、音乐——任何可以嵌入的内容。
S3 向量存储结构
结构与传统 S3 相同:
- Bucket – 在区域内唯一的名称。
- Index – 桶内唯一的名称;可根据需求进行配置。
索引配置选项
| 设置 | 描述 |
|---|---|
| Dimension | 数值(1–4096),表示每个向量包含多少个数字。例如,维度为 5 时会得到类似 [1, 2, 1, 4, 5] 的向量。 |
| Distance Metric | 选择 Cosine(余弦相似度)或 Euclidean(欧氏距离)来定义查询时的相似度度量。 |
| Encryption | 使用桶级加密或为索引单独覆盖。选项包括: • SSE‑KMS(使用 AWS KMS 密钥的服务器端加密) • SSE‑S3(使用 Amazon S3 管理的密钥的服务器端加密) |
| Tagging | 为每个向量附加任意标签(例如 region、category、audience)。标签充当元数据,使得搜索可以在纯向量相似度之外进行过滤。AWS 可以自动生成标签,也可以手动设置。 |
示例:创建和查询向量
下面是一个完整的 Python 示例,演示:
- 使用 Amazon Titan embed‑text‑v2 生成嵌入。
- 将向量存储在 S3 向量索引中。
- 执行语义搜索,可选择按标签过滤。
import boto3
import json
region = "us-west-2"
bucket = "my-sales-bucket"
index = "my-sales-index"
bedrock = boto3.client("bedrock-runtime", region_name=region)
s3vectors = boto3.client("s3vectors", region_name=region)
# --- 1. Populate the vector index with sample sales data ---
items = [
{
"key": "laptop-general-sale",
"text": "10% off all laptops this weekend in our electronics section.",
"metadata": {"category": "laptop", "audience": "all", "discount": "10%"}
},
{
"key": "laptop-student-sale",
"text": "15% discount on lightweight laptops for students and university use.",
"metadata": {"category": "laptop", "audience": "students", "discount": "15%"}
},
{
"key": "phone-sale",
"text": "20% off latest smartphones with long‑lasting battery.",
"metadata": {"category": "phone", "audience": "all", "discount": "20%"}
}
]
vectors = []
for item in items:
resp = bedrock.invoke_model(
modelId="amazon.titan-embed-text-v2:0",
body=json.dumps({"inputText": item["text"]})
)
embedding = json.loads(resp["body"].read())["embedding"]
vectors.append({
"key": item["key"],
"data": {"float32": embedding},
"metadata": {
"source_text": item["text"],
**item["metadata"]
}
})
s3vectors.put_vectors(
vectorBucketName=bucket,
indexName=index,
vectors=vectors
)
# --- 2. Query the index for "laptops for students" ---
query_text = "Do you have any sales on laptops for students?"
resp = bedrock.invoke_model(
modelId="amazon.titan-embed-text-v2:0",
body=json.dumps({"inputText": query_text})
)
query_embedding = json.loads(resp["body"].read())["embedding"]
# Plain semantic search
response = s3vectors.query_vectors(
vectorBucketName=bucket,
indexName=index,
queryVector={"float32": query_embedding},
topK=3,
returnDistance=True,
returnMetadata=True
)
print("Top matches:")
print(json.dumps(response["vectors"], indent=2))
# Optional: restrict to laptop category only
response_filtered = s3vectors.query_vectors(
vectorBucketName=bucket,
indexName=index,
queryVector={"float32": query_embedding},
topK=3,
filter={"category": "laptop"},
returnDistance=True,
returnMetadata=True
)
print("Laptop‑only matches:")
print(json.dumps(response_filtered["vectors"], indent=2))
使用的查询: “Do you have any sales on laptops for students?”
注意: 示例中显示的价格为近似值。有关详细定价,请参阅官方 AWS 文档。
希望本指南对你有所帮助!欢迎使用自己的数据进行实验,让向量存储为你的应用带来魔力。如果有任何问题,请在下方评论区留下。