| A Vector DB is a database that stores data as high-dimensional vectors, enabling efficient similarity searches based on vector embeddings generated by machine learning models. JSON-based Vector DBs offer the benefit of storing both vector embeddings and associated metadata in a single, flexible JSON document, simplifying data management, allowing for more complex filtering and querying based on metadata, and facilitating easier integration with applications that already leverage JSON for data handling. JSON Document Structure{
"id": "doc_001",
"content": "Your main text content here",
"metadata": {
"title": "Document Title",
"source": "source_system",
"created_at": "2025-10-01T16:57:09Z",
"category": "documentation",
"tags": ["api", "bedrock"]
},
"embedding": [0.1, -0.2, 0.3, ...],
"chunk_index": 0,
"parent_doc_id": "original_doc_001"
}
S3 Organization
s3://your-bucket/
├── documents/
│ ├── raw/ # Original documents
│ └── processed/ # Chunked and embedded
├── embeddings/
│ ├── by_date/2025/10/01/
│ └── by_category/api/
└── indexes/
└── vector_index.json
Key Recommendations
Chunking Strategy: • Keep chunks 500-1000 tokens for optimal Bedrock performance • Include overlapping context (50-100 tokens) between chunks • Store chunk relationships via parent_doc_id Embedding Storage: • Use Amazon Titan Embeddings or Cohere for consistency with Bedrock • Store embeddings as arrays in JSON for direct querying • Consider separate embedding files for large datasets Metadata Design: • Include searchable fields (title, category, tags) • Add timestamps for freshness scoring • Store source attribution for citations Multiple files is definitely better for your use case 1) Performance BenefitsSingle JSON Issues: - Must load entire file into memory for any query
- S3 charges for full file download even for partial data
- No parallel processing capability
- Becomes unwieldy as data grows
Multiple Files Advantages: - Load only relevant chunks
- Parallel S3 reads across files
- Incremental updates without reprocessing everything
- Better memory management
2) Recommended Structures3://your-bucket/embeddings/
├── chunk_001.json
├── chunk_002.json
├── chunk_003.json
└── index.json # Metadata index
Individual chunk file:
{
"id": "chunk_001",
"content": "...",
"embedding": [...],
"metadata": {...}
}
Index file:
{
"chunks": [
{"id": "chunk_001", "file": "chunk_001.json", "category": "api"},
{"id": "chunk_002", "file": "chunk_002.json", "category": "docs"}
],
"last_updated": "2025-10-01T16:58:51Z"
}
Query Strategy
1. Read lightweight index file first 2. Filter relevant chunk files based on metadata 3. Load only matching chunk files 4. Perform vector similarity search This approach scales much better and integrates well with your existing Bedrock API - you can add vector search as a preprocessing step before sending context to your completion endpoints. - Start small: Begin with ~100-500 chunks per file, adjust based on your query patterns.
Amazon Bedrock Code Exampleimport boto3
# Create a client
client = boto3.client(service_name="bedrock-runtime")
# Example prompt
prompt = """You are a helpful assistant.
Summarize the following text in 3 bullet points:
"Amazon Bedrock makes it easy to build and scale generative AI applications
using foundation models without needing to manage infrastructure.""""
response = client.invoke_model(
modelId="anthropic.claude-v2", # You can choose different models
body=json.dumps({
"prompt": prompt,
"max_tokens_to_sample": 300,
"temperature": 0.7,
"top_p": 0.9
}),
accept="application/json",
contentType="application/json"
)
# Parse response
output = json.loads(response['body'].read())
print(output["completion"])
Amazon Bedrock with FAISS import boto3
import faiss
import numpy as np
import json
# 1. Initialize Bedrock client
client = boto3.client("bedrock-runtime")
# 2. Create documents (knowledge base)
documents = [
"Amazon Bedrock lets you build generative AI apps with foundation models.",
"FAISS is a library for efficient similarity search and clustering of dense vectors.",
"Retrieval-Augmented Generation (RAG) improves LLMs by grounding answers in external knowledge."
]
# 3. Create embeddings with Amazon Titan Embeddings
def get_embedding(text):
response = client.invoke_model(
modelId="amazon.titan-embed-text-v1",
body=json.dumps({"inputText": text}),
contentType="application/json",
accept="application/json"
)
output = json.loads(response["body"].read())
return np.array(output["embedding"])
embeddings = [get_embedding(doc) for doc in documents]
# 4. Build FAISS index
dim = len(embeddings[0])
index = faiss.IndexFlatL2(dim)
index.add(np.array(embeddings).astype("float32"))
# 5. Query workflow
query = "How can I combine FAISS with Bedrock?"
query_vector = get_embedding(query).astype("float32").reshape(1, -1)
# Find top-k relevant documents
k = 2
distances, indices = index.search(query_vector, k)
retrieved_docs = [documents[i] for i in indices[0]]
context = "\n".join(retrieved_docs)
# 6. Send to Claude for response
prompt = f"""You are an AI assistant.
Answer the question using the context below.
Context:
{context}
Question:
{query}
"""
response = client.invoke_model(
modelId="anthropic.claude-v2",
body=json.dumps({
"prompt": prompt,
"max_tokens_to_sample": 300,
"temperature": 0.7
}),
contentType="application/json",
accept="application/json"
)
output = json.loads(response["body"].read())
print("AI Response:\n", output["completion"])
|