Claude plugin eval: testea tus skills antes de compartirlas
Claude plugin eval prueba tu skill en un sandbox con y sin plugin, puntúa con graders y falla el CI bajo un umbral. Cómo escribir la suite y leer el JSON.

Escribes una skill que genera mensajes de commit. La pruebas en tu sesión, funciona a la primera y la metes en un plugin para el equipo.
Una semana después nadie la usa. Claude no la invoca cuando alguien escribe "hazme el commit de esto". En tu máquina sí se disparaba, pero en tu máquina también estaban tu CLAUDE.md, tus otras skills y la conversación donde la escribiste.
Eso no era un test. Era una demo. Y claude plugin eval existe justo para separar las dos cosas.
En corto: claude plugin eval ejecuta tu plugin contra una suite de casos en sesiones aisladas, tres veces con el plugin y tres sin él, y puntúa cada ejecución con graders. Te dice si la skill se dispara, si el resultado es correcto y cuánto aporta frente a no tenerla. Con --json y --threshold se convierte en un gate de CI.
¿Qué es claude plugin eval?
claude plugin eval es el comando de Claude Code que ejecuta un plugin contra una suite de casos de prueba (un prompt realista más uno o varios graders de aprobado/suspenso) y devuelve una puntuación comparada contra una ejecución sin el plugin.
Llegó en Claude Code v2.1.269, publicada el 11 de septiembre de 2026, según el changelog oficial. La referencia está en la guía de evals de plugins (consultada en octubre de 2026). Pide también Git 2.31 o superior si tienes git instalado.
El marco general de por qué evaluar skills ya lo cubrimos en cómo evaluar habilidades de agentes de IA. Este post va del comando: archivos, flags, salida y CI.
Cómo se escribe una suite de claude plugin eval
Una suite vive en evals/ dentro del plugin. Cada caso es un directorio con un prompt.md y al menos un grader en graders/. Sin grader, el caso no carga.
commit-helper/
├── .claude-plugin/plugin.json
├── skills/commit-message/SKILL.md
└── evals/
├── rename-function/
│ ├── prompt.md
│ └── graders/
│ ├── skill-fired.md
│ ├── conventional.md
│ └── criteria.md
└── results/ # lo escribe cada ejecución; va a .gitignore
No tienes que escribirlo a mano. claude plugin eval init lee tu plugin, te pregunta qué es un buen resultado, propone casos y graders, los prueba una vez y escribe los archivos. Para una plantilla vacía: claude plugin eval init --bare rename-function.
Ejemplo mínimo: una skill de mensajes de commit
El prompt.md es el ejemplo de la documentación oficial, que también usa una skill de commits. El cuerpo es lo que escribiría un usuario, sin nombrar la skill:
---
max_turns: 10
allowed_tools: [Read, Glob, Grep, Skill]
---
Write me a commit message for this change: I renamed getUser to fetchUser and updated the three call sites.
Primer grader, skill-fired.md: ¿se disparó tu skill?
---
type: tool_used
tool: Skill
input_match: 39;"skill"\s*:\s*"(?:[\w-]+:)?commit-message"39;
---
Segundo grader, conventional.md: el formato, con una regex que no cuesta nada. Supone que tu skill impone Conventional Commits y que un renombrado es un refactor (con ! si rompe compatibilidad).
---
type: regex
pattern: 39;(^|\n)refactor(\([\w-]+\))?!?: 39;
target: last_message
---
Tercer grader, criteria.md: el contenido, juzgado por un segundo modelo.
---
type: llm
---
PASS if the commit subject mentions renaming getUser to fetchUser.
FAIL if the subject is generic, such as "update code", or omits the new name.
Añade un segundo caso con una petición que no debe disparar la skill y un grader tool_used con min: 0, max: 0 y arm: both. Una skill que se dispara siempre es tan mala como una que no se dispara nunca.
Cómo puntúan los evals de plugins: graders, baseline y Δ
Cada caso se ejecuta tres veces por defecto. La puntuación de una ejecución es la fracción de graders aprobados (ponderada si usas weight); la del caso, la media. Pasa si llega al --threshold, que por defecto es 1.0.
La clave es el baseline sin plugin. Obtienes WITH, W/OUT y su diferencia, Δ. En el ejemplo de la guía oficial, un caso saca 1.00 con el plugin y 0.33 sin él: Δ de +0.67. Si un caso saca 1.0 con y sin plugin, tu plugin no es lo que lo hace pasar.
| Tipo de grader | Qué comprueba | Coste extra |
|---|---|---|
regex |
Regex de JavaScript sobre el mensaje final, la traza o un archivo | Ninguno |
tool_used |
Si se llamó a una tool, con min/max |
Ninguno |
tool_order |
Que una tool se llamó antes que otra | Ninguno |
file_exists |
Que Claude creó un archivo que encaja con un glob | Ninguno |
llm |
Un modelo juez vota PASS en al menos 2 de 3 votos | Llamadas al juez |
baseline |
Que el resultado cumple los criterios al menos tan bien como una transcripción de referencia | Llamadas al juez |
No hay graders con código propio. Y los tool_used sobre Skill no puntúan en el modo de dos brazos, porque sin plugin nunca pasarían e inflarían la Δ: salen como indicador.
El sandbox: qué ve la skill durante el eval
Cada ejecución arranca un claude -p hijo con home, directorio de trabajo y configuración temporales. Solo se carga tu plugin: tu CLAUDE.md, tus settings, tus hooks, tus MCP y tus otras skills no existen ahí.
Bash, Write, Edit, WebFetch y WebSearch desaparecen salvo que los concedas con --allow-tools, y Bash corre bajo el sandbox del sistema operativo. Los servidores MCP reales no arrancan por defecto: se sustituyen por mocks en evals/mocks/<server>/<tool>.md. Y el agente no puede leer el directorio de evals, así que no ve los graders.
El reporte JSON y el gate de CI
Cada vez que lanzas el comando se escribe aggregate-result.json y un report.html autocontenido en evals/results/<timestamp>/. El JSON lleva schemaVersion: 1. Lo que suele leer un script de CI: aggregates.overallScore, aggregates.casesPassed, aggregates.meanDelta, partial y costUsd.
El comando que propone la doc para CI:
claude plugin eval . \
--trust-plugin \
--json results.json \
--threshold 0.8 \
--model claude-sonnet-5 \
--judge-model claude-haiku-4-5 \
--no-publish \
--max-cost-usd 20
--trust-plugin evita que el job se bloquee en el aviso de confianza. Fijar --model impide que un cambio de modelo parezca una regresión de tu plugin. El exit code hace el resto: 0 si todo supera el umbral, 1 si algún caso queda por debajo o no carga, 2 si se cortó por coste o credenciales. El runner necesita Claude Code instalado y credenciales como ANTHROPIC_API_KEY.
Ojo: la Δ nunca cambia el exit code. Si quieres fallar cuando el plugin no aporta nada, léela del JSON:
jq -e 39;.partial != true and .aggregates.meanDelta > 039; results.json
Evals de plugins frente a probar a mano, skill-creator o un harness propio
| Criterio | Probar a mano | claude plugin eval |
skill-creator | Harness propio |
|---|---|---|---|---|
| Aislamiento | Ninguno: tu contexto contamina | Sesión limpia por ejecución | Dentro de tu conversación | El que construyas |
| Baseline sin skill | No | Sí, automático | Sí | Si lo programas |
| CI | No | Exit codes y JSON versionado | No es su objetivo | Sí, con trabajo |
| Límite o riesgo | Te engaña: "a mí me funciona" | Solo plugins; cada ejecución es una llamada facturada | Su evals.json no es compatible con plugin eval |
Mantenimiento y graders que nadie revisa |
Mi opinión: si la skill sale de tu máquina, en un plugin para tu equipo o un marketplace, el eval es el mínimo. Probar a mano solo demuestra que funciona con tu contexto, y ese contexto es justo lo que no viaja.
Para skills personales, skill-creator basta. Si aún no has escrito la primera, empieza por cómo crear una skill con Claude Code que tu agente realmente use.
¿Y /skill-doctor?
Existe, pero mide otra cosa. /skill-doctor (v2.1.252 o superior) enseña cuánto contexto consume cada skill y con qué frecuencia se usa, para decidir cuáles apagar. No ejecuta casos. Úsalo después de compartir, para ver si alguien la usa de verdad.
Límites del comando
Cuesta dinero real. Cada ejecución y cada grader llm es una llamada a tu cuenta. Un caso son seis ejecuciones por defecto, más tres llamadas al juez por grader llm en cada una. Como referencia, la salida de ejemplo de la documentación muestra un caso de seis ejecuciones con 74 s y 0,41 $ estimados a precio de lista. Pon siempre --max-cost-usd y usa --ablation none mientras iteras.
En Windows nativo, las suites que conceden Bash no corren. No hay backend de sandbox y Claude Code rechaza cada run que concede Bash o PowerShell, así que esas suites van por WSL2. En Linux necesitas bubblewrap y socat.
Es nuevo y tiene aristas abiertas. El issue #99246 de anthropics/claude-code reporta que el eval no carga las dependencies de plugin.json, así que el plugin no carga y los casos se puntúan sobre el modelo sin plugin. El issue #96121 describe que los agentes del propio plugin (agents/*.md) no se registran en el sandbox, aunque la doc actual dice que sí se cargan. Ambos seguían abiertos el 9 de octubre de 2026; si tu skill lanza agentes propios, compruébalo con --keep-temp antes de fiarte del score.
Pasar no significa que sea seguro. El aislamiento limita al agente, no al código del plugin: hooks y servidores MCP reales corren fuera del sandbox. Y si usas una suscripción de claude.ai con artifacts, el reporte se publica como artifact privado salvo que pases --no-publish; con API key se queda en local. En un repo privado, ponlo de todas formas.
Qué hacer hoy con tu skill
Mete tu skill más usada en un plugin y ejecuta claude plugin eval init desde su raíz. Después lanza claude plugin eval . --runs 1 --ablation none y mira una sola cosa: si el grader tool_used: Skill pasa. Según la guía oficial, es el hallazgo más habitual en la primera ejecución: Δ cercano a cero con ese grader en rojo. Casi siempre se arregla en la description de la skill, no en sus instrucciones.
Si quieres el flujo completo de especificar, construir y verificar con Claude Code, es lo que hacemos en el curso Construye con IA. Y para montar el harness alrededor del código que genera la IA, el Workshop SDD + Agentic Engineering va justo de eso.
Preguntas frecuentes
¿Qué versión de Claude Code necesito para claude plugin eval?
La v2.1.269 o posterior, y Git 2.31 o superior si tienes git instalado. Si ves el mensaje de que el comando está en early access, tu build es anterior: ejecuta claude update.
¿Puedo evaluar una skill de Claude Code que no está en un plugin?
Necesitas un directorio con plugin.json o .claude-plugin/plugin.json, o un plugin de tipo skills-directory. Para skills personales o de proyecto, la doc propone compararlas desactivándolas con skillOverrides o usar el plugin skill-creator.
¿Son compatibles los evals de skill-creator con plugin eval?
No. skill-creator usa evals/evals.json y el comando usa directorios con prompt.md y graders/. Ninguna de las dos herramientas lee los casos de la otra.
¿Por qué el comando sale con código 1 si los resultados parecen buenos?
Porque el --threshold por defecto es 1.0, y cualquier caso por debajo de la puntuación perfecta hace salir con 1. Fija un umbral realista, como 0.8. El código 1 también cubre un caso que no carga, que se reporta en stderr.
Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.
¿Quieres construir con agentes en serio?
Curso «Construye con IA» con Claude Code, de la idea al producto.
Developer con más de 15 años en frontend y creador de Dominicode. Escribe sobre IA aplicada al desarrollo de software.
¿Te resultó útil este artículo?
Compártelo con tu comunidad y ayuda a otros desarrolladores.