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.
Contenido revisado 2026.09.20Incluye archivos de ejemplo
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_id
Texto del ticket sintético
Clasificación esperada
T101
No se puede abrir la hoja de cálculo de nóminas antes del proceso de pago de hoy.
HIGH · FINANCE
T102
La luz de la sala de reuniones B parpadea, pero la sala todavía se puede usar.
LOW · FACILITIES
T103
El 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.
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.
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
Problema
Qué debería revelar el comprobador
La IA añade una explicación antes del JSON
json.load falla porque el archivo no es un único valor JSON válido.
Un objeto utiliza urgency en lugar de priority
Falla la comprobación de claves exactas.
priority es urgent
Falla la comprobación de valores permitidos.
T103 aparece dos veces
Falla 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 incorrecta
Se 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.
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.
Las explicaciones y los ejemplos son de elaboración propia. Puedes consultar los comportamientos y conceptos relacionados en las siguientes fuentes oficiales.
Convierte “automatiza esto” en una descripción de tarea ejecutable. Adjunta una muestra sintética sin datos sensibles y un resultado esperado comprobado manualmente para completar una solicitud de script que totalice registros de trabajo por equipo.
Comprueba una función de agregación con cuatro filas que puedes calcular manualmente y 12 unit tests. Verifica no solo valores normales, sino también entrada vacía, cero, decimales y entrada no válida.
Divide un resumen plausible en hechos, cálculos e interpretaciones. Recalcula proporciones y promedios a partir de datos mensuales sintéticos y reescribe las frases con fuentes faltantes o causas exageradas para convertirlas en afirmaciones comprobables.
Trata una expresión regular generada por IA como un borrador, no como una regla terminada. Crea una pequeña tabla de pruebas sintéticas, compara las coincidencias esperadas con las reales, corrige el patrón y guarda un informe de revisión antes de usarlo con datos reales.