synthesizeAnswer — gestor de síntesis de respuestas del Oráculo
Descripción
synthesizeAnswer es la función crítica encargada de extraer y decodificar la respuesta JSON del modelo Gemma en los modos oracle, help y tutor de la Biblioteca.
Ubicada en functions/api/mcp/handlers/archivo-core.ts (línea 1138), es async y pública (is_exported: true). Su misión es:
- Llamar a Gemma con un prompt contextualizado (help/oracle/tutor).
- Parsear el JSON que Gemma devuelve (idealmente con la clave
answer). - Extraer la respuesta enriquecida — con markdown (
**bold**, citas) en modo oracle, plana en help. - Garantizar robustez: cuando el parseo JSON falla (evento frecuente en Gemma 4 con markdown largo), aplicar rescates regex inteligentes antes de devolver un fallback genérico.
Entrada / Salida
Parámetros
synthesizeAnswer(
chunks: ChunkMatch[], // Resultados del retrieval (top matches del índice vectorial)
question: string, // Pregunta del usuario
mode: 'oracle' | 'help' | 'tutor', // Modo de síntesis
env: Env // Secretos (API keys de Gemma)
): Promise<string>
Devuelve
- string: la respuesta sintetizada (enriquecida o plana según el modo).
- Si no logra extraer respuesta válida: fallback genérico (
"Tu pregunta es muy amplia..."en oracle, similar en otros modos).
Sub-componentes
1. buildOraclePrompts / buildHelpPrompts / buildTutorPrompts
- Generan el prompt específico del modo (líneas 945, 848, 1052).
- Oracle: pide respuestas ricas en markdown y fuentes citadas.
- Help: respuestas cortas y planas.
- Tutor: estilo educativo, con preguntas abiertas.
2. Llamada a Gemma
- Invoca la API de Google Generative AI con
mode: "json"para forzar salida JSON. - Modelo: Gemma 4 (26B tokens, v4-a4b-it).
- Timeout y retry delegados a nivel de
Env.
3. Rescate de JSON (refactor PR #96)
-
Pasada 1 — ESTRICTA (
/"answer"\s*:\s*"((?:[^"\\]|\\.)*)"/.exec(sanitized)?.[1]):- Respeta escapes JSON estándar (
\",\\,\n,\r,\t). - Corta en la primera comilla SIN escapar.
- Suficiente cuando el problema son caracteres basura tras el
}o newlines raw.
- Respeta escapes JSON estándar (
-
Pasada 2 — GREEDY:
- Localiza la clave
"answer":. - Extrae desde su valor hasta la última comilla del string saneado (el cierre real).
- Tolera comillas internas raw — footgun típico de Gemma 4 en markdown largo.
- Ejemplo:
**Auditoría Suprema**seguido de una cita"..."rompía el JSON.parse. La greedy devuelve el answer completo.
- Localiza la clave
-
Decodificación centralizada:
const decodeJsonEscapes = (s: string): string => s .replace(/\\n/g, '\n') .replace(/\\r/g, '\r') .replace(/\\t/g, '\t') .replace(/\\"/g, '"') .replace(/\\\\/g, '\\') .trim();Aplica tanto al candidato estricto como al greedy; toma el más largo de los dos.
4. Fallback genérico
Si ningún rescate logra extraer texto, devuelve:
- Oracle:
"Tu pregunta es muy amplia. Consulta la documentación específica." - Help: variante más corta.
- Tutor: invita a reformular.
Beneficiarios
Todos los endpoints de síntesis heredan de synthesizeAnswer:
POST /api/oracle— consulta inteligente con citas.POST /api/help— respuesta rápida.POST /api/tutor— diálogo educativo.
Fuente de datos
ChunkMatch[]viene de[[entity--functions--handler--searchchunks]](retrieval vectorial + D1 fallback).- Los chunks contienen:
text: párrafo extraído del documento.source: ruta del archivo (ej:AUDITORIA_SUPREMA.md).score: similitud coseno (0.0–1.0).startLine,endLine: ubicación en el doc original.
Casos de uso recientes
PR #96 (2026-06-05): Robustez JSON — rescate greedy para Gemma 4 con markdown.
- Síntoma: Oracle fallaba en
"¿Qué es la auditoría suprema?"→ devolvía fallback aunque el retrieval encontrabaAUDITORIA_SUPREMA.md(score 0.54). - Causa: comilla sin escapar en
**Auditoría Suprema**"..."rompía el JSON.parse; la pasada estricta devolvía solo**Auditoría Suprema**→ vacío tras decodificación → fallback. - Fix: greedy extrae el answer completo; se conserva el candidato más largo de ambas pasadas.
- Validación local: 4 casos (comilla interna, JSON válido, newline+basura, escapes correctos) — todos pasan.
Véase también
- [[entity—functions—handler—searchchunks]]
- [[entity—functions—handler—buildoracleprompts]]
- [[entity—functions—handler—buildhelpprompts]]
- [[entity—functions—handler—buildtutorprompts]]
- [[concept—biblioteca—gemma-orchestration]]
- [[concept—biblioteca—robustez-json]]
- [[feature—biblioteca—oracle-v1]]