Volver a la wiki

Tabla D1: oraculo_queries (telemetría Oráculo de EL)

Tabla D1: oraculo_queries

Migración: 0031_create_oraculo_queries.sql · Añadida en: s72 (2026-05-19)

Tabla de telemetría para el Oráculo de EL. Registra metadatos de cada llamada a POST /api/oraculo/ask para iterar el prompt, detectar gaps en el corpus y medir latencia. No almacena respuestas (privacidad + tamaño de BD).


Schema

CREATE TABLE IF NOT EXISTS oraculo_queries (
  id             INTEGER PRIMARY KEY AUTOINCREMENT,
  question       TEXT    NOT NULL,
  sources_count  INTEGER NOT NULL DEFAULT 0,   -- chunks usados (0 = sin matches)
  top_relevance  REAL,                          -- score mejor chunk (0..1) o NULL
  duration_ms    INTEGER NOT NULL DEFAULT 0,
  mode           TEXT    NOT NULL DEFAULT 'oracle',  -- por si se añaden variantes
  created_at     TEXT    NOT NULL DEFAULT (datetime('now'))
);

CREATE INDEX IF NOT EXISTS idx_oraculo_queries_created_at
  ON oraculo_queries(created_at DESC);

Campos

CampoTipoDescripción
idINTEGER PKAutoincremento
questionTEXTPregunta del usuario (truncada a 500 chars en el handler)
sources_countINTEGERNúmero de chunks usados en la respuesta. 0 = sin matches en Vectorize/D1
top_relevanceREALScore coseno del chunk más relevante (rango 0..1). NULL si sources_count=0
duration_msINTEGERLatencia total del handler desde recepción hasta respuesta
modeTEXTSiempre 'oracle' en esta versión. Campo reservado para variantes futuras
created_atTEXTISO 8601 UTC. Índice DESC para consultas recientes primero

Uso para análisis

-- Preguntas frecuentes (sin matches → gap en corpus)
SELECT question, COUNT(*) as n
FROM oraculo_queries
WHERE sources_count = 0
GROUP BY question
ORDER BY n DESC
LIMIT 20;

-- Latencia promedio por día
SELECT DATE(created_at) as dia, AVG(duration_ms) as avg_ms, COUNT(*) as calls
FROM oraculo_queries
GROUP BY dia
ORDER BY dia DESC;

-- Calidad de retrieval (relevancia promedio)
SELECT DATE(created_at) as dia, AVG(top_relevance) as avg_rel
FROM oraculo_queries
WHERE top_relevance IS NOT NULL
GROUP BY dia;

Inserción best-effort

El handler logQuery() en functions/api/oraculo/ask.ts envuelve el INSERT en try/catch silencioso. Si D1 no está disponible o el INSERT falla por cualquier razón, la respuesta al cliente no se ve afectada. Este patrón está documentado explícitamente en el commit como “best-effort para no bloquear respuesta”.


Contexto de diseño

La decisión de no almacenar respuestas responde a:

  1. Tamaño: las respuestas pueden ser largas (hasta 350 palabras en markdown); acumularlas inflaría la BD D1 con bajo valor.
  2. Contenido sensible: las respuestas pueden incluir fragmentos de ADRs, decisiones de equipo, datos internos.
  3. Propósito de la telemetría: basta con saber qué se pregunta y cómo va el retrieval, no qué se responde.

Véase también

Subir