Herramientas de usuario

Herramientas del sitio


cursos:sdd:20-evaluacion-skills

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
cursos:sdd:20-evaluacion-skills [2026/11/05 22:23] – Renumera el tema y sus referencias tras añadir el tema 7 (AGENTS.md) claudecursos:sdd:20-evaluacion-skills [2026/11/06 08:37] (actual) – Renumerar el curso: Estructura de un skill pasa al 10 y los temas siguientes suben un número: movida a cursos:sdd:21-evaluacion-skills claude
Línea 1: Línea 1:
-====== 20. Evaluación de skills ====== 
- 
-Una //skill// se prueba como el código: primero que **está bien hecha** (los checks) y después que **funciona** (los //evals//), repitiendo cada prueba varias veces porque el modelo no responde siempre igual. Cómo se construye la //skill// está en [[cursos:sdd:09-creando-skills|Estructura de un skill]]. 
- 
-Más información: 
- 
-  * [[https://github.com/anthropics/skills/tree/main/skills/skill-creator|skill-creator]]: la //skill// de Anthropic para crear y evaluar //skills//. 
-  * [[https://www.anthropic.com/research/statistical-approach-to-model-evals|A statistical approach to model evaluations]]: por qué un resultado de //eval// sin su intervalo de confianza no dice nada. 
-  * [[https://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval#Wilson_score_interval|Wilson score interval]]: el intervalo que se usa aquí para la tasa de aprobado. 
- 
----- 
- 
-===== 1. Los checks: la forma ===== 
- 
-Antes de probar si una //skill// funciona, se comprueba que **está bien hecha**: una lista de comprobaciones que tiene que pasar entera antes de darla por terminada. Casi todo lo del [[cursos:sdd:09-creando-skills|tema 9]] se puede comprobar con un script, sin gastar tokens: 
- 
-  * La carpeta y el H1 se llaman igual que el ''name'', y hay un solo ''SKILL.md''. 
-  * La ''description'' existe y no pasa de 1.024 caracteres. 
-  * La tabla índice está antes de cualquier otra sección y no hay huérfanos ni rutas a ficheros que no existen. 
-  * Nombres en //kebab-case//, sin repetir la carpeta y sin carpetas fuera de la tabla. 
-  * Todo ''.md'' de más de 100 líneas tiene índice; ninguno pasa de 2.500 palabras. 
-  * Las de procedimiento tienen ''User Input'', ''Outline'', ''STOP conditions'' y ''Quick Guidelines'' con 10 puntos como máximo. 
- 
-Lo demás (que la ''description'' diga el cuándo, que no haya teoría que el modelo ya sabe, que cada ❌ lleve su porqué) lo revisa un modelo o una persona. 
- 
-<note tip>Esa lista y su script se guardan en una //skill// de conocimiento, ''k-skill'', con todas las reglas del tema 9. Así el agente las aplica al crear o revisar cualquier //skill// del proyecto.</note> 
- 
-===== 2. evals/: el comportamiento ===== 
- 
-Una batería de casos que se repite **al editar la //skill// y al cambiar de modelo**. Cada caso responde a dos preguntas: 
- 
-  * **¿Se activa?** Que se cargue solo dice que el modelo la encontró, no que la siguiera. 
-  * **¿Aporta?** El caso se ejecuta **con la //skill// y sin ella**, y la diferencia de nota es lo que aporta. Si sin ella también aprueba, sobra para ese caso. 
- 
-<sxh text;gutter:false> 
-.claude/skills/k-servicios/evals/ 
-├── update-sin-filtrar/          <- un caso, con el nombre de lo que prueba 
-│   ├── prompt.md                <- lo que escribiría el usuario 
-│   ├── case.yaml                <- opcional: dice qué script prepara los ficheros 
-│   ├── fixture.sh               <- opcional: crea los ficheros de partida 
-│   └── graders/ 
-│       ├── filtra-campos.md     <- un evaluador por fichero 
-│       └── skill-activada.md 
-└── results/                     <- las notas de cada evaluación; va en .gitignore 
-</sxh> 
- 
-==== El caso ==== 
- 
-  * **''prompt.md''**: lo que pediría un usuario, **sin nombrar la //skill//**: si la nombra, se prueba que obedece, no que se activa. En el frontmatter, cuántas vueltas puede dar el agente (''max_turns'') y cuántas veces se ejecuta el caso (''runs''). 
-<sxh markdown;title:evals/update-sin-filtrar/prompt.md> 
---- 
-max_turns: 30 
-runs: 10 
---- 
-Añade a PedidoServiceImpl un método update que permita cambiar la dirección y el teléfono del pedido. 
-</sxh> 
-  * **''fixture.sh''**: deja los ficheros mínimos de partida, aquí un ''PedidoServiceImpl.java'' sin ''update''. Lo enlaza ''case.yaml'': 
-<sxh yaml;title:evals/update-sin-filtrar/case.yaml> 
-schema_version: "1.1" 
-name: update-sin-filtrar 
-context: 
-  scaffold_script: fixture.sh 
-</sxh> 
- 
-==== Los evaluadores ==== 
- 
-En ''graders/'', un evaluador por fichero, con su ''type'' en el frontmatter. Sobre el resultado, con un modelo que hace de juez: 
- 
-<sxh markdown;title:evals/update-sin-filtrar/graders/filtra-campos.md> 
---- 
-type: llm 
-focus: { source: file, path: PedidoServiceImpl.java } 
---- 
-PASS si el update solo deja cambiar la dirección y el teléfono. 
-FAIL si copia sobre la entidad todo lo que recibe, o si el cliente puede cambiar el estado o el importe. 
-</sxh> 
- 
-Y sobre el proceso, con un script: 
- 
-<sxh markdown;title:evals/update-sin-filtrar/graders/skill-activada.md> 
---- 
-type: tool_used 
-tool: Skill 
-input_match: '"skill"\s*:\s*"k-servicios"' 
---- 
-</sxh> 
- 
-Los tipos de evaluador: 
- 
-^ Tipo ^ Aprueba cuando ^ Lo aplica ^ 
-| ''regex'' | Un patrón aparece (o no) en la respuesta o en un fichero | Un script | 
-| ''tool_used'' | Se llamó a una herramienta, con ''min'' y ''max'' veces | Un script | 
-| ''tool_order'' | Una herramienta se llamó antes que otra | Un script | 
-| ''file_exists'' | Se creó un fichero que cumple el patrón | Un script | 
-| ''llm'' | Un juez vota PASS en dos de tres votos | Un modelo juez | 
- 
-Cómo se hacen bien: 
- 
-  * **Al menos 3 casos**, sacados de **fallos reales** del modelo sin la //skill//, y **uno negativo**: un prompt parecido en el que la //skill// no debe activarse. 
-  * **Al menos 2 evaluadores por caso**: uno sobre el resultado y otro sobre el proceso. 
-  * **Deterministas primero**: ''regex'' sobre ficheros largos; ''llm'' solo para salidas cortas y con un PASS y un FAIL concretos. 
-  * **El juez, de otro modelo** que el evaluado: un modelo tiende a aprobar lo suyo. 
- 
-<note important>**''skill-activada'' no cuenta en la nota.** Sin la //skill// siempre suspende, así que inflaría la diferencia. Claude Code lo sabe: un ''tool_used'' sobre ''Skill'' solo dice si se activó.</note> 
- 
-<note warning>**El modelo evaluado no puede leer ''evals/''.** Si ve los criterios, aprueba por imitación. Ni el prompt ni ''fixture.sh'' apuntan a nada de ''evals/''.</note> 
- 
-==== Ejecutarlos ==== 
- 
-En Claude Code, con ''claude plugin eval'' y la carpeta de la //skill//. Por defecto ejecuta cada caso con la //skill// y sin ella, y da la diferencia: 
- 
-<sxh bash> 
-claude plugin eval .claude/skills/k-servicios --scaffold --runs 10 --judge-model haiku 
-</sxh> 
- 
-  * ''--scaffold'': ejecuta el ''fixture.sh'' de cada caso. Sin él, el caso empieza sin ficheros. 
-  * ''--runs 10'': veces que se ejecuta cada caso (por defecto, 3; ver la sección siguiente). 
-  * ''--judge-model haiku'': el modelo de los evaluadores ''llm''. 
-  * ''--case update-sin-filtrar'': solo ese caso. 
- 
-Al terminar saca una tabla por caso con su nota y su ''PASS%'', y deja el detalle en ''evals/results/<fecha>/''. 
- 
----- 
- 
-===== 3. Repetir la prueba: intervalos de confianza ===== 
- 
-El modelo no responde siempre igual, así que cada caso se ejecuta $n$ veces y lo que se mide es la **tasa de aprobado**: $k$ aprobados de $n$. Esa tasa es una estimación de la de verdad, y con pocas ejecuciones, muy imprecisa. Lo que dice cuánto te puedes fiar es su **intervalo de confianza al 95 %**: el rango en el que está la tasa real. 
- 
-<note important>**3 de 3 no es un 100 %.** Con 3 ejecuciones, todo aprobado solo dice que la tasa real está entre el 44 % y el 100 %: la //skill// podría fallar más de la mitad de las veces. Y 3 es lo que hace ''claude plugin eval'' por defecto.</note> 
- 
-==== El intervalo de Wilson ==== 
- 
-Con $\hat p = k/n$ y $z = 1{,}96$ para el 95 %: 
- 
-$$\frac{\hat p + \frac{z^2}{2n} \pm z\sqrt{\frac{\hat p(1-\hat p)}{n} + \frac{z^2}{4n^2}}}{1 + \frac{z^2}{n}}$$ 
- 
-No uses la fórmula de clase de estadística, $\hat p \pm z\sqrt{\hat p(1-\hat p)/n}$: con todo aprobado o todo suspendido da un intervalo de anchura cero, justo en los casos más frecuentes en un //eval//. 
- 
-Con este script se calcula a partir de lo que da ''claude plugin eval'': 
- 
-<sxh python;title:intervalo.py> 
-import sys 
-from math import sqrt 
- 
-def wilson(k, n, z=1.96): 
-    p = k / n 
-    centro = (p + z*z/(2*n)) / (1 + z*z/n) 
-    margen = z * sqrt(p*(1-p)/n + z*z/(4*n*n)) / (1 + z*z/n) 
-    return centro - margen, centro + margen 
- 
-k, n = int(sys.argv[1]), int(sys.argv[2]) 
-bajo, alto = wilson(k, n) 
-print(f"{k}/{n}: {bajo:.0%} – {alto:.0%}") 
-</sxh> 
- 
-<sxh bash> 
-python3 intervalo.py 9 10 
-</sxh> 
- 
-<sxh markdown> 
-9/10: 60% – 98% 
-</sxh> 
- 
-Lo que da según el número de ejecuciones: 
- 
-^ Resultado ^ Intervalo al 95 % ^ 
-| 3/3 | 44 % – 100 % | 
-| 5/5 | 57 % – 100 % | 
-| 10/10 | 72 % – 100 % | 
-| 20/20 | 84 % – 100 % | 
-| 9/10 | 60 % – 98 % | 
-| 5/10 | 24 % – 76 % | 
- 
-==== ¿Aporta la skill? Que no se solapen ==== 
- 
-La //skill// aporta en un caso cuando el intervalo **con** ella y el intervalo **sin** ella **no se solapan**. Si se solapan, la diferencia puede ser suerte: 
- 
-^ Ejecuciones ^ Con la //skill// ^ Sin la //skill// ^ ¿Aporta? ^ 
-| 10 | 9/10 (60 % – 98 %) | 5/10 (24 % – 76 %) | No se sabe: se solapan | 
-| 30 | 27/30 (74 % – 97 %) | 15/30 (33 % – 67 %) | Sí | 
- 
-Cuántas veces ejecutar: 
- 
-  * **10 por caso** para empezar: ''--runs 10'' o ''runs: 10'' en el ''prompt.md''. 
-  * **30 en los casos que se solapan**, solo esos, con ''--case'': 
-<sxh bash> 
-claude plugin eval .claude/skills/k-servicios --scaffold --runs 30 --case update-sin-filtrar 
-</sxh> 
- 
-<note tip>Si con 30 ejecuciones los intervalos siguen solapándose, la //skill// no aporta en ese caso, o aporta tan poco que no compensa los tokens que añade.</note> 
- 
----- 
- 
-===== Ejercicios ===== 
- 
-==== Ejercicio 1 ==== 
- 
-Crea la carpeta ''evals/'' de la //skill// ''do-crear-test'' del [[cursos:sdd:09-creando-skills#ejercicio_3|ejercicio 3 del tema 9]] con tres casos: dos que salgan de fallos que hayas visto al pedir tests sin la //skill// y uno negativo. Rellena la tabla: 
- 
-^ Caso ^ Prompt ^ Evaluador del resultado ^ Evaluador del proceso ^ 
-| | | | | 
-| | | | | 
-| | | | | 
- 
-==== Ejercicio 2 ==== 
- 
-Calcula el intervalo de confianza al 95 % de cada resultado y di si la //skill// aporta en cada caso: 
- 
-^ Caso ^ Con la //skill// ^ Intervalo ^ Sin la //skill// ^ Intervalo ^ ¿Aporta? ^ 
-| ''test-con-id'' | 10/10 | | 6/10 | | | 
-| ''test-sin-mock'' | 8/10 | | 7/10 | | | 
-| ''test-negativo'' | 3/3 | | 3/3 | | | 
- 
-==== Ejercicio 3 ==== 
- 
-Ejecuta los casos del ejercicio 1 con ''--runs 10''. Rellena la tabla y repite con ''--runs 30'' los casos en los que los intervalos se solapen: 
- 
-^ Caso ^ Ejecuciones ^ Con la //skill// ^ Intervalo ^ Sin la //skill// ^ Intervalo ^ ¿Aporta? ^ 
-| | | | | | | | 
-| | | | | | | | 
-| | | | | | | | 
  
cursos/sdd/20-evaluacion-skills.1793913816.txt.gz · Última modificación: por claude