Extendiendo Mi Blog con Corrección de Texto por Amazon Nova

2025-07-05
This post cover image
#aws
#cloud
#genai
#serverless

Este archivo ha sido traducido automáticamente por IA, pueden ocurrir errores

Bloguear se ha convertido realmente en algo que disfruto hacer a lo largo de los años. A menudo, construyo algo y luego escribo una publicación sobre la solución y lo que aprendí. Más de una vez, ha sido sobre arquitectura sin servidor y basada en eventos. Sin embargo, hay una cosa que no me gusta: como hablante no nativo de inglés, tiendo a cometer errores ortográficos y gramaticales, y aunque corrijo varias veces, siempre se me escapa algo.

Anteriormente he extendido mi blog con generación de voz usando Amazon Polly y aprendizaje gamificado con cuestionarios automatizados.

Esta vez, es momento de una adición más a esto, que también me ayudará y ahorrará tiempo. Ese es un servicio de corrección automatizada usando Amazon Nova.

Mi Problema

Cuando escribo mis publicaciones del blog, me enfoco en la solución y la arquitectura, presentándola y mostrándola de una buena manera. Tengo mucho menos enfoque en la ortografía, aunque sí tengo una extensión de corrección ortográfica instalada en VSCode. Luego, corregir mis publicaciones toma mucho tiempo, y para ser honesto, no siempre soy tan minucioso. Entonces, lo que necesitaba era una solución automatizada que pudiera:

Mantener mi estilo de escritura: No quiero que la corrección cambie mi voz o explicaciones técnicas. Preservar el formato markdown: Mis publicaciones del blog están escritas en markdown con bloques de código, enlaces e imágenes. Integrarse sin problemas: La solución debería encajar en mi solución existente con generación de voz y cuestionarios. Ser rentable: Ejecutarse solo en ciertos Pull-requests, y ser sin servidor y basada en eventos como la solución de voz y cuestionarios.

Presentando Amazon Nova

Amazon Nova son los LLMs propios de Amazon que fueron anunciados en re:Invent 2024. Antes de Nova, había varios modelos Titan, y para ser honesto, Titan no era tan bueno. Nova, por otro lado, es realmente bueno y es una opción buena y rentable. Los modelos Nova están disponibles a través de Amazon Bedrock, como muchos otros modelos, que proporciona una API para acceder a varios modelos de lenguaje grandes.

¿Qué es Amazon Bedrock?

Amazon Bedrock es un servicio completamente administrado que facilita el acceso a muchos modelos fundacionales. Todos están disponibles a través de una sola API y me permite construir grandes soluciones de IA generativa de manera fácil. Bedrock nos ofrece:

Elección de modelos: Acceso a modelos de Amazon, Anthropic, Meta y varios más, con nuevos modelos siendo agregados constantemente. Integración fácil: Sin servidor y administrado, con llamadas API simples sin administrar infraestructura. Capacidades de ajuste fino: Personalizar modelos con tus propios datos. Seguridad y privacidad de datos: Nuestros datos no se usan para entrenar ningún modelo. Agentes de Bedrock: Agentes que pueden ser usados para construir aplicaciones que combinan LLMs y APIs para crear soluciones poderosas.

Modelos de Amazon Nova

Amazon Nova ofrece, en este momento, cuatro modelos diferentes de comprensión/razonamiento, 2 modelos creativos y 1 modelo de voz.

Los modelos de comprensión pueden manejar diferentes entradas como texto, imágenes, video, documentos y código. Todos devuelven la respuesta en texto. Estos modelos son:

  • Nova Micro: Solo texto, baja latencia y respuestas rápidas con bajo costo.
  • Nova Lite: Modelo multimodal de bajo costo que es súper rápido procesando texto, imágenes y video.
  • Nova Pro: Modelo multimodal muy capaz, por un buen precio, que ofrece un gran equilibrio de precisión, velocidad y costo para una amplia gama de tareas.
  • Nova Premier: El modelo multimodal más capaz para tareas complejas, no disponible en muchas regiones.

