Uso de IA en el trabajo

Usar ejemplos few-shot para hacer más consistente la salida de la IA y comprobarla automáticamente

Muestra a una IA algunos ejemplos de la estructura exacta de salida que quieres y después valida el JSON devuelto antes de utilizarlo. Un pequeño conjunto de tickets sintéticos demuestra cómo funcionan conjuntamente los ejemplos de formato y las comprobaciones automáticas.

Ver el índice

La traducción se ha realizado con IA. Comprueba el código, las unidades y los valores junto con el original. La revisión por hablantes nativos de cada idioma aún no se ha completado. English

Para quién esEsta guía está dirigida a personas que utilizan IA para transformar elementos de trabajo repetitivos y necesitan una salida predecible y legible por máquinas en lugar de texto libre.

Preparación
  • Python 3.12 y un comando de terminal que inicie esa versión.
  • Acceso a un asistente de IA donde puedas pegar el prompt de ejemplo.
  • Un editor de texto que pueda guardar archivos JSON en UTF-8.
  • Para la validación solo se requiere la biblioteca estándar de Python: csv, json y pathlib.

01Definir el contrato de salida antes de escribir el prompt

Supongamos que quieres que una IA convierta tickets breves de soporte en registros estructurados. Cada resultado debe contener exactamente cuatro claves: ticket_id, priority, owner_team y action. priority puede ser LOW, MEDIUM o HIGH. owner_team puede ser IT, FACILITIES o FINANCE. Los cuatro valores deben ser cadenas no vacías.

La idea importante es definir el formato independientemente de la respuesta de la IA. La IA produce un registro candidato. Tu script decide si ese candidato cumple la estructura requerida.

02Crear tres tickets sintéticos

Los siguientes tickets son sintéticos y fueron escritos específicamente para este artículo. Son deliberadamente simples para que puedas determinar manualmente el resultado estructurado previsto.

ticket_idTexto del ticket sintéticoClasificación esperada
T101No se puede abrir la hoja de cálculo de nóminas antes del proceso de pago de hoy.HIGH · FINANCE
T102La luz de la sala de reuniones B parpadea, pero la sala todavía se puede usar.LOW · FACILITIES
T103El portátil del nuevo empleado no puede conectarse al Wi-Fi de la oficina.MEDIUM · IT

Para este tutorial, las acciones esperadas también están fijadas de antemano: T101 debe ser Check payroll workbook access, T102 debe ser Inspect meeting room B light y T103 debe ser Troubleshoot laptop Wi-Fi connection. Estos valores esperados forman parte del ejercicio sintético y no son reglas generales para operaciones reales de soporte.

03Dar a la IA ejemplos del formato exacto

Un prompt few-shot incluye uno o más ejemplos completados antes de las nuevas entradas. Las demostraciones siguientes muestran tanto el estilo de clasificación como la forma exacta del JSON. Utilizan tickets sintéticos distintos de los tres elementos que se comprobarán.

text
Convert each ticket into a JSON object.

Rules:
- Return one JSON array only.
- Do not add explanations or Markdown.
- Use exactly these keys in every object: ticket_id, priority, owner_team, action.
- priority must be LOW, MEDIUM, or HIGH.
- owner_team must be IT, FACILITIES, or FINANCE.

Example 1 input:
Ticket ID: E001
Text: Printer on floor 2 is out of paper.

Example 1 output:
{"ticket_id":"E001","priority":"LOW","owner_team":"IT","action":"Refill or check floor 2 printer"}

Example 2 input:
Ticket ID: E002
Text: Expense approval file is unavailable before today's reimbursement deadline.

Example 2 output:
{"ticket_id":"E002","priority":"HIGH","owner_team":"FINANCE","action":"Check expense approval file access"}

Now process these tickets:
T101: Payroll spreadsheet cannot be opened before today's payment run.
T102: Meeting room B light is flickering but the room is still usable.
T103: New employee laptop cannot connect to the office Wi-Fi.

Los ejemplos muestran más que los nombres de los campos. Demuestran valores de categoría en mayúsculas, frases de acción breves, cadenas JSON entre comillas y la ausencia de comentarios alrededor. Esto reduce la ambigüedad sobre cómo debe presentarse la respuesta.

04Definir la salida esperada antes de ver la respuesta de la IA

