La proliferación de sistemas de IA conversacionales ha introducido una fragmentación arquitectónica común: los datos operacionales residen en bases de datos transaccionales, mientras que los embeddings vectoriales para búsqueda semántica se almacenan en bases de datos vectoriales dedicadas. Esta dualidad genera sobrecarga operativa, costos duplicados y desafíos de sincronización, resultando en posibles inconsistencias entre los datos transaccionales y los índices vectoriales.
La introducción de la búsqueda vectorial nativa en Amazon DynamoDB aborda este problema fundamental al permitir la coexistencia de datos estructurados y embeddings vectoriales en una única tabla. Esto simplifica la arquitectura, reduce la latencia de sincronización y mejora la coherencia de los datos, permitiendo que los agentes de IA accedan a ambos tipos de información a través de una interfaz unificada. La integración con AWS Bedrock Agents y DynamoDB Streams facilita la automatización del ciclo de vida de los embeddings, desde su generación hasta su indexación en tiempo real.
Históricamente, la gestión de datos para diferentes patrones de acceso (transaccional vs. búsqueda semántica) ha requerido soluciones especializadas. La evolución de las bases de datos NoSQL para incorporar capacidades de búsqueda vectorial representa un paso hacia la convergencia de estos patrones, optimizando la infraestructura y el modelo de programación para aplicaciones de IA.
Arquitectura del Sistema
La arquitectura propuesta se centra en un diseño de tabla única en Amazon DynamoDB, que soporta tanto patrones de acceso de clave-valor para datos operacionales como búsqueda de vecinos más cercanos aproximados (ANN) para consultas semánticas. Un agente de AWS Bedrock actúa como orquestador, interpretando las consultas del usuario y enrutando las solicitudes a las funciones de AWS Lambda apropiadas, denominadas 'action groups'.
Los componentes clave incluyen una tabla de DynamoDB configurada con un índice vectorial, que almacena documentos, metadatos y embeddings de 1024 dimensiones. El agente de Bedrock gestiona la conversación, la selección de herramientas y la síntesis de respuestas. Las funciones Lambda de 'action group' ejecutan la API SearchVectors de DynamoDB para búsquedas semánticas y las APIs CRUD estándar de DynamoDB para operaciones transaccionales. Un pipeline de DynamoDB Streams, configurado con StreamViewType a NEW_AND_OLD_IMAGES, dispara una función Lambda de 'embedding pipeline'. Esta Lambda genera automáticamente embeddings utilizando Amazon Titan Text Embeddings V2 para contenido nuevo o modificado y los escribe de vuelta al mismo ítem de DynamoDB, donde el índice vectorial los indexa automáticamente.
La generación de embeddings en el pipeline incluye una guarda para prevenir bucles infinitos, comparando el contenido antiguo y nuevo antes de generar un nuevo embedding. El índice vectorial de DynamoDB requiere el modo de capacidad 'on-demand' y soporta hasta cinco índices por tabla, con un máximo de 4096 dimensiones cada uno. Las consultas SearchVectors requieren un atributo HASH en SearchSchema para particionar los resultados y solo admiten operadores de igualdad. Las respuestas están limitadas a 16 MB y no soportan paginación, lo que implica que TopK debe ser modesto.
Flujo de Consulta Semántica del Agente IA
- 1 Usuario Envía consulta en lenguaje natural
- 2 Agente Bedrock Analiza la solicitud, selecciona herramienta
- 3 Lambda (Action Group) Genera embedding de la consulta (Titan Text Embeddings V2)
- 4 DynamoDB Ejecuta SearchVectors API contra índice vectorial
- 5 Lambda (Action Group) Procesa resultados de búsqueda
- 6 Agente Bedrock Sintetiza respuesta y la envía al usuario
Flujo de Sincronización de Embeddings
- 1 Aplicación Escribe/Modifica contenido en DynamoDB
- 2 DynamoDB Streams Captura el cambio (INSERT/MODIFY)
- 3 Lambda (Embedding Pipeline) Activada por Streams, compara contenido (OldImage/NewImage)
- 4 Amazon Titan Text Embeddings V2 Genera embedding para el contenido modificado
- 5 DynamoDB Actualiza el mismo ítem con el nuevo embedding
- 6 DynamoDB Vector Index Indexa automáticamente el nuevo embedding
| Capa | Tecnología | Justificación |
|---|---|---|
| storage | Amazon DynamoDB | Base de datos NoSQL para datos operacionales y almacenamiento de embeddings vectoriales con búsqueda nativa. vs DynamoDB + Base de datos vectorial separada (ej. Pinecone, Weaviate), DynamoDB + Amazon OpenSearch Service (para búsqueda vectorial) Single-table design, vector index, on-demand capacity mode, StreamViewType=NEW_AND_OLD_IMAGES |
| compute | AWS Lambda | Funciones serverless para 'action groups' de agentes IA y para el pipeline de generación de embeddings. vs AWS Fargate, Amazon EC2 Python 3.12+, ReportBatchItemFailures, Dead-Letter Queues (SQS) |
| data-processing | Amazon Titan Text Embeddings V2 | Modelo de IA para generar embeddings vectoriales a partir de texto. vs Otros modelos de embeddings de Bedrock, Modelos de embeddings auto-hosteados Modelo 'amazon.titan-embed-text-v2:0' |
| orchestration | Amazon Bedrock Agents | Orquestación de agentes de IA, selección de herramientas y síntesis de respuestas. vs Implementación manual de lógica de orquestación (ej. LangChain), Otros frameworks de agentes de IA Integración con modelos Anthropic Claude o Amazon Nova |
| messaging | Amazon DynamoDB Streams | Captura de cambios en tiempo real para disparar el pipeline de generación de embeddings. vs Polling de la tabla DynamoDB, AWS EventBridge StreamViewType=NEW_AND_OLD_IMAGES |
Trade-offs
Ganancias
- ▲ Reducción de complejidad de infraestructura
- ▲ Menor costo operativo
- ▲ Sincronización de datos en tiempo real
- ▲ Consistencia de datos entre operacionales y vectoriales
Costes
- △ Restricciones en la flexibilidad de consulta de búsqueda vectorial (solo igualdad, sin paginación)
- △ Límites en el tamaño de respuesta (16 MB) y TopK (100 ítems)
- △ Dependencia de DynamoDB como almacén primario
def generate_embedding(text):
response = bedrock_runtime.invoke_model(
body=json.dumps({"inputText": text}),
modelId="amazon.titan-embed-text-v2:0",
accept="application/json",
contentType="application/json"
)
response_body = json.loads(response.get("body").read())
return response_body.get("embedding")def lambda_handler(event, context):
for record in event['Records']:
if record['eventName'] == 'INSERT' or record['eventName'] == 'MODIFY':
new_image = record['dynamodb'].get('NewImage', {})
old_image = record['dynamodb'].get('OldImage', {})
new_content = new_image.get('content', {}).get('S')
old_content = old_image.get('content', {}).get('S')
if new_content and (new_content != old_content or 'embedding' not in new_image):
# Generate embedding and write back
pass # Actual logic omitted for brevityFundamentos Teóricos
La búsqueda de vecinos más cercanos (Nearest Neighbor Search, NNS) y su variante aproximada (Approximate Nearest Neighbor, ANN) son problemas fundamentales en la ciencia de la computación y la recuperación de información. Algoritmos como Locality-Sensitive Hashing (LSH), árboles KD o, más recientemente, estructuras basadas en grafos como Hierarchical Navigable Small Worlds (HNSW), buscan optimizar la recuperación de ítems similares en espacios de alta dimensión.
La capacidad de DynamoDB para realizar búsqueda vectorial nativa se alinea con la investigación en bases de datos que exploran la integración de capacidades de búsqueda semántica directamente en los motores de almacenamiento transaccional. Esto refleja una tendencia a reducir la complejidad de la arquitectura de datos, un concepto que se ha explorado en la literatura académica sobre bases de datos políglotas y la convergencia de modelos de datos. La gestión de la consistencia entre los datos operacionales y los índices secundarios (como los índices vectoriales) es un desafío conocido, abordado aquí mediante un patrón de Change Data Capture (CDC) a través de DynamoDB Streams, un concepto que tiene raíces en sistemas de replicación de bases de datos y Data Warehousing.