He seleccionado Nova Pro para mi tarea ya que, para la corrección de publicaciones del blog, proporciona un gran equilibrio de precisión y rentabilidad. Maneja la comprensión del contexto, mantiene el estilo de escritura y hace pequeñas correcciones sin sobre-editar mi contenido.

Los modelos creativos son:

  • Amazon Nova Canvas: Un modelo de generación de imágenes de alta calidad.
  • Amazon Nova Reel: Un modelo de generación de video.

Amazon Nova Canvas y Amazon Nova Reel no están, ahora mismo, disponibles en muchas regiones. Tienes que usar us-east-1 (N. Virginia), eu-west-1 (Irlanda), o ap-northeast-1 (Tokio).

El modelo de voz es:

  • Amazon Nova Sonic: Que entrega conversaciones de voz en tiempo real similares a las humanas.

Amazon Nova Sonic está, ahora mismo, disponible en us-east-1 (N. Virginia), eu-north-1 (Estocolmo), y ap-northeast-1 (Tokio) y soporta inglés (US, UK) y español.

No tener modelos disponibles en todas las regiones o incluso las mismas regiones puede convertirse en un problema al construir nuestras aplicaciones.

Inferencia Inter-Regional

Una cosa que necesitamos mencionar es la configuración de inferencia inter-regional en Bedrock, que se hace a través de modelos de inferencia. Lo que esto hace es que nuestras llamadas se enrutan automáticamente a la región con los recursos más disponibles, asegurando que nuestras llamadas puedan ser cumplidas. Cuando usamos los modelos Nova fuera de us-east-1 (N. Virginia) y AWS GovCloud (US-West), necesitamos usar un perfil de inferencia al llamar la API de Bedrock. Si no lo hacemos, seremos golpeados por un error diciendo que el modelo no está disponible en la región de manera sin servidor.

Como ejemplo, si llamamos el eu.amazon.nova-pro-v1:0 desde eu-west-1, donde corre mi solución, nuestra llamada de inferencia se mantendrá dentro de la región EU y la inferencia puede ser hecha desde una de las regiones EU: eu-central-1, eu-north-1, eu-west-1, eu-west-3.

Arquitectura de la Solución

En la publicación aprendizaje gamificado con cuestionarios automatizados, introduzco la arquitectura. Está construida en Amazon EventBridge, dividida en múltiples servicios, y corre como un Patrón Saga.

Imagen mostrando resumen del pipeline actual

Como se explica en la publicación arriba, realizo dos cosas principales: genero el cuestionario para el aprendizaje gamificado y uso Polly para generar voz que lee mi publicación del blog. Esta es una mezcla de acciones de GitHub que construirán la página y subirán a un bucket de staging en S3. Después de que la subida al bucket de staging esté completa, las acciones de GitHub publicarán un evento en un event-bus de EventBridge y aquí es donde mi parte basada en AWS toma el control.

El pipeline de CI/CD basado en AWS es basado en eventos y sin servidor. Los servicios principales usados son StepFunctions, Lambda y EventBridge. El flujo está basado en un patrón saga donde los servicios de dominio entregan publicando eventos de dominio en el event-bus, que moverá la saga al siguiente paso.

Como mi generación de voz se hace desde los archivos HTML renderizados, para mayor precisión, simplemente no podía conectar la corrección como un primer paso en este Patrón Saga. La solución se convirtió en agregar acciones de GitHub en la saga. Un día podría alejarme de las Acciones de GitHub a algo más, pero por ahora, será parte de toda la solución.

Entonces, agregaré la siguiente parte, que ahora corre cuando mi Pull-Request es abierto:

Imagen mostrando resumen del pipeline de corrección

En esta parte, obtengo información de GitHub, y llamo a Amazon Nova a través de Amazon Bedrock para hacer mi corrección. Cuando se completa, el servicio agrega un nuevo commit al PR con el archivo markdown actualizado.

Ejecutando las Partes de Voz y Cuestionario

