S3 Vectors 如何工作:AWS 新向量存储的友好指南

发布: (2025年12月7日 GMT+8 18:24)
6 min read
原文: Dev.to

Source: Dev.to

为什么使用向量?

我们都知道 AWS S3 是什么,对吧?它是那种众所周知、便宜且持久的对象存储,已经使用了数十年。当你第一次听到 S3 向量 时,可能会出现几个问题:

  • 什么是向量?
  • 向量只适用于数学家吗?
  • 它们与 AI 有什么关系?
  • 为什么它们带有 S3 前缀?

下面我们将回答这些问题,并展示 S3 向量是如何工作的。

什么是向量存储,为什么在 AI 中需要它?

向量 是一种既有大小(幅度)又有方向的数学对象,通常表示为有序数字列表,例如 ["tell"] = [0, 2, 1, 10, …, 3]
这些数字并非随机,它们编码了语义意义。例如,单词 EspressoLatte 的向量会非常相似,因为它们指的是相似类型的咖啡。

向量数据库

向量数据库(vector DB)专为使用近似最近邻(ANN)算法进行相似性搜索而构建。关系型数据库也能进行相似性搜索,但在大规模时效率不高。

典型工作流:

  1. 你的应用查询向量存储。
  2. 存储返回最近的向量(块)。
  3. 将这些块作为上下文提供给大型语言模型(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为每个向量附加任意标签(例如 regioncategoryaudience)。标签充当元数据,使得搜索可以在纯向量相似度之外进行过滤。AWS 可以自动生成标签,也可以手动设置。

示例:创建和查询向量

下面是一个完整的 Python 示例,演示:

  1. 使用 Amazon Titan embed‑text‑v2 生成嵌入。
  2. 将向量存储在 S3 向量索引中。
  3. 执行语义搜索,可选择按标签过滤。
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 文档。


希望本指南对你有所帮助!欢迎使用自己的数据进行实验,让向量存储为你的应用带来魔力。如果有任何问题,请在下方评论区留下。

Back to Blog

相关文章

阅读更多 »