Ingest Bibliotecario en 3 capas: pre-LLM + Haiku + Sonnet caching
ADR — Ingest Bibliotecario en 3 capas: pre-LLM + Haiku + Sonnet caching
Contexto
El Bibliotecario-Ingest es el agente automático del Supercontexto que mantiene la wiki viva tras cada merge a main en CreaRack-Pro y CreaRackSL-workspace. Vive en .github/scripts/bib_ingest.py y se dispara desde .github/workflows/post-merge-ingest.yml (eventos pull_request: closed + merged==true y push: main).
En la sesión 7 del plan Supercontexto (Fase 3, 2026-04-22) el ingest quedó operativo con un único modelo: Claude Sonnet 4.6 procesando todo merge que llegara. Una primera medición arrojó ~$0.17 por run de ~55k tokens. Con un volumen estimado de ~10 pushes/día (CreaRack-Pro + workspace) la proyección era de ~$50/mes solo en ingest, sin contar Fase 4 (Query con cierre), Fase 5 (Lint automatizado) ni el Curator diario, todos consumidores adicionales de Anthropic API.
Edu pidió optimizar la economía antes de avanzar al resto del plan. La sesión 8 (2026-04-22) adelantó la evaluación Haiku que originalmente vivía en Fase 6 y la fundió con un filtro pre-LLM y prompt caching en una sola entrega.
Problema
Tres observaciones empíricas convergen:
- La mayor parte de los merges son triviales para la wiki:
chore:,style:,test:,ci:,docs:, bumps de versión, refactors mecánicos, commits del propio Supercontexto que tocansrc/content/wiki/. Estos no merecen análisis profundo y no aportan páginas nuevas. - Los merges “no triviales” requieren juicio: distinguir un
feat:con lógica nueva de unfeat:cosmético no se resuelve con reglas duras — necesita un LLM que entienda el diff. - El system prompt + las 7 tool definitions del Bibliotecario son idénticas en cada iteración del agentic loop: ~6-8k tokens repetidos entre 5 y 25 veces por run. Cobrarlos a precio completo en cada vuelta es desperdicio.
Pagar Sonnet 4.6 a tarifa plena en los tres escenarios es indefendible cuando el coste por commit trivial es el mismo que por commit valioso.
Opciones consideradas
1. Solo Sonnet, todo lo que merge llega. Simplicidad máxima: un único modelo, un único prompt. Calidad de extracción óptima en todos los casos. Coste base ~$50/mes con tendencia a crecer linealmente con el ritmo de commits del equipo. Descartada por economía insostenible — el ingest es solo una de las cinco fases consumidoras.
2. Solo Haiku, todo lo que merge llega. ~5× más barato que Sonnet por token. Suficiente para clasificar y para páginas simples, pero insuficiente para extraer correctamente entidades de PRs grandes con múltiples archivos ricos (modelos + endpoints + servicios + migraciones). Sacrifica calidad estructural de las páginas (tags densos, related correctos, secciones obligatorias del schema). Descartada porque la wiki Supercontexto tiene requisitos de densidad que Haiku cumple peor en runs largos.
3. Filtro humano (revisión manual de qué disparar). Coste API cero. Trasladar la decisión a Edu o Dani vía label de PR o aprobación explícita. Elimina por completo el riesgo de gastar en triviales. Descartada por dos razones: (a) introduce fricción en cada merge y un SPOF humano contrario a la Regla 17, y (b) el sistema dejaría de ser auto-mantenido — la promesa central del Supercontexto operativo.
4. Pipeline 3-tier (pre-LLM filter + Haiku triage + Sonnet con caching). Adoptada. Cascada de tres capas, cada una más cara y más informada que la anterior, con criterio de salida temprana en cualquiera de ellas.
Decisión
bib_ingest.py ejecuta tres tiers en cascada. La primera decisión skip corta el flujo y registra el motivo en bib_wiki_log vía log_skip_to_mcp para auditoría desde el Pulse.
Tier 1 — Filtro pre-LLM (coste 0)
decide_pre_llm_skip() aplica reglas estáticas en orden:
is_wiki_only_pr()— todos los archivos caen enSKIP_ONLY_PATTERNS(src/content/wiki/,.github/scripts/bib_,.github/workflows/post-merge-ingest,scripts/harness/,public/supercontext/). Cubre commits del propio sistema.is_trivial_commit_type()— el título empieza porSKIP_COMMIT_TYPES(chore,style,test,ci,perf,docs,build,supercontext) y ninguno de los archivos cae enRICH_PATH_PATTERNS(/models.py,/api.py,/services.py,/services/,/handlers/,/tasks.py,/schemas.py,/admin.py,functions/api/,functions/_lib/,migrations/). Unchore:que tocamodels.pysigue al tier siguiente.- Diff total inferior a
MIN_DIFF_LINES_THRESHOLD = 30líneas (additions + deletionsde la GitHub API) sin paths ricos.
Coste de este tier: 0 tokens API. Filtra empíricamente el grueso del tráfico.
Tier 2 — Triage con Haiku 4.5 (~$0.01 por invocación)
triage_with_haiku() invoca claude-haiku-4-5 con un TRIAGE_SYSTEM_PROMPT corto (criterios process / skip) y el contexto del PR (título, descripción, lista de archivos, primeros ~12k chars del diff). Haiku responde JSON estructurado de una sola línea: {"decision":"process"|"skip","reason":"...","likely_type":"entity_page|feature_page|..."|null}.
Si Haiku falla o devuelve JSON inválido, el fallback es conservador: decision = "process". Es preferible pagar un Sonnet de más que perder una página por un parser frágil.
Tier 3 — Sonnet 4.6 con prompt caching
Solo si Tier 2 dice process. run_ingest() ejecuta el agentic loop contra claude-sonnet-4-6 con hasta 25 iteraciones y las 7 tools MCP (bib_impact_query, bib_context_query, bib_ask, bib_search_nodes, wiki_create_page, wiki_update_page, wiki_log_event).
El system prompt y la última tool definition se marcan con cache_control: {"type": "ephemeral"} (TTL 5 minutos). En la iteración 1 se paga cache_creation_input_tokens; en las iteraciones 2 a N se paga cache_read_input_tokens a aproximadamente ~10% del coste regular sobre los tokens cacheados. La telemetría loguea cache_read y cache_write por iteración para auditar la efectividad del caching.
Consecuencias
- Positivo · ahorro real medido: proyección de ~80% (de ~$50/mes a ~$10/mes), validada con el primer caso real en sesión 9 — un PR no trivial procesado por el pipeline completo costó ~$0.40 con
cache_read = 76 204tokens en una sola pasada de 64k tokens totales. - Positivo · auto-mantenido: cero intervención humana en la decisión de gasto. Cumple Regla 17.
- Positivo · auditable: cada skip (Tier 1 o Tier 2) genera fila en
bib_wiki_logcon razón legible. El Pulse muestra el ratio skip/process y el origen. - Positivo · graceful degradation: si Haiku cae, fallback a Sonnet. Si Anthropic está caído por completo, el filtro pre-LLM aún funciona y los skips quedan registrados.
- Negativo · falsos negativos en Tier 1: un commit
feat:muy corto (<30 líneas) que toque solo archivos fuera deRICH_PATH_PATTERNSpuede ser saltado por el umbral de líneas. Riesgo aceptado a cambio del ahorro; un commit así rara vez introduce una página wiki real. - Negativo · juicio frágil de Haiku en Tier 2: Haiku puede decir
skipsobre un PR que merecía página, o lo contrario. El fallback conservador aprocessmitiga el primer caso solo cuando el JSON es inválido, no cuando Haiku decide bien-pero-mal. - Negativo · TTL de caching corto: 5 minutos de
ephemeralsignifica que si el agentic loop pausa más de eso (rate limit, retry largo) el cache expira y la siguiente iteración paga creation de nuevo. Hasta hoy no se ha observado en runs reales — los loops cierran en <2 min. - Negativo · mantenimiento de listas estáticas:
SKIP_COMMIT_TYPES,RICH_PATH_PATTERNSySKIP_ONLY_PATTERNSviven en código y deben actualizarse cuando aparezcan nuevas convenciones de commit o nuevos directorios estructuralmente “ricos”. Sin proceso recurrente de revisión, el filtro envejece. - Pendiente · métricas operativas: el ratio real skip pre-LLM / Haiku / Sonnet a 1-2 semanas de uso real está marcado en
STATE.mdcomo deuda observacional. Sin esos datos, el ahorro proyectado del 80% es estimación sustentada en un único punto de medición.
Status
Accepted. En producción desde 2026-04-22 (sesión 8). Métricas operativas pendientes de evaluación 1-2 semanas tras el cierre del plan.
Véase también
- [[feature—supercontext—reconcile-d1-repo]] — branch de reconciliación D1↔repo que se dispara tras cualquier skip (pre-LLM o Haiku) para mantener D1 sincronizado con el front-matter del repo.
- [[concept—biblioteca—supercontexto]] — concepto raíz del sistema wiki-grafo que este pipeline alimenta.
- [[feature—supercontext—fase-4-query-con-cierre]] — pipeline análogo de tres capas aplicado a
bib_ask(auto-archive de respuestas como concept_pages). - [[decision—20260424—supercontexto-operativo]] — ADR hermano del cierre de plan y paso a modo operativo.
- [[decision—20260422—lint-two-tier]] — ADR hermano sobre el lint en dos capas (incremental diario + consolidación semanal) que reutiliza la filosofía de cascada económica.
- [[decision—20260403—multi-tenancy-rls]] — ADR hermano sobre multi-tenancy y RLS, citado por entidades del grafo que el ingest produce.