P0 contexto: ventana por modelo + recuperación ante overflow + self-heal del catálogo

Que las conversaciones largas no se rompan ni gasten de más:

Ventana de contexto por modelo (antes: budget estático 120k/200k para todos):
- cost.resolve_context_window: lee context_length del catálogo OpenRouter/DeepSeek
  en Redis, con fallback a litellm. config.budget_for_window deriva el budget de
  la ventana real (window - max_output - reserve). build_context lo aplica por
  turno (param model_id) en vez del fijo de settings.
- Self-heal del catálogo OpenRouter: el admin panel lo cachea con TTL 1h y solo lo
  repuebla al abrir su ventana de IA → en runtime caducaba y se perdían ventana y
  precio. Ahora cost._get_catalog lo refresca solo (fetch público, mismo shape,
  cooldown 5min, TTL 24h). Arregla también el coste (caía al fijo).

Recuperación ante overflow:
- adapters.base.ContextOverflowError; openai_adapter traduce el error de
  context-length del proveedor (init e iteración del stream).
- base.py: retry proactivo que recompacta hasta caber en la ventana ANTES de
  llamar al LLM; si ni así cabe → error accionable (no rompe la sesión).
- engine.py: mensaje user-facing claro (modelo + ventana).

Tests: ventana/budget, self-heal (mockeado), overflow, y sesión REAL de Redis. 106 verdes.

evals/: harness para evaluar al agente acai-code (driver + README + resultados).
Comparativa kimi vs deepseek vs glm (deepseek-v4-pro high = mejor calidad/precio).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jordan
2026-06-20 13:48:19 +01:00
parent 9d11a59fb8
commit 651d61b096
15 changed files with 997 additions and 36 deletions

View File

