Skip to content

WebPerf Snippets: progressive disclosure en Claude Skills

Published:

En los artículos anteriores de esta serie expliqué cómo se organizan los WebPerf Snippets como Skills y cómo los scripts devuelven JSON estructurado para minimizar el trabajo del agente. Queda un tercer nivel de optimización: cuánto contexto consume cada Skill al activarse.

El problema no es que los scripts sean grandes. Es que el SKILL.md cargaba todo el conocimiento disponible en el momento de activación, aunque la mayor parte no fuera necesaria para decidir qué script ejecutar.

El sistema de progressive disclosure de Anthropic

La guía oficial de Skills de Anthropic (The Complete Guide to Building Skills for Claude) define tres niveles de contenido con un principio claro: cargar solo lo necesario en cada momento, y acceder al detalle únicamente cuando se necesita.

L1 — Frontmatter YAML (siempre en contexto)

---
name: webperf-core-web-vitals
description: Intelligent Core Web Vitals analysis...
---

El frontmatter forma parte del system prompt permanente. Está en contexto en cada conversación, independientemente de qué Skill esté activa. Por eso existe un límite de 1.024 caracteres en la descripción: ese contenido se paga siempre.

L2 — Cuerpo del SKILL.md (cargado al activar la Skill)

Se carga cuando el agente determina que la Skill es relevante. Debe contener lo estrictamente necesario para que el agente decida qué script ejecutar: lista de scripts disponibles, flujos de trabajo y árboles de decisión. Cada kilobyte aquí se consume en cada sesión donde la Skill se activa.

L3 — references/, scripts/, assets/ (cargados bajo demanda)

Documentación detallada, descripciones de cada snippet, tablas de umbrales, esquemas de resultados. Se leen únicamente cuando el agente los necesita para interpretar un resultado concreto. Hasta ese momento, el coste es cero.

El problema: todo era L2

El generador de Skills, scripts/generate-skills.js, añadía al cuerpo del SKILL.md cuatro bloques que podían haberse quedado en L3:

Tabla de snippets con descripciones truncadas

| LCP Trail | Tracks every LCP candidate element during page load and highlights each one with a distinct pastel-c |

El recorte a 100 caracteres no aportaba valor real. Ni era suficiente para entender el snippet, ni dejaba al agente decidir cuándo consultarlo.

Bloque de instrucciones de ejecución duplicado cinco veces

Las mismas seis líneas aparecían de forma idéntica en los cinco Skills de categoría, siendo ya cubiertas por el meta-Skill webperf:

1. mcp__chrome-devtools__navigate_page  → navigate to target URL
2. mcp__chrome-devtools__evaluate_script → run snippet code
3. mcp__chrome-devtools__get_console_message → capture console output

SCHEMA.md inaccesible

El archivo .claude/skills/SCHEMA.md (19 KB) documenta el esquema completo de valores de retorno JSON para los 47 scripts. Existía pero ningún Skill lo referenciaba. Imposible que el agente lo consultara.

La solución: mover el detalle a L3

Todos los cambios se han realizado en un único archivo: scripts/generate-skills.js del repositorio webperf-snippets. Los Skills son artefactos generados y no se editan directamente.

Crear references/snippets.md con el detalle completo

En lugar de añadir al cuerpo del SKILL.md una sección por snippet (con descripción y tabla de umbrales), se escribe un archivo separado en L3:

const snippetLines = [];
for (const meta of metas) {
  snippetLines.push(`---`);
  snippetLines.push(`## ${meta.title}`);
  if (meta.description) {
    snippetLines.push("");
    snippetLines.push(meta.description);
  }
  snippetLines.push("");
  snippetLines.push(`**Script:** \`scripts/${meta.basename}.js\``);
  if (meta.thresholds) {
    snippetLines.push("");
    snippetLines.push("**Thresholds:**");
    snippetLines.push("");
    snippetLines.push(meta.thresholds);
  }
}
fs.writeFileSync(
  path.join(refsDir, "snippets.md"),
  snippetLines.join("\n") + "\n"
);

Sustituir la tabla truncada por una lista compacta

❌ Antes:

## Available Snippets

| Snippet   | Description                                                                                          | File                 |
| --------- | ---------------------------------------------------------------------------------------------------- | -------------------- |
| LCP Trail | Tracks every LCP candidate element during page load and highlights each one with a distinct pastel-c | scripts/LCP-Trail.js |

✅ Después:

## Scripts

- `scripts/LCP-Trail.js` — LCP Trail
- `scripts/LCP.js` — Largest Contentful Paint (LCP)

Descriptions and thresholds: `references/snippets.md`

Copiar SCHEMA.md a references/schema.md

const schemaSrc = path.join(CLAUDE_SKILLS_DIR, "SCHEMA.md");
if (fs.existsSync(schemaSrc)) {
  fs.copyFileSync(schemaSrc, path.join(refsDir, "schema.md"));
}

Con esto, el agente puede consultar el esquema completo cuando recibe un resultado inesperado, sin que ese coste de 19 KB se pague en cada sesión.

Eliminar las instrucciones de ejecución duplicadas

Se eliminó el bloque repetido de los cinco Skills de categoría y se sustituyó por una línea de referencia al final:

> Execute via `mcp__chrome-devtools__evaluate_script` → read with `mcp__chrome-devtools__get_console_message`.

Añadir sección ## References al final del SKILL.md

## References

- `references/snippets.md` — Descriptions and thresholds for each script
- `references/schema.md` — Return value schema for interpreting script output

La estructura resultante

skills/webperf-core-web-vitals/
  SKILL.md                    ← L2: lista de scripts + workflows
  scripts/
    CLS.js                    ← L3: ejecutado cuando se necesita
    LCP.js
    ...
  references/
    snippets.md               ← L3: descripciones y umbrales
    schema.md                 ← L3: esquema de valores de retorno

Resultados

SkillAntesDespuésReducción
webperf-loading24.199 B11.149 B−54%
webperf-core-web-vitals13.890 B10.266 B−26%
webperf-interaction17.143 B12.443 B−27%
webperf-media13.273 B12.017 B−9%
webperf-resources11.700 B11.026 B−6%
Total L282.916 B59.612 B−28%

Los Skills con menor reducción (webperf-media, webperf-resources) tienen WORKFLOWS.md extensos con árboles de decisión detallados. Ese contenido es deliberadamente L2: el agente lo necesita en el momento de decidir qué script ejecutar.

En una auditoría completa con tres Skills activas simultáneamente, el L2 pasa de ~55 KB a ~34 KB. Los ~18 KB de references/snippets.md y los 19 KB de references/schema.md quedan disponibles bajo demanda. En el caso típico de una sesión de diagnóstico (ejecutar dos o tres scripts, interpretar resultados directos), nunca se leen.

Conclusión

El sistema de progressive disclosure no cambia lo que el agente puede hacer: todos los snippets siguen disponibles, todas las descripciones siguen accesibles, el schema sigue consultable. Lo que cambia es cuándo se paga el coste de ese conocimiento.

El agente carga lo mínimo para tomar decisiones. El detalle existe, pero solo aparece en contexto cuando es necesario para interpretar un resultado concreto. Para una colección de 47 snippets distribuidos en seis Skills, la diferencia entre cargar todo siempre y cargar solo lo necesario es de más de 20 KB por sesión de análisis completo, y cero bytes de contexto de detalle en el caso habitual.


Next Post
WebPerf Snippets agent-first: retornos estructurados y tokens mínimos