🏢 LegalFlowAI ☁️ AWS Bedrock 🇪🇺 eu-west-1 (Irlanda) ⚡ Nivel Avanzado

AWS Bedrock Integration Guide

Integración enterprise de modelos de IA en AWS para LegalFlowAI — SaaS B2B de automatización legal con cumplimiento RGPD.

Modelo principal Claude 3.5 Sonnet v2
Region eu-west-1
Presupuesto < 500 €/mes
Casos de uso RAG + Streaming + Guardrails
Generado por CULTIVA IA · Jun 2026
🏗️
Arquitectura de Integración
LegalFlowAI → AWS Bedrock (eu-west-1)
Flujo de datos — dentro de AWS eu-west-1
⚖️
LegalFlowAI
App Python/FastAPI
🔐
IAM Role
Permisos mínimos
☁️
Bedrock
Claude 3.5 Sonnet
🛡️
Guardrails
PII + Off-topic
📋
CloudWatch
Logs + métricas
Cumplimiento RGPD Toda la inferencia ocurre en eu-west-1 (Irlanda). Los datos de los contratos nunca salen de la región AWS. AWS firma el DPA (Data Processing Addendum) requerido bajo RGPD.
⚙️
1. Setup y Credenciales IAM
Instalación, configuración y política IAM mínima para LegalFlowAI
⚠️
Paso obligatorio previo Habilitar modelos en la consola AWS: Bedrock → Model Access → Habilitar "Claude 3.5 Sonnet v2" en eu-west-1 antes de ejecutar cualquier código.
bash — instalación
# Instalar dependencias
pip install boto3

# Configurar credenciales AWS (dev local)
aws configure
# AWS Access Key ID: AKIAIOSFODNN7LEGALAI
# AWS Secret Access Key: xxxxxxxxxxxxxxxx
# Default region: eu-west-1
# Output format: json

# En producción (EC2/ECS): usar IAM Role adjunto, NO credenciales estáticas
# Variables de entorno para CI/CD:
export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7LEGALAI"
export AWS_SECRET_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxx"
export AWS_DEFAULT_REGION="eu-west-1"
json — iam policy (legalflowai-bedrock)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      // Permisos mínimos: solo modelos aprobados en eu-west-1
      "Effect": "Allow",
      "Action": [
        "bedrock:Converse",
        "bedrock:ConverseStream"
      ],
      "Resource": [
        "arn:aws:bedrock:eu-west-1::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0"
      ]
    },
    {
      // Permiso para Knowledge Bases de jurisprudencia
      "Effect": "Allow",
      "Action": [
        "bedrock:RetrieveAndGenerate",
        "bedrock:Retrieve"
      ],
      "Resource": [
        "arn:aws:bedrock:eu-west-1:123456789012:knowledge-base/KBJURISPRUDENCIA"
      ]
    }
  ]
}
🤖
2. Modelos Disponibles en Bedrock
Selección recomendada para casos de uso legal
Model ID Proveedor Mejor para Estado
anthropic.claude-3-5-sonnet-20241022-v2:0 Anthropic Análisis contratos, drafting, RAG ✓ En uso
anthropic.claude-3-5-haiku-20241022-v1:0 Anthropic Clasificación rápida, resúmenes simples Alternativa rápida
anthropic.claude-3-opus-20240229-v1:0 Anthropic Análisis legal complejo, razonamiento Máxima calidad
cohere.command-r-plus-v1:0 Cohere RAG alternativo, multilingüe RAG
meta.llama3-70b-instruct-v1:0 Meta Procesamiento en volumen (open-weight) Open-weight
ℹ️
Nota región En eu-west-1 no todos los modelos están disponibles. Verificar disponibilidad en la consola AWS antes de habilitarlos. Claude 3.5 Sonnet v2 está disponible en eu-west-1.
💬
3. Converse API — Análisis de Contratos
Caso de uso real: extraer cláusulas clave de contratos de arrendamiento
python — analizar_contrato.py
import boto3
from typing import Optional

# Cliente Bedrock en eu-west-1 (cumplimiento RGPD)
bedrock = boto3.client("bedrock-runtime", region_name="eu-west-1")

SYSTEM_PROMPT = """Eres un asistente legal especializado en derecho español.
Analiza contratos y extrae información clave en formato JSON estructurado.
IMPORTANTE: No reveles datos personales identificables fuera del análisis solicitado.
Responde siempre en español."""