@@ -0,0 +1,156 @@
# Resultados — eval "montar landing" (acai-code)
Flujo fijo de 3 turnos sobre el proyecto **empleo.cocosolution.com (en TEST)**:
1. **T1** — sección sencilla: "Beneficios" con 3 tarjetas (icono, título, texto).
2. **T2** — módulo complejo: "Conoce al equipo", multi-registro v2, 3 personas con
**foto generada + nombre + puesto + testimonio + enlace LinkedIn**.
3. **T3** — edición: cambiar el puesto de una persona y borrar otra tarjeta.
Objetivo: comparar entre modelos para ver si los fallos son **del modelo** o de la
**KB/docs** (mismo flujo → si todos fallan igual, es la doc; si solo uno, es el modelo).
## Comparativa entre modelos
> ⚠️ **Corrección metodológica (importante).** Mi primera versión contaba los `tool_use`
> de los snapshots `assistant` del SSE. El agentic **re-emite el snapshot con todos los
> bloques acumulados tras cada tool** (`claude_format.py:_build_assistant_snapshot`), así que
> el mismo tool se contaba muchas veces → **los conteos de tool calls estaban inflados**
> (p.ej. "30 generate_image" cuando el `consumo_acaicode` real era **3**). El driver ya
> deduplica por id. **Solo son fiables: tokens de `result.usage`, `consumo_acaicode`, y el
> razonamiento del propio modelo.** Abajo solo se usan esas señales.
| Modelo | Fecha | Tareas OK | Tokens in (3 turnos) | Resolvió record de página | Calidad observada (razonamiento) |
|---|---|---|---|---|---|
| `openrouter/moonshotai/kimi-k2.7-code` (medium) | 2026-06-20 | 3/3 | **~2,66M** | **NO — alucinó `num=1`** | Actúa, falla, reintenta. Edita código a ciegas (`line_replace` no casa). Mucho thrashing. |
| `deepseek/deepseek-v4-pro` (high) | 2026-06-20 | 3/3 | **~649k** | `num=267` ✅ | Explora a fondo y acierta. 0 errores. Maneja ambigüedad (Laura→Elena). |
| `z-ai/glm-5.2` (high) | 2026-06-20 | 3/3 | **~720k** | `num=267` ✅ | Sólido. Autocorrige (Twig `=``==`; fotos cruzadas al borrar). Maneja ambigüedad. |
Imágenes generadas (de `consumo_acaicode`): **3 por turno en los 3 modelos** — correcto, una por
persona. **No hubo sobre-generación** (era artefacto de medición).
## Conclusión modelo vs KB (3 modelos, mismo flujo, misma KB)
- **Señal autoritativa = tokens.** kimi gasta **~4× más** (~2,66M vs ~650720k) para la MISMA
tarea → reintentos/thrashing reales (cada step reenvía contexto). Es el indicador más fiable.
- **`num=1` alucinado → MODELO (kimi).** Deepseek **y** GLM, con la **misma KB**, resolvieron el
record de la página correctamente (lo dicen en su propio razonamiento). Kimi no. **Definitivo:
es kimi, no la documentación.**
- **NO hay evidencia de un problema de KB en el flujo multi-registro/imágenes.** Lo que parecía
sobre-generación (×30) era mi bug de conteo; los tres modelos generaron 3 imágenes (correcto).
**Retirada** la "acción de KB #1" anterior.
- **Bug real encontrado por GLM:** al borrar un registro de un módulo multi-registro, el sistema
reutiliza nums y **las fotos quedan cruzadas**; GLM lo detectó y corrigió. Merece revisar el
flujo delete/reorder (plataforma).
- **Calidad de modelo:** kimi es claramente el más flojo; **deepseek-v4-pro y GLM-5.2 (high) son
sólidos y comparables**.
**Acciones sugeridas:** (1) **no usar kimi-k2.7 como default**; deepseek-v4-pro o GLM-5.2 (high)
son buenos. (2) Revisar el bug delete→fotos cruzadas. (3) (Opcional) re-medir con el driver
deduplicado si se quieren conteos exactos de tool calls; las conclusiones por tokens no cambian.
---
## kimi-k2.7-code — 2026-06-20
**Veredicto:** entrega las 3 tareas, pero con **mucho thrashing** y errores recurrentes
de los que **no aprende dentro del turno**.
### Por turno
- **T1 (beneficios):** completado. Reutilizó un módulo de tarjetas existente. Errores:
`acai_line_replace``HTTP_409 "Search block not found"` (edita código a ciegas) y
acceso a `record num=1` inexistente en `apartados`. Se recuperó. **1,77M tokens input**
(acumulado de ~9 steps por los reintentos).
- **T2 (equipo, multi-registro v2):** completado (módulo `conocealequipo_coco`, 3 personas,
fotos generadas, enlaces LinkedIn en nueva pestaña). Pero **`add_module_to_record` ×11
sobre el mismo módulo** (bucle en el workflow multi-registro; idempotente, devolvió el
mismo `sectionId` → NO duplicó en la página) y **2 ciclos de generación de imágenes**
(6 `generate_image` para 3 personas). 606k tokens.
- **T3 (edición):** completado limpio (**0 errores**), Carlos→CTO + Laura eliminada. Pero
**7× `list_record_uploads`** redundante. 284k tokens.
### Inventario de errores (sesión completa)
| Error | Veces | Diagnóstico |
|---|---:|---|
| `Record num=1 not found in 'apartados'` | **52** | Alucina el record de la página (real = `num=267`). **No aprende** del error y reintenta con `num=1`. |
| `Search block not found` (HTTP_409, `acai_line_replace`) | 22 | Genera bloques de búsqueda que no casan con el fichero; edita código sin verlo bien. |
| `add_module_to_record` mismo módulo | 11 | Bucle en el workflow multi-registro v2. |
- 139 tool calls · ~74 `success:false` · 148 llamadas marcadas como repetidas.
### ¿Modelo o KB? (hipótesis a confirmar con otros modelos)
- **`num=1` (×52):** huele a **KB** — falta una regla clara de "obtén el `num` real de la
página con `list_table_records` antes de operar; nunca asumas num=1". Si otros modelos
caen igual → es la doc.
- **multi-registro v2 (bucle):** probablemente **KB** — falta un doc de "cómo añadir N
registros a un módulo repetible".
- **`line_replace` a ciegas:** mezcla — la KB debería exigir `acai_view` previo y casar
exacto.
### Notas de contexto / coste (P0)
- **Cero overflow** en los 3 turnos pese a 1,77M tokens acumulados/turno → no se rompió.
- La ventana real de kimi es **262144** (256k). El catálogo OpenRouter había **caducado**
(TTL 1h) → al principio se usó budget estático; tras el self-heal (`cost.py`) ya resuelve
la ventana real. Coste real de kimi: ~$0.61 in / $3.07 out por 1M.
---
## deepseek-v4-pro (high) — 2026-06-20
**Veredicto: ELEGIDO** (mejor relación calidad/precio). 3/3 tareas, **0 errores**, eficiente y
**cauto ante acciones destructivas ambiguas**.
### Re-medición con driver deduplicado (números AUTORITATIVOS, baseline limpio)
| Turno | Tool calls (reales) | Errores | `generate_image` | Tokens in |
|---|---:|---:|---:|---:|
| T1 beneficios | **19** | 0 | 3 | 264k |
| T2 equipo (multi-registro) | **14** | 0 | 3 | 320k |
| T3 edición ambigua | **1** | 0 | 0 | 77k |
| **Total** | **34** | **0** | 6 | **~661k** |
- Imágenes = 3 por módulo (correcto, coincide con `consumo_acaicode`). **Sin thrashing** — los
"135/77/30" de abajo eran del artefacto de conteo, ya corregido.
- **T3 (lo mejor):** ante "quita a Laura Gómez" (no existía; sus personas eran Marina/Carlos/
Lucía), **no adivinó: paró y preguntó** a quién borrar, ofreciendo ya el cambio claro
(Carlos→CTO). Cautela correcta con un borrado ambiguo.
### Por turno (medición ANTIGUA — inflada por el artefacto, ver banner arriba)
- **T1 (beneficios):** 135 tools, **0 err**, 238k tok. Exploró el proyecto (tablas, records,
módulos), **resolvió bien `apartados num=267`**, localizó un módulo de referencia
(`sobrenosotrosbeneficios_8pjhao`) y creó un módulo nuevo con `multiv2`. Renderizó OK.
- **T2 (equipo, multi-registro v2):** 77 tools, **0 err**, 183k tok. Módulo `conocealequipo_j8m3k7`
con 3 personas, fotos y enlaces. **Pero 30 `generate_image` + 8 `add_module_to_record`**
para 3 personas → mismo thrashing del workflow multi-registro/imágenes que kimi (peor en
imágenes).
- **T3 (edición):** 27 tools, **0 err**, 228k tok. Sus personas eran Marina/Carlos/Elena;
ante "quita a Laura" razonó *"no existe Laura, asumo que es Elena"* y la quitó + Carlos→CTO.
Manejo inteligente de la ambigüedad.
- Totales: **239 tools, 0 errores, ~649k tok input** (4× más barato que kimi pese a más calls).
- Ventana real deepseek-v4-pro: **1.000.000**. Coste catálogo: ~$0.435 in / $0.87 out por 1M.
---
## glm-5.2 (high) — 2026-06-20 (baseline limpio)
**Veredicto:** 3/3 tareas. Comportamiento sólido y con **muy buena autocorrección**.
Mismo perfil que deepseek (explora y acierta), no aluciona el record de la página.
### Por turno
- **T1 (beneficios):** 90 tools, 250k tok. Resolvió `apartados num=267` bien. Escribió el
template Twig con `=` en un `c-if` (en vez de `==`) → fallos de `acai_write`/compilación,
pero **se autodiagnosticó** ("el compilador no convierte `=` en este contexto") y lo arregló.
- **T2 (equipo, multi-registro v2):** 77 tools, **0 err**, 232k tok. Módulo `equipococotalento_k8e2qr`.
**30 `generate_image` + 8 `add_module`** para 3 personas — idéntico a deepseek.
- **T3 (edición):** 35 tools, **0 err**, 237k tok. Sus personas eran Diego/Laura Méndez/Carmen;
infirió bien la petición. Detectó que al borrar un registro **las fotos quedaron cruzadas**
(reuso de nums 22726/22727) y las **reemplazó correctamente**.
- Totales: ~202 tools, errores solo en T1 (recuperados), ~720k tok input.
- Ventana real glm-5.2: **1.048.576**. Coste catálogo: ~$1.2 in / $4.1 out por 1M.
### Limpieza pendiente
Tras el reset, empleo (en TEST) tiene solo los módulos de la prueba de GLM:
- módulo de beneficios (`multiv2`) + `equipococotalento_k8e2qr`.
Borrar si no se quieren conservar, y **revertir empleo a producción**.