<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Fernando Silva T</title>
    <description>The latest articles on DEV Community by Fernando Silva T (@fernandosilvot).</description>
    <link>https://dev.to/fernandosilvot</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1774484%2Fc44b2c8a-ceeb-4ac9-8947-bdffe7048292.jpeg</url>
      <title>DEV Community: Fernando Silva T</title>
      <link>https://dev.to/fernandosilvot</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fernandosilvot"/>
    <language>en</language>
    <item>
      <title>Crea tu asistente personal en los Meta Glasses.</title>
      <dc:creator>Fernando Silva T</dc:creator>
      <pubDate>Fri, 27 Feb 2026 22:56:03 +0000</pubDate>
      <link>https://dev.to/aws-espanol/crea-tu-asistente-personal-en-los-meta-glasses-4nen</link>
      <guid>https://dev.to/aws-espanol/crea-tu-asistente-personal-en-los-meta-glasses-4nen</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__1774484"&gt;
    &lt;a href="/fernandosilvot" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&gt;
        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1774484%2Fc44b2c8a-ceeb-4ac9-8947-bdffe7048292.jpeg" alt="fernandosilvot image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/fernandosilvot"&gt;Fernando Silva T&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/fernandosilvot"&gt;AWS Community Builder | Estudiante de Ingeniería Informática en Duoc UC. Apasionado por AWS, desarrollo Full-Stack y proyectos open source. Siempre buscando aprender y colaborar.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;br&gt;
Implementación de un asistente de IA con &lt;strong&gt;entrada de voz y visión&lt;/strong&gt; para lentes inteligentes usando Android, &lt;strong&gt;&lt;a href="https://aws.amazon.com/es/bedrock/" rel="noopener noreferrer"&gt;Amazon Bedrock&lt;/a&gt;&lt;/strong&gt; y &lt;strong&gt;&lt;a href="https://aws.amazon.com/es/blogs/aws/introducing-claude-sonnet-4-5-in-amazon-bedrock-anthropics-most-intelligent-model-best-for-coding-and-complex-agents/" rel="noopener noreferrer"&gt;Claude Sonnet 4.5&lt;/a&gt;&lt;/strong&gt;, sin dependencia de la IA nativa de Meta ni restricciones geográficas.

&lt;p&gt;Este proyecto aborda cuatro problemas técnicos concretos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wake word detection sin librerías externas
&lt;/li&gt;
&lt;li&gt;Conversión de frames del SDK de Meta a formatos compatibles con Bedrock
&lt;/li&gt;
&lt;li&gt;Uso de la Converse API con input multimodal (imagen + texto)
&lt;/li&gt;
&lt;li&gt;Coordinación de flujos asíncronos en Jetpack Compose
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; Kotlin · Jetpack Compose · Meta Wearables DAT SDK · Amazon Bedrock&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Nivel:&lt;/strong&gt; Intermedio&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Repositorio:&lt;/strong&gt; &lt;a href="https://github.com/fernandosilvot/aws-bedrock-meta-glasses" rel="noopener noreferrer"&gt;https://github.com/fernandosilvot/aws-bedrock-meta-glasses&lt;/a&gt;  &lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;Todo comenzó con una conversación casual. &lt;a href="https://dev.to/elizabethfuentes12"&gt;Elizabeth Fuentes&lt;/a&gt; me comentó sobre el &lt;strong&gt;&lt;a href="https://wearables.developer.meta.com/docs/reference/android/dat/0.4" rel="noopener noreferrer"&gt;Meta Wearables DAT SDK&lt;/a&gt;&lt;/strong&gt; — una API que Meta había liberado para desarrolladores que permitía integrar funcionalidades personalizadas a los &lt;strong&gt;Meta Smart Glasses&lt;/strong&gt;, más allá de la IA nativa de Meta.&lt;/p&gt;

&lt;p&gt;La idea me fascinó de inmediato: ¿Y si pudiera conectar estos lentes con &lt;strong&gt;Amazon Bedrock&lt;/strong&gt; y usar &lt;strong&gt;Claude Sonnet 4.5&lt;/strong&gt; en lugar de la IA de Meta? ¿Podría crear un asistente que no solo escuchara, sino que también &lt;strong&gt;viera&lt;/strong&gt; lo que yo veo?&lt;/p&gt;

&lt;p&gt;El resultado es &lt;strong&gt;Meta-Rock&lt;/strong&gt;, un asistente activado por voz que captura el frame actual de la cámara, lo envía junto al texto de la consulta y reproduce la respuesta mediante TTS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbcmckw6sdd8xexmv7yxy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbcmckw6sdd8xexmv7yxy.png" alt="Pantalla Principal"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  El problema y la visión
&lt;/h2&gt;

&lt;p&gt;Los &lt;strong&gt;Meta Ray-Ban Smart Glasses&lt;/strong&gt; vienen con IA integrada de Meta, pero tienen una limitación importante: &lt;strong&gt;solo está disponible en ciertos países&lt;/strong&gt;. En Chile, donde vivo, no puedo acceder a esa funcionalidad nativa.&lt;/p&gt;

&lt;p&gt;Además, incluso si estuviera disponible, quería explorar las posibilidades de integrar modelos de IA más avanzados y personalizables. ¿Qué podría lograr si conectara estos lentes directamente con &lt;strong&gt;Amazon Bedrock&lt;/strong&gt; y &lt;strong&gt;Claude Sonnet 4.5&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Objetivo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Construir un asistente hands-free que combine audio y visión, delegando toda la inferencia a Bedrock.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Arquitectura
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Flujo de datos
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfs6k844cu4s2pa3os97.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfs6k844cu4s2pa3os97.png" alt="Flujo de datos"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pipeline resumido:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wake word → &lt;code&gt;SpeechRecognizer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Captura de frame desde los lentes
&lt;/li&gt;
&lt;li&gt;Conversión I420 → JPEG
&lt;/li&gt;
&lt;li&gt;Request multimodal a Bedrock
&lt;/li&gt;
&lt;li&gt;Respuesta → Text-to-Speech
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Stack tecnológico
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capa&lt;/th&gt;
&lt;th&gt;Tecnología&lt;/th&gt;
&lt;th&gt;Justificación&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;td&gt;Jetpack Compose&lt;/td&gt;
&lt;td&gt;Estado reactivo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voz&lt;/td&gt;
&lt;td&gt;Android SpeechRecognizer&lt;/td&gt;
&lt;td&gt;API nativa&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Video&lt;/td&gt;
&lt;td&gt;Meta Wearables DAT SDK&lt;/td&gt;
&lt;td&gt;Acceso directo a cámara&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IA&lt;/td&gt;
&lt;td&gt;Amazon Bedrock&lt;/td&gt;
&lt;td&gt;Inferencia multimodal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modelo&lt;/td&gt;
&lt;td&gt;Claude Sonnet 4.5&lt;/td&gt;
&lt;td&gt;Razonamiento visual sólido&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Demostración en video
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Meta-Rock en ejecución
&lt;/h3&gt;

&lt;p&gt;El video muestra el flujo completo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Activación por wake word
&lt;/li&gt;
&lt;li&gt;Captura del frame desde los lentes
&lt;/li&gt;
&lt;li&gt;Envío multimodal a Bedrock
&lt;/li&gt;
&lt;li&gt;Respuesta hablada
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📽️ &lt;strong&gt;Video de demostración:&lt;/strong&gt;  &lt;/p&gt;






&lt;h2&gt;
  
  
  Desafíos técnicos y decisiones de diseño
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Wake word detection sin librerías externas
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Decisión:&lt;/strong&gt; usar &lt;code&gt;SpeechRecognizer&lt;/code&gt; en escucha pasiva.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Motivación:&lt;/strong&gt; evitar dependencias comerciales y mantener el stack 100% nativo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trade-offs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Falsos positivos en ambientes ruidosos
&lt;/li&gt;
&lt;li&gt;Mayor consumo de batería
&lt;/li&gt;
&lt;li&gt;Latencia aproximada de 500 ms
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SpeechManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;onWakeWord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;onTranscript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Unit&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;speechRecognizer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SpeechRecognizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSpeechRecognizer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;startPassiveListening&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;intent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Intent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RecognizerIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ACTION_RECOGNIZE_SPEECH&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;putExtra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RecognizerIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;EXTRA_LANGUAGE_MODEL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                    &lt;span class="nc"&gt;RecognizerIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LANGUAGE_MODEL_FREE_FORM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;putExtra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RecognizerIntent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;EXTRA_PARTIAL_RESULTS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;speechRecognizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startListening&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;checkForWakeWord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;normalized&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lowercase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;normalized&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hey friday"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;normalized&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"oye viernes"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;onWakeWord&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Aceptable para prototipo funcional y pruebas reales.&lt;/p&gt;


&lt;h3&gt;
  
  
  2. Envío constante de contexto visual
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Decisión clave:&lt;/strong&gt; enviar siempre el frame de la cámara junto al texto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Motivación técnica:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clasificadores por palabras clave son frágiles
&lt;/li&gt;
&lt;li&gt;Consultas ambiguas requieren visión (“¿y esto?”)
&lt;/li&gt;
&lt;li&gt;El modelo puede ignorar la imagen si no es relevante
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onTranscriptReady&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TAG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Transcript: $transcript"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;frame&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;currentFrameProvider&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Siempre captura el frame&lt;/span&gt;

    &lt;span class="n"&gt;_uiState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NovaState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PROCESSING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="n"&gt;transcript&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="n"&gt;sentWithImage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;processingJob&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;viewModelScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Dispatchers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;systemPrompt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Prompts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;bedrockClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;askWithImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;systemPrompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;bedrockClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;askTextOnly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;systemPrompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Costo:&lt;/strong&gt; mayor consumo de tokens y ancho de banda&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Beneficio:&lt;/strong&gt; lógica simple y UX consistente&lt;/p&gt;


&lt;h3&gt;
  
  
  3. Conversión de formatos de video
&lt;/h3&gt;

&lt;p&gt;El SDK de Meta entrega frames en formato &lt;strong&gt;I420 (YUV)&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Bedrock requiere imágenes codificadas (JPEG).&lt;/p&gt;

&lt;p&gt;Pipeline implementado:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I420 → NV21 → Bitmap → JPEG (85%)&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;i420ToNV21&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i420&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ByteArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;ByteArray&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;frameSize&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;nv21&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ByteArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frameSize&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Copiar Y&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arraycopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nv21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frameSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Intercalar U y V para NV21&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;uvIndex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frameSize&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;uIndex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frameSize&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;vIndex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frameSize&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;frameSize&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="n"&gt;until&lt;/span&gt; &lt;span class="n"&gt;frameSize&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;nv21&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;uvIndex&lt;/span&gt;&lt;span class="p"&gt;++]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i420&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vIndex&lt;/span&gt;&lt;span class="p"&gt;++]&lt;/span&gt;
        &lt;span class="n"&gt;nv21&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;uvIndex&lt;/span&gt;&lt;span class="p"&gt;++]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i420&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;uIndex&lt;/span&gt;&lt;span class="p"&gt;++]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;nv21&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;bitmapToBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bitmap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bitmap&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;ByteArray&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;stream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ByteArrayOutputStream&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;bitmap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Bitmap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CompressFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;JPEG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toByteArray&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El 85% de compresión mantiene legibilidad de texto con menor latencia.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Integración con Bedrock (Converse API)
