ADR: Migración síntesis Help Widget a Gemma 4 E2B Q4_0 self-host
⚠️ SUPERSEDED · s53 (08-05-2026) — solo 1 día después de su aceptación.
Esta decisión fue revertida en s53. El catálogo de Google AI Studio NO ofrece Gemma 4 E2B (solo
gemma-4-26b-a4b-itygemma-4-31b-it), pero la dependencia de un servidor self-host fue eliminada al dar de bajapve-epyc-02. La síntesis del Help Widget vive ahora en Google AI Studio Paid Tier congemma-4-26b-a4b-it(mismo modelo que Auto-Plan/CNS/ITSM, unifica el stack AI bajo Regla 8).Referencias:
- Baja del servidor: ver entity [[entity—biblioteca—service—llama-help]] (también archived).
- Estado actual del stack AI: [[decision—20260511—cleanup-openrouter-monoproveedor-google-genai]] (s55).
ADR conservado como referencia histórica del intento self-host.
Fecha: 2026-05-07
Autor: @Esquembri
Commit: 8600d883a5c3342216ea5578c090191dbc867884
Estado: Superseded (s53)
Contexto
El Help Widget de CreaRack Pro usa un pipeline RAG para responder preguntas de usuarios: el endpoint bib_ask (CF Pages Function) recupera chunks del Archivo vía Vectorize + D1, y luego llama a un modelo LLM externo para sintetizar la respuesta final (synthesizeAnswer en archivo-core.ts).
Historial de backends de síntesis
| Fecha | Backend | Modelo | Motivo de cambio |
|---|---|---|---|
| 2026-04-28 | OpenRouter | Gemma 4 26B-A4B-IT | Sustituye Gemini 2.5 Flash (ver decision--20260428) |
| 2026-05-07 AM | Google AI Studio (paid tier) | Gemma 4 26B-A4B-IT | OpenRouter devolvía 401 “User not found” — ruptura producción |
| 2026-05-07 PM | llama.cpp self-host | Gemma 4 E2B Q4_0 | Este ADR |
La cuenta OpenRouter rompió en producción (s52). Se migró de emergencia a Google AI Studio paid tier con el mismo modelo 26B. Sin embargo, ese backend presentaba problemas propios:
- Latencia: ~28 s por consulta (modelo 26B, scratchpad visible).
- Scratchpad leak: el modelo emitía chain-of-thought en texto plano; requería una función
stripScratchpad()frágil con marcadores===INICIO===/===FIN===. - Estilo robótico: respuestas con 5 negritas y citas por línea, estilo no coloquial.
- GDPR: datos salen de la infraestructura EU hacia servidores de Google.
Decisión
Migrar synthesizeAnswer a un servidor llama.cpp self-hosted ejecutando Gemma 4 E2B Q4_0 (unsloth/gemma-4-E2B-it-GGUF) en LXC 100 de pve-epyc-02, expuesto públicamente via Cloudflare Tunnel como https://llama-help.crearack.com.
Cambios de código (commit 8600d88)
archivo-core.ts:SYNTHESIS_MODEL:gemma-4-26b-a4b-it→gemma-4-E2B-it-Q4_0GOOGLE_AI_BASE_URL→LLAMA_HELP_URL = "https://llama-help.crearack.com/v1/chat/completions"- Formato de request: Gemini
contents[]→ OpenAI-compatiblemessages: [system, user] - Parsing:
candidates[0].content.parts[0].text→choices[0].message.content - Prompt:
system_prompt+user_promptseparados (estilo más coloquial, sin marcadores) stripScratchpad(): eliminada (llama-server con--jinjaseparareasoning_contentautomáticamente)
biblioteca/ask.tsyarchivo.ts: env guardGOOGLE_AI_API_KEY→LLAMA_HELP_API_KEYtypes.ts: añadeLLAMA_HELP_API_KEY?: stringal interfaceEnv
Infraestructura paralela (ejecutada manualmente, s52 PM)
- LXC 100 en pve-epyc-02: nuevo systemd unit
llama-server-e2b.service- Puerto 8081 (localhost only), túnel via CF hacia
llama-help.crearack.com - Modelo: Gemma 4 E2B Q4_0 (
unsloth/gemma-4-E2B-it-GGUF) - Sampling oficial Gemma 4:
temp=1.0 / top_p=0.95 / top_k=64 --jinjahabilitado (separa chain-of-thought areasoning_content)- 16 threads, ctx 16384, sin mmproj (text-only)
- Puerto 8081 (localhost only), túnel via CF hacia
- CF Tunnel: expone LXC 100:8081 como subdominio público HTTPS
Motivaciones
1. GDPR / soberanía de datos
Los datos de los usuarios (preguntas + fragmentos de documentación) no salen de la infraestructura de Edu (pve-epyc-02). Cumple el constraint de equipo documentado en memoria feedback_no_openrouter_no_gemini_solo_gemma4_aistudio_eu (s52).
2. Latencia
- Antes (26B AI Studio): ~28 s
- Ahora (E2B Q4_0 self-host): ~5–15 s a ~43 tok/s
3. Estilo de respuesta
El modelo 2B con prompt sistema específico responde de forma coloquial, con frases cortas, sin las 5 negritas/cita por línea que producía el 26B en AI Studio.
4. Simplicidad técnica
- Elimina
stripScratchpad()y la dependencia de marcadores frágiles. - API OpenAI-compatible: menos código de adaptación que la API Gemini.
--jinjaen llama-server separa automáticamente chain-of-thought.
5. Constraint de equipo
Cumple “Solo Gemma 4, NO Gemini, NO OpenRouter” (s52).
Consecuencias
Positivas
- Latencia reducida 2-5×.
- Respuestas con mejor estilo UX.
- GDPR EU compliant.
- Código más simple (eliminación de
stripScratchpad). - Sin dependencia de APIs externas de pago para síntesis.
Riesgos / trade-offs
- Disponibilidad: si pve-epyc-02 cae o el CF Tunnel se interrumpe,
bib_askretorna 503. No hay fallback automático a AI Studio. - Calidad: el modelo E2B (2B params) es significativamente menor que el 26B. En preguntas complejas puede ser menos preciso.
- Mantenimiento infra: el systemd unit y el túnel CF son infra adicional gestionada manualmente.
- Nueva variable de entorno:
LLAMA_HELP_API_KEYdebe configurarse en CF Pages (secreto). Hasta que esté configurada,bib_askretorna 503.
Alternativas descartadas
| Alternativa | Razón de descarte |
|---|---|
| Mantener Google AI Studio 26B | Latencia ~28s, scratchpad leak, GDPR fuera EU |
| OpenRouter | 401 “User not found” en producción, fiabilidad |
| Gemini 2.5 Flash | Viola constraint “Solo Gemma 4” del equipo |
| Modelo diferente en self-host | El equipo mantiene constraint Gemma 4; E2B es el único GGUF 2B disponible |
Véase también
- [[decision—20260428—gemma-4-via-openrouter-migration]]
- [[entity—biblioteca—service—llama-help]]
- [[feature—biblioteca—bib-ask-synthesis]]
- [[entity—biblioteca—handler—archivo-core]]
- [[concept—infra—self-host-llm]]