CreaRack-SL

Tool MCP bib_ask_rejections — Análisis de rechazos del pre-filter de bib_ask

Resumen

Tool MCP que agrupa y analiza los rechazos de pre-filter aplicados por bib_ask (rechazos automáticos sin invocar el LLM). Permite evaluar si el threshold ARCHIVE_MIN_CHARS=500 es demasiado estricto o si hay contenido denso siendo descartado innecesariamente.

Introducida en commit s90 (28-05-2026) como respuesta a necesidad de observabilidad profunda del pipeline de ingesta de conocimiento.

Contexto

bib_ask tiene un pre-filter que rechaza preguntas sin necesidad de LLM:

  • Answer demasiado corta (<500c).
  • Sources insuficientes.
  • Patrón de caller-disabled.

Estos rechazos se registran en bib_wiki_log con operation='query' + actor='agent-query-rejection' + artifacts JSON con detalles (question, answer_length, sources_count, question_words, reason).

Firma de la tool

bib_ask_rejections(
  days: number = 7,
  min_chars: number = 0,
  max_chars: number = 100000,
  limit: number = 50
) → {
  days: number,
  min_chars: number,
  max_chars: number,
  total_rejections: number,
  rejections_in_range: number,
  reasons_breakdown: [
    {
      reason: string,
      count: number
    }
  ],
  samples: [
    {
      question: string,
      answer_length: number,
      sources_count: number,
      question_words: number,
      reason: string,
      duration_ms: number,
      created_at: string
    }
  ]
}

Parámetros

  • days (opcional, default=7): Ventana retrospectiva en días.
  • min_chars (opcional, default=0): Mínima longitud de answer para incluir en samples.
  • max_chars (opcional, default=100000): Máxima longitud de answer para incluir en samples.
  • limit (opcional, default=50): Máximo número de samples a devolver (internamente se piden 5x para tener margen tras filtrar).

Retorno

  • total_rejections: Total de rechazos en la ventana (sin filtro min/max).
  • rejections_in_range: Rechazos que caen en el rango [min_chars, max_chars] (pueden ser menos que limit si no hay suficientes).
  • reasons_breakdown: Tabla de frecuencias por razón de rechazo (p.ej. “pre-filter:answer-too-short-or-sparse”), ordenada desc.
  • samples: Array de detalles de los rechazos más recientes en rango, up to limit.

Implementación

Ubicada en functions/api/mcp/handlers/wiki.ts::wikiBibAskRejections() (líneas ~2000–2090).

Logging en archivo.ts

Cuando bib_ask rechaza por pre-filter (y no por caller-disabled), se registra:

// Best-effort: si falla el log no rompemos bib_ask
await env.DB.prepare(
  `INSERT INTO bib_wiki_log (operation, actor, summary, artifacts, tokens_used, duration_ms)
   VALUES ('query', 'agent-query-rejection', ?, ?, 0, ?)`
)
  .bind(
    `bib_ask rejected: ${archiveOutcome.reason}`.slice(0, 500),
    JSON.stringify({
      question: question.slice(0, 300),
      answer_length: result.answer.length,
      sources_count: result.sources.length,
      question_words: questionWords,
      reason: archiveOutcome.reason,
    }),
    result.durationMs,
  )
  .run();

Razones conocidas (valores de reason):

  • pre-filter:answer-too-short-or-sparse — <500c de respuesta.
  • pre-filter:insufficient-sources — <2 fuentes.
  • caller-disabled — invocante deshabilitó bib_ask (se ignora en logging).

Casos de uso

  1. Evaluar threshold ARCHIVE_MIN_CHARS=500: Si hay muchos rechazos en rango 300–500c, quizá el threshold es demasiado estricto.

    Ejemplo: bib_ask_rejections(days=7, min_chars=300, max_chars=500) → si rejections_in_range > 5% del total, considerar bajar a 350c.

  2. Detectar patrones de preguntas rechazadas: ¿Qué tipos de preguntas generan respuestas cortas? (p.ej. preguntas de sí/no, nombres simples).

  3. Auditar cambios de pre-filter: Si haces cambios heurísticos en bib_ask, comparar reasons_breakdown antes/después.

Ejemplo de salida

{
  "days": 7,
  "min_chars": 0,
  "max_chars": 100000,
  "total_rejections": 23,
  "rejections_in_range": 15,
  "reasons_breakdown": [
    { "reason": "pre-filter:answer-too-short-or-sparse", "count": 19 },
    { "reason": "pre-filter:insufficient-sources", "count": 4 }
  ],
  "samples": [
    {
      "question": "¿Cuál es la versión de Django?",
      "answer_length": 180,
      "sources_count": 1,
      "question_words": 5,
      "reason": "pre-filter:answer-too-short-or-sparse",
      "duration_ms": 23,
      "created_at": "2026-05-28T09:45:12Z"
    }
  ]
}

Registro de cambios

VersiónCambioFecha
1.0Introducción en s90 + logging en archivo.ts2026-05-28

Notas de implementación

  • Best-effort logging: Si el INSERT a bib_wiki_log falla, no rompe bib_ask. El catch lo silencia.
  • Truncado de question: Se guarda solo los primeros 300c (espacio limitado en JSON artifacts). Los samples devueltos también están truncados.
  • Parsing defensivo: La tool usa try-catch al parsear artifacts JSON; si está malformado, se salta esa fila.

Véase también

  • [[entity—biblioteca—tool—bib-pipeline-stats]]
  • [[entity—biblioteca—tool—bib-ask]]
  • [[feature—biblioteca—lint-limit-bump-auto-alert]]
  • [[concept—biblioteca—supercontexto]]