Para este ejercicio sintético, la respuesta esperada es el array JSON siguiente. Guarda la respuesta real de la IA como ai_output.json antes de ejecutar el comprobador. No edites silenciosamente una respuesta malformada primero; el objetivo del comprobador es revelar si la respuesta original cumplió el contrato.

json
[
  {
    "ticket_id": "T101",
    "priority": "HIGH",
    "owner_team": "FINANCE",
    "action": "Check payroll workbook access"
  },
  {
    "ticket_id": "T102",
    "priority": "LOW",
    "owner_team": "FACILITIES",
    "action": "Inspect meeting room B light"
  },
  {
    "ticket_id": "T103",
    "priority": "MEDIUM",
    "owner_team": "IT",
    "action": "Troubleshoot laptop Wi-Fi connection"
  }
]

Debe haber exactamente 3 objetos y 12 valores de campo en total. Cada una de las tres prioridades permitidas aparece una vez y cada uno de los tres equipos propietarios permitidos aparece una vez.

05Validar automáticamente la respuesta de la IA

Guarda el script siguiente como check_ai_output.py. Valida la sintaxis JSON, la longitud del array, las claves exactas, los tipos de datos, los valores de categoría permitidos, los IDs de ticket y las clasificaciones sintéticas esperadas. Escribe un CSV de revisión solo después de analizar la respuesta de la IA.

python
import csv
import json
from pathlib import Path

SOURCE = Path("ai_output.json")
OUTPUT_DIR = Path("outputs") / "few_shot_check_result"
REPORT = OUTPUT_DIR / "format_check.csv"

EXPECTED = {
    "T101": ("HIGH", "FINANCE", "Check payroll workbook access"),
    "T102": ("LOW", "FACILITIES", "Inspect meeting room B light"),
    "T103": ("MEDIUM", "IT", "Troubleshoot laptop Wi-Fi connection"),
}
REQUIRED_KEYS = {"ticket_id", "priority", "owner_team", "action"}
PRIORITIES = {"LOW", "MEDIUM", "HIGH"}
TEAMS = {"IT", "FACILITIES", "FINANCE"}


def main() -> None:
    if not SOURCE.is_file():
        raise FileNotFoundError(f"AI output not found: {SOURCE}")
    if OUTPUT_DIR.exists():
        raise FileExistsError(f"Output folder already exists: {OUTPUT_DIR}")

    with SOURCE.open("r", encoding="utf-8") as stream:
        data = json.load(stream)

    if not isinstance(data, list):
        raise ValueError("Top-level JSON value must be an array.")
    if len(data) != len(EXPECTED):
        raise ValueError(f"Expected {len(EXPECTED)} objects, got {len(data)}.")

    rows = []
    seen = set()
    for index, item in enumerate(data, start=1):
        errors = []
        if not isinstance(item, dict):
            raise ValueError(f"Item {index} is not a JSON object.")

        if set(item) != REQUIRED_KEYS:
            errors.append("keys")

        for key in REQUIRED_KEYS:
            if key not in item or not isinstance(item.get(key), str) or not item.get(key).strip():
                errors.append(f"invalid_{key}")

        ticket_id = item.get("ticket_id", "")
        if ticket_id in seen:
            errors.append("duplicate_ticket_id")
        seen.add(ticket_id)

        if item.get("priority") not in PRIORITIES:
            errors.append("priority")
        if item.get("owner_team") not in TEAMS:
            errors.append("owner_team")

        expected = EXPECTED.get(ticket_id)
        if expected is None:
            errors.append("unexpected_ticket_id")
        else:
            actual = (
                item.get("priority"),
                item.get("owner_team"),
                item.get("action"),
            )
            if actual != expected:
                errors.append("content_mismatch")

        rows.append({
            "item": index,
            "ticket_id": ticket_id,
            "status": "PASS" if not errors else "FAIL",
            "errors": ";".join(errors),
        })

    missing_ids = set(EXPECTED) - seen
    if missing_ids:
        raise ValueError(f"Missing ticket IDs: {sorted(missing_ids)}")

    OUTPUT_DIR.parent.mkdir(parents=True, exist_ok=True)
    OUTPUT_DIR.mkdir()
    with REPORT.open("x", encoding="utf-8", newline="") as stream:
        writer = csv.DictWriter(
            stream,
            fieldnames=["item", "ticket_id", "status", "errors"],
        )
        writer.writeheader()
        writer.writerows(rows)

    failures = sum(row["status"] == "FAIL" for row in rows)
    print(f"Objects checked: {len(rows)}.")
    print(f"Passed: {len(rows) - failures}; failed: {failures}.")
    print(f"Report: {REPORT.as_posix()}")

    if failures:
        raise RuntimeError("AI output failed one or more checks.")