&lt;/h3&gt;

&lt;p&gt;Se utiliza una única llamada con input multimodal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Texto del usuario
&lt;/li&gt;
&lt;li&gt;Imagen capturada
&lt;/li&gt;
&lt;li&gt;System prompt dependiente del idioma
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BedrockClient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BedrockRuntimeClient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"us-east-1"&lt;/span&gt;
        &lt;span class="n"&gt;credentialsProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StaticCredentialsProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;accessKeyId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;secretAccessKey&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;askWithImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bitmap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;systemPrompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;imageBytes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bitmapToBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;request&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ConverseRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;modelId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"us.anthropic.claude-sonnet-4-5-20250929-v1:0"&lt;/span&gt;
            &lt;span class="n"&gt;system&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SystemContentBlock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;systemPrompt&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nc"&gt;Message&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;role&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ConversationRole&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;
                    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="nc"&gt;ContentBlock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                            &lt;span class="nc"&gt;ImageBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ImageFormat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Jpeg&lt;/span&gt;
                                &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ImageSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imageBytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                            &lt;span class="p"&gt;}&lt;/span&gt;
                        &lt;span class="p"&gt;),&lt;/span&gt;
                        &lt;span class="nc"&gt;ContentBlock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;inferenceConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;maxTokens&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;
                &lt;span class="n"&gt;temperature&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.7F&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;converse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asMessage&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;asText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La inferencia se realiza directamente desde Android usando el SDK oficial de AWS para Kotlin.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Gestión de estado en la UI
&lt;/h3&gt;

&lt;p&gt;Se definen estados explícitos para coordinar audio, video e inferencia:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NovaState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;IDLE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;// Esperando "Hey Viernes"&lt;/span&gt;
    &lt;span class="nc"&gt;LISTENING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// Escuchando pregunta&lt;/span&gt;
    &lt;span class="nc"&gt;PROCESSING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// Enviando a Bedrock&lt;/span&gt;
    &lt;span class="nc"&gt;RESPONDING&lt;/span&gt;      &lt;span class="c1"&gt;// Mostrando/leyendo respuesta&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;NovaUiState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;NovaState&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NovaState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IDLE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sentWithImage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto reduce errores visuales y facilita el debugging.&lt;/p&gt;




&lt;h2&gt;
  
  
  Casos de uso validados
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Identificación visual (objetos, colores, texto)
&lt;/li&gt;
&lt;li&gt;Lectura de pantallas
&lt;/li&gt;
&lt;li&gt;Consultas generales con o sin contexto visual
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El modelo decide dinámicamente si usar la imagen.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resultados
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Latencia end-to-end: 2–3 segundos
&lt;/li&gt;
&lt;li&gt;Precisión wake word: ~95% en ambientes silenciosos
&lt;/li&gt;
&lt;li&gt;Consumo de batería: ~15% por hora
&lt;/li&gt;
&lt;li&gt;Tamaño del APK: 12.4 MB
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Lecciones técnicas
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Optimizar demasiado temprano complica la arquitectura
&lt;/li&gt;
&lt;li&gt;JPEG al 85% es un buen punto de equilibrio
&lt;/li&gt;
&lt;li&gt;Wake word sin SDK dedicado tiene límites claros
&lt;/li&gt;
&lt;li&gt;Claude maneja bien inputs multimodales ruidosos
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Próximos pasos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Clasificador local ligero para decidir envío de imagen
&lt;/li&gt;
&lt;li&gt;Optimización de consumo energético
&lt;/li&gt;
&lt;li&gt;Nuevos flujos de análisis visual continuo
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Construir Meta-Rock fue un desafío técnico fascinante que surgió de una necesidad real: &lt;strong&gt;acceder a funcionalidades de IA en los Meta Ray-Ban que no están disponibles en mi región&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Pero más allá de resolver esa limitación, este proyecto me permitió explorar las posibilidades de integrar wearables con modelos de IA de última generación. ¿Qué más se puede lograr cuando tienes acceso directo a la cámara de unos lentes inteligentes y a modelos como Claude Sonnet 4.5?&lt;/p&gt;

&lt;p&gt;Lo más emocionante es que esto es solo el comienzo. Planeo seguir mejorando Meta-Rock, explorando nuevas funcionalidades y documentando cada avance en futuros blogs. Desde análisis de escenas en tiempo real hasta traducción visual instantánea, las posibilidades son infinitas.&lt;/p&gt;

&lt;p&gt;Este proyecto me enseñó que las limitaciones geográficas o de plataforma no tienen por qué detenerte. Con las herramientas adecuadas (AWS, SDKs abiertos, creatividad), puedes construir soluciones que no solo resuelven tus necesidades, sino que abren puertas a experiencias completamente nuevas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recursos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Repositorio GitHub:&lt;/strong&gt; &lt;a href="https://github.com/fernandosilvot/aws-bedrock-meta-glasses" rel="noopener noreferrer"&gt;aws-bedrock-meta-glasses&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repo original de Meta:&lt;/strong&gt; &lt;a href="https://github.com/facebook/meta-wearables-dat-android/tree/main/samples/CameraAccess" rel="noopener noreferrer"&gt;CameraAccess Sample&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meta Wearables SDK:&lt;/strong&gt; &lt;a href="https://wearables.developer.meta.com/docs/reference/android/dat/0.4" rel="noopener noreferrer"&gt;Documentación oficial&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Bedrock:&lt;/strong&gt; &lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/conversation-inference.html" rel="noopener noreferrer"&gt;Converse API&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Sonnet 4.5:&lt;/strong&gt; &lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html" rel="noopener noreferrer"&gt;Modelo en Bedrock&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Agradecimientos
&lt;/h2&gt;

&lt;p&gt;Este proyecto no hubiera sido posible sin:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://dev.to/elizabethfuentes12"&gt;Elizabeth Fuentes&lt;/a&gt;&lt;/strong&gt; por compartir el descubrimiento del Meta Wearables DAT SDK y motivarme a explorar esta tecnología&lt;/li&gt;
&lt;li&gt;El equipo de &lt;strong&gt;Meta&lt;/strong&gt; por abrir el SDK de los Ray-Ban a la comunidad de desarrolladores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS&lt;/strong&gt; por hacer Bedrock accesible y proporcionar modelos de IA de clase mundial&lt;/li&gt;
&lt;li&gt;La comunidad de &lt;strong&gt;AWS Community Builders&lt;/strong&gt; por el apoyo constante y el intercambio de conocimientos&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;¿Tienes preguntas o ideas para mejorar Meta-Rock?&lt;/strong&gt; Déjalas en los comentarios o contáctame en &lt;a href="https://fernandosilvot.cl" rel="noopener noreferrer"&gt;fernandosilvot.cl&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Made with ❤️ in Chile 🇨🇱&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>android</category>
      <category>meta</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Fernando Silva T</dc:creator>
      <pubDate>Sat, 20 Dec 2025 04:05:32 +0000</pubDate>
      <link>https://dev.to/fernandosilvot/-30k4</link>
      <guid>https://dev.to/fernandosilvot/-30k4</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/aws/build-agentic-video-analysis-with-twelvelabs-pegasus-and-strands-agents-sdk-5a0m" class="crayons-story__hidden-navigation-link"&gt;Build Agentic Video Analysis with TwelveLabs Pegasus in minutes&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;
          &lt;a class="crayons-logo crayons-logo--l" href="/aws"&gt;
            &lt;img alt="AWS logo" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F1726%2F2a73f1e6-7995-4348-ae37-44b064274c59.png" class="crayons-logo__image"&gt;
          &lt;/a&gt;

          &lt;a href="/elizabethfuentes12" class="crayons-avatar  crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F717518%2Fb550b165-b8b9-405d-acfb-e5dc846765b0.png" alt="elizabethfuentes12 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/elizabethfuentes12" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Elizabeth Fuentes L
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Elizabeth Fuentes L
                
              
              &lt;div id="story-author-preview-content-3116696" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/elizabethfuentes12" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F717518%2Fb550b165-b8b9-405d-acfb-e5dc846765b0.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Elizabeth Fuentes L&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

            &lt;span&gt;
              &lt;span class="crayons-story__tertiary fw-normal"&gt; for &lt;/span&gt;&lt;a href="/aws" class="crayons-story__secondary fw-medium"&gt;AWS&lt;/a&gt;
            &lt;/span&gt;
          &lt;/div&gt;
          &lt;a href="https://dev.to/aws/build-agentic-video-analysis-with-twelvelabs-pegasus-and-strands-agents-sdk-5a0m" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Dec 20 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/aws/build-agentic-video-analysis-with-twelvelabs-pegasus-and-strands-agents-sdk-5a0m" id="article-link-3116696"&gt;
          Build Agentic Video Analysis with TwelveLabs Pegasus in minutes
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/aws"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;aws&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/python"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;python&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/aws/build-agentic-video-analysis-with-twelvelabs-pegasus-and-strands-agents-sdk-5a0m" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;30&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/aws/build-agentic-video-analysis-with-twelvelabs-pegasus-and-strands-agents-sdk-5a0m#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            7 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>ai</category>
      <category>aws</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Diseño e Implementación de Arquitectura CTF LLaitun: de la Primera Experiencia al Liderazgo Técnico</title>
      <dc:creator>Fernando Silva T</dc:creator>
      <pubDate>Sun, 10 Aug 2025 23:36:16 +0000</pubDate>
      <link>https://dev.to/aws-espanol/diseno-e-implementacion-de-arquitectura-ctf-llaitun-de-la-primera-experiencia-al-liderazgo-tecnico-2bbf</link>
      <guid>https://dev.to/aws-espanol/diseno-e-implementacion-de-arquitectura-ctf-llaitun-de-la-primera-experiencia-al-liderazgo-tecnico-2bbf</guid>
      <description>&lt;p&gt;En este artículo quiero llevarte conmigo en un recorrido que empezó en 2024, cuando era un estudiante curioso que se unió al equipo del &lt;strong&gt;&lt;a href="https://ciberlab.uc.cl/" rel="noopener noreferrer"&gt;Ciberlab&lt;/a&gt;&lt;/strong&gt;, y terminó (por ahora) en 2025, liderando toda la arquitectura AWS del CTF Llaitun. Fueron &lt;strong&gt;195 participantes, 70 equipos, 8 horas continuas&lt;/strong&gt; y un uptime de &lt;strong&gt;99.9%&lt;/strong&gt;, con una arquitectura híbrida que unió la nube y la infraestructura física como si fueran uno solo.&lt;/p&gt;

&lt;p&gt;No es solo tecnología. Es la historia de cómo la mentoría, la perseverancia y el trabajo en equipo pueden cambiar el rumbo de una carrera.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es el CTF Llaitun y en qué se diferencia de otros CTF?
&lt;/h2&gt;