def analizar_contrato(texto_contrato: str, tipo: str = "arrendamiento") -> dict:
    """Extrae cláusulas clave de un contrato usando Claude 3.5 Sonnet."""

    response = bedrock.converse(
        modelId="anthropic.claude-3-5-sonnet-20241022-v2:0",
        messages=[
            {
                "role": "user",
                "content": [{"text": f"""Analiza este contrato de {tipo}:

---
{texto_contrato}
---

Extrae en JSON:
- partes (arrendador, arrendatario)
- duracion (inicio, fin, prorrogas)
- renta (importe, actualizacion_IPC)
- fianza (meses, deposito_comunidad)
- clausulas_especiales (lista)
- riesgos_detectados (lista con descripcion y severidad)"""}]
            }
        ],
        system=[{"text": SYSTEM_PROMPT}],
        inferenceConfig={
            "maxTokens": 2048,
            "temperature": 0.1,  # Baja temp para mayor precisión
        },
        # Guardrail para bloquear PII y contenido fuera de dominio
        guardrailConfig={
            "guardrailIdentifier": "legalflowai-rgpd-guard",
            "guardrailVersion": "1",
            "trace": "enabled",
        },
    )

    texto = response["output"]["message"]["content"][0]["text"]

    # Log de tokens consumidos (para control de costes)
    usage = response["usage"]
    print(ff"Tokens — input: {usage['inputTokens']} | output: {usage['outputTokens']}")
    # Coste aprox: (input * 3€/M) + (output * 15€/M) — Claude 3.5 Sonnet

    return {"analisis": texto, "tokens": usage}

# Ejemplo de uso
resultado = analizar_contrato(contrato_pdf_texto, tipo="arrendamiento comercial")
print(resultado["analisis"])
4. Streaming — Drafting en Tiempo Real
UX fluida para el asistente de redacción de cláusulas legales
python — draft_clausula_stream.py
import boto3
from collections.abc import Generator

bedrock = boto3.client("bedrock-runtime", region_name="eu-west-1")

def draft_clausula_stream(
    tipo_clausula: str,
    contexto: str,
    jurisdiccion: str = "España"
) -> Generator[str, None, None]:
    """
    Genera una cláusula legal en streaming.
    Uso en FastAPI con StreamingResponse para UX en tiempo real.
    """
    response = bedrock.converse_stream(
        modelId="anthropic.claude-3-5-sonnet-20241022-v2:0",
        messages=[{
            "role": "user",
            "content": [{"text": f"""Redacta una cláusula de {tipo_clausula}
para un contrato bajo legislación de {jurisdiccion}.

Contexto del contrato:
{contexto}

Formato: texto legal formal, párrafos numerados, sin ambigüedades."""}]
        }],
        system=[{"text": "Eres abogado especialista en derecho mercantil español."}],
        inferenceConfig={"maxTokens": 1500, "temperature": 0.2},
    )

    # Iterar sobre chunks del stream
    for event in response["stream"]:
        if "contentBlockDelta" in event:
            delta = event["contentBlockDelta"]["delta"]
            if "text" in delta:
                yield delta["text"]

# Ejemplo: integración con FastAPI
from fastapi import FastAPI
from fastapi.responses import StreamingResponse

app = FastAPI()

@app.post("/draft/clausula")
async def draft_endpoint(tipo: str, contexto: str):
    return StreamingResponse(
        draft_clausula_stream(tipo, contexto),
        media_type="text/event-stream"
    )
📚
5. RAG — Base de Jurisprudencia
Knowledge Base Bedrock con jurisprudencia española (OpenSearch Serverless)
ℹ️
Setup Knowledge Base Crear la KB en la consola AWS: Bedrock → Knowledge Bases → Create. Fuente de datos: bucket S3 s3://legalflowai-jurisprudencia-eu/. Embeddings: Amazon Titan Embeddings v2. Vector store: OpenSearch Serverless (gestionado por Bedrock).
python — consulta_jurisprudencia_rag.py
import boto3

bedrock_agent = boto3.client(
    "bedrock-agent-runtime",
    region_name="eu-west-1"
)

KB_ID = "KBJURISPRUDENCIA"  # Obtenido al crear la Knowledge Base
MODEL_ARN = (
    "arn:aws:bedrock:eu-west-1::foundation-model/"
    "anthropic.claude-3-5-sonnet-20241022-v2:0"
)

