KikoCis commited on
Commit
f0ce937
·
verified ·
1 Parent(s): 4946dda

Ventana elastica + cabecera incondicional

Browse files
Files changed (1) hide show
  1. js/acer-core.js +50 -1
js/acer-core.js CHANGED
@@ -242,6 +242,7 @@ const DEFAULTS = {
242
  PIN_QUERY_TERMS: true, // lo que la pregunta nombra no se desaloja jamás
243
  PIN_MAX: 40,
244
  // — presupuesto —
 
245
  TAIL_MIN_FRAC: 0.10, // SUELO garantizado para los ultimos turnos
246
  HEAD_FRAC: 0.05, // reserva para los PRIMEROS mensajes, sin puntuar
247
  // (solo bajo presión — ver autotune)
@@ -306,7 +307,14 @@ function autotune(historyTok, budgetTok, O) {
306
  // Así que no es un peso ni un desempate universal: es un INTERRUPTOR, y el
307
  // barrido dice dónde va. Umbral medido entre 0,17 (neutral) y 0,34 (dañino).
308
  const recencyTiebreak = pressure < O.AUTO_RECENCY_PRESSURE;
309
- const headOn = pressure < O.AUTO_RECENCY_PRESSURE; // misma puerta, misma razón
 
 
 
 
 
 
 
310
  const recencyWeight = O.RECENCY_WEIGHT * (1 - pressure); // solo informativo
311
 
312
  return { pressure, recentFrac, recencyWeight, recencyTiebreak, headOn };
@@ -561,6 +569,12 @@ function selectAndEmit(ctx, budgetTok, O) {
561
  }
562
  remaining.delete(best);
563
  const it = byId.get(best), c = cost(it);
 
 
 
 
 
 
564
  if (used + c > budgetTok) continue;
565
  keep.add(best); used += c;
566
  const bs = tok.get(best);
@@ -568,9 +582,44 @@ function selectAndEmit(ctx, budgetTok, O) {
568
  if (used >= budgetTok) break;
569
  }
570
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
571
  for (const it of pool) {
572
  const id = idOf(it);
573
  if (keep.has(id)) continue;
 
574
  const c = cost(it);
575
  if (used + c > budgetTok) continue;
576
  keep.add(id); used += c;
 
242
  PIN_QUERY_TERMS: true, // lo que la pregunta nombra no se desaloja jamás
243
  PIN_MAX: 40,
244
  // — presupuesto —
245
+ ELASTIC: true, // no rellenar con lo irrelevante (ver selectAndEmit)
246
  TAIL_MIN_FRAC: 0.10, // SUELO garantizado para los ultimos turnos
247
  HEAD_FRAC: 0.05, // reserva para los PRIMEROS mensajes, sin puntuar
248
  // (solo bajo presión — ver autotune)
 
307
  // Así que no es un peso ni un desempate universal: es un INTERRUPTOR, y el
308
  // barrido dice dónde va. Umbral medido entre 0,17 (neutral) y 0,34 (dañino).
309
  const recencyTiebreak = pressure < O.AUTO_RECENCY_PRESSURE;
310
+ // La cabecera va SIEMPRE, sin puerta. Antes se apagaba con holgura porque
311
+ // "ahí el encargo sobrevive solo" — y era cierto, pero solo porque
312
+ // rellenábamos el presupuesto hasta el borde con todo lo que cupiera. Al
313
+ // añadir la ventana elástica y dejar de rellenar, el encargo se cayó del
314
+ // 100 % al 0 % a presupuesto 16.000. Su supervivencia era un accidente del
315
+ // relleno, no una propiedad de tener sitio. Cuesta un 5 % y ya está medido
316
+ // que no resta: incondicional.
317
+ const headOn = true;
318
  const recencyWeight = O.RECENCY_WEIGHT * (1 - pressure); // solo informativo
319
 
320
  return { pressure, recentFrac, recencyWeight, recencyTiebreak, headOn };
 
569
  }
570
  remaining.delete(best);
571
  const it = byId.get(best), c = cost(it);
572
+ // La ventana elástica manda TAMBIÉN aquí. El MMR ordena por diversidad
573
+ // DENTRO de lo relevante; no es una excusa para colar relleno. Sin esta
574
+ // línea la puerta no servía de nada: el material sin relevancia entraba
575
+ // por este bucle antes de llegar al relleno final, y la medida salía
576
+ // idéntica con y sin ella.
577
+ if (O.ELASTIC && it.score < 10) continue;
578
  if (used + c > budgetTok) continue;
579
  keep.add(best); used += c;
580
  const bs = tok.get(best);
 
582
  if (used >= budgetTok) break;
583
  }
584
  }
585
+ // ── VENTANA ELÁSTICA ───────────────────────────────────────────────────────
586
+ // El presupuesto es un TECHO, no una cuota que haya que agotar. Medido, sin
587
+ // esto se iba en líneas sin una sola palabra en común con la pregunta el
588
+ // 38 % del presupuesto a 3.000 y el 56 % a 16.000 — más de la mitad, relleno.
589
+ //
590
+ // Y eso no es inofensivo: nuestro propio resultado dice que recuperar bien
591
+ // BATE al contexto completo (F1 28,09 contra 22,56 del historial entero), o
592
+ // sea que lo irrelevante no es lastre neutro, DISTRAE. Rellenar hasta el
593
+ // borde con material de relevancia cero es reintroducir a mano justo aquello
594
+ // que la compresión venía a quitar.
595
+ //
596
+ // Así que la ventana se dimensiona con la EVIDENCIA: se para cuando se acaba
597
+ // lo relevante (estrato ≥ 10) en vez de cuando se acaban los tokens. Es el
598
+ // umbral de corte por puntuación de toda la vida en recuperación; la cabecera
599
+ // y la cola siguen siendo incondicionales, que para eso son reservas.
600
+ //
601
+ // ⚠️ NO es un regalo, es un INTERCAMBIO, y el banco solo ve un lado. Medido
602
+ // (8 semillas, presencia del dato — NO calidad de la respuesta):
603
+ //
604
+ // presupuesto ahorro de tokens coste en hechos
605
+ // 3.000 −1 % ±0,0 ← régimen de la app
606
+ // 8.000 2 % ±0,0
607
+ // 16.000 26 % −1,8
608
+ // 32.000 60 % −8,9
609
+ //
610
+ // Con el presupuesto que usan los productos (3.000 y 5.000) sale GRATIS: ahí
611
+ // hay más material relevante que sitio, y la puerta no llega a dispararse.
612
+ // Con holgura canja recall por tokens, y si eso compensa depende de algo que
613
+ // ESTE banco no puede ver: mide si el dato está presente, no si la respuesta
614
+ // sale mejor. La hipótesis a favor es nuestro propio titular —recuperar bien
615
+ // BATE al contexto completo, luego lo irrelevante resta— pero mientras no se
616
+ // corra el banco de F1 con un modelo respondiendo, el −8,9 a 32.000 es un
617
+ // número real y la ganancia es una conjetura. Queda dicho, no disimulado.
618
+ const RELEVANT = 10;
619
  for (const it of pool) {
620
  const id = idOf(it);
621
  if (keep.has(id)) continue;
622
+ if (O.ELASTIC && it.score < RELEVANT) break; // se acabó la evidencia
623
  const c = cost(it);
624
  if (used + c > budgetTok) continue;
625
  keep.add(id); used += c;