S3 Vectors Basics
This page takes you from an empty account to a working similarity search: create a vector bucket, create an index, turn text into an embedding, write it, and query it back - in both boto3 and the AWS SDK v3.
Busca en todas las páginas de la documentación
This page takes you from an empty account to a working similarity search: create a vector bucket, create an index, turn text into an embedding, write it, and query it back - in both boto3 and the AWS SDK v3.
S3 Vectors uses its own client (s3vectors), separate from the normal s3 client. The embedding step uses Amazon Bedrock, whose invoke_model API is stable and shown here with confidence. The S3 Vectors calls themselves are a new 2026 surface, so where a name might still move, there is a short verify-at-build-time note.
pip install boto3 (boto3 1.43.x, Python 3.10+). TypeScript: npm install @aws-sdk/client-s3vectors @aws-sdk/client-bedrock-runtime (Node.js 18+).aws configure, environment variables, or an IAM role - the SDK resolves them automatically.s3vectors:* on your bucket/index and bedrock:InvokeModel for the embedding model.amazon.titan-embed-text-v2:0 in your region.# --- Python (boto3) ---
pip install boto3// --- TypeScript (AWS SDK v3) ---
npm install @aws-sdk/client-s3vectors @aws-sdk/client-bedrock-runtimeA vector bucket is a distinct bucket type. It holds vector indexes rather than ordinary objects, so you create it with the s3vectors client, not s3.
# --- Python (boto3) ---
import boto3
sv = boto3.client("s3vectors")
resp = sv.create_vector_bucket(vectorBucketName="my-vectors")
print(resp.get("vectorBucketArn"))
# Verify exact operation/parameter names against current boto3 docs (2026 API surface).// --- TypeScript (AWS SDK v3) ---
import { S3VectorsClient, CreateVectorBucketCommand } from "@aws-sdk/client-s3vectors";
const sv = new S3VectorsClient({});
const resp = await sv.send(new CreateVectorBucketCommand({ vectorBucketName: "my-vectors" }));
console.log(resp.vectorBucketArn);
// Verify exact operation/parameter names against current @aws-sdk/client-s3vectors docs (2026 API surface).s3vectors / S3VectorsClient - a separate service from s3.AES256) encryption; pass encryptionConfiguration for SSE-KMS.An index fixes two things you cannot change later: the dimension (vector length) and the distance metric. Both must match the embedding model you plan to use.
# --- Python (boto3) ---
import boto3
sv = boto3.client("s3vectors")
sv.create_index(
vectorBucketName="my-vectors",
indexName="docs",
dataType="float32",
dimension=1024, # Titan Text Embeddings v2 default
distanceMetric="cosine", # or "euclidean"
metadataConfiguration={"nonFilterableMetadataKeys": ["raw_text"]},
)
# Verify exact operation/parameter names against current boto3 docs (2026 API surface).// --- TypeScript (AWS SDK v3) ---
import { S3VectorsClient, CreateIndexCommand } from "@aws-sdk/client-s3vectors";
const sv = new S3VectorsClient({});
await sv.send(new CreateIndexCommand({
vectorBucketName: "my-vectors",
indexName: "docs",
dataType: "float32",
dimension: 1024, // Titan Text Embeddings v2 default
distanceMetric: "cosine", // or "euclidean"
metadataConfiguration: { nonFilterableMetadataKeys: ["raw_text"] },
}));
// Verify exact operation/parameter names against current @aws-sdk/client-s3vectors docs (2026 API surface).dimension must equal your embedding length exactly - 1024 for Titan v2, 1536 for many OpenAI-style models.distanceMetric is cosine or euclidean; use what your model recommends (cosine for most text embeddings).nonFilterableMetadataKeys marks large or unused-for-filtering fields (like the source text) so they are stored but not indexed for filtering.Before you can store a vector you need one. Bedrock's invoke_model on amazon.titan-embed-text-v2:0 turns text into a 1024-float embedding. This API is stable.
# --- Python (boto3) ---
import boto3, json
bedrock = boto3.client("bedrock-runtime")
def embed(text: str) -> list[float]:
resp = bedrock.invoke_model(
modelId="amazon.titan-embed-text-v2:0",
body=json.dumps({"inputText": text}),
)
return json.loads(resp["body"].read())["embedding"]
vec = embed("How do I rotate IAM access keys?")
print(len(vec)) # 1024// --- TypeScript (AWS SDK v3) ---
import { BedrockRuntimeClient, InvokeModelCommand } from "@aws-sdk/client-bedrock-runtime";
const bedrock = new BedrockRuntimeClient({});
async function embed(text: string): Promise<number[]> {
const resp = await bedrock.send(new InvokeModelCommand({
modelId: "amazon.titan-embed-text-v2:0",
body: JSON.stringify({ inputText: text }),
}));
return JSON.parse(new TextDecoder().decode(resp.body)).embedding;
}
const vec = await embed("How do I rotate IAM access keys?");
console.log(vec.length); // 1024amazon.titan-embed-text-v2:0 returns a 1024-dimension vector by default.inputText field; the response body is a stream you decode then parse.embedding array is your float32 data - its length must equal the index dimension.cosine.put_vectors takes a list, so a single call can write one vector or a batch. Each entry has a unique key, the float data, and optional metadata.
# --- Python (boto3) ---
import boto3
sv = boto3.client("s3vectors")
text = "Rotate access keys every 90 days and delete unused ones."
sv.put_vectors(
vectorBucketName="my-vectors",
indexName="docs",
vectors=[{
"key": "iam-key-rotation",
"data": {"float32": embed(text)}, # embed() from example 3
"metadata": {"topic": "iam", "raw_text": text},
}],
)
# Verify exact operation/parameter names against current boto3 docs (2026 API surface).// --- TypeScript (AWS SDK v3) ---
import { S3VectorsClient, PutVectorsCommand } from "@aws-sdk/client-s3vectors";
const sv = new S3VectorsClient({});
const text = "Rotate access keys every 90 days and delete unused ones.";
await sv.send(new PutVectorsCommand({
vectorBucketName: "my-vectors",
indexName: "docs",
vectors: [{
key: "iam-key-rotation",
data: { float32: await embed(text) }, // embed() from example 3
metadata: { topic: "iam", raw_text: text },
}],
}));
// Verify exact operation/parameter names against current @aws-sdk/client-s3vectors docs (2026 API surface).key; writing the same key again overwrites that vector (an upsert).data.float32 is the embedding array, and its length must match the index dimension.metadata is a free-form document - keep filterable fields small and mark bulky ones non-filterable at index creation.put_vectors call for throughput - see the batch-loading page.query_vectors embeds nothing for you - you pass an already-computed query vector and ask for the topK closest stored vectors.
# --- Python (boto3) ---
import boto3
sv = boto3.client("s3vectors")
q = embed("what is the policy on old credentials?") # embed() from example 3
res = sv.query_vectors(
vectorBucketName="my-vectors",
indexName="docs",
topK=3,
queryVector={"float32": q},
returnMetadata=True,
returnDistance=True,
)
for hit in res["vectors"]:
print(hit["key"], round(hit.get("distance", 0), 4), hit.get("metadata", {}).get("topic"))
# Verify exact operation/parameter names against current boto3 docs (2026 API surface).// --- TypeScript (AWS SDK v3) ---
import { S3VectorsClient, QueryVectorsCommand } from "@aws-sdk/client-s3vectors";
const sv = new S3VectorsClient({});
const q = await embed("what is the policy on old credentials?");
const res = await sv.send(new QueryVectorsCommand({
vectorBucketName: "my-vectors",
indexName: "docs",
topK: 3,
queryVector: { float32: q },
returnMetadata: true,
returnDistance: true,
}));
for (const hit of res.vectors ?? []) {
console.log(hit.key, hit.distance?.toFixed(4), hit.metadata?.topic);
}
// Verify exact operation/parameter names against current @aws-sdk/client-s3vectors docs (2026 API surface).topK sets how many neighbors come back; the result list is ordered nearest-first.returnMetadata and returnDistance default to off - opt in when you need them (metadata filtering requires s3vectors:GetVectors too).distance means a closer match; how to read it depends on the metric you chose.Related: Vector Indexes & Similarity Search Queries - tuning top-k, metadata filters, and reading distances.
Beyond search, you can fetch or remove specific vectors by their keys with get_vectors and delete_vectors.
# --- Python (boto3) ---
import boto3
sv = boto3.client("s3vectors")
got = sv.get_vectors(
vectorBucketName="my-vectors", indexName="docs",
keys=["iam-key-rotation"], returnMetadata=True,
)
print(got["vectors"][0]["metadata"])
sv.delete_vectors(
vectorBucketName="my-vectors", indexName="docs",
keys=["iam-key-rotation"],
)
# Verify exact operation/parameter names against current boto3 docs (2026 API surface).// --- TypeScript (AWS SDK v3) ---
import { S3VectorsClient, GetVectorsCommand, DeleteVectorsCommand } from "@aws-sdk/client-s3vectors";
const sv = new S3VectorsClient({});
const got = await sv.send(new GetVectorsCommand({
vectorBucketName: "my-vectors", indexName: "docs",
keys: ["iam-key-rotation"], returnMetadata: true,
}));
console.log(got.vectors?.[0]?.metadata);
await sv.send(new DeleteVectorsCommand({
vectorBucketName: "my-vectors", indexName: "docs",
keys: ["iam-key-rotation"],
}));
// Verify exact operation/parameter names against current @aws-sdk/client-s3vectors docs (2026 API surface).get_vectors fetches by exact key - it is a lookup, not a similarity search.delete_vectors removes by key; to replace a vector, just put_vectors the same key again.list_vectors (paginated) to enumerate keys in an index when you do not know them.Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+). Amazon S3 Vectors is a fast-moving 2026 API - verify exact operation and parameter names against current docs.
Revisado por Chris St. John·Última actualización: 23 jul 2026