Tool MCP bib_eval_retrieval: harness A/B del retrieval
Resumen
Tool MCP reproducible para validar y calibrar el retrieval sin redeploy. Compara variantes (baseline = chunks enteros vs trim = recortado a frases relevantes) sobre un set de preguntas reales o custom, produciendo métricas cuantificables: tokens en contexto, reducción %, scores y solapamiento de chunks.
Rol: Harness A/B del ArcRift cherry-pick #1 (sentence-trimming).
Invocación
bib_eval_retrieval(
questions?: string[], // preguntas a evaluar (opt)
variants?: ('baseline' | 'trim')[], // variantes (default ['baseline', 'trim'])
top_k?: number, // chunks (default 5, max 20)
trim_threshold?: number, // coseno mínimo (default 0.38)
trim_window?: number, // contexto ±N frases (default 1)
synthesize?: boolean, // sintetizar respuestas (default false, lento/caro)
source_type?: string, // filtro: tipo de fuente
app?: string // filtro: app Django
)
Parámetros detallados
questions (opcional)
Array de preguntas a evaluar.
Comportamiento:
- Si se pasan: evaluar exactamente esas preguntas.
- Si vacío o se omite: cargar las últimas 15 preguntas reales de
oraculo_queries(consultaSELECT question FROM oraculo_queries WHERE ... GROUP BY question ORDER BY MAX(id) DESC LIMIT 15).
Recomendación: usar preguntas golden (casos típicos, edge cases) para reproducibilidad. Ej:
{
"questions": [
"¿Qué es multi-tenancy?",
"¿Cómo se configura RLS?",
"¿Cuál es el flow de autenticación?"
]
}
variants (opcional, default ['baseline', 'trim'])
Variantes del retrieval a comparar.
baseline: chunks enteros, sin trimming.trim: recortado a frases relevantes portrim_threshold+ ventana.
Ejemplo: variants: ['baseline', 'trim'] → correr ambas, comparar.
top_k (opcional, default 5)
Número de chunks a recuperar por pregunta. Max 20 (para evitar overload).
trim_threshold (opcional, default 0.38)
Coseno mínimo (0.0–1.0) para conservar una frase en la variante trim.
- 0.38 = umbral default (calibrado en ArcRift).
- 0.40–0.45 = más estricto, menos frases, menos tokens.
- 0.30–0.35 = más permisivo, más ruido, más tokens.
Uso para calibración:
bib_eval_retrieval(
questions: ["¿Multi-tenancy?"],
trim_threshold: 0.42
)
// Ejecutar múltiples runs con thresholds distintos
// para hallar el óptimo (máx reducción, mín overlap loss)
trim_window (opcional, default 1)
Frases de contexto ±N alrededor de las frases relevantes.
- 0 = solo frases seleccionadas, sin contexto.
- 1 = ±1 frase (default: equilibrio ruido/contexto).
- 2+ = más contexto, menos reducción de tokens.
synthesize (opcional, default false)
Si true: sintetizar la respuesta con Gemma/Oraculo por variante. Mucho más lento y caro (llama al LLM).
false: aislar retrieval puro (rápido, barato, recomendado para calibración).true: incluiransweren cada variante (útil para validar calidad end-to-end).
source_type, app (opcionales)
Filtros de búsqueda:
source_type: tipo de fuente (ej"doc","wiki","code").app: app Django (ej"core","monitoring","signage").
Ejemplo: evaluar solo chunks de la app core:
bib_eval_retrieval(
questions: [...],
app: "core"
)
Salida
JSON con estructura:
{
"summary": {
"questions": 3,
"top_k": 5,
"trim_threshold": 0.38,
"trim_window": 1,
"avg_tokens_baseline": 156,
"avg_tokens_trim": 89,
"token_reduction_pct": 43,
"avg_overlap_vs_baseline": 0.92
},
"results": [
{
"question": "¿Qué es multi-tenancy? (primer 100 chars)",
"variants": {
"baseline": {
"chunk_ids": [123, 456, 789],
"top_score": 0.845,
"tokens": 180,
"tokens_before": 200
},
"trim": {
"chunk_ids": [123, 456],
"top_score": 0.845,
"tokens": 95,
"tokens_before": 200,
"overlap_vs_baseline": 0.67,
"answer": "Multi-tenancy es ... [truncado a 600 chars si synthesize=true]"
}
}
},
// ... más resultados
]
}
summary
Agregación sobre todas las preguntas evaluadas:
questions: número de preguntas.top_k,trim_threshold,trim_window: parámetros usados.avg_tokens_baseline: promedio de tokens por pregunta (retrieval completo).avg_tokens_trim: promedio de tokens con trimming.token_reduction_pct: % reducción (100 * (1 - trim/baseline)).avg_overlap_vs_baseline: fracción promedio de chunks que baseline y trim comparten (ej 0.92 = 8% de chunks perdidos con trim).
results
Array de resultados por pregunta:
question: primeros 100 caracteres de la pregunta.variants.baseline:chunk_ids: IDs de chunks recuperados.top_score: score de similitud del chunk #1 (coseno).tokens: estimación pre-trimming.tokens_before: duplicatokens(legacy).
variants.trim:chunk_ids: IDs tras recorte (subset de baseline en general).top_score: idem (no cambia por trimming, es score del chunk original).tokens: estimación post-trimming (< baseline).tokens_before: estimación pre-trimming (= baseline.tokens).overlap_vs_baseline: fracción de chunks trim que están en baseline (ej 0.67 = 67% overlap).answer: respuesta sintetizada (solo sisynthesize=true).
Workflow de calibración
1. Línea base
bib_eval_retrieval(
top_k: 5,
trim_threshold: 0.38, // default
trim_window: 1
)
// Salida: avg_tokens_baseline=156, avg_tokens_trim=89, token_reduction_pct=43, overlap=0.92
// Interpretación: 43% menos tokens, perdemos <10% de chunks
2. Ajustar threshold
bib_eval_retrieval(
top_k: 5,
trim_threshold: 0.40, // más estricto
trim_window: 1
)
// Salida: avg_tokens_trim=75, token_reduction_pct=52, overlap=0.88
// Interpretación: más reducción, pero 12% chunks perdidos
bib_eval_retrieval(
top_k: 5,
trim_threshold: 0.35, // más permisivo
trim_window: 1
)
// Salida: avg_tokens_trim=110, token_reduction_pct=30, overlap=0.95
// Interpretación: menos reducción, pero casi sin perder chunks
Decisión: elegir threshold que balancee reducción y overlap. Ej, 0.40 con overlap 0.88 es aceptable si el beneficio de tokens es importante.
3. Validar con synthesis
Una vez calibrado threshold, opcionalmente sintetizar para validar que las respuestas siguen siendo correctas:
bib_eval_retrieval(
questions: ["¿Multi-tenancy?", "¿RLS?"],
trim_threshold: 0.40,
synthesize: true
)
// Verifica que `answer` en `variants.trim` sigue siendo precisa
4. Desplegar
Una vez validado, actualizar en el entorno:
RETRIEVAL_TRIM=1
RETRIEVAL_TRIM_THRESHOLD=0.40
# redeploy
Implementación
Handler: functions/api/mcp/handlers/archivo.ts:467–574.
Lógica:
- Validar env
AI+ DB. - Si no hay
questions, cargar desdeoraculo_queries. - Para cada pregunta:
- Embeddings de la query.
- Por cada variante:
retrieve()con parámetros correspondientes. - Registrar métricas (chunk_ids, tokens, scores).
- Opcionalmente sintetizar.
- Agregar en
summary. - Retornar JSON.
Tool registration: functions/api/mcp/tools.ts:999–1015.
Véase también
- [[feature—biblioteca—arcrift-cherry-pick-1]]
- [[entity—functions—service—sentence-trimming]]
- [[entity—functions—handler—archivo-ask]]
- [[concept—observability—metrics]]
- [[concept—testing—a-b-harness]]