def consultar_jurisprudencia(pregunta: str) -> dict:
    """
    RAG sobre la base de jurisprudencia española.
    Devuelve respuesta fundamentada + fuentes citadas.
    """

    # Opción 1: Retrieve & Generate (respuesta completa)
    response = bedrock_agent.retrieve_and_generate(
        input={"text": pregunta},
        retrieveAndGenerateConfiguration={
            "type": "KNOWLEDGE_BASE",
            "knowledgeBaseConfiguration": {
                "knowledgeBaseId": KB_ID,
                "modelArn": MODEL_ARN,
                "retrievalConfiguration": {
                    "vectorSearchConfiguration": {
                        "numberOfResults": 5  # Top 5 sentencias relevantes
                    }
                },
                "generationConfiguration": {
                    "promptTemplate": {
                        "textPromptTemplate": """Eres un asistente legal experto.
Responde basándote SOLO en la jurisprudencia proporcionada.
Si no encuentras respuesta en los documentos, indícalo explícitamente.
Cita siempre el número de sentencia y tribunal.

Documentos: $search_results$
Pregunta: $query$"""
                    }
                }
            },
        },
    )

    respuesta = response["output"]["text"]

    # Extraer fuentes citadas
    citations = response.get("citations", [])
    fuentes = [
        c["retrievedReferences"][0]["location"]["s3Location"]["uri"]
        for c in citations
        if c.get("retrievedReferences")
    ]

    return {"respuesta": respuesta, "fuentes": fuentes}

# Uso
resultado = consultar_jurisprudencia(
    "¿Cuál es el plazo de preaviso en arrendamientos comerciales en España?"
)
print(resultado["respuesta"])
print("Fuentes:", resultado["fuentes"])
🛡️
6. Guardrails — Cumplimiento RGPD
Guardrail configurado para bloquear PII y consultas fuera del dominio legal
⚠️
Crear Guardrail en consola AWS Bedrock → Guardrails → Create → Configurar los filtros de contenido, PII y denied topics (ver código de configuración abajo).
python — crear_guardrail_rgpd.py
import boto3

bedrock_mgmt = boto3.client("bedrock", region_name="eu-west-1")

# Crear guardrail para LegalFlowAI
guardrail = bedrock_mgmt.create_guardrail(
    name="legalflowai-rgpd-guard",
    description="Guardrail RGPD para LegalFlowAI — bloquea PII y off-topic",

    # Bloquear temas NO relacionados con derecho
    topicPolicyConfig={
        "topicsConfig": [
            {
                "name": "off-topic-no-legal",
                "definition": "Consultas no relacionadas con derecho, contratos, o legislación",
                "examples": ["¿Cuál es la capital de Francia?", "Escribe un poema"],
                "type": "DENY",
            }
        ]
    },

    # Detectar y enmascarar PII (RGPD)
    sensitiveInformationPolicyConfig={
        "piiEntitiesConfig": [
            {"type": "SPAIN_NIE", "action": "ANONYMIZE"},
            {"type": "SPAIN_NIF", "action": "ANONYMIZE"},
            {"type": "EMAIL", "action": "ANONYMIZE"},
            {"type": "PHONE", "action": "ANONYMIZE"},
            {"type": "NAME", "action": "ANONYMIZE"},
        ]
    },

    # Mensajes de bloqueo en español
    blockedInputMessaging="Consulta no permitida. LegalFlowAI responde solo a preguntas sobre derecho y contratos.",
    blockedOutputsMessaging="La respuesta contenía información sensible y ha sido bloqueada por cumplimiento RGPD.",
)

guardrail_id = guardrail["guardrailId"]
print(ff"Guardrail creado: {guardrail_id}")

# Publicar versión estable
bedrock_mgmt.create_guardrail_version(guardrailIdentifier=guardrail_id)
print("Guardrail v1 publicado.")
💡
7. Best Practices para LegalFlowAI
Recomendaciones operacionales y de costes
🌍
Residencia de datos Usar siempre eu-west-1 (Irlanda). AWS garantiza que los datos no salen de la región. Nunca usar regiones US para datos de clientes europeos.
Streaming siempre en UI Usar converse_stream para todas las interfaces de usuario. Reduce la latencia percibida de 8s a ~1s primer token. Clave para el asistente de drafting.
💰
Control de costes Loguear inputTokens y outputTokens en CloudWatch. Usar Haiku para clasificación inicial (10x más barato) y Sonnet solo para análisis profundo.
🔒
IAM mínimo Nunca usar credenciales de usuario root. IAM Role con permisos solo para los modelos específicos y la KB de jurisprudencia. Rotar claves trimestralmente.
📊
Monitorización Habilitar CloudWatch Logs para todas las llamadas a Bedrock. Configurar alarmas en: latencia P95 > 5s, tasa de bloqueo guardrail > 5%, coste diario > 20€.
🔄
Fallback cross-region Usar inference profiles para fallback automático a eu-central-1 (Frankfurt) si eu-west-1 no tiene capacidad. Transparente para la aplicación.
🧪
Temperatura baja para legal Usar temperature: 0.1 para análisis y extracción de datos. Solo subir a 0.3-0.4 para drafting creativo de cláusulas donde se busca variedad.
📋
Tags para auditoría Etiquetar todas las llamadas con {"Application": "LegalFlowAI", "CostCenter": "AI-Inference"} para desglose de costes por cliente en AWS Cost Explorer.