Amazon Bedrock y Servicios de IA Gestionados
Amazon Bedrock
Bedrock es el servicio de AWS para acceder a Foundation Models sin administrar infraestructura. Ofrece modelos de Anthropic, Meta, Cohere, Stability AI y Amazon.
Invocar Modelos
import boto3
import json
bedrock = boto3.client("bedrock-runtime", region_name="us-east-1")
# Claude via Bedrock
response = bedrock.invoke_model(
modelId="anthropic.claude-sonnet-4-20250514-v1:0",
contentType="application/json",
accept="application/json",
body=json.dumps({
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1024,
"messages": [
{"role": "user", "content": "Explica RAG en 3 oraciones."}
],
"temperature": 0,
}),
)
result = json.loads(response["body"].read())
print(result["content"][0]["text"])
Streaming para Baja Latencia
# invoke_model_with_response_stream reduce TTFB (Time To First Byte)
# retornando tokens progresivamente en lugar de esperar la respuesta completa
response = bedrock.invoke_model_with_response_stream(
modelId="anthropic.claude-sonnet-4-20250514-v1:0",
body=json.dumps({
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 2048,
"messages": [{"role": "user", "content": "Genera un plan de migración"}],
}),
)
# Anthropic API emite estos event types en orden:
# message_start → content_block_start → content_block_delta (×N) →
# content_block_stop → message_delta → message_stop
# Solo content_block_delta contiene texto generado
for event in response["body"]:
chunk = json.loads(event["chunk"]["bytes"])
if chunk["type"] == "content_block_delta":
# end="" evita saltos de línea entre tokens
# flush=True fuerza impresión inmediata (sin buffer)
print(chunk["delta"]["text"], end="", flush=True)
Embeddings con Amazon Titan
response = bedrock.invoke_model(
modelId="amazon.titan-embed-text-v2:0",
body=json.dumps({
"inputText": "Autenticación JWT",
"dimensions": 1024,
"normalize": True,
}),
)
embedding = json.loads(response["body"].read())["embedding"]
# Vector de 1024 dimensiones, listo para indexar
Bedrock Knowledge Bases (RAG Gestionado)
bedrock_agent = boto3.client("bedrock-agent-runtime")
# Query a Knowledge Base (RAG completamente gestionado)
response = bedrock_agent.retrieve_and_generate(
input={"text": "¿Cuál es la política de vacaciones?"},
retrieveAndGenerateConfiguration={
"type": "KNOWLEDGE_BASE",
"knowledgeBaseConfiguration": {
"knowledgeBaseId": "KB-xxxx",
"modelArn": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-sonnet-4-20250514-v1:0",
"retrievalConfiguration": {
"vectorSearchConfiguration": {
"numberOfResults": 5,
}
},
},
},
)
print(response["output"]["text"])
# Incluye citations con fuentes
for citation in response.get("citations", []):
for ref in citation.get("retrievedReferences", []):
print(f" Fuente: {ref['location']['s3Location']['uri']}")
Amazon OpenSearch Serverless (Vector Engine)
from opensearchpy import OpenSearch, RequestsHttpConnection
from requests_aws4auth import AWS4Auth
credentials = boto3.Session().get_credentials()
auth = AWS4Auth(
credentials.access_key,
credentials.secret_key,
"us-east-1",
"aoss",
session_token=credentials.token,
)
client = OpenSearch(
hosts=[{"host": "xxxx.us-east-1.aoss.amazonaws.com", "port": 443}],
http_auth=auth,
use_ssl=True,
connection_class=RequestsHttpConnection,
)
# Crear índice vectorial
index_body = {
"settings": {
"index.knn": True, # Habilita búsqueda KNN (K-Nearest Neighbors) en el índice
},
"mappings": {
"properties": {
"embedding": {
"type": "knn_vector",
"dimension": 1536,
"method": {
# hnsw = Hierarchical Navigable Small World algorithm
# Grafo multicapa para búsqueda aproximada de vecinos cercanos
"name": "hnsw",
# faiss = Facebook AI Similarity Search engine
# Motor optimizado para búsqueda de similitud en vectores densos
"engine": "faiss",
"parameters": {
# m=16: conexiones por nodo (mayor = más preciso pero más RAM)
"m": 16,
# ef_construction=256: tamaño de lista de candidatos durante
# la construcción del índice (mayor = mejor calidad, más lento de indexar)
"ef_construction": 256,
},
},
},
"content": {"type": "text"},
"metadata": {"type": "object"},
}
},
}
client.indices.create("knowledge-base", body=index_body)
# Búsqueda vectorial
results = client.search(
index="knowledge-base",
body={
"size": 5,
"query": {
"knn": {
"embedding": {
"vector": query_embedding,
"k": 5,
}
}
},
},
)
Amazon SageMaker para Custom Models
import sagemaker
from sagemaker.huggingface import HuggingFace
# get_execution_role() obtiene el IAM role asociado a la instancia de SageMaker
# Este role necesita permisos para S3, ECR, CloudWatch, etc.
role = sagemaker.get_execution_role()
# Fine-tuning de un modelo custom
huggingface_estimator = HuggingFace(
entry_point="train.py",
source_dir="./training",
# ml.g5.2xlarge para training: GPU A10G (24GB VRAM) — suficiente para LoRA fine-tuning
instance_type="ml.g5.2xlarge",
instance_count=1,
role=role,
transformers_version="4.37.0",
pytorch_version="2.1.0",
py_version="py310",
hyperparameters={
"model_name": "meta-llama/Llama-4-Scout-17B-16E",
"epochs": 3,
"learning_rate": 2e-5,
# lora_r=16: rango de las matrices LoRA (Low-Rank Adaptation)
# Mayor rango = más parámetros entrenables = más expresividad pero más VRAM
# Valores comunes: 8, 16, 32. 16 es buen balance costo/calidad
"lora_r": 16,
},
)
# .fit() ejecuta el flujo completo de training:
# 1. Provisiona instancia GPU (ml.g5.2xlarge)
# 2. Descarga datos desde S3
# 3. Ejecuta train.py con los hyperparameters
# 4. Sube modelo entrenado a S3 al finalizar
# 5. Termina la instancia (solo pagas por tiempo de uso)
huggingface_estimator.fit({"train": "s3://bucket/train", "test": "s3://bucket/test"})
# .deploy() crea un endpoint HTTP persistente (24/7) para inferencia
# Usa instance type más pequeño que training: inferencia requiere menos VRAM
predictor = huggingface_estimator.deploy(
initial_instance_count=1,
instance_type="ml.g5.xlarge", # GPU más pequeña para inferencia (deploy ≠ train)
endpoint_name="custom-llm-endpoint",
)
Arquitectura de Referencia: RAG en AWS
┌──────────────────────────────────────────────────────────────┐
│ RAG Architecture on AWS │
│ │
│ S3 (Documents) ──► Lambda (Processor) ──► Bedrock (Embed) │
│ │ │ │
│ │ ▼ │
│ │ OpenSearch Serverless │
│ │ (Vector Store) │
│ │ │ │
│ API Gateway ──► Lambda/ECS (API) ──► Bedrock (Claude) │
│ │ │ │ │
│ │ ├── OpenSearch (Retrieve) │
│ │ ├── DynamoDB (Session/Cache) │
│ │ └── CloudWatch (Logs + Metrics) │
│ │ │
│ CloudFront ──► S3 (Frontend SPA) │
└──────────────────────────────────────────────────────────────┘
Servicios Complementarios
| Servicio | Uso en AI Engineering |
|---|---|
| Lambda | APIs serverless, procesamiento de documentos |
| ECS/Fargate | Servicios con estado, streaming, websockets |
| SQS/SNS | Colas de procesamiento async |
| Step Functions | Orquestación de pipelines de indexación |
| DynamoDB | Cache de sesiones, metadata, rate limiting |
| ElastiCache | Cache de embeddings, respuestas |
| CloudWatch | Métricas, logs, alarmas |
| X-Ray | Tracing distribuido |
Resumen
AWS proporciona una plataforma completa para IA generativa:
- Bedrock — Acceso a Foundation Models sin infraestructura
- Knowledge Bases — RAG gestionado con S3 + OpenSearch
- OpenSearch Serverless — Vector DB escalable
- SageMaker — Fine-tuning y deploy de modelos custom
- Serverless stack — Lambda, API Gateway, DynamoDB para APIs
🧠 Preguntas de Repaso
1. En Amazon Bedrock con streaming, ¿qué tipo de evento contiene el texto generado?
- A) message_start
- B) content_block_start
- C) content_block_delta — es el único que contiene texto generado
- D) message_stop
Respuesta: C) — El orden de eventos es: message_start → content_block_start → content_block_delta (×N) → content_block_stop → message_delta → message_stop. Solo los eventos
content_block_deltacontienen el texto generado progresivamente.
2. ¿Qué parámetros HNSW se configuran en OpenSearch Serverless para un índice vectorial?
- A)
k=10ydistance=cosine - B)
m=16(conexiones por nodo) yef_construction=256(candidatos al construir), con motor FAISS - C)
dimensions=1024ynormalize=true - D)
max_tokens=8000yoverlap=200
Respuesta: B) — OpenSearch Serverless usa el algoritmo HNSW con motor FAISS.
m=16controla las conexiones por nodo (más = más preciso pero más RAM) yef_construction=256controla los candidatos durante la construcción del índice.
3. Para fine-tuning con LoRA en SageMaker, ¿qué instance se recomienda para modelos de 7B-13B parámetros?
- A) ml.m5.xlarge (CPU general)
- B) ml.g5.2xlarge (GPU A10G, 24GB VRAM)
- C) ml.p4d.24xlarge (8× A100)
- D) ml.t3.medium (burstable)
Respuesta: B) — La ml.g5.2xlarge con GPU A10G (24GB VRAM) es la recomendada para LoRA fine-tuning de modelos 7B-13B. Los 24GB de VRAM son suficientes para LoRA (que entrena solo ~0.06% de parámetros). Las p4d son para modelos mayores (30B-70B).
4. ¿Qué ventaja ofrece Bedrock Knowledge Bases sobre implementar RAG manualmente?
- A) Es más barato que cualquier otra solución
- B) Proporciona RAG gestionado con indexación automática de S3, retrieval integrado y citations con fuentes incluidas
- C) Permite usar modelos custom no disponibles en Bedrock
- D) Es más rápido que implementaciones custom con LangChain
Respuesta: B) — Bedrock Knowledge Bases ofrece RAG "gestionado" donde AWS maneja la indexación de documentos desde S3, el retrieval con OpenSearch, y la generación. Además incluye citations automáticas con referencia a las fuentes originales en S3.