if __name__ == "__main__":
    main()

06Comprobar el resultado esperado

Si ai_output.json coincide exactamente con la salida sintética esperada, los 3 objetos deberían aprobar. El texto de consola esperado que aparece a continuación se obtuvo manualmente y no es un registro de ejecución.

text
Objects checked: 3.
Passed: 3; failed: 0.
Report: outputs/few_shot_check_result/format_check.csv
  • Confirma que el nivel superior sea un array JSON y no texto que rodea a un array.
  • Confirma que cada objeto contenga exactamente las cuatro claves obligatorias.
  • Confirma que no falte ningún ticket ni haya tickets duplicados.
  • Confirma que priority y owner_team utilicen únicamente las etiquetas permitidas.
  • Ejecuta de nuevo el comprobador sin cambiar OUTPUT_DIR. Debería detenerse con FileExistsError en lugar de sobrescribir el informe anterior.

07Reconocer fallos comunes y limitaciones

ProblemaQué debería revelar el comprobador
La IA añade una explicación antes del JSONjson.load falla porque el archivo no es un único valor JSON válido.
Un objeto utiliza urgency en lugar de priorityFalla la comprobación de claves exactas.
priority es urgentFalla la comprobación de valores permitidos.
T103 aparece dos vecesFalla la comprobación de ID de ticket duplicado y puede faltar otro ID esperado.
La estructura JSON es válida pero la clasificación es incorrectaSe registra content_mismatch para este ejercicio sintético.

El prompting few-shot mejora la orientación, pero no garantiza una salida determinista. Distintos sistemas de IA, configuraciones, contextos o prompts posteriores pueden cambiar la respuesta. Mantén el validador incluso después de varias ejecuciones satisfactorias.

Este ejemplo valida deliberadamente un esquema pequeño con comprobaciones de Python escritas a mano. Los esquemas de producción más grandes pueden beneficiarse de un sistema formal de esquemas y una validación semántica independiente. Recuerda también que un JSON válido solo demuestra un resultado de formato: la clasificación subyacente puede seguir siendo incorrecta desde el punto de vista factual u operativo.

Registro de ejecución y verificación

2026-09-20 · ejemplo revisado manualmente · objetivo: Python 3.12 · biblioteca estándar: csv, json, pathlib · sin ejecución

  • Se definieron manualmente 3 tickets sintéticos y sus valores esperados de priority, owner team y action.
  • Se comprobó manualmente que el JSON esperado contiene exactamente 3 objetos y 4 claves por objeto.
  • Se confirmó manualmente que LOW, MEDIUM y HIGH aparecen una vez cada uno y que IT, FACILITIES y FINANCE aparecen una vez cada uno.
  • Se revisó el comprobador para el análisis JSON, las comprobaciones de claves exactas, las cadenas no vacías, los valores permitidos, los IDs duplicados, los IDs ausentes y la comparación con el contenido esperado.
  • Se obtuvo manualmente el resultado esperado de 3 aprobados y 0 fallos.
Límites de la verificación
  • El autor de esta respuesta no consultó ningún sistema de IA, por lo que no se probó la consistencia real del modelo.
  • El comprobador de Python no se ejecutó y no se crearon archivos JSON ni CSV.
  • Las clasificaciones sintéticas son valores esperados específicos del ejercicio, no reglas generales de asignación de soporte.
  • Una estructura válida no demuestra que una clasificación generada por IA sea objetivamente correcta.
  • Las URL de la documentación oficial se proporcionaron a partir de ubicaciones de documentación conocidas, pero no se comprobaron en línea.

Criterios de redacción y verificación de todo el sitio

Fuentes de referencia

Las explicaciones y los ejemplos son de elaboración propia. Puedes consultar los comportamientos y conceptos relacionados en las siguientes fuentes oficiales.