Ahora, necesito una manera de integrar e iniciar los pasos de Voz y Cuestionario, que antes estaba ejecutando cuando el PR era creado. En su lugar, ahora tengo una Acción de GitHub que detectará el commit de corrección y comenzará ese flujo. Dando una solución con dos partes distintas.

Imagen mostrando el resumen completo del pipeline de corrección

Ahora he creado dos partes distintas en el flujo. Toda la lógica principal está corriendo en AWS y la Acción de GitHub construye el blog de staging e invoca las diferentes partes, enviando diferentes eventos a EventBridge.

Inmersión Técnica Profunda

Hagamos una inmersión técnica profunda en la solución y el servicio real de corrección.

StepFunction

El corazón de todo es un orquestador implementado con StepFunctions. Verificará los archivos, realizará la corrección y creará el nuevo commit.

Imagen mostrando el StepFunction

El trabajo es básicamente llevado a cabo por tres funciones Lambda. La función Lambda central es la que realiza la corrección real. Las funciones que verifican el PR y crean un nuevo commit ambas usan Octokit. Para ver cómo funcionan estas, revisa mis publicaciones anteriores. Me enfocaré en el corrector real.

Función Lambda de Corrección

La función inicializará todo, creará el prompt, y llamará a Nova y Bedrock, y almacenará la versión corregida en S3. La publicación original también se mantiene y el archivo solo se renombra.

import json
import os
import boto3
from botocore.exceptions import ClientError

def handler(event, context):
    print("Received event:", json.dumps(event, indent=2))

    try:
        bucket = event.get("S3Bucket")
        key = event.get("Key")

        if not bucket or not key:
            raise ValueError("Both 'bucket' and 'key' must be provided in the event")

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

        response = s3_client.get_object(Bucket=bucket, Key=key)
        file_content = response["Body"].read().decode("utf-8")

        prompt = f"""You are a professional technical editor and proofreader, expert in AWS and Cloud computing. Please carefully proofread the following markdown blog post for spelling and grammatical errors. 
        Instructions:
        - Fix any spelling mistakes
        - Correct grammatical errors
        - Maintain the original markdown formatting
        - Keep the tone and style consistent
        - Do not change the meaning or structure of the content
        - Return only the corrected markdown text without any additional commentary
        - Do not surround the proofread version with ```markdown

        Here is the markdown content to proofread:
        {file_content}"""

        request_body = {
            "messages": [{"role": "user", "content": [{"text": prompt}]}],
            "inferenceConfig": {
                "temperature": 0.1,
                "topP": 0.9,
                "maxTokens": 10240,
            },
        }

        bedrock_response = bedrock_client.invoke_model(
            modelId="eu.amazon.nova-pro-v1:0",
            body=json.dumps(request_body),
            contentType="application/json",
        )

        response_body = json.loads(bedrock_response["body"].read())
        proofread_content = response_body["output"]["message"]["content"][0]["text"]

        if key.endswith(".md"):
            base_name = key[:-3]
        else:
            base_name = key

        original_backup_key = f"{base_name}-original.md"

        s3_client.copy_object(
            Bucket=bucket,
            CopySource={"Bucket": bucket, "Key": key},
            Key=original_backup_key,
        )

        s3_client.put_object(
            Bucket=bucket,
            Key=key,
            Body=proofread_content.encode("utf-8"),
            ContentType="text/markdown",
        )

        return {
            "statusCode": 200,
            "body": json.dumps(
                {
                    "message": "Proofreading completed successfully",
                    "proofread_file": f"s3://{bucket}/{key}",
                    "backup_file": f"s3://{bucket}/{original_backup_key}",
                    "original_length": len(file_content),
                    "proofread_length": len(proofread_content),
                }
            ),
        }

    except ClientError as e:
        error_code = e.response["Error"]["Code"]
        error_message = e.response["Error"]["Message"]
        print(f"AWS Client Error ({error_code}): {error_message}")

        return {
            "statusCode": 500,
            "body": json.dumps(
                {
                    "error": "AWS Client Error",
                    "error_code": error_code,
                    "message": error_message,
                }
            ),
        }

    except ValueError as e:
        print(f"Validation Error: {str(e)}")
        return {
            "statusCode": 400,
            "body": json.dumps({"error": "Validation Error", "message": str(e)}),
        }

    except Exception as e:
        print(f"Unexpected error: {str(e)}")
        return {
            "statusCode": 500,
            "body": json.dumps({"error": "Internal Server Error", "message": str(e)}),
        }

