{"id":122,"date":"2026-03-08T23:07:49","date_gmt":"2026-03-08T23:07:49","guid":{"rendered":"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/construyendo-pipelines-de-ia-en-produccin-leccione\/"},"modified":"2026-03-18T22:00:23","modified_gmt":"2026-03-18T22:00:23","slug":"construyendo-pipelines-de-ia-en-produccin-leccione","status":"publish","type":"post","link":"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/construyendo-pipelines-de-ia-en-produccin-leccione\/","title":{"rendered":"Construyendo Pipelines de IA en Producci\u00f3n: Lecciones de 10K+ Generaciones"},"content":{"rendered":"<p>El viernes <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/setting-up-github-actions-for-python-applications\/\" title=\"a las\">a las<\/a> 3pm del segundo sprint que tuvimos con IA corriendo en <a href=\"https:\/\/m.do.co\/c\/06956e5e2802\" title=\"DigitalOcean para Producci\u00f3n\" rel=\"nofollow sponsored\" target=\"_blank\">producci\u00f3n<\/a>, empuj\u00e9 un &#8220;cambio menor&#8221; al pipeline de generaci\u00f3n de contenido. Sin suficientes tests de carga. Sin entender bien qu\u00e9 pasaba cuando el proveedor respond\u00eda con un 529.<\/p>\n<p>A las 11pm ten\u00edamos 400 jobs atascados en cola, el equipo de soporte recibiendo tickets, y yo con tres terminales abiertas tratando de entender <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/arquitectura-impulsada-por-eventos-2026-por-qu-los\/\" title=\"Por Qu\u00e9\">por qu\u00e9<\/a> nuestro sistema de reintentos estaba atacando la API como si quisiera tumb\u00e1rsela.<\/p>\n<p>Eso fue hace ocho meses. Desde entonces hemos procesado m\u00e1s de 10,000 generaciones en <a href=\"https:\/\/m.do.co\/c\/06956e5e2802\" title=\"DigitalOcean para Producci\u00f3n\" rel=\"nofollow sponsored\" target=\"_blank\">producci\u00f3n<\/a> para un producto B2B que analiza documentos legales. Somos cuatro backend developers. No tenemos un equipo de ML. <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">Lo que<\/a> aprendimos en ese proceso <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/benchmarks-de-asistentes-de-cdigo-ia-pruebas-de-re\/\" title=\"es lo que\">es lo que<\/a> quiero compartir aqu\u00ed.<\/p>\n<h2>El modelo no era el cuello de botella (yo cre\u00ed que s\u00ed)<\/h2>\n<p>Cuando empezamos, dedicamos demasiado tiempo eligiendo modelos, afinando temperatura, discutiendo prompts. Esas cosas importan, pero el cuello de botella real en <a href=\"https:\/\/m.do.co\/c\/06956e5e2802\" title=\"DigitalOcean para Producci\u00f3n\" rel=\"nofollow sponsored\" target=\"_blank\">producci\u00f3n<\/a> era la <a href=\"https:\/\/m.do.co\/c\/06956e5e2802\" title=\"Infraestructura Cloud con DigitalOcean\" rel=\"nofollow sponsored\" target=\"_blank\">infraestructura<\/a> alrededor del modelo, no el modelo en s\u00ed.<\/p>\n<p>El primer problema serio fue la cola de jobs. Usamos Celery con Redis. El worker no era el culpable \u2014 el problema era que cuando un job tardaba 90 segundos (timeout del proveedor), el worker quedaba bloqueado y no procesaba nada m\u00e1s. Pasamos a workers con <code>asyncio<\/code> y el throughput casi se triplic\u00f3. Un cambio de arquitectura <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/edge-computing-en-2026-por-qu-los-desarrolladores\/\" title=\"de dos\">de dos<\/a> d\u00edas que debimos hacer desde el principio.<\/p>\n<p>Despu\u00e9s vino la falta de idempotencia. Un job pod\u00eda ejecutarse dos veces si el ACK llegaba tarde al broker. Resultado: doble costo, datos duplicados en base <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/rag-profundo-estrategias-de-chunking-bases-de-dato\/\" title=\"de Datos\">de datos<\/a>, l\u00f3gica de deduplicaci\u00f3n que tuvimos que agregar a posteriori. Solucionable, pero tardamos m\u00e1s de <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">lo que<\/a> deber\u00eda haber tomado reconocer el problema.<\/p>\n<p>Y los logs. Durante el primer mes ten\u00edamos <code>print(\"Error\")<\/code> en varios lugares del c\u00f3digo. Muy profesional. Cuando algo fallaba <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/setting-up-github-actions-for-python-applications\/\" title=\"a las\">a las<\/a> 2am era imposible reconstruir qu\u00e9 hab\u00eda pasado.<\/p>\n<p>La conclusi\u00f3n que tardamos demasiado en sacar: antes de optimizar el prompt, verifica que tu <a href=\"https:\/\/m.do.co\/c\/06956e5e2802\" title=\"Infraestructura Cloud con DigitalOcean\" rel=\"nofollow sponsored\" target=\"_blank\">infraestructura<\/a> pueda manejar fallos del proveedor sin hacer colapsar todo lo dem\u00e1s. La arquitectura que terminamos usando \u2014 FastAPI como gateway, Celery async, PostgreSQL para estado de jobs, Redis para cola y rate limiting \u2014 no tiene nada de especial. Pero funciona, y sobrevive a errores transitorios sin drama.<\/p>\n<h2>Gesti\u00f3n de costos: el susto del primer billing statement<\/h2>\n<p>El primer mes de <a href=\"https:\/\/m.do.co\/c\/06956e5e2802\" title=\"DigitalOcean para Producci\u00f3n\" rel=\"nofollow sponsored\" target=\"_blank\">producci\u00f3n<\/a> real lleg\u00f3 la factura: $340 USD. Para un proyecto interno en fase de validaci\u00f3n, eso era mucho. Y lo peor era que no ten\u00edamos idea de d\u00f3nde ven\u00eda exactamente ese gasto.<\/p>\n<p>Despu\u00e9s <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/edge-computing-en-2026-por-qu-los-desarrolladores\/\" title=\"de dos\">de dos<\/a> d\u00edas revisando logs (que ya hab\u00edamos mejorado un poco para entonces), descubrimos que el 60% del costo ven\u00eda de reintentos fallidos que mandaban el prompt completo cada vez, incluyendo contexto que no necesitaba replicarse. Otro 15% ven\u00eda de jobs de prueba que yo mismo hab\u00eda corrido durante el desarrollo y que olvid\u00e9 desactivar en staging.<\/p>\n<p>Me dio verg\u00fcenza. Pero bueno, as\u00ed se aprende.<\/p>\n<p>Lo que implementamos para tener visibilidad real desde esa semana:<\/p>\n<pre><code class=\"language-python\">from dataclasses import dataclass, field\nfrom typing import Dict\n\n# Precios en USD por mill\u00f3n de tokens \u2014 revisa la p\u00e1gina de pricing peri\u00f3dicamente\nCOSTO_POR_MTOKEN: Dict[str, Dict[str, float]] = {\n    &quot;claude-sonnet-4-6&quot;:        {&quot;input&quot;: 3.00, &quot;output&quot;: 15.00},\n    &quot;claude-haiku-4-5-20251001&quot;: {&quot;input&quot;: 0.80, &quot;output&quot;:  4.00},\n    &quot;gpt-4o&quot;:                    {&quot;input&quot;: 2.50, &quot;output&quot;: 10.00},\n}\n\n@dataclass\nclass TrackerCosto:\n    modelo: str\n    tokens_entrada: int = 0\n    tokens_salida: int = 0\n    costo_usd: float = 0.0\n\n    def registrar(self, usage) -&gt; float:\n        &quot;&quot;&quot;\n        Recibe el objeto 'usage' de la respuesta de la API.\n        Retorna el costo incremental de esta sola llamada.\n        &quot;&quot;&quot;\n        precios = COSTO_POR_MTOKEN.get(self.modelo, {&quot;input&quot;: 0, &quot;output&quot;: 0})\n        costo = (\n            usage.input_tokens  * precios[&quot;input&quot;]  \/ 1_000_000 +\n            usage.output_tokens * precios[&quot;output&quot;] \/ 1_000_000\n        )\n        self.tokens_entrada += usage.input_tokens\n        self.tokens_salida  += usage.output_tokens\n        self.costo_usd      += costo\n        return costo\n\n    def resumen(self) -&gt; dict:\n        return {\n            &quot;modelo&quot;:        self.modelo,\n            &quot;tokens_entrada&quot;: self.tokens_entrada,\n            &quot;tokens_salida&quot;:  self.tokens_salida,\n            &quot;costo_usd&quot;:     round(self.costo_usd, 6),\n        }\n<\/code><\/pre>\n<p>Cada worker instancia un tracker, registra cada llamada, y al terminar el job persiste el resumen en PostgreSQL junto al resultado. Ahora tenemos dashboards por tipo de documento, por usuario, por semana. El costo promedio por generaci\u00f3n con Sonnet nos qued\u00f3 en $0.0031 USD. Con Haiku bajamos a $0.0008 para los pasos donde la calidad no necesita ser m\u00e1xima \u2014 clasificaci\u00f3n del tipo de documento, por ejemplo.<\/p>\n<p>Un gotcha que no anticip\u00e9: los tokens de entrada crecen r\u00e1pido si tienes un system prompt largo. Ten\u00edamos uno de 800 palabras que se mandaba en cada llamada. Lo comprimimos a 340 palabras sin perder calidad apreciable, y eso redujo el costo de entrada un 12%. No enorme, pero tampoco despreciable a escala.<\/p>\n<h2>Reintentos y timeouts: <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/arquitectura-impulsada-por-eventos-2026-por-qu-los\/\" title=\"Por Qu\u00e9\">por qu\u00e9<\/a> el viernes fue un desastre<\/h2>\n<p>El problema con reintentos ingenuos \u2014 y este fue exactamente mi error de aquel viernes \u2014 es que cuando el proveedor est\u00e1 bajo carga, un sistema que reintenta agresivamente puede empeorar la situaci\u00f3n para todos. Literalmente contribuyes al problema que intentas resolver.<\/p>\n<p>Hay dos categor\u00edas de error que se deben tratar distinto: los transitorios (timeouts, 429, 529, 503) y los definitivos (400, 401, 403). Para los primeros, backoff exponencial con jitter. Para los segundos, ni lo intentes.<\/p>\n<pre><code class=\"language-python\">import asyncio\nimport time\nimport logging\nfrom anthropic import Anthropic, APIStatusError, APITimeoutError, APIConnectionError\n\nlogger = logging.getLogger(__name__)\ncliente = Anthropic()\n\nasync def generar_con_reintento(\n    prompt: str,\n    modelo: str = &quot;claude-sonnet-4-6&quot;,\n    max_intentos: int = 3,\n    timeout_seg: float = 30.0,\n) -&gt; str:\n    &quot;&quot;&quot;\n    Wrapper de <a href=\"https:\/\/m.do.co\/c\/06956e5e2802\" title=\"DigitalOcean para Producci\u00f3n\" rel=\"nofollow sponsored\" target=\"_blank\">producci\u00f3n<\/a>. Notas importantes:\n    - timeout_seg=30 viene de medir el p95 real durante 2 semanas (era ~18s).\n      Empezamos con 60s y los workers lentos bloqueaban todo el pipeline.\n    - El jitter en backoff es no-negociable: sin \u00e9l, m\u00faltiples workers\n      reintentan exactamente al mismo tiempo y la cosa empeora.\n    - Solo reintentamos 5xx y errores de red. Los 4xx (salvo 429) son bugs.\n    &quot;&quot;&quot;\n    for intento in range(max_intentos):\n        try:\n            respuesta = await asyncio.wait_for(\n                asyncio.to_thread(\n                    cliente.messages.create,\n                    model=modelo,\n                    max_tokens=1024,\n                    messages=[{&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: prompt}],\n                ),\n                timeout=timeout_seg,\n            )\n            return respuesta.content[0].text\n\n        except asyncio.TimeoutError:\n            # asyncio.wait_for lanza esto \u2014 diferente a APITimeoutError\n            logger.warning(&quot;Timeout local en intento %d\/%d&quot;, intento + 1, max_intentos)\n            if intento == max_intentos - 1:\n                raise\n\n        except APITimeoutError:\n            # La librer\u00eda lo lanza por sus propios mecanismos internos\n            logger.warning(&quot;APITimeout en intento %d\/%d&quot;, intento + 1, max_intentos)\n            if intento == max_intentos - 1:\n                raise\n\n        except APIStatusError as e:\n            if e.status_code in (429, 529):\n                espera = min(60, 10 * (2 ** intento))\n                logger.info(&quot;Rate limit %d, esperando %.1fs&quot;, e.status_code, espera)\n                await asyncio.sleep(espera)\n                continue\n            elif e.status_code &gt;= 500:\n                pass  # Backoff normal abajo\n            else:\n                raise  # 400, 401, 403: no reintentar, es un bug nuestro\n\n        except APIConnectionError:\n            logger.warning(&quot;Error de conexi\u00f3n en intento %d\/%d&quot;, intento + 1, max_intentos)\n\n        if intento &lt; max_intentos - 1:\n            # Jitter: fracci\u00f3n de segundo aleatoria basada en monotonic clock\n            espera = (2 ** intento) + (time.monotonic() % 1.0)\n            await asyncio.sleep(espera)\n\n    raise RuntimeError(f&quot;Fallaron todos los {max_intentos} intentos para modelo={modelo}&quot;)\n<\/code><\/pre>\n<p>Lo que no esperaba \u2014 <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/event-driven-architecture-in-2026-why-microservice\/\" title=\"y esto\">y esto<\/a> me cost\u00f3 una hora de debugging ese viernes \u2014 es que <code>asyncio.TimeoutError<\/code> y <code>APITimeoutError<\/code> son dos excepciones distintas que hay que capturar por separado. El primero lo lanza <code>asyncio.wait_for<\/code> cuando se agota el timeout local. El segundo lo lanza la librer\u00eda de Anthropic si usa sus propios mecanismos internos de timeout. Si solo capturas uno, el otro se te escapa silenciosamente hacia arriba <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/claude-vs-gpt-4o-vs-gemini-20-qu-modelo-de-ia-usar\/\" title=\"en el\">en el<\/a> stack y termina matando el worker.<\/p>\n<p>El timeout de 30 segundos tampoco es arbitrario. Medimos el p95 de latencia durante <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/tcnicas-avanzadas-de-prompt-engineering-chain-of-t\/\" title=\"dos semanas\">dos semanas<\/a> con histogramas de Prometheus, y estaba en 18 segundos. El p99, que es donde la cosa se pone interesante, llegaba a 45 segundos en momentos de alta carga del proveedor. Para an\u00e1lisis de documentos legales \u2014 no tiempo real \u2014 el p99 alto es aceptable. Para un chatbot interactivo, definitivamente no.<\/p>\n<h2>Observabilidad: ver para creer<\/h2>\n<p>Durante los primeros <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/edge-computing-en-2026-por-qu-los-desarrolladores\/\" title=\"dos meses\">dos meses<\/a> ten\u00edamos observabilidad terrible. Sab\u00edamos si un job terminaba o fallaba, pero no <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/arquitectura-impulsada-por-eventos-2026-por-qu-los\/\" title=\"Por Qu\u00e9\">por qu\u00e9<\/a> fallaba, cu\u00e1nto tardaba en cada paso, ni cu\u00e1l era la distribuci\u00f3n <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/kubernetes-vs-docker-swarm-vs-nomad-comparacin-de\/\" title=\"Real de\">real de<\/a> latencias.<\/p>\n<p>El cambio m\u00e1s importante fue el structured logging. Cada evento del pipeline emite un JSON con campos fijos: <code>job_id<\/code>, <code>modelo<\/code>, <code>paso<\/code>, <code>duracion_ms<\/code>, <code>tokens_entrada<\/code>, <code>tokens_salida<\/code>, <code>costo_usd<\/code>, y <code>error<\/code> si aplica. Eso nos permite hacer queries en CloudWatch Logs Insights sin necesitar un sistema de observabilidad m\u00e1s caro. Cada job tiene un ID \u00fanico que viaja por todo el pipeline \u2014 cuando algo falla, busco ese ID y veo exactamente qu\u00e9 pas\u00f3 en orden.<\/p>\n<p>Agregamos tambi\u00e9n una alerta que se dispara cuando el costo acumulado del d\u00eda supera el 120% del promedio de los \u00faltimos siete d\u00edas. Parece simple. Nos salv\u00f3 dos veces de bugs que mandaban jobs duplicados sin <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/08\/configuracin-de-argocd-para-gitops-tutorial-paso-a\/\" title=\"que nadie\">que nadie<\/a> se diera <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/kubernetes-vs-docker-swarm-vs-nomad-container-orch\/\" title=\"Cuenta Hasta\">cuenta hasta<\/a> el d\u00eda siguiente.<\/p>\n<p>Algo que me arrepiento de no haber hecho desde el inicio: integrar OpenTelemetry para trazas distribuidas. Ahora ser\u00eda trabajo retrofitear. Si ya tienes Jaeger o Honeycomb en tu stack, hazlo desde el d\u00eda uno. No es mucho <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/claude-vs-gpt-4o-vs-gemini-20-qu-modelo-de-ia-usar\/\" title=\"Trabajo en\">trabajo en<\/a> ese momento, y es much\u00edsimo trabajo despu\u00e9s.<\/p>\n<h2>Sin rodeos: <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">lo que<\/a> har\u00eda si empezara ma\u00f1ana<\/h2>\n<p>Tracking de costos desde el d\u00eda uno. No el d\u00eda que llegue la primera factura sorpresa \u2014 desde el principio. Es una hora de trabajo que se paga sola en la primera semana. Ir a ciegas en <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">lo que<\/a> gastas lleva directo a una conversaci\u00f3n inc\u00f3moda con quien paga las facturas \u2014 y, por experiencia, esa conversaci\u00f3n es mucho menos divertida que un incidente de <a href=\"https:\/\/m.do.co\/c\/06956e5e2802\" title=\"DigitalOcean para Producci\u00f3n\" rel=\"nofollow sponsored\" target=\"_blank\">producci\u00f3n<\/a> <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/setting-up-github-actions-for-python-applications\/\" title=\"a las\">a las<\/a> 11pm.<\/p>\n<p>Despu\u00e9s, modelos m\u00e1s baratos donde la calidad no sea cr\u00edtica. El 40% de nuestro pipeline corre en Haiku sin p\u00e9rdida apreciable <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/claude-vs-gpt-4o-vs-gemini-20-qu-modelo-de-ia-usar\/\" title=\"en el\">en el<\/a> resultado final, <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">lo que<\/a> reduce el costo total un 30%. <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/05\/copilot-vs-cursor-vs-codeium\/\" title=\"Vale la Pena\">Vale la pena<\/a> medir cu\u00e1les pasos realmente necesitan el modelo caro.<\/p>\n<p>Para el manejo de errores: trata los fallos del proveedor como parte del dise\u00f1o normal, no como casos extremos. Backoff con jitter, distinci\u00f3n clara entre errores transitorios y definitivos, timeouts basados en m\u00e9tricas reales \u2014 no en corazonadas. Ese viernes me ense\u00f1\u00f3 que un sistema que reintenta sin considerar el impacto colectivo es peor que uno que simplemente falla limpio.<\/p>\n<p>Y <a href=\"https:\/\/blog.rebalai.com\/es\/2026\/03\/09\/configuracin-de-github-actions-para-aplicaciones-p\/\" title=\"lo que\">lo que<\/a> m\u00e1s contradice el instinto inicial: no toques los prompts hasta tener m\u00e9tricas. Pasamos semanas ajust\u00e1ndolos a mano antes de tener evaluaci\u00f3n automatizada. No sab\u00edamos si los cambios ayudaban. Mide primero, optimiza despu\u00e9s.<\/p>\n<p>No tengo certeza de que todo esto escale sin ajustes m\u00e1s all\u00e1 de unas decenas de miles de generaciones por d\u00eda \u2014 no hemos llegado a ese volumen todav\u00eda. Pero los principios se mantienen: observabilidad desde el inicio, manejo expl\u00edcito de errores, control de costos por llamada. Lo dem\u00e1s es afinar.<\/p>\n<p><!-- Reviewed: 2026-03-06 | Status: ready_to_publish | Changes: removed AI tells (So\/lecci\u00f3n pr\u00e1ctica\/ciudadanos de primera clase\/contraintuitivo opener), restructured recommendation section to break parallel imperative pattern, merged redundant closing paragraphs, tightened section header --><\/p>\n","protected":false},"excerpt":{"rendered":"<p>El viernes a las 3pm del segundo sprint que tuvimos con IA corriendo en producci\u00f3n , empuj\u00e9 un \u201ccambio menor\u201d al pipeline de generaci\u00f3n de contenido.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1],"tags":[],"class_list":["post-122","post","type-post","status-publish","format-standard","hentry","category-general"],"_links":{"self":[{"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/posts\/122","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/comments?post=122"}],"version-history":[{"count":21,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/posts\/122\/revisions"}],"predecessor-version":[{"id":628,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/posts\/122\/revisions\/628"}],"wp:attachment":[{"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/media?parent=122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/categories?post=122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.rebalai.com\/es\/wp-json\/wp\/v2\/tags?post=122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}