&lt;p&gt;Un &lt;strong&gt;Capture The Flag (CTF)&lt;/strong&gt; es una competencia de ciberseguridad donde los participantes resuelven retos técnicos para obtener &lt;strong&gt;“banderas”&lt;/strong&gt; digitales y sumar puntos.&lt;br&gt;
El &lt;strong&gt;CTF Llaitun&lt;/strong&gt;, organizado por el &lt;strong&gt;Centro de Innovación UC&lt;/strong&gt;, &lt;strong&gt;Ejercito de Chile&lt;/strong&gt; y &lt;strong&gt;Duoc Uc&lt;/strong&gt; en Chile, lleva esta experiencia a otro nivel: combina entornos &lt;strong&gt;virtuales en la nube&lt;/strong&gt; con &lt;strong&gt;infraestructura física real&lt;/strong&gt; para simular ataques y defensas en escenarios de &lt;strong&gt;infraestructura crítica&lt;/strong&gt; como plantas industriales, sistemas SCADA y entornos operativos.&lt;/p&gt;

&lt;p&gt;Mientras que en un CTF tradicional todo sucede en un laboratorio aislado, el &lt;strong&gt;Llaitun&lt;/strong&gt; exige una arquitectura híbrida robusta, capaz de conectar la nube con sistemas On-premise bajo condiciones reales, resistiendo picos de tráfico, ataques constantes y cambios en tiempo real durante la competencia.&lt;/p&gt;
&lt;h2&gt;
  
  
  🎯 De Colaborador a Líder Técnico
&lt;/h2&gt;
&lt;h3&gt;
  
  
  CTF Llaitun 2024: Primeros pasos en un mundo real
&lt;/h3&gt;

&lt;p&gt;Recuerdo entrar al proyecto en 2024 con nervios y emoción. Era mi primer gran evento de ciberseguridad: &lt;strong&gt;aproximante 200 profesionales&lt;/strong&gt;, &lt;strong&gt;80 equipos&lt;/strong&gt;, simuladores, sistemas críticos, y yo, estudiante de segundo año de &lt;strong&gt;Analista Programador Computacional&lt;/strong&gt;, tratando de absorber cada detalle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mi rol&lt;/strong&gt; fue claro: colaborar en el diseño de la arquitectura junto a &lt;a href="https://www.linkedin.com/in/martin-tourneboeuf-713b5696/" rel="noopener noreferrer"&gt;Martin Tourneboeuf&lt;/a&gt;. Pero nada fue sencillo. Nos enfrentamos al reto de &lt;strong&gt;conectar AWS con la infraestructura On-premise del Ejército y del Duoc Uc&lt;/strong&gt;, y la solución terminó siendo &lt;strong&gt;dos VPNs&lt;/strong&gt; que trabajaban en paralelo. Funcionaba, sí, pero con complejidad y riesgos.&lt;/p&gt;

&lt;p&gt;Ese año aprendí que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;La nube no es solo &lt;strong&gt;"Desplegar"&lt;/strong&gt;; es pensar en escalabilidad, resiliencia, en el todo del proyecto y la mejora continua.&lt;/li&gt;
&lt;li&gt;La buena comunicación en el equipo es tan importante como la configuración del entorno.&lt;/li&gt;
&lt;li&gt;La presión real de saber que no debían fallar las conexiones ya que era mi responsabilidad.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbu6r8x2rq8rnwbk34lqi.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbu6r8x2rq8rnwbk34lqi.jpg" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  CTF Llaitun 2025: El salto al liderazgo
&lt;/h3&gt;

&lt;p&gt;Un año después, las cosas eran distintas. Ya en mi tercer año de &lt;strong&gt;Ingeniería en Informática&lt;/strong&gt;, el reto era mío: &lt;strong&gt;diseñar y mantener yo solo toda la arquitectura híbrida&lt;/strong&gt; que daría vida al evento.&lt;/p&gt;

&lt;p&gt;No quise repetir la historia de las dos VPNs. Aposté por algo más arriesgado: una &lt;strong&gt;gateway híbrida única&lt;/strong&gt;. Menos conexiones, menos puntos de falla, más simplicidad. Esto implicó semanas de pruebas, consultas con mentores como &lt;a href="https://www.linkedin.com/in/ysabeltroconisit/" rel="noopener noreferrer"&gt;Ysabel Troconis&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/lizfue/" rel="noopener noreferrer"&gt;Elizabeth Fuentes&lt;/a&gt; y &lt;a href="https://www.linkedin.com/in/maisfloro/" rel="noopener noreferrer"&gt;María Isabel&lt;/a&gt;, y noches de diagramas y simulaciones.&lt;/p&gt;

&lt;p&gt;Fue un proceso muy tenso, volví a sentir la presión del año pasado &lt;strong&gt;"No debía fallar"&lt;/strong&gt;, cada cambio que se realizaban en los desafíos o en los &lt;strong&gt;sistemas SCADA&lt;/strong&gt; los probe para adecuar toda la arquitectura, &lt;strong&gt;estaba muy nervioso&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;El día del evento, vi cómo todo funcionaba sin caídas, con tráfico constante de cientos de participantes. Fue una mezcla de alivio y orgullo que es difícil de describir.&lt;/p&gt;

&lt;p&gt;uno de los comentarios que recibí posteriormente me marco de grata manera:&lt;/p&gt;

&lt;p&gt;💬 "Increíble trabajo, puedo dar fe de lo robusta y eficiente que fue toda la infraestructura..." – &lt;a href="https://www.linkedin.com/feed/update/urn:li:ugcPost:7353994932023365632?commentUrn=urn%3Ali%3Acomment%3A%28ugcPost%3A7353994932023365632%2C7354003582133645312%29&amp;amp;dashCommentUrn=urn%3Ali%3Afsd_comment%3A%287354003582133645312%2Curn%3Ali%3AugcPost%3A7353994932023365632%29" rel="noopener noreferrer"&gt;Fernando Gómez&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyte1ya3sssxys520ugr2.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyte1ya3sssxys520ugr2.webp" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🏛️ Evolución Arquitectónica
&lt;/h2&gt;
&lt;h4&gt;
  
  
  2024: limitaciones y aprendizajes
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Conexiones redundantes y complejas.&lt;/li&gt;
&lt;li&gt;Configuraciones duplicadas.&lt;/li&gt;
&lt;li&gt;Latencia innecesaria.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  2025: simplicidad elegante
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Una sola conexión para todo el tráfico.&lt;/li&gt;
&lt;li&gt;Menos puntos de fallo.&lt;/li&gt;
&lt;li&gt;Mejor rendimiento.&lt;/li&gt;
&lt;li&gt;Gestión centralizada.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sgxgdg0i68fpedkoimo.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sgxgdg0i68fpedkoimo.jpg" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🔧 Desafíos Técnicos Superados
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Antes&lt;/strong&gt;: dos VPNs para dos flujos distintos de comunicación.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Después&lt;/strong&gt;: una arquitectura unificada con failover automático y rutas optimizadas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El proceso incluyó analizar el tráfico del año anterior, optimizar el routing, y hacer pruebas exhaustivas para garantizar que nada fallara bajo presión.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Farz7gmjsf7o5279ihgec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Farz7gmjsf7o5279ihgec.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  👥 El Ecosistema de Apoyo
&lt;/h2&gt;

&lt;p&gt;Nada de esto fue un trabajo en solitario. Detrás hubo personas que creyeron en mí y me guiaron:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mentores&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/martin-tourneboeuf-713b5696/" rel="noopener noreferrer"&gt;Martin Tourneboeuf&lt;/a&gt; (Dreamlab), &lt;a href="https://www.linkedin.com/in/ysabeltroconisit/" rel="noopener noreferrer"&gt;Ysabel Troconis&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/lizfue/" rel="noopener noreferrer"&gt;Elizabeth Fuentes Leone&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/maisfloro/" rel="noopener noreferrer"&gt;María Isabel Florez&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compañeros&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/bruno-alejandro-urrea-ortiz/" rel="noopener noreferrer"&gt;Bruno Urrea&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/sebasti%C3%A1n-porma-campos-874838292/" rel="noopener noreferrer"&gt;Sebastián Porma&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/marcos-sepulveda-bernales-62824b364/" rel="noopener noreferrer"&gt;Marcos Sepúlveda&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/joshua-zavala-z/" rel="noopener noreferrer"&gt;Joshua Zavala&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/pedro-emilio-carrasco-atenas-a6a4b9292/" rel="noopener noreferrer"&gt;Pedro Carrasco&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Duoc Uc&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/viviana-soto-58a106296/" rel="noopener noreferrer"&gt;Viviana Soto&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/cristian-barra-abascal/" rel="noopener noreferrer"&gt;Cristian Barra Abascal&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Centro de Innovación UC&lt;/strong&gt; y &lt;strong&gt;Ejército de Chile&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6ksp7ueciihwbf6oh1s.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi6ksp7ueciihwbf6oh1s.jpg" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  📌 Lecciones Clave
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Planifica antes de ejecutar&lt;/strong&gt;: una buena arquitectura nace en la hoja de papel antes que en la consola.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Menos, es Más&lt;/strong&gt;: reducir la complejidad aumenta la resiliencia.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Escucha a las personas que quieren aportar&lt;/strong&gt;: sus experiencias te ahorran errores costosos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;La presión real es un maestro implacable&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  🚀 Conclusión
&lt;/h2&gt;

&lt;p&gt;El CTF Llaitun fue mucho más que un reto técnico: fue un laboratorio de crecimiento personal. Aprendí que la confianza se gana a base de resultados, que liderar es también saber escuchar, y que las soluciones más elegantes son las que parecen obvias... después de meses de trabajo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Seguimos adelante, construyendo y aprendiendo en cada desafío.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc8ejelme5eb79k2ic089.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc8ejelme5eb79k2ic089.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Links:
&lt;/h4&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/4BxLDpMl7Po"&gt;
  &lt;/iframe&gt;
&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/mZC14lC-DJM"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Integrando Podcasts a Kiu: Cómo Construí un Agente Virtual Serverless con AWS Bedrock y Pinecone</title>
      <dc:creator>Fernando Silva T</dc:creator>
      <pubDate>Fri, 06 Jun 2025 20:53:40 +0000</pubDate>
      <link>https://dev.to/aws-espanol/integrando-podcasts-a-kiu-como-construi-un-agente-virtual-serverless-con-aws-bedrock-y-pinecone-3l6e</link>
      <guid>https://dev.to/aws-espanol/integrando-podcasts-a-kiu-como-construi-un-agente-virtual-serverless-con-aws-bedrock-y-pinecone-3l6e</guid>
      <description>&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;Tuve la oportunidad de unirme al equipo de &lt;a href="https://www.kiu-ai.com/" rel="noopener noreferrer"&gt;Kiu&lt;/a&gt;, un proyecto innovador que permite conocer charlas, meetups y eventos de la comunidad AWS. Descubrí Kiu en el AWS Community Day Chile 2024 y me fascinó desde el primer momento.&lt;/p&gt;

&lt;p&gt;En febrero, &lt;a href="https://www.linkedin.com/in/hazelsaenz/" rel="noopener noreferrer"&gt;Hazel Saenz&lt;/a&gt; me invitó a participar en el equipo. Mi primera tarea fue integrar contenido de podcasts dentro de Kiu, creando un subagente virtual capaz de consultar y procesar esta información para responder preguntas de forma precisa y eficiente.&lt;/p&gt;

&lt;p&gt;En este blog compartiré cómo diseñé y desplegué una infraestructura serverless robusta usando AWS CDK en Python, integrando Pinecone para búsquedas vectoriales y Amazon Bedrock para inteligencia artificial. Además, te contaré los desafíos técnicos que enfrenté y cómo los superé para entregar una solución segura, escalable y automatizada.&lt;/p&gt;




&lt;h2&gt;
  
  
  El problema y el objetivo
&lt;/h2&gt;

&lt;p&gt;Kiu es un agente virtual que responde consultas utilizando inteligencia artificial apoyada en bases de conocimiento actualizadas. Nuestro objetivo era incorporar el mundo de los podcasts para enriquecer la base y mejorar la experiencia del usuario.&lt;/p&gt;

&lt;p&gt;Para esto, necesitábamos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extraer datos de podcasts desde una API externa y limpiarlos.&lt;/li&gt;
&lt;li&gt;Almacenar esta información estructurada en un bucket S3, que funciona como base de conocimiento.&lt;/li&gt;
&lt;li&gt;Usar Pinecone para búsquedas semánticas rápidas y eficientes.&lt;/li&gt;
&lt;li&gt;Que el agente Bedrock acceda a esta base para responder consultas.&lt;/li&gt;
&lt;li&gt;Automatizar la actualización periódica de los datos.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  La solución técnica
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Arquitectura Serverless con AWS CDK y Python
&lt;/h3&gt;

&lt;p&gt;Me recomendaron implementar toda la infraestructura como código usando AWS CDK en Python, lo que facilitó mantener la solución versionada, segura y reproducible.&lt;/p&gt;

&lt;p&gt;Los componentes clave fueron:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://aws.amazon.com/es/s3/" rel="noopener noreferrer"&gt;Amazon S3&lt;/a&gt;&lt;/strong&gt;: Bucket cifrado y versionado para almacenar archivos JSON con la información procesada de los podcasts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://aws.amazon.com/es/lambda/" rel="noopener noreferrer"&gt;AWS Lambda&lt;/a&gt;&lt;/strong&gt;: Función que consulta la API externa, procesa los datos limpiando y normalizando el texto, y actualiza el bucket S3.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://docs.aws.amazon.com/es_es/lambda/latest/dg/chapter-layers.html" rel="noopener noreferrer"&gt;Lambda Layers&lt;/a&gt;&lt;/strong&gt;: Capas que contienen las librerías comunes (&lt;code&gt;requests&lt;/code&gt;, &lt;code&gt;unidecode&lt;/code&gt;) para optimizar despliegues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://aws.amazon.com/es/secrets-manager/" rel="noopener noreferrer"&gt;AWS Secrets Manager&lt;/a&gt;&lt;/strong&gt;: Almacena de forma segura las credenciales de la API externa, como URL y cookies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://aws.amazon.com/es/solutions/implementations/instance-scheduler-on-aws/" rel="noopener noreferrer"&gt;AWS Scheduler&lt;/a&gt;&lt;/strong&gt;: Programa la ejecución semanal automática de la función Lambda para mantener la base actualizada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://aws.amazon.com/es/bedrock/" rel="noopener noreferrer"&gt;Amazon Bedrock&lt;/a&gt;&lt;/strong&gt;: Configura el agente virtual Kiu para consultar la base de conocimiento.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.pinecone.io/" rel="noopener noreferrer"&gt;Pinecone&lt;/a&gt;&lt;/strong&gt;: Base de datos vectorial para búsquedas semánticas con un índice de dimensión 1024.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Flujo de datos
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05tb1zdc8511c5pzv6np.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05tb1zdc8511c5pzv6np.png" alt="Diagrama" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;El Scheduler activa semanalmente la función Lambda.&lt;/li&gt;
&lt;li&gt;Lambda obtiene las credenciales desde Secrets Manager.&lt;/li&gt;
&lt;li&gt;Lambda consulta y procesa los datos de la API externa.&lt;/li&gt;
&lt;li&gt;La información limpia y estructurada se almacena en S3.&lt;/li&gt;
&lt;li&gt;El agente Bedrock utiliza esta base para responder consultas.&lt;/li&gt;
&lt;li&gt;Pinecone facilita búsquedas semánticas rápidas y precisas.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Desafíos y aprendizajes
&lt;/h2&gt;

&lt;p&gt;El proyecto implicó una curva de aprendizaje significativa y varios retos técnicos, que me ayudaron a crecer profesionalmente.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Aprender AWS CDK en Python
&lt;/h3&gt;

&lt;p&gt;Aunque conocía CDK, tuve que aprender a usarlo correctamente en Python para alinearme con el equipo. Aquí un fragmento donde se define el bucket S3 y el secreto para las credenciales:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PodcastKiuStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;construct_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                 &lt;span class="n"&gt;pinecone_api_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pinecone_connection_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="n"&gt;api_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;construct_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;kb_bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PodcastKnowledgeBase&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;versioned&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;encryption&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BucketEncryption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;S3_MANAGED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;removal_policy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;RemovalPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RETAIN&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;api_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secretsmanager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PodcastApiSecret&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;secret_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;podcast-api-credentials&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Credenciales para acceder a la API de podcasts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;generate_secret_string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;secretsmanager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SecretStringGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;secret_string_template&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;API_URL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;api_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;COOKIE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cookie&lt;/span&gt;
                &lt;span class="p"&gt;}),&lt;/span&gt;
                &lt;span class="n"&gt;generate_string_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dummy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Integrar Pinecone con Amazon Bedrock
&lt;/h3&gt;

&lt;p&gt;Fue un reto configurar la knowledge base para usar Pinecone como base vectorial para búsquedas semánticas y configurar los roles necesarios para Bedrock:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;bedrock_agent_role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BedrockAgentRole&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;assumed_by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ServicePrincipal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock.amazonaws.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;kb_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grant_read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bedrock_agent_role&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;knowledge_base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CfnKnowledgeBase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MyKnowledgeBaseKiuPodcast&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;KnowledgeBasePineconeKiuPodcast&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Knowledge base for the podcast content with pinecone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;role_arn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;role_arn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;knowledge_base_configuration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CfnKnowledgeBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;KnowledgeBaseConfigurationProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VECTOR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;vector_knowledge_base_configuration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CfnKnowledgeBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;VectorKnowledgeBaseConfigurationProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;embedding_model_arn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arn:aws:bedrock:us-east-1::foundation-model/amazon.titan-embed-text-v2:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;storage_configuration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CfnKnowledgeBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StorageConfigurationProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PINECONE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;pinecone_configuration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CfnKnowledgeBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PineconeConfigurationProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="n"&gt;connection_string&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pinecone_connection_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;credentials_secret_arn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pinecone_url_secret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secret_arn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;field_mapping&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CfnKnowledgeBase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PineconeFieldMappingProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="n"&gt;text_field&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="n"&gt;metadata_field&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;metafield&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                    &lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Función Lambda para Procesamiento de Datos
&lt;/h3&gt;

&lt;p&gt;Diseñé una función Lambda que consulta la API, procesa los datos limpiando texto con expresiones regulares y &lt;code&gt;unidecode&lt;/code&gt;, y almacena la información en S3:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;secrets_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;secretsmanager&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;secret_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secrets_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_secret_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SecretId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;API_SECRET_ARN&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SecretString&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="n"&gt;api_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;API_URL&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;COOKIE&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Cookie&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;podcasts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;processed_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;podcast&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;podcasts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;clean_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;podcast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;clean_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;podcast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;processed_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;podcast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;podcast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;published_date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;podcast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;published_date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;processed_timestamp&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoked_function_arn&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="n"&gt;s3_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;s3_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;Bucket&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;KB_BUCKET_NAME&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;processed_podcasts.json&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;processed_data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;ContentType&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Seguridad: Roles IAM y Políticas granulares
&lt;/h3&gt;

&lt;p&gt;Configuré roles con permisos mínimos necesarios para Lambda y Bedrock, garantizando la seguridad del sistema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;lambda_role&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PodcastProcessorRole&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;assumed_by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ServicePrincipal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lambda.amazonaws.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;lambda_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_managed_policy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ManagedPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_aws_managed_policy_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;service-role/AWSLambdaBasicExecutionRole&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;lambda_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_to_policy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PolicyStatement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;s3:PutObject&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;s3:GetObject&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;s3:ListBucket&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;kb_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bucket_arn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;kb_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bucket_arn&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;lambda_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_to_policy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PolicyStatement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;secretsmanager:GetSecretValue&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;api_secret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secret_arn&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Pruebas Unitarias para asegurar calidad
&lt;/h3&gt;

&lt;p&gt;Implementé pruebas unitarias que simulan la interacción con Secrets Manager, S3 y la API externa para validar el procesamiento de datos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestLambdaFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;lambda_function.boto3.client&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;lambda_function.requests.get&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_successful_processing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_boto3_client&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;mock_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MagicMock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;mock_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invoked_function_arn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;test-arn&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
        &lt;span class="c1"&gt;# mocks configurados...
&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lambda_function&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="n"&gt;mock_context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;statusCode&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Procesados 1 podcasts&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="n"&gt;mock_s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put_object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assert_called_once&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Emojis en los títulos de los episodios
&lt;/h3&gt;

&lt;p&gt;Durante las pruebas unitarias descubrí un problema curioso: si el título de un pódcast incluía un emoji, los metadatos no se almacenaban correctamente y fallaba el envío a S3. Este detalle, aunque pequeño, tenía un impacto directo en la integridad del flujo de datos. Con la ayuda de &lt;a href="https://www.linkedin.com/in/cmgonzalez89" rel="noopener noreferrer"&gt;Chris Gonzalez&lt;/a&gt;, logramos identificar el origen del error y validamos el manejo de emojis usando la &lt;a href="https://www.unicode.org/emoji/charts/full-emoji-list.html" rel="noopener noreferrer"&gt;tabla oficial de Unicode&lt;/a&gt;. Esta corrección fue clave para asegurar que todos los títulos —emoji incluidos— se procesaran de forma segura y consistente.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Este proyecto ha sido para mí una gran curva de aprendizaje, no solo en términos técnicos, sino también en el trabajo colaborativo. Integrar tecnologías como AWS CDK en Python, Pinecone y Amazon Bedrock me llevó a salir de mi zona de confort y a descubrir nuevas formas de construir soluciones serverless escalables y seguras.&lt;/p&gt;

&lt;p&gt;Además, trabajar en equipo ha sido fundamental. Cada compañero aporta desde distintos frentes, y esa sinergia nos está permitiendo avanzar con velocidad y calidad. Un agradecimiento muy especial a &lt;a href="https://www.linkedin.com/in/hazelsaenz/" rel="noopener noreferrer"&gt;Hazel Saenz&lt;/a&gt;, quien ha sido una guía constante, enseñándome mucho, apoyándome en cada error y alentándome a seguir mejorando. Su paciencia y conocimiento han sido claves para mi crecimiento dentro del proyecto y para la entrega exitosa de esta funcionalidad.&lt;/p&gt;

&lt;p&gt;Estoy emocionado por lo que viene y orgulloso de ser parte de este equipo que está construyendo el futuro de Kiu con tecnologías punteras.&lt;/p&gt;




&lt;h2&gt;
  
  
  Recursos
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/es_es/cdk/v2/guide/work-with-cdk-python.html" rel="noopener noreferrer"&gt;AWS CDK Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_bedrock-readme.html" rel="noopener noreferrer"&gt;Amazon Bedrock CDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.pinecone.io/blog/amazon-bedrock-integration/" rel="noopener noreferrer"&gt;Pinecone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Repositorio GitHub: &lt;em&gt;Próximamente disponible&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Integración IoT y Generative AI: Cómo Crear una App que Cuenta Chistes Basados en la Temperatura</title>
      <dc:creator>Fernando Silva T</dc:creator>
      <pubDate>Mon, 27 Jan 2025 19:01:04 +0000</pubDate>
      <link>https://dev.to/aws-espanol/integracion-iot-y-generative-ai-como-crear-una-app-que-cuenta-chistes-basados-en-la-temperatura-522</link>
      <guid>https://dev.to/aws-espanol/integracion-iot-y-generative-ai-como-crear-una-app-que-cuenta-chistes-basados-en-la-temperatura-522</guid>
      <description>&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;En la era de la tecnología inteligente, combinar el Internet de las Cosas (IoT) con la Inteligencia Artificial Generativa abre un mundo de oportunidades. Imagina una App que, al detectar un aumento en la temperatura, responde presentando un chiste en una pantalla OLED.&lt;/p&gt;

&lt;p&gt;En este tutorial, te guiaremos a través de cada paso para desarrollar esta innovadora App, explorando cómo la integración de sensores de temperatura con algoritmos de IA puede crear interacciones más humanas y entretenidas.&lt;/p&gt;




&lt;h3&gt;
  
  
  Requisitos Previos:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/es/resources/create-account/?sc_channel=el&amp;amp;sc_campaign=datamlwave&amp;amp;sc_content=cicdcfnaws&amp;amp;sc_geo=mult&amp;amp;sc_country=mult&amp;amp;sc_outcome=acq" rel="noopener noreferrer"&gt;Cuenta de AWS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://catalog.us-east-1.prod.workshops.aws/workshops/3d705026-9edc-40e8-b353-bdabb116c89c/en-US" rel="noopener noreferrer"&gt;Conocimientos básicos de Python&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/elizabethfuentes12/iniciando-aws-iot-conectando-nodemcu-con-aws-iot-3f2j"&gt;Arudino Ide y NodeMCU ESP8266 configurados&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Costo para completar:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.amazon.com/-/es/Internet-desarrollo-inal%C3%A1mbrico-funciona-Micropython/dp/B07R4MVSCY/ref=sr_1_6?__mk_es_US=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;amp;dchild=1&amp;amp;keywords=NodeMCU+ESP8266&amp;amp;qid=1600307883&amp;amp;sr=8-6" rel="noopener noreferrer"&gt;NodeMCU ESP8266&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.amazon.com/-/es/unidades-pulgadas-autoluminosa-compatible-Raspberry/dp/B09C5K91H7/ref=sr_1_3?__mk_es_US=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;amp;crid=O25PGQJSO17E&amp;amp;dib=eyJ2IjoiMSJ9.7iH3rOHsk3MI0myNs5qg3Ukd1bSZsnqx8nhATL_WbVaSxl_go--zpgT60oUZRQ9WTZPiUkShz8C3BpYFYV4EmSjrk7ntolGQIw-jKVtBZc4tm-dzX2EzrF14ZS42hQTPa6gx6I_q9HkWexlCBNnvrigwTyP5x-QTIirU5kCLXtV7bmdOCOGSaBtPKEq9q-QbdKf7h3OGfpQxuq6otPMkR9IzOl_Abu_DGVRDQa_Nl98.m8VnCC27WgzQeU3-fo5RUElCA7hJb_E1t7xCNCXZi7I&amp;amp;dib_tag=se&amp;amp;keywords=modulo+oled&amp;amp;qid=1737226266&amp;amp;sprefix=modulo+oled%2Caps%2C486&amp;amp;sr=8-3" rel="noopener noreferrer"&gt;OLED I2C IIC&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.amazon.com/-/es/unidades-pulgadas-autoluminosa-compatible-Raspberry/dp/B09C5K91H7/ref=sr_1_3?__mk_es_US=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;amp;crid=O25PGQJSO17E&amp;amp;dib=eyJ2IjoiMSJ9.7iH3rOHsk3MI0myNs5qg3Ukd1bSZsnqx8nhATL_WbVaSxl_go--zpgT60oUZRQ9WTZPiUkShz8C3BpYFYV4EmSjrk7ntolGQIw-jKVtBZc4tm-dzX2EzrF14ZS42hQTPa6gx6I_q9HkWexlCBNnvrigwTyP5x-QTIirU5kCLXtV7bmdOCOGSaBtPKEq9q-QbdKf7h3OGfpQxuq6otPMkR9IzOl_Abu_DGVRDQa_Nl98.m8VnCC27WgzQeU3-fo5RUElCA7hJb_E1t7xCNCXZi7I&amp;amp;dib_tag=se&amp;amp;keywords=modulo+oled&amp;amp;qid=1737226266&amp;amp;sprefix=modulo+oled%2Caps%2C486&amp;amp;sr=8-3" rel="noopener noreferrer"&gt;AM2302 DHT22&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://aws.amazon.com/es/bedrock/pricing/" rel="noopener noreferrer"&gt;Precios de Amazon Bedrock&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://aws.amazon.com/es/iot-core/pricing/" rel="noopener noreferrer"&gt;Precios de AWS IoT Core&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://aws.amazon.com/es/lambda/pricing/" rel="noopener noreferrer"&gt;Precios de AWS Lambda&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ¿Cómo funciona esta aplicación?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdihdf4vfa92q9bjylpp9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdihdf4vfa92q9bjylpp9.png" alt="Diagrama de la app" width="800" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;El flujo comienza con el NodeMCU ESP8266, que está equipado con el sensor de temperatura AM2302 DHT22 para medir la temperatura ambiente. Estos datos se envían a AWS IoT mediante el protocolo MQTT, publicándose en el tópico &lt;code&gt;esp8266/pub&lt;/code&gt;. &lt;a href="https://aws.amazon.com/es/iot-core/" rel="noopener noreferrer"&gt;AWS IoT Core&lt;/a&gt; evalúa si la temperatura supera el umbral establecido de 30°C. Si es así, se activa una función &lt;a href="https://aws.amazon.com/es/lambda/" rel="noopener noreferrer"&gt;Lambda&lt;/a&gt; que genera un chiste utilizando &lt;a href="https://aws.amazon.com/es/bedrock/" rel="noopener noreferrer"&gt;Amazon Bedrock&lt;/a&gt;. Este chiste se envía de vuelta al ESP8266 a través de MQTT, publicándose en el tópico &lt;code&gt;esp8266/joke&lt;/code&gt;. Finalmente, el ESP8266 recibe el chiste y lo muestra en la pantalla OLED conectada.&lt;/p&gt;

&lt;p&gt;Este flujo permite que la aplicación responda de manera dinámica a los cambios en la temperatura, ofreciendo contenido entretenido y personalizado para ti.&lt;/p&gt;




&lt;h2&gt;
  
  
  Muestra los pasos para llegar a la solución
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Diagrama de conexión
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmddl2gh38ibt52plii1w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmddl2gh38ibt52plii1w.png" alt="Diagrama de conexión" width="718" height="688"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Para que la App funcione correctamente, es fundamental seguir el diagrama de conexión entre el NodeMCU ESP8266, el sensor de temperatura AM2302 DHT22 y la pantalla OLED I2C. Asegúrate de que cada componente esté conectado a los pines adecuados. Es importante destacar que el código está específicamente adaptado para estas conexiones; cualquier modificación en la configuración podría afectar el rendimiento de la App o su funcionamiento.
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Paso 1: Acceder a la Consola de AWS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inicie sesión en la consola de administración de AWS utilizando sus credenciales.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Paso 2: Navegar a AWS IoT Core&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;En la barra de búsqueda de la consola, escriba &lt;a href="https://aws.amazon.com/es/iot-core/" rel="noopener noreferrer"&gt;AWS IoT Core&lt;/a&gt; y seleccione el servicio correspondiente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9qq1wvrrxvpb6t4i13y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs9qq1wvrrxvpb6t4i13y.png" alt="Navegar AWS IoT Core" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 3: Acceder a la Sección de Objetos&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;En el panel de navegación izquierdo, haga clic en &lt;code&gt;Administrar&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Luego, seleccione &lt;code&gt;Todos los dispositivos&lt;/code&gt; y, posteriormente, &lt;code&gt;Objetos&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fprq2kfayqrcp1gmv7t9j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fprq2kfayqrcp1gmv7t9j.png" alt="Panel para ir a objetos" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 4: Crear un Nuevo Objeto&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Haga clic en el botón &lt;code&gt;Crear objeto&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Elija la opción &lt;code&gt;Crear un único objeto&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Asigne un nombre único a su objeto que lo identifique claramente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfxfsy20u6854fpnn5al.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmfxfsy20u6854fpnn5al.png" alt="Crear objeto" width="800" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65ky0izo0kujjvej6azt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65ky0izo0kujjvej6azt.png" alt="Crear un único objeto" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjswzdcxph8w6z0qs8570.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjswzdcxph8w6z0qs8570.png" alt="Asignar nombre" width="800" height="833"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 5: Configurar Certificados&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Seleccione &lt;code&gt;Crear certificados&lt;/code&gt; para generar automáticamente un nuevo certificado que permitirá una comunicación segura entre su dispositivo y AWS IoT.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89kgxye5r7ydzefpw90d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89kgxye5r7ydzefpw90d.png" alt="Crear certificados" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 6: Crear una Política de IoT&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Para otorgar los permisos necesarios, cree una política con la siguiente configuración JSON:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"iot:Connect"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"iot:Publish"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"iot:Receive"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"iot:Subscribe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1cl2u4bhmrwk2zsrk4uy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1cl2u4bhmrwk2zsrk4uy.png" alt="Crear una Política de IoT" width="800" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 7: Finalizar la Creación del Objeto&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Revise todas las configuraciones y haga clic en &lt;code&gt;Crear objeto&lt;/code&gt; para completar el proceso.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft6kbxb2i6xdg7zp1aplp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft6kbxb2i6xdg7zp1aplp.png" alt="Finalizar la Creación del Objeto" width="800" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 8: Guardar Archivos Importantes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Descargue y almacene de forma segura los siguientes archivos proporcionados:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Punto de enlace de Amazon Trust Services&lt;/strong&gt;: Necesario para que su dispositivo se conecte al punto de enlace correcto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Certificado del dispositivo&lt;/strong&gt;: Identifica de manera única a su dispositivo en AWS IoT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clave privada&lt;/strong&gt;: Utilizada para autenticar su dispositivo durante la comunicación.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4foynl57kz8hxhedwwyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4foynl57kz8hxhedwwyw.png" alt="Guardar Archivos Importantes" width="593" height="904"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 9: Verificar la Conectividad&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Para asegurarse de que su dispositivo puede comunicarse con AWS IoT, realice una prueba de conectividad.&lt;/li&gt;
&lt;li&gt;En la consola de AWS IoT, navegue a &lt;code&gt;Conectar&lt;/code&gt; y luego seleccione &lt;code&gt;Conectar un dispositivo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Siga las instrucciones proporcionadas para su tipo de dispositivo específico.&lt;/li&gt;
&lt;li&gt;Por ejemplo, puede utilizar el comando &lt;code&gt;ping&lt;/code&gt; para verificar la conectividad con el punto de enlace de AWS IoT:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ping your-endpoint.iot.us-east-1.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reemplace &lt;code&gt;your-endpoint&lt;/code&gt; con el punto de enlace específico de su cuenta, que puede encontrar en la sección de detalles del objeto creado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funopngxtz9arbk27b594.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funopngxtz9arbk27b594.png" alt="Verificar la Conectividad" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 10: Crear un Rol de AWS IAM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para que nuestra función Lambda interactúe correctamente con otros servicios de AWS, necesitamos crear un rol de IAM con los permisos adecuados.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Acceder al servicio IAM&lt;/strong&gt;: Inicia sesión en la consola de administración de AWS y, en la barra de búsqueda, escribe &lt;a href="https://aws.amazon.com/es/iam/" rel="noopener noreferrer"&gt;IAM&lt;/a&gt; y selecciona el servicio correspondiente.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Crear un nuevo rol&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;En el panel de navegación izquierdo, haz clic en "Roles" y luego en "Crear rol".&lt;/li&gt;
&lt;li&gt;Selecciona "AWS service" como tipo de entidad de confianza y elige "Lambda" como servicio que usará este rol.&lt;/li&gt;
&lt;li&gt;Haz clic en "Siguiente: Permisos".&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Asignar permisos al rol&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;En la lista de políticas, busca y selecciona las siguientes:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AmazonBedrockFullAccess&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AWSIoTFullAccess&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CloudWatchLogsFullAccess&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tras seleccionar las políticas, haz clic en "Siguiente: Etiquetas" y luego en "Siguiente: Revisar".&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Nombrar y crear el rol&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asigna un nombre descriptivo al rol, como &lt;code&gt;AWSLambdaBedrockRole&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Revisa la configuración y haz clic en "Crear rol".&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwovhnf9im2kclo9bxqj8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwovhnf9im2kclo9bxqj8.png" alt="Crear un Rol de AWS IAM" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 11: Crear una Función Lambda&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ahora, crearemos una función &lt;a href="https://aws.amazon.com/es/lambda/" rel="noopener noreferrer"&gt;Lambda&lt;/a&gt; que procesará los datos de temperatura y generará chistes cuando se superen ciertos umbrales.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Acceder al servicio Lambda&lt;/strong&gt;: En la consola de AWS, busca "Lambda" en la barra de búsqueda y selecciona el servicio.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Crear una nueva función&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Haz clic en "Crear función".&lt;/li&gt;
&lt;li&gt;Elige "Crear desde cero".&lt;/li&gt;
&lt;li&gt;Configura los siguientes detalles:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nombre de la función&lt;/strong&gt;: &lt;code&gt;Bedrock-IotLambda&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tiempo de ejecución&lt;/strong&gt;: Selecciona &lt;code&gt;Python 3.12&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arquitectura&lt;/strong&gt;: Selecciona &lt;code&gt;arm64&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permisos&lt;/strong&gt;: Selecciona "Usar un rol existente" y elige &lt;code&gt;AWSLambdaBedrockRole&lt;/code&gt; creado anteriormente.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Haz clic en "Crear función".&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxkahl3c3bt3xk8ngq06n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxkahl3c3bt3xk8ngq06n.png" alt="Crear una Función Lambda" width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 12: Configurar la Función Lambda&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para que la función Lambda se active cuando se detecten temperaturas superiores a 30°C, configuraremos un desencadenador de AWS IoT.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Añadir un desencadenador&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;En la página de detalles de la función Lambda, desplázate hasta la sección "Desencadenadores" y haz clic en "Añadir desencadenador".&lt;/li&gt;
&lt;li&gt;Selecciona "AWS IoT" de la lista.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Crear una regla de IoT personalizada&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elige "Crear una regla nueva".&lt;/li&gt;
&lt;li&gt;Proporciona un nombre y una descripción para la regla, por ejemplo:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nombre de la regla&lt;/strong&gt;: &lt;code&gt;High_Temperature_Trigger&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Descripción&lt;/strong&gt;: &lt;code&gt;Activa la función Lambda cuando la temperatura supera los 30°C&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;En "Instrucción de consulta de regla", ingresa la siguiente consulta:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt;
 &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="s1"&gt;'esp8266/pub'&lt;/span&gt;
 &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;temperature&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Haz clic en "Crear regla".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbzpcae0fhwnojxfd1xx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbzpcae0fhwnojxfd1xx.png" alt="Configurar la Función Lambda" width="800" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso 13: Clonar Repositorio&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ Clonar el repositorio&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/fernandosilvot/App-IoT_GenAI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/fernandosilvot/App-IoT_GenAI" rel="noopener noreferrer"&gt;Repositorio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ Ir a:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd App-IoT_GenAI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Paso 14: Integrar Código&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Copia el código llamado &lt;a href="https://github.com/fernandosilvot/App-IoT_GenAI/blob/main/lambda.py" rel="noopener noreferrer"&gt;lambda.py&lt;/a&gt;. Este código, como puedes intuir, es para la función Lambda. Debes subir el código y luego realizar el despliegue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6zuytxegantjd9zqellr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6zuytxegantjd9zqellr.png" alt="Lambda" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A continuación, el código para el ESP8266 en Arduino IDE comienza con &lt;a href="https://github.com/fernandosilvot/App-IoT_GenAI/blob/main/Main.ino" rel="noopener noreferrer"&gt;Main.ino&lt;/a&gt;. Completa los campos con la red Wi-Fi y su contraseña, así como el nombre del dispositivo en AWS y el broker de AWS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft94r1cwzbxs6d1ftpneq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft94r1cwzbxs6d1ftpneq.png" alt="Main.ino" width="594" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En el código &lt;a href="https://github.com/fernandosilvot/App-IoT_GenAI/blob/main/env.h" rel="noopener noreferrer"&gt;env.h&lt;/a&gt;, debes integrar los siguientes certificados en este orden:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Punto de enlace de Amazon Trust Services (Amazon trust services endpoint)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Certificado del dispositivo (Device certificate)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clave privada (Private key file)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft29326mwuvaymr6mio8m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft29326mwuvaymr6mio8m.png" alt="env.h" width="427" height="461"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;La integración del Internet de las Cosas (IoT) con la Inteligencia Artificial Generativa abre nuevas posibilidades. Este proyecto combina hardware accesible y servicios de AWS para crear una aplicación que responde dinámicamente al detectar un aumento en la temperatura, generando contenido entretenido y personalizado.&lt;/p&gt;

&lt;p&gt;A lo largo del desarrollo, enfrenté desafíos significativos debido a mi inexperiencia con Arduino IDE y el funcionamiento de la ESP8266. Afortunadamente, conté con el valioso apoyo de Marcos Sepúlveda, quien me guió en temas como MQTT y los detalles técnicos de este módulo, y de &lt;a href="https://dev.to/elizabethfuentes12"&gt;Elizabeth Fuentes&lt;/a&gt;, quien proporcionó algunos de los materiales necesarios y me ayudó a tener una visión más clara del proyecto.&lt;/p&gt;

&lt;p&gt;Uno de los principales retos fue que la ESP8266 solo acepta peticiones HTTP y no HTTPS. Inicialmente, consideré crear una &lt;a href="https://aws.amazon.com/es/api-gateway/" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt;, pero solo permite peticiones HTTPS. Sin embargo, otra opción era usar una instancia &lt;a href="https://aws.amazon.com/es/ec2/" rel="noopener noreferrer"&gt;EC2&lt;/a&gt; para mantener una API; lamentablemente, esta opción incrementaría los costos de manera significativa. Con el apoyo de Elizabeth, exploré otras alternativas y decidí implementar una función Lambda que enviara las respuestas por MQTT directamente al ESP8266. Anteriormente, Marcos me explicó que la ESP8266 podía no solamente enviar datos, si no también recibir datos a través de MQTT, lo que facilitó esta solución.&lt;/p&gt;

&lt;p&gt;Este proyecto me permitió aprender sobre las limitaciones técnicas de la ESP8266 y sobre cómo superar problemas complejos con creatividad y colaboración. Agradezco el apoyo recibido y estoy satisfecho de haber completado este desafío.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>iot</category>
      <category>programming</category>
    </item>
    <item>
      <title>AWS CLI: Instalación en Windows y Linux, y Uso Básico</title>
      <dc:creator>Fernando Silva T</dc:creator>
      <pubDate>Sat, 21 Dec 2024 18:55:14 +0000</pubDate>
      <link>https://dev.to/aws-espanol/aws-cli-instalacion-en-windows-y-linux-y-uso-basico-l2e</link>
      <guid>https://dev.to/aws-espanol/aws-cli-instalacion-en-windows-y-linux-y-uso-basico-l2e</guid>
      <description>&lt;h2&gt;
  
  
  ¿Qué es la AWS CLI?
&lt;/h2&gt;

&lt;p&gt;La AWS Command Line Interface (CLI) es una herramienta que permite interactuar con los servicios de AWS desde la línea de comandos, simplificando tareas como la gestión de recursos, la automatización de procesos y la integración con scripts personalizados. En este artículo, aprenderás a instalar la AWS CLI en Windows y Linux, y a realizar operaciones básicas.&lt;/p&gt;




&lt;h2&gt;
  
  
  Instalación en Windows
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Descargar el instalador&lt;/strong&gt;: Ve al siguiente enlace y descarga el archivo &lt;code&gt;.msi&lt;/code&gt;: &lt;a href="https://awscli.amazonaws.com/AWSCLIV2.msi" rel="noopener noreferrer"&gt;Descargar AWS CLI para Windows&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ejecutar el instalador&lt;/strong&gt;: Haz doble clic en el archivo descargado y sigue las instrucciones del asistente.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzw4qoea5fkkhyxmtt401.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzw4qoea5fkkhyxmtt401.png" alt="instalador windows 1" width="488" height="380"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5po3wyu39hhagpaeq2i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5po3wyu39hhagpaeq2i.png" alt="instalador windows 2" width="495" height="376"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ld28x1vt085y2tiy910.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ld28x1vt085y2tiy910.png" alt="instalador windows 3" width="486" height="378"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verificar la instalación&lt;/strong&gt;: Abre una ventana de comandos (cmd o PowerShell) y ejecuta:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   aws &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si la instalación fue exitosa, deberías ver algo similar a:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   aws-cli/2.x.x Python/3.x.x Windows/x86_64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffks15n0sf5p8huvpvksi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffks15n0sf5p8huvpvksi.png" alt="Instalacion exitosa" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Instalación en Linux
&lt;/h2&gt;

&lt;p&gt;1- &lt;strong&gt;Descargar el paquete&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   curl &lt;span class="s2"&gt;"https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s2"&gt;"awscliv2.zip"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmpbh3jzr6wafi1mchrz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmpbh3jzr6wafi1mchrz.png" alt="Linux 1" width="800" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2- &lt;strong&gt;Extraer el contenido&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   unzip awscliv2.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuklfm10lsj36mv25gqpo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuklfm10lsj36mv25gqpo.png" alt="Linux 2" width="800" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3- &lt;strong&gt;Instalar AWS CLI&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo&lt;/span&gt; ./aws/install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fijyaticzm3vg977pzqvo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fijyaticzm3vg977pzqvo.png" alt="Linux 3" width="428" height="42"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4- &lt;strong&gt;Verificar la instalación&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   aws &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verifica que la salida sea similar a:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   aws-cli/2.x.x Python/3.x.x Linux/x86_64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh2uyhn3ll603ofgls5ud.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh2uyhn3ll603ofgls5ud.png" alt="Linux 4" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Si no tienes &lt;code&gt;unzip&lt;/code&gt; instalado, puedes instalarlo ejecutando &lt;code&gt;sudo apt install unzip&lt;/code&gt; (Debian/Ubuntu) o &lt;code&gt;sudo yum install unzip&lt;/code&gt; (CentOS/RedHat).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Configuración de AWS CLI
&lt;/h2&gt;

&lt;p&gt;Tras la instalación, necesitas configurar tus credenciales:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ejecuta el comando de configuración&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   aws configure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Proporciona la siguiente información&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS Access Key ID&lt;/strong&gt;: Tu clave de acceso.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Secret Access Key&lt;/strong&gt;: Tu clave secreta.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default region name&lt;/strong&gt;: La región por defecto (ejemplo: &lt;code&gt;us-east-1&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default output format&lt;/strong&gt;: El formato de salida (&lt;code&gt;json&lt;/code&gt;, &lt;code&gt;yaml&lt;/code&gt;, &lt;code&gt;text&lt;/code&gt; o &lt;code&gt;table&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Si no sabes donde conseguir tu &lt;strong&gt;AWS Access Key ID&lt;/strong&gt;, &lt;strong&gt;AWS Secret Access Key&lt;/strong&gt; recomiendo ir a mi anterior blog &lt;a href="https://dev.to/fernandosilvot/potenciando-aplicaciones-de-ia-con-aws-bedrock-y-streamlit-4eh8"&gt;Potenciando Aplicaciones de IA con AWS Bedrock y Streamlit&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Esto creará los archivos de configuración en &lt;code&gt;~/.aws/config&lt;/code&gt; y &lt;code&gt;~/.aws/credentials&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxdewahq0lgx7toyclas.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxdewahq0lgx7toyclas.png" alt="configuracion" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Uso Básico de AWS CLI
&lt;/h2&gt;

&lt;p&gt;Con la AWS CLI configurada, puedes comenzar a interactuar con los servicios de AWS. A continuación, algunos comandos básicos:&lt;/p&gt;

&lt;h3&gt;
  
  
  S3: Almacenamiento en la nube
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Listar buckets&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws s3 &lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Crear un bucket&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws s3 mb s3://mi-nuevo-bucket
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subir un archivo&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;archivo.txt s3://mi-nuevo-bucket/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Descargar un archivo&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;s3://mi-nuevo-bucket/archivo.txt &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyy8z53irfxisoqo4o2x6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyy8z53irfxisoqo4o2x6.png" alt="Buckets" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  EC2: Servidores virtuales
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Listar instancias en ejecución&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 describe-instances &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="s2"&gt;"Name=instance-state-name,Values=running"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jexjwfsq46a5qqgl63p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jexjwfsq46a5qqgl63p.png" alt="Ec2" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Iniciar una instancia&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 start-instances &lt;span class="nt"&gt;--instance-ids&lt;/span&gt; Id-instancia
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Detener una instancia&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ec2 stop-instances &lt;span class="nt"&gt;--instance-ids&lt;/span&gt; Id-instancia
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovcrc1ttxw23ed8ioo3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovcrc1ttxw23ed8ioo3b.png" alt="Ec2 -1" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  IAM: Gestión de usuarios
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Listar usuarios&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws iam list-users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzo4sxp5shijqtthlurk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzo4sxp5shijqtthlurk.png" alt="IAM" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Crear un nuevo usuario&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws iam create-user &lt;span class="nt"&gt;--user-name&lt;/span&gt; nuevo-usuario
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkybabq6snyo5nypsa6ul.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkybabq6snyo5nypsa6ul.png" alt="IAM 2" width="800" height="253"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Consejos Finales
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automatización&lt;/strong&gt;: Crea scripts bash o PowerShell para automatizar tareas repetitivas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentación&lt;/strong&gt;: Consulta siempre la &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html" rel="noopener noreferrer"&gt;documentación oficial de AWS CLI&lt;/a&gt; para explorar más funcionalidades.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seguridad&lt;/strong&gt;: Nunca compartas tus claves de acceso y utiliza IAM para asignar permisos de forma granular.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;¡Y eso es todo! Ahora tienes una guía básica para comenzar a usar la AWS CLI en tus proyectos. 🚀&lt;/p&gt;

</description>
      <category>aws</category>
      <category>develop</category>
      <category>linux</category>
      <category>windows</category>
    </item>
    <item>
      <title>Potenciando Aplicaciones de IA con AWS Bedrock y Streamlit</title>
      <dc:creator>Fernando Silva T</dc:creator>
      <pubDate>Tue, 17 Dec 2024 18:40:41 +0000</pubDate>
      <link>https://dev.to/aws-espanol/potenciando-aplicaciones-de-ia-con-aws-bedrock-y-streamlit-4eh8</link>
      <guid>https://dev.to/aws-espanol/potenciando-aplicaciones-de-ia-con-aws-bedrock-y-streamlit-4eh8</guid>
      <description>&lt;p&gt;Este blog detalla cómo construir una aplicación de inteligencia artificial utilizando &lt;strong&gt;AWS Bedrock&lt;/strong&gt; y &lt;strong&gt;Streamlit&lt;/strong&gt;, en la que puedes realizar tareas como el procesamiento de lenguaje natural y la generación de imágenes. Este proyecto se basa en AWS Bedrock para interactuar con modelos de IA avanzados como Claude 3 y modelos de generación de imágenes como Stability AI.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Configuración de AWS Credentials&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Para que tu aplicación de Streamlit se conecte a los servicios de AWS, necesitas configurar correctamente las credenciales de AWS. A continuación te explico cómo obtener y configurar las claves de acceso necesarias: &lt;strong&gt;AWS_ACCESS_KEY_ID&lt;/strong&gt;, &lt;strong&gt;AWS_SECRET_ACCESS_KEY&lt;/strong&gt;, y &lt;strong&gt;AWS_DEFAULT_REGION&lt;/strong&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Paso a Paso para Obtener las Credenciales de AWS:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Inicia sesión en la &lt;a href="https://aws.amazon.com/console/" rel="noopener noreferrer"&gt;Consola de Administración de AWS&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyn4jvzkp4dnxhtvm5v3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyn4jvzkp4dnxhtvm5v3r.png" alt="console" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;En el menú superior derecho, haz clic en tu nombre de usuario y selecciona &lt;strong&gt;"My Security Credentials"&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd0qqk7410pczrq3kertz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd0qqk7410pczrq3kertz.png" alt="My Security Credentials" width="312" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;En la sección &lt;strong&gt;"Access keys (access key ID and secret access key)"&lt;/strong&gt;, haz clic en &lt;strong&gt;"Create New Access Key"&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpk9v5ykgl0jxgsx80t9y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpk9v5ykgl0jxgsx80t9y.png" alt="Create New Access Key" width="800" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se generará una nueva clave de acceso. Descarga el archivo de claves, ya que solo podrás ver la &lt;strong&gt;AWS_ACCESS_KEY_ID&lt;/strong&gt; y &lt;strong&gt;AWS_SECRET_ACCESS_KEY&lt;/strong&gt; una vez.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sdh7xm698m5qbcmppqa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sdh7xm698m5qbcmppqa.png" alt="clave de acceso" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asegúrate de guardar esta información en un lugar seguro.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para completar la configuración de las credenciales, deberás colocar las variables obtenidas en un archivo &lt;code&gt;.env&lt;/code&gt;, de manera que tu aplicación de Python pueda acceder a ellas sin exponer las claves directamente en el código.&lt;/p&gt;

&lt;p&gt;Ejemplo de archivo &lt;code&gt;.env&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tu_aws_access_key_id
&lt;span class="nv"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tu_aws_secret_access_key
&lt;span class="nv"&gt;AWS_DEFAULT_REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;us-west-2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. &lt;strong&gt;Explicación del Código&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;El código de esta aplicación utiliza varios servicios y librerías importantes para interactuar con AWS Bedrock y generar imágenes utilizando IA. A continuación explicamos las partes más esenciales del código:&lt;/p&gt;

&lt;h5&gt;
  
  
  2.1 &lt;strong&gt;Cargar las Variables de Entorno&lt;/strong&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;

&lt;span class="c1"&gt;# Cargar las variables de entorno desde un archivo .env
&lt;/span&gt;&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La librería &lt;code&gt;dotenv&lt;/code&gt; permite cargar las credenciales desde un archivo &lt;code&gt;.env&lt;/code&gt;, protegiendo las claves de acceso.&lt;/p&gt;

&lt;h5&gt;
  
  
  2.2 &lt;strong&gt;Conexión a AWS Bedrock&lt;/strong&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="c1"&gt;# Crear un cliente para el servicio Bedrock de AWS
&lt;/span&gt;&lt;span class="n"&gt;aws_bedrock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;bedrock-runtime&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;aws_access_key_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;aws_secret_access_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;region_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AWS_DEFAULT_REGION&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Con &lt;code&gt;boto3&lt;/code&gt;, la biblioteca oficial de AWS para Python, nos conectamos al servicio de &lt;strong&gt;Bedrock&lt;/strong&gt; de AWS, que proporciona acceso a modelos como &lt;strong&gt;Claude 3&lt;/strong&gt; para procesamiento de texto y &lt;strong&gt;Stable Diffusion XL&lt;/strong&gt; para generación de imágenes.&lt;/p&gt;

&lt;h5&gt;
  
  
  2.3 &lt;strong&gt;Generación de Imágenes&lt;/strong&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;request_payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text_prompts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cfg_scale&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;steps&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;model_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aws_bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request_payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;image_model_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;decode_image_from_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta función envía un &lt;strong&gt;prompt&lt;/strong&gt; al modelo de generación de imágenes de AWS Bedrock y obtiene una imagen como respuesta, la cual luego se decodifica y se muestra al usuario.&lt;/p&gt;

&lt;h5&gt;
  
  
  2.4 &lt;strong&gt;Análisis de Imágenes&lt;/strong&gt;
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;analizar_imagen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ruta_imagen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;texto&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Invoca Claude 3 para el análisis de imágenes y devuelve un texto normal.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;tipo_archivo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;imagen_base64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;codificador_base64_imagen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ruta_imagen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;prompt_sistema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Describe cada detalle que puedas sobre esta imagen, sé extremadamente minucioso.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic_version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bedrock-2023-05-31&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt_sistema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;image&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;base64&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;media_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tipo_archivo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;imagen_base64&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;texto&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Usa el prompt del sistema&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;respuesta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aws_bedrock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="n"&gt;modelId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;anthropic.claude-3-sonnet-20240229-v1:0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;contentType&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;salida_llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;respuesta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;())[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;salida_llm&lt;/span&gt;  &lt;span class="c1"&gt;# Devuelve el texto normal
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este bloque de código, la función &lt;strong&gt;&lt;code&gt;analizar_imagen&lt;/code&gt;&lt;/strong&gt; utiliza &lt;strong&gt;Claude 3&lt;/strong&gt; (un modelo de lenguaje de AWS) para analizar una imagen y devolver una descripción detallada de su contenido.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Configuración de Streamlit&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Streamlit facilita la creación de interfaces web interactivas con Python. En este caso, hemos configurado un panel lateral para elegir entre diferentes tareas de IA. Dependiendo de la opción seleccionada, el usuario puede generar imágenes, realizar análisis de texto o más.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;streamlit&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;

&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_page_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;page_title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Potenciando Aplicaciones de IA con AWS Bedrock y Streamlit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page_icon&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wide&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Menú de Opciones&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;selectbox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Selecciona la tarea de IA&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Inicio&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Procesamiento de Lenguaje&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Generación de imágenes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Descripción de Imágenes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Inicio&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output_format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SVG&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Potenciando Aplicaciones de IA con AWS Bedrock y Streamlit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        Esta aplicación web permite interactuar con modelos de inteligencia artificial para realizar tareas de procesamiento de lenguaje natural y generación de imágenes.
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este fragmento configura el título y las opciones de la interfaz, permitiendo al usuario interactuar con las distintas funcionalidades de la aplicación.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mi Proyecto
&lt;/h2&gt;

&lt;p&gt;He trabajado en este proyecto como una forma de integrar poderosos servicios de AWS con Streamlit para crear aplicaciones de inteligencia artificial accesibles y fáciles de usar. Si deseas ver el código fuente o probar la aplicación en vivo, puedes hacerlo a través del siguiente enlace:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/fernandosilvot/my_talk_at_pycon_2024" rel="noopener noreferrer"&gt;Ver el proyecto en GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1d3jkypquakpp72lhi0t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1d3jkypquakpp72lhi0t.png" alt="My proyecto" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Qué puedes encontrar en el proyecto?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Generación de imágenes utilizando AWS Bedrock &lt;/li&gt;
&lt;li&gt;Análisis de imágenes usando el modelo Claude 3 de AWS.&lt;/li&gt;
&lt;li&gt;Ejemplo de cómo integrar Streamlit con los servicios de AWS.&lt;/li&gt;
&lt;li&gt;Instrucciones detalladas sobre cómo configurar el entorno de desarrollo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No dudes en explorar el código y hacer preguntas o sugerencias sobre cómo mejorar la aplicación. ¡Estaré encantado de recibir tu feedback!&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusión
&lt;/h4&gt;

&lt;p&gt;Este proyecto demuestra cómo utilizar los servicios de AWS Bedrock para potenciar aplicaciones de inteligencia artificial con Streamlit. La configuración correcta de las credenciales de AWS es crucial para garantizar el acceso a los servicios de AWS, y con las herramientas de Python como &lt;code&gt;boto3&lt;/code&gt; y &lt;code&gt;langchain_aws&lt;/code&gt;, puedes integrar fácilmente modelos avanzados de procesamiento de lenguaje y generación de imágenes.&lt;/p&gt;

</description>
      <category>bedrock</category>
      <category>langchain</category>
      <category>aws</category>
      <category>community</category>
    </item>
    <item>
      <title>Guía Completa para Crear una Web Estática con AWS S3 y AWS CLI</title>
      <dc:creator>Fernando Silva T</dc:creator>
      <pubDate>Mon, 15 Jul 2024 02:27:56 +0000</pubDate>
      <link>https://dev.to/aws-espanol/guia-completa-para-crear-una-web-estatica-con-aws-s3-y-aws-cli-c2j</link>
      <guid>https://dev.to/aws-espanol/guia-completa-para-crear-una-web-estatica-con-aws-s3-y-aws-cli-c2j</guid>
      <description>&lt;p&gt;En esta guía, aprenderemos cómo crear y alojar una web estática utilizando Amazon S3 y AWS CLI. &lt;/p&gt;

&lt;h2&gt;
  
  
  Introducción
&lt;/h2&gt;

&lt;p&gt;Amazon S3 (Simple Storage Service) es un servicio de almacenamiento de objetos ofrecido por Amazon Web Services (AWS). Es ideal para alojar sitios web estáticos, ya que proporciona una forma sencilla y escalable de almacenar archivos. Utilizando AWS CLI, podemos gestionar nuestras credenciales de forma segura y automatizar el proceso de despliegue de nuestro sitio web.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requisitos Previos
&lt;/h2&gt;

&lt;p&gt;Antes de comenzar, asegúrate de tener:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Una cuenta de AWS activa.
# Guía Completa para Crear una Web Estática con AWS S3 y AWS CLI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En esta guía, aprenderás cómo crear y alojar una web estática utilizando Amazon S3 y AWS CLI. Sigue estos pasos para configurar y desplegar tu sitio web de manera eficiente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requisitos Previos
&lt;/h2&gt;

&lt;p&gt;Antes de comenzar, asegúrate de tener:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Una cuenta de AWS activa.&lt;/li&gt;
&lt;li&gt;AWS CLI instalado en tu máquina.&lt;/li&gt;
&lt;li&gt;Credenciales de AWS configuradas en tu máquina.&lt;/li&gt;
&lt;li&gt;Un sitio web estático (archivos HTML, CSS y JavaScript listos).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Paso 1: Crear un Bucket en Amazon S3
&lt;/h2&gt;

&lt;p&gt;Primero, necesitamos crear un bucket en Amazon S3 para almacenar los archivos de nuestro sitio web.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Abre la consola de administración de AWS y navega a S3.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjn0ubrzdhp5927u1lvt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhjn0ubrzdhp5927u1lvt.png" alt="Image description" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Haz clic en "Crear bucket".&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yzj2szuj115hvqxvkmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yzj2szuj115hvqxvkmd.png" alt="Image description" width="800" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Proporciona un nombre único para tu bucket (por ejemplo, &lt;code&gt;mi-sitio-web-estatico&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkchgdg2llgwn3d8uthn2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkchgdg2llgwn3d8uthn2.png" alt="Image description" width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Selecciona una región.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deshabilita "Bloquear todo el acceso público" y marca la casilla de consentimiento.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjiwbwpvkvad5mgq3pvec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjiwbwpvkvad5mgq3pvec.png" alt="Image description" width="800" height="752"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Haz clic en "Create bucket".&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxp9y5cturikcivuu6hrb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxp9y5cturikcivuu6hrb.png" alt="Image description" width="800" height="541"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Paso 2: Configurar el Bucket para Alojar una Web Estática
&lt;/h2&gt;

&lt;p&gt;Una vez creado el bucket, necesitamos configurarlo para alojar nuestro sitio web estático.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;En la consola de S3, selecciona tu bucket.&lt;/li&gt;
&lt;li&gt;Ve a la pestaña "Propiedades".&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2blh3zy43s9zl62ph5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2blh3zy43s9zl62ph5h.png" alt="Image description" width="615" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;En la sección "Alojamiento de sitios web estáticos", haz clic en "Editar".&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwqfesc3sj9qn2lh648zg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwqfesc3sj9qn2lh648zg.png" alt="Image description" width="800" height="365"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Selecciona "Habilitar" y elige "Alojar un sitio web estático".&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft3sutxnrdkfcnijvxv6l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft3sutxnrdkfcnijvxv6l.png" alt="Image description" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Especifica los nombres de los archivos de índice y error (por ejemplo, &lt;code&gt;index.html&lt;/code&gt; y &lt;code&gt;error.html&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gmbigwjbbcpwltzutge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7gmbigwjbbcpwltzutge.png" alt="Image description" width="800" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Guarda los cambios.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssu81laoo0gs34zj9qz0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssu81laoo0gs34zj9qz0.png" alt="Image description" width="800" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Paso 3: Subir Archivos al Bucket de S3
&lt;/h2&gt;

&lt;p&gt;Utilizando AWS CLI, subiremos los archivos de nuestro sitio web al bucket de S3.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Abre una terminal y navega al directorio donde están los archivos de tu sitio web.&lt;/li&gt;
&lt;li&gt;Ejecuta el siguiente comando para copiar todos los archivos al bucket de S3:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;sync&lt;/span&gt; ./ s3://mi-sitio-web-estatico/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando copiará todos los archivos en el directorio actual al bucket de S3. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Este comando lo uso cada vez que estoy a punto de hacer un git push a mi rama principal, cuando logre poder automatizarlo lo subiré&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Guarda los cambios.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Paso 4: Acceder a tu Sitio Web
&lt;/h2&gt;

&lt;p&gt;Ahora, tu sitio web estático debería estar disponible públicamente. Puedes acceder a él utilizando la URL proporcionada en la sección "Static website hosting" de las propiedades de tu bucket de S3.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;En esta guía, hemos aprendido cómo crear y alojar una web estática utilizando Amazon S3 y AWS CLI. Este es un método efectivo y económico para alojar sitios web estáticos, aprovechando la escalabilidad y fiabilidad de AWS. Si tienes alguna pregunta o necesitas más ayuda, no dudes en dejar un comentario. ¡Buena suerte con tu sitio web!&lt;/p&gt;




&lt;p&gt;Cualquier mejora que tengas no dudes en decirme y lo podré actualizar. Muchas gracias por venir a mi primer blog.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>aws</category>
      <category>s3</category>
      <category>staticwebapps</category>
    </item>
  </channel>
</rss>