Ingeniería de Prompts

Una parte importante que no debe ser olvidada es la ingeniería de prompts. El prompt necesita ser claro e incluir instrucciones detalladas sobre cómo debe actuar el LLM. Necesité iterar el prompt varias veces para obtener el resultado que necesitaba. Mi prompt incluye instrucciones específicas para:

  • Corregir errores ortográficos y gramaticales
  • Mantener el formato markdown original
  • Preservar la terminología técnica
  • Mantener el estilo y tono de escritura consistente
  • Devolver solo el contenido corregido sin comentarios

Al final, el siguiente prompt me dio el resultado que quería.

You are a professional technical editor and proofreader, expert in AWS and Cloud computing. Please carefully proofread the following markdown blog post for spelling and grammatical errors. 
Instructions:
- Fix any spelling mistakes
- Correct grammatical errors
- Maintain the original markdown formatting
- Keep the tone and style consistent
- Do not change the meaning or structure of the content
- Return only the corrected markdown text without any additional commentary
- Do not surround the proofread version with ```markdown

Here is the markdown content to proofread:

Iniciando la Parte de Voz y Cuestionario

La segunda parte del flujo, generando voz y cuestionario, corre cuando un nuevo commit con el mensaje de commit "Proofread by Amazon Nova" es agregado al pull-request. La acción inicia cuando el evento synchronize ocurre. La primera parte revisa el commit y obtiene el último mensaje de commit. Los pasos después de eso luego revisarán el mensaje.

name: Start Polly Voice and Quiz Flow

on:
  pull_request:
    types: [synchronize]
    paths:
      - "**/posts/*.md"

jobs:
  check-commit:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./
    outputs:
      message: $NaN
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          ref: $

      - name: Get last commit message
        id: commit-msg
        run: |
          message=$(git log -1 --pretty=format:"%s" HEAD)
          echo "Last commit message: ${message}"
          echo "message=${message}" >> $GITHUB_OUTPUT

  build:
    needs: check-commit
    if: contains(needs.check-commit.outputs.message, 'Proofread by Amazon Nova')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install and Build
        run: |
          npm ci
          npm run build

  deploy:
    needs: build
    runs-on: ubuntu-latest

    permissions:
      id-token: write
      contents: read

    steps:
      - name: Upload build blog to S3
        working-directory: ./
        run: |
          aws s3 sync --delete public/. s3://<My-Staging-Bucket>
          aws events put-events --entries '....'

Conclusión

Extender mi blog con corrección automatizada usando Amazon Nova me ha ahorrado mucho tiempo. Ahora hago una corrección rápida yo mismo, luego delego la parte grande a Amazon Nova. La extensión encaja perfectamente en el diseño basado en eventos que ya tenía en su lugar.

Entonces, con Bedrock y Amazon Nova, junto con un enfoque sin servidor, creé y extendí mi solución que es:

  • Confiable: Calidad de corrección consistente para cada publicación
  • Rentable: Modelo de pago por uso con costos operacionales mínimos

Más importante, la corrección automatizada me permite enfocarme en lo que más disfruto, crear contenido técnico que ayuda a otros a aprender sobre tecnologías de nube.

Hacia adelante, tengo varias otras ideas que mejorarán mi blog usando Amazon Nova e IA. ¡Mantente atento para más soluciones divertidas!

Palabras Finales

No olvides seguirme en LinkedIn y para más contenido, lee el resto de mis Blogs.

¡Como dice Werner! ¡Ahora Ve a Construir!