CtrlK
BlogDocsLog inGet started
Tessl Logo

katas-validation-retry-feedback

Validacion y retry con error feedback especifico; distinguir recuperable de no recuperable; max 2-3 intentos y luego escalar.

SKILL.md
Quality
Evals
Security

Kata 26 · Validación y Retry con Error Feedback

Qué es

Cuando una extracción tipada falla la validación (Pydantic / JSON Schema), no se reintenta a ciegas: se hace retry-with-error-feedback. La nueva llamada incluye el documento original, la extracción que falló y el error específico que produjo la validación, con la instrucción de corregir solo lo que el error señala. Se permiten máximo 2-3 intentos. La distinción clave es entre errores recuperables (formato, tipo, campo mal estructurado) y no recuperables (el dato simplemente no existe en la fuente).

Por qué importa (falla que evita)

  • Reintentar con el mismo prompt, sin feedback, es puro ruido: el modelo no sabe qué corregir y repite el mismo error.
  • Aceptar una salida que falló validación en silencio rompe los contratos downstream que dependen del schema.
  • Reintentar cuando el dato no existe en la fuente garantiza una alucinación: el modelo inventará un valor para satisfacer el schema.

Modelo mental

  • Loop: extract → validate → (si error) extract+feedback → validate.
  • Máximo 2-3 intentos; el feedback debe ser el error específico, no un mensaje genérico.
  • Tras N intentos sin éxito: marcar needs_human_review con la cadena de errores acumulados.
  • Error recuperable (formato) y error no recuperable (información ausente en la fuente) son ramas distintas del flujo.
  • Si el 80% de los fallos es el mismo error sistemático, el fix no es subir max_retries: es ajustar el schema/prompt o normalizar en post-process.

Patrón correcto

def is_recoverable(error_str):
    # recuperable = formato/tipo (reintentar con feedback);
    # no recuperable = dato ausente en la fuente (escalar, NO inventar)
    return any(k in error_str.lower() for k in ["format", "type", "invalid", "malformed"])

def extract_with_retry(client, doc, schema, max_retries=2):
    errors = []                       # cadena de errores, no solo el último
    extraction = None
    for attempt in range(max_retries + 1):
        feedback = (
            f"Intento previo falló: {errors[-1]}\n"
            f"Output previo: {extraction}\n"
            "Corrige SOLO lo que el error señala."
        ) if errors else ""
        resp = client.messages.create(
            tools=[schema],
            tool_choice={"type": "tool", "name": schema["name"]},
            messages=[{"role": "user", "content": doc + feedback}],
        )
        extraction = resp.tool_use.input
        try:
            validate(extraction, schema)
            return {**extraction, "attempts": attempt + 1}
        except ValidationError as e:
            errors.append(str(e))
            if not is_recoverable(str(e)):   # no recuperable → escalar de inmediato
                return {**(extraction or {}), "needs_human_review": True,
                        "error_chain": errors, "classification": "non-recoverable"}
    return {**(extraction or {}), "needs_human_review": True, "error_chain": errors}

Anti-patrón

for _ in range(5):
    ext = extract(doc)
    try:
        validate(ext)
        return ext
    except Exception:
        continue  # mismo prompt, sin feedback: ruido puro
# ...y aceptar una salida fallida en silencio downstream

Mismo prompt cinco veces sin feedback específico, más aceptar la salida fallida sin marcarla.

Argumento de certificación

  • Distinguir error recuperable (formato) de no recuperable (dato ausente en la fuente).
  • Describir el loop con feedback específico (error real, no mensaje genérico).
  • Identificar patrones sistemáticos para un fix estructural en lugar de subir retries.
  • Escalar con la cadena de errores cuando max_retries se agota (needs_human_review).

Cuándo activar

  • Una extracción tipada (Pydantic / JSON Schema) falla validación y hay que decidir el retry.
  • Escenarios CI/CD y Structured Extraction donde el contrato downstream exige salida válida.
  • Cuando aparece un loop de reintentos sin feedback o se acepta salida inválida en silencio.

Skills relacionadas

  • katas-provenance-preservation
  • katas-confidence-stratified-sampling
  • katas-false-positive-criteria
  • katas-multipass-prompt-chaining

Packet

Capas del packet, cargables bajo demanda (disciplina ICM: una capa por vez, nunca todas juntas): knowledge/ cuerpo de conocimiento · prompts/ prompts listos · examples/ salida de ejemplo · agents/ subagentes del packet · templates/ plantilla de output.

Repository
JaviMontano/claude-plugins
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.