Tabla D1: oraculo_queries — Telemetría del Oráculo de EL
Descripción
Tabla D1 (Cloudflare) que registra la telemetría de cada llamada a POST /api/oraculo/ask. Creada en la migración 0031_create_oraculo_queries.sql (PR #50, s72 · 2026-05-19).
No almacena respuestas generadas — solo la pregunta (truncada a 500 chars), contadores de retrieval y latencia. Esto mantiene la BD ligera y evita reproducir contenido potencialmente sensible.
Schema
CREATE TABLE IF NOT EXISTS oraculo_queries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
question TEXT NOT NULL, -- pregunta del usuario, max 500 chars
sources_count INTEGER NOT NULL DEFAULT 0, -- nº de chunks usados en síntesis (0 = sin matches)
top_relevance REAL, -- score coseno del mejor chunk (0.0–1.0), NULL si 0 matches
duration_ms INTEGER NOT NULL DEFAULT 0, -- latencia total del handler en ms
mode TEXT NOT NULL DEFAULT 'oracle', -- variante del modo (reservado para futuras extensiones)
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX IF NOT EXISTS idx_oraculo_queries_created_at
ON oraculo_queries(created_at DESC);
Columnas
| Columna | Tipo | Descripción |
|---|---|---|
id | INTEGER PK | Autoincremental |
question | TEXT | Pregunta enviada por el usuario, truncada a 500 chars en el handler |
sources_count | INTEGER | Número de chunks de bib_chunks utilizados en la síntesis. 0 indica que no hubo matches en el grafo |
top_relevance | REAL | Score de similitud coseno del chunk más relevante (0.0–1.0). NULL cuando sources_count = 0 |
duration_ms | INTEGER | Latencia total del handler onRequestPost desde startedAt hasta el INSERT |
mode | TEXT | Siempre 'oracle' por ahora. Campo reservado por si se añaden variantes del Oráculo |
created_at | TEXT | ISO datetime UTC (datetime('now') de SQLite/D1) |
Índices
| Índice | Columna | Motivo |
|---|---|---|
idx_oraculo_queries_created_at | created_at DESC | Facilita la limpieza periódica por fecha y consultas de telemetría recientes |
Comportamiento del INSERT
El INSERT se ejecuta en la función logQuery() de functions/api/oraculo/ask.ts. Es best-effort:
try {
await env.DB.prepare(
`INSERT INTO oraculo_queries (question, sources_count, top_relevance, duration_ms, mode)
VALUES (?, ?, ?, ?, 'oracle')`
).bind(question.slice(0, 500), sourcesCount, topRelevance, durationMs).run();
} catch {
// silencioso — no bloquea la respuesta al usuario
}
Si el INSERT falla (p. ej. D1 no disponible o schema mismatch tras una migración), la respuesta al usuario no se ve afectada.
Casos de uso
- Iterar el prompt: revisar qué pregunta el equipo para ajustar el system prompt del modo
oracle. - Detectar gaps en el corpus: filas con
sources_count = 0indican áreas del universo EsfericLabs no indexadas enbib_chunks. - Métricas de latencia:
AVG(duration_ms)agrupado por día para detectar regresiones de rendimiento. - Relevancia media:
AVG(top_relevance)como proxy de calidad del retrieval.
Consultas útiles (D1 / Wrangler)
-- Preguntas sin matches en el grafo (gaps de corpus)
SELECT question, created_at FROM oraculo_queries
WHERE sources_count = 0 ORDER BY created_at DESC LIMIT 20;
-- Latencia media por día
SELECT date(created_at) AS dia, ROUND(AVG(duration_ms)) AS avg_ms, COUNT(*) AS queries
FROM oraculo_queries GROUP BY 1 ORDER BY 1 DESC LIMIT 14;
-- Top relevance media por semana
SELECT strftime('%Y-W%W', created_at) AS semana, ROUND(AVG(top_relevance), 3) AS avg_rel
FROM oraculo_queries WHERE top_relevance IS NOT NULL GROUP BY 1 ORDER BY 1 DESC;
Migración
- Archivo:
migrations/0031_create_oraculo_queries.sql - Número: 0031
- Fecha: 2026-05-19
- PR: #50 (s72)
Véase también
- [[feature—workspace—oraculo-de-el]]
- [[workspace—que-es-workspace]]
- [[workspace—dashboard]]