Categoría: Productivity

  • Cómo reparar rápidamente archivos JSON mal formados: manual de campo para desarrolladores

    Cómo reparar rápidamente archivos JSON mal formados: manual de campo para desarrolladores

    Tu llamada a la API acaba de fallar con JSONDecodeError: Expecting property name enclosed in double quotes. El reloj corre. Los datos venían de un LLM y, en algún punto de esa respuesta de 2000 tokens, una sola coma final ha matado toda tu pipeline.

    A mayo de 2026, la forma más rápida de reparar archivos JSON mal formados es usar librerías automatizadas como json_repair (Python) o jsonrepair (npm). Estas herramientas están diseñadas específicamente para corregir al instante los errores de sintaxis generados por los LLM. Para las reparaciones manuales, los sospechosos habituales son las comas finales, las comillas simples o las claves sin comillas: las tres violaciones más comunes del estándar RFC 8259.

    La solución más rápida: json_repair para salidas de LLM

    Los parseadores estándar como json.loads() de Python son estrictos por diseño. Un solo carácter mal colocado dispara un JSONDecodeError y todo se detiene. Este es un problema cotidiano en 2026, porque los LLM envuelven habitualmente el JSON en texto conversacional, truncan respuestas a mitad de frase o esparcen comentarios que rompen la especificación.

    La librería json_repair es la solución de referencia. Según GitHub, este proyecto acumula más de 4700 estrellas a 2026. Funciona «adivinando» la intención de la cadena: cierra llaves faltantes, añade comillas y elimina el texto sobrante que rodea al bloque JSON.

    Proceso sencillo de 3 pasos de json_repair: Entrada (rota) -> Adivinar intención -> Salida (válida)

    Python: antes y después

    Instalación: pip install json-repair

    La entrada rota:

    import json_repair
    
    bad_json = '{"user": "Alice", "status": tru'
    decoded_object = json_repair.loads(bad_json)
    

    Lo que ocurrió entre bastidores: json_repair detectó que tru probablemente era true, añadi la llave de cierre faltante y devolvió un diccionario de Python válido. Cero intervención manual.

    Modo Salvage: cuando los datos están realmente feos

    Para los casos más difíciles, json_repair (v0.59.5+) incluye un Modo Salvage. Como se indica en la documentación del proyecto, este modo está construido específicamente para respuestas de IA truncadas o logs corruptos. Puede forzar arrays a objetos o descartar elementos demasiado dañados para salvar, garantizando que la salida se ajuste a tu esquema.

    import json_repair
    
    # Salvage mode for severely truncated data
    result = json_repair.loads(
        '{"items": [{"id": 1, "name": "Widget"}, {"id": 2, "na',
        salvage_mode=True
    )
    # Result: {'items': [{'id': 1, 'name': 'Widget'}, {'id': 2}]}
    # Dropped the incomplete 'na' but saved everything else
    

    Alternativa con npm

    Para proyectos Node.js, el CLI jsonrepair hace el mismo trabajo:

    # Fix a file in place
    npx jsonrepair broken.json > fixed.json
    
    # Fix a string in a script
    const { jsonrepair } = require('jsonrepair');
    const fixed = jsonrepair('{"name": "test",}');
    

    Depuración manual: encontrar qué rompió la especificación

    Cuando la automatización no basta, necesitas encontrar exactamente dónde el archivo viola RFC 8259. JSON es mucho menos indulgente que YAML o JavaScript. Como explica el equipo de diagnóstico de JSONParser: «El parser falla en el primer carácter que no logra interpretar, lo cual suele ser un síntoma posterior de un problema originado varias líneas antes».

    Los tres asesinos del JSON

    Asesino 1: comas finales

    Según la DEV Community, las comas finales son la causa número 1 de fallos de parseo. Son válidas en JavaScript, pero ilegales después del último elemento de un array u objeto JSON.

    // BROKEN - trailing comma after "active"
    {
      "name": "Alice",
      "status": "active",
    }
    
    // FIXED - no comma before closing brace
    {
      "name": "Alice",
      "status": "active"
    }
    

    Asesino 2: comillas simples

    JSON exige comillas dobles (") tanto para claves como para valores de cadena. Muchos desarrolladores de Python y JavaScript usan por accidente comillas simples ('). Como señala TidyCode, esto es una corrección obligatoria.

    // BROKEN - single quotes
    {'name': 'Alice'}
    
    // FIXED - double quotes
    {"name": "Alice"}
    

    Asesino 3: claves sin comillas

    En JavaScript puedes escribir { name: "Alice" }. En JSON, cada clave necesita comillas dobles.

    // BROKEN - unquoted key
    {name: "Alice"}
    
    // FIXED - quoted key
    {"name": "Alice"}
    

    Comparación lado a lado de la sintaxis de JSON inválido frente a JSON válido

    El error «Unexpected Token»

    Cuando un validador marca «Unexpected Token», significa que el parser se topó con NaN, Infinity o undefined: constantes de JavaScript que JSON no admite. JSON solo permite null, true, false y números.

    // BROKEN - NaN is not valid JSON
    {"score": NaN, "result": Infinity}
    
    // FIXED - replace with null or valid values
    {"score": null, "result": null}
    

    Parseo estricto vs. parseo de reparación: cuándo usar cada uno

    El enfoque correcto depende del origen de tus datos. Los archivos de configuración editados por humanos merecen un parseo estricto que obligue al autor a corregir los errores. Los datos generados por máquinas, provenientes de LLM o logs de API, necesitan un parseo basado en reparación.

    Característica Estricto (json.loads) Reparación (json_repair)
    Comas finales Lanza JSONDecodeError Se eliminan automáticamente
    Comillas simples Falla Se convierten a comillas dobles
    Datos truncados Falla Cierra llaves/comillas abiertas
    Comentarios Falla Se eliminan automáticamente
    Caso de uso ideal Archivos de configuración editados por humanos Salidas de LLM, logs de API

    Reparaciones guiadas por esquema con Pydantic

    Puedes guiar el proceso de reparación usando Pydantic v2 o JSON Schema. Al proporcionar a json_repair un esquema, la herramienta hace más que corregir sintaxis: puede corregir tipos (convertir la cadena "1" en el número 1) y rellenar campos obligatorios ausentes con valores por defecto.

    from pydantic import BaseModel
    import json_repair
    
    class User(BaseModel):
        id: int
        name: str
        active: bool = True
    
    # Broken JSON with wrong types
    raw = '{"id": "42", "name": "Alice"}'
    repaired = json_repair.loads(raw)
    
    # Validate against schema
    user = User(**repaired)
    # user.id is now int(42), user.active defaults to True
    

    Como señaló Stefano Baccianella en la cita de su proyecto de 2025, este enfoque está optimizado para el JSON «mayoritariamente correcto pero técnicamente inválido» que los modelos de lenguaje tienden a producir.

    Manejar archivos de varios gigabytes sin caerse

    Reparar un fragmento de 10 KB es fácil. Arreglar un archivo de 2 GB requiere una estrategia que no devore toda tu RAM. Cargar el archivo entero en memoria provoca errores de memoria agotada (OOM).

    Estrategia 1: streaming con ijson

    Para conjuntos de datos masivos, usa ijson para procesar la información pieza a pieza. Como menciona Scrapfly, ijson procesa los datos de forma incremental. Combínalo con un script de limpieza que corrija problemas línea a línea antes del parseo.

    import ijson
    
    # Stream through a large JSON file
    with open('huge_broken.json', 'r') as f:
        for item in ijson.items(f, 'records.item'):
            # Process each item individually
            process(item)
    

    Estrategia 2: tubería CLI para máxima eficiencia

    El enfoque más eficiente en memoria para archivos grandes es usar el CLI jsonrepair y enviar la salida directamente a un archivo nuevo:

    # Streams repair, never loads full file into memory
    jsonrepair large_broken.json > fixed.json
    

    Esto es notablemente más eficiente en memoria que cargar el archivo en Python o en un navegador.

    Conclusión

    Reparar JSON mal formado ya no es una tarea manual gracias a librerías conscientes de la IA como json_repair. Aún necesitas conocer los fundamentos de RFC 8259: sin comas finales, sin comillas simples, sin claves sin comillas, pero la automatización es el único enfoque práctico para los datos a escala en 2026.

    El flujo de trabajo es sencillo: prueba primero una librería de reparación. Si falla, usa un validador para localizar el error de sintaxis exacto. Así mantienes tus aplicaciones en marcha incluso cuando los datos entrantes son menos que perfectos.

    Preguntas frecuentes

    ¿Admite JSON oficialmente comentarios o comillas simples?

    No. El estándar RFC 8259 prohíbe estrictamente los comentarios. Las comillas simples también son inválidas: solo se permiten comillas dobles para claves y cadenas. Sin embargo, herramientas como json_repair pueden eliminar comentarios y convertir comillas automáticamente para que los archivos sean parseables por librerías estándar.

    ¿Cómo manejo archivos JSON mal formados muy grandes sin caerme?

    Usa un parser de streaming como ijson para procesar los datos en bloques. Evita cargar la cadena mal formada entera en una sola variable. Para los resultados más rápidos, usa herramientas de reparación por CLI que envíen la salida directamente a un archivo nuevo en disco sin mantener todo en memoria.

    ¿Cuál es la diferencia entre JSON mal formado y JSON inválido?

    El JSON mal formado (malformed) viola las reglas de sintaxis (llaves faltantes, claves sin comillas, comas finales) y por tanto es imposible de parsear. El JSON inválido (invalid) cumple todas las reglas de sintaxis, pero no coincide con un JSON Schema concreto (por ejemplo, un campo es una cadena cuando el esquema espera un entero). Reparar JSON mal formado es reparación estructural; reparar JSON inválido es cuestión de integridad de datos.

    ¿Puedo usar json_repair con validación de Pydantic?

    Sí. Ejecuta primero json_repair.loads() para corregir los errores de sintaxis y luego pasa el diccionario reparado a tu modelo Pydantic para validación de tipos y aplicación del esquema. Este enfoque en dos pasos cubre tanto los problemas estructurales como los semánticos.

    ¿Qué pasa con JSON que lleva comentarios estilo JavaScript?

    El JSON estándar no admite comentarios, pero json_repair puede eliminar automáticamente los comentarios // y /* */. Si necesitas comentarios en tus archivos de configuración, considera usar el formato JSONC (JSON con comentarios) y un parser compatible como json5 para Python.

  • Cómo escribir prompts de IA con un formateador: ingeniería estructurada para desarrolladores

    Cómo escribir prompts de IA con un formateador: ingeniería estructurada para desarrolladores

    Conoces esa frustración cuando la salida de tu IA no se parece en nada a lo que pediste: el JSON está mal formado, el tono es incorrecto y la mitad de tus instrucciones fueron ignoradas. El problema no es el modelo, sino cómo estás formateando el prompt.

    Para dominar cómo escribir prompts de IA con un formateador, implementa el marco RTCCO (Role, Task, Context, Constraints, Output) usando delimitadores estructurados como XML o JSON. Esto trata a los prompts como activos de software modulares, lo que puede reducir las alucinaciones del modelo hasta en un 60% y recortar el tiempo de procesamiento manual en un 75% a mayo de 2026.

    Por qué tus prompts en forma de párrafo siguen fallando

    Para 2026, el trabajo profesional con IA ha pasado de «chatear» al Prompt-as-Code (PaC). El problema de los prompts en forma de párrafo —esos bloques largos de texto sin estructura— es que los modelos tienen dificultades para separar tus instrucciones reales de los datos en segundo plano o los requisitos de salida mezclados en ellos.

    Los datos de PromptOT muestran que pasar a la ingeniería estructurada puede reducir los errores en un 60% y acelerar el procesamiento manual en un 75%. Alex Ostrovskyy describe los prompts codificados de forma rígida como el «equivalente moderno de los números mágicos en el código fuente»: sistemas frágiles que son casi imposibles de actualizar sin romper algo.

    Antes vs. Después: la diferencia del formateo

    Antes (sin estructura):

    You are a helpful coding assistant. Please write a Python function that validates
    email addresses. Make sure it handles edge cases like plus signs and subdomains.
    The output should be in JSON format with a valid boolean and the cleaned email.
    Also make sure you add proper error handling and don't forget logging.
    

    Después (RTCCO + delimitadores XML):

    <system_instructions>
      <role>Senior Python engineer specializing in input validation</role>
      <primary_objective>Write a production-grade email validator</primary_objective>
    </system_instructions>
    
    <context>
      Must handle: plus addressing ([email protected]), subdomains,
      internationalized domains. Target: Python 3.11+.
    </context>
    
    <task_requirements>
      <rules>
        - Use only stdlib (no regex shortcuts)
        - Return structured JSON
        - Include type hints
      </rules>
      <steps>
        1. Parse the input string
        2. Validate format per RFC 5322
        3. Return JSON with "valid" boolean and "cleaned_email"
      </steps>
    </task_requirements>
    
    <output_format>
      {"valid": bool, "cleaned_email": str, "error": str | null}
    </output_format>
    

    Mismo objetivo, resultados radicalmente diferentes. La versión formateada no le deja al modelo ningún margen para la ambigüedad.

    El marco RTCCO: el esqueleto de tu prompt

    La industria ha convergido en RTCCO como la arquitectura estándar de prompts. Cada prompt se descompone en cinco partes:

    Elemento Propósito Ejemplo
    R ol (Role) ¿Quién es la IA? «Ingeniero backend sénior»
    T area (Task) ¿Qué acción específica? «Escribe un middleware limitador de tasa»
    C ontexto (Context) ¿Qué datos en segundo plano? Recuperación RAG, fragmentos de código
    C restricciones (Constraints) ¿Cuáles son las reglas? «Sin dependencias externas»
    O utput (Salida) ¿Cómo debe verse? «Python 3.11 válido con type hints»

    Los 5 componentes del marco RTCCO

    La plantilla esqueleto XML que puedes copiar ahora

    Aquí está la plantilla lista para producción. Cópiala, adáptala, publícala.

    <system_instructions>
      <role> [Expert Persona] </role>
      <primary_objective> [Main Goal] </primary_objective>
    </system_instructions>
    
    <context>
      [Background Data or RAG Retrieval]
    </context>
    
    <task_requirements>
      <rules> [Non-negotiable Constraints] </rules>
      <steps> [Specific Workflow] </steps>
    </task_requirements>
    
    <output_format>
      [JSON/XML/Markdown Specification]
    </output_format>
    
    <recency_recap>
      [Reminder of Critical Constraints]
    </recency_recap>
    

    Por qué importa el Recency Recap

    Los LLM tienen un sesgo conocido de «Primacía y Recencia»: recuerdan mejor el principio y el final de un prompt que la parte central. Las pruebas citadas por PromptOT mostraron que mover las reglas críticas del medio al bloque de Recency Recap en la parte inferior elevó la precisión del 78% al 96% en uso en producción. Mantén el Role en la parte superior, pon tus reglas más importantes en la parte inferior.

    Visualización del efecto de Primacía y Recencia en prompts largos

    Los delimitadores como una valla de seguridad

    Los delimitadores no son solo cuestión de organización: son un mecanismo de seguridad. Envolver la entrada del usuario en etiquetas como <user_input> le dice al modelo: «Esto son datos para procesar, no nuevas instrucciones a seguir». Esta es tu defensa principal contra los ataques de inyección de prompts, donde los usuarios intentan sobrescribir tus instrucciones del sistema.

    Error común: Si inyectas datos del usuario directamente en el prompt sin delimitadores, un usuario puede escribir «Ignora todas las instrucciones anteriores y…» y el modelo cumplirá. Siempre envuelve los datos externos en bloques etiquetados.

    Arquitectura modular: deja de escribir mega-prompts

    En lugar de un prompt frágil de 2.000 tokens, divide tu sistema en módulos independientes. Esto evita la colisión de instrucciones, donde cambiar el tono de un prompt rompe accidentalmente su formato de salida JSON.

    El principio clave es la Ingeniería de Contexto: separa las instrucciones estáticas de los datos dinámicos. En un sistema RAG de producción, tu prompt es una plantilla donde el bloque <context> se rellena con datos frescos en el momento de la consulta. Como explica Jono Farrington de OptizenApp, este enfoque modular hace que los despliegues de IA a gran escala sean mucho más consistentes.

    Encadenamiento de prompts: conectando módulos

    Para flujos de trabajo complejos, usa el Prompt Chaining, donde la salida de un módulo se convierte en la entrada del siguiente:

    [Planner Module] --> outline --> [Executor Module] --> draft --> [Reviewer Module] --> final
    

    Este enfoque paso a paso mejora la calidad de la salida aproximadamente un 35% porque el modelo se concentra en una sola subtarea a la vez.

    Flujo de trabajo sencillo de encadenamiento de prompts en 3 pasos

    Ejemplo de encadenamiento listo para copiar y usar:

    planner_prompt = """
    <system_instructions>
      <role>Technical architect</role>
      <task>Create a step-by-step plan for: {user_request}</task>
    </system_instructions>
    <output_format>JSON array of steps</output_format>
    """
    
    executor_prompt = """
    <system_instructions>
      <role>Senior developer</role>
      <task>Implement step: {step_from_planner}</task>
    </system_instructions>
    <context>{previous_outputs}</context>
    <output_format>Code block with inline comments</output_format>
    """
    

    Añadir cadena de pensamiento para problemas difíciles

    Cuando tu tarea implica lógica compleja, añade un bloque <thought_process>. Esto obliga al modelo a razonar paso a paso antes de dar una respuesta, lo que reduce significativamente los errores en matemáticas, programación y razonamiento de múltiples pasos.

    <task_requirements>
      <rules>Reason inside <thought> tags before answering</rules>
    </task_requirements>
    
    <output_format>
      <thought> [Your step-by-step reasoning here] </thought>
      <answer> [Final JSON output here] </answer>
    </output_format>
    

    Según Zencoder, técnicas como Tree-of-Thoughts (ToT) extienden esto al pedir al modelo que evalúe múltiples caminos de solución simultáneamente y elija el mejor. Esto es especialmente valioso para decisiones de arquitectura donde no hay una única respuesta correcta.

    Advertencia sobre el costo de tokens

    El razonamiento estructurado consume más tokens. Un bloque típico de <thought_process> añade 200-500 tokens por solicitud. A escala, esto significa mayores costos de API. La contrapartida es la precisión: pagas más por solicitud pero necesitas menos reintentos y menos corrección manual.

    Preparación para producción: versionado, pruebas y CI/CD

    El último paso es tratar los prompts como software. Usa el Versionado Semántico (v1.0.0) para que tu equipo pueda rastrear cambios y revertir al instante cuando una nueva versión del prompt degrade los resultados.

    PromptOT informa que las empresas que gestionan más de 50 prompts pueden ahorrar hasta 400.000 dólares al año al centralizar la gestión y reducir el tiempo que los ingenieros dedican a ajustes manuales.

    Configurar un pipeline CI/CD de prompts

    # .github/workflows/prompt-tests.yml
    name: Prompt Quality Gate
    on: [push]
    jobs:
      test-prompts:
        runs-on: ubuntu-latest
        steps:
          - name: Run Golden Dataset Tests
            run: |
              # Test against 50-200 curated cases
              python scripts/eval_prompts.py \
                --dataset golden_dataset.json \
                --judge-model gpt-4 \
                --min-score 0.85
    
          - name: Regression Check
            run: |
              # Compare new version vs. production
              python scripts/compare_versions.py \
                --staging v2.1.0 \
                --production v2.0.3 \
                --threshold 0.05
    

    Un prompt solo se gradúa de Staging a Production una vez que pasa estas puertas de calidad evaluadas por un «LLM-as-a-judge».

    Conclusión

    La ingeniería de prompts estructurada con formateadores ya no es opcional: es la línea base para cualquiera que construya herramientas de IA confiables. El marco RTCCO, los delimitadores XML y la arquitectura modular son tu pila para convertir salidas impredecibles de LLM en resultados consistentes y listos para producción.

    Comienza con tus prompts más usados y refactorízalos al marco RTCCO usando la plantilla XML anterior. Muévelos al control de versiones, configura una evaluación básica y tendrás una infraestructura de prompts que escala.

    Preguntas frecuentes

    ¿Cómo convierto mis prompts en forma de párrafo al formato de bloques RTCCO?

    Primero identifica la Tarea central y sepárala del Contexto. Envuelve las instrucciones en etiquetas <rules> y proporciona 3-5 ejemplos en etiquetas <examples>. Incluso puedes usar un LLM para que te ayude: dale el prompt «reanaliza este texto no estructurado en el marco RTCCO usando delimitadores XML» y hará el trabajo pesado por ti.

    ¿Debo usar delimitadores XML, JSON o Markdown?

    XML es el estándar de oro actual para separar instrucciones de contenido largo en modelos como Claude y GPT-5 debido a su jerarquía estricta. JSON es mejor cuando necesitas entrada/salida programática para integraciones de API. Markdown funciona para prompts sencillos y legibles por humanos, pero carece de la definición estricta de límites que necesitan los prompts de producción complejos y multicapa.

    ¿Cómo implemento pruebas CI/CD automatizadas para prompts?

    Configura un conjunto de pruebas con un «Golden Dataset» (50-200 casos de prueba curados) y un «LLM-as-a-judge» para evaluar las salidas según una rúbrica. Integra estas pruebas en tu pipeline de GitHub Actions o Jenkins para que cualquier cambio en el prompt se valide en precisión y tono antes del despliegue.

    ¿Cuál es el error más común al cambiar a prompts estructurados?

    Sobrecargar el bloque <context>. Los desarrolladores a menudo vierten bases de código o documentos enteros en el contexto, lo que diluye la atención del modelo. Mantén el contexto enfocado solo en lo directamente relevante para la tarea. Si necesitas hacer referencia a documentos grandes, usa la recuperación RAG para extraer solo las secciones pertinentes.