cursos:sdd:09-creando-skills
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| cursos:sdd:09-creando-skills [2026/11/05 22:22] – borrado - editor externo (Fecha desconocida) 127.0.0.1 | cursos:sdd:09-creando-skills [2026/11/05 22:39] (actual) – Quitados enlaces a secciones del tema 8 que ya no existen claude | ||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| + | ====== 9. Estructura de un skill ====== | ||
| + | |||
| + | Qué es una //skill//, su frontmatter y cómo se redacta están en [[cursos: | ||
| + | Más información: | ||
| + | |||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | |||
| + | |||
| + | Cada //skill// es una carpeta dentro de la carpeta de //skills// del proyecto. La carpeta en concreto depende de la herramienta: | ||
| + | |||
| + | * **OpenCode**: | ||
| + | * **Claude Code**: '' | ||
| + | |||
| + | OpenCode también lee '' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 1. Tipos de skills ===== | ||
| + | |||
| + | Hay dos tipos de //skills//: | ||
| + | |||
| + | * **Las que saben cosas**: describen las convenciones del proyecto (cómo son los servicios, cómo se escriben los tests). No hacen nada solas: las cargan otras //skills// y los agentes. | ||
| + | * **Las que hacen cosas**: ejecutan un proceso por fases (crear un servicio, revisar un PR). Las lanzas tú con ''/'' | ||
| + | |||
| + | Lo que hace una //skill// que hace cosas es, en el fondo, el trabajo de un [[cursos: | ||
| + | |||
| + | * **Un agente no tiene carpeta propia.** Es un único fichero en '' | ||
| + | * **Lanzarlo es más engorroso.** En Claude Code un agente se lanza con '' | ||
| + | <sxh bash> | ||
| + | @agent-crear-servicio R-12 | ||
| + | / | ||
| + | </ | ||
| + | |||
| + | Normalmente no hace falta convertirla en agente: lo que aporta un agente es empezar con el contexto vacío, y eso ya se consigue lanzando la //skill// en una sesión limpia, con ''/ | ||
| + | |||
| + | <sxh markdown; | ||
| + | --- | ||
| + | name: do-crear-servicio | ||
| + | description: | ||
| + | context: fork | ||
| + | --- | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | <note tip> | ||
| + | |||
| + | ===== 2. El nombre ===== | ||
| + | |||
| + | El nombre de la //skill// (su carpeta y su '' | ||
| + | |||
| + | * **'' | ||
| + | * **'' | ||
| + | |||
| + | Detrás del prefijo, en // | ||
| + | |||
| + | Ventajas del prefijo: | ||
| + | |||
| + | * **No chocan con los comandos de Claude Code**, que también se lanzan con ''/'' | ||
| + | * **Escribiendo ''/ | ||
| + | |||
| + | |||
| + | ===== 3. Estructura de carpetas y ficheros ===== | ||
| + | |||
| + | Una //skill// no suele ser un único '' | ||
| + | |||
| + | ==== Qué hay en cada carpeta ==== | ||
| + | |||
| + | ^ Carpeta o fichero ^ Contiene ^ Ejemplo ^ | ||
| + | | '' | ||
| + | | ''< | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | |||
| + | |||
| + | ==== Qué carpetas tiene cada tipo ==== | ||
| + | |||
| + | Las que suele tener cada [[# | ||
| + | |||
| + | ^ Carpeta ^ Skill de conocimiento ('' | ||
| + | | '' | ||
| + | | ''< | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | |||
| + | La de conocimiento guarda lo que **se sabe**: temas, ejemplos y documentación. La que hace guarda lo que **se ejecuta**: subagentes, plantillas de lo que genera y scripts. Si una '' | ||
| + | |||
| + | ==== Ejemplo: k-servicios ==== | ||
| + | |||
| + | Para explicar la estructura de carpetas de un skill , lo vamos a hacer con un ejemplo de un skill que " | ||
| + | |||
| + | <sxh text; | ||
| + | .claude/ | ||
| + | ├── SKILL.md | ||
| + | ├── transacciones.md | ||
| + | ├── templates/ | ||
| + | │ | ||
| + | ├── examples/ | ||
| + | │ | ||
| + | ├── references/ | ||
| + | │ | ||
| + | ├── scripts/ | ||
| + | │ | ||
| + | └── assets/ | ||
| + | └── errores.schema.json | ||
| + | |||
| + | </ | ||
| + | |||
| + | ==== Ejemplo: do-crear-servicio ==== | ||
| + | |||
| + | La //skill// que crea un servicio a partir de un requisito de '' | ||
| + | |||
| + | <sxh text; | ||
| + | .claude/ | ||
| + | ├── SKILL.md | ||
| + | ├── agents/ | ||
| + | │ | ||
| + | ├── templates/ | ||
| + | │ | ||
| + | └── scripts/ | ||
| + | └── sin-test.py | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | ===== 4. SKILL.md y < | ||
| + | En el fichero '' | ||
| + | |||
| + | El motivo de hace esto es para ahorrar contexto. A veces un skill trata de varios temas relacionados. Por ejemplo, si vamos a cear un CRUD, podríamos tener un skill que sepa hacer CRUDs y en ese caso hablaría sobre controladores, | ||
| + | |||
| + | |||
| + | ==== La description y la frase de entrada ==== | ||
| + | |||
| + | La '' | ||
| + | |||
| + | ^ ^ '' | ||
| + | | Cuándo la lee | Siempre: está en contexto junto con las de todas las //skills// | Solo cuando la //skill// ya está cargada | | ||
| + | | Para qué | Decidir si carga la //skill// | Saber qué es y cómo actuar | | ||
| + | | Qué dice | Qué es y **cuándo usarla**, con las palabras que escribiría el usuario | En las '' | ||
| + | |||
| + | <sxh markdown; | ||
| + | --- | ||
| + | name: do-crear-servicio | ||
| + | description: | ||
| + | specs/. Usar cuando se pida crear, añadir o generar un servicio o una clase *Service. | ||
| + | --- | ||
| + | |||
| + | # do-crear-servicio | ||
| + | |||
| + | Eres un desarrollador del servidor: conviertes un requisito de `specs/` en un `*Service` con su test. | ||
| + | </ | ||
| + | |||
| + | La frase de entrada es imprescindible cuando la //skill// se ejecuta sin pasar por la '' | ||
| + | |||
| + | * **Con '' | ||
| + | * **Cuando la lanzas tú con ''/ | ||
| + | |||
| + | <note tip>Si la frase de entrada repite la '' | ||
| + | |||
| + | |||
| + | ===== 5. El índice ===== | ||
| + | |||
| + | La tabla índice del '' | ||
| + | |||
| + | * **Un fichero que no está en la tabla es un huérfano**: | ||
| + | * **'' | ||
| + | * **Cada fichero se cita además donde se usa**, diciendo cuándo cargarlo. La tabla da la visión de conjunto; la cita, el momento. | ||
| + | <sxh markdown> | ||
| + | ✅ En la Fase 2, copia `templates/ | ||
| + | ❌ Ver también `templates/ | ||
| + | </ | ||
| + | * **Todo '' | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== 6. Dos tipos de skill ===== | ||
| + | |||
| + | |||
| + | ==== Skill de conocimiento ==== | ||
| + | |||
| + | <sxh markdown; | ||
| + | --- | ||
| + | name: k-servicios | ||
| + | description: | ||
| + | errores de negocio). Usar al escribir, revisar o probar una clase *Service. | ||
| + | --- | ||
| + | |||
| + | # k-servicios | ||
| + | |||
| + | Reglas de las clases `*Service` del servidor. La cargan `do-crear-servicio` y `do-revisar-pr`. | ||
| + | |||
| + | ## Índice | ||
| + | |||
| + | | Fichero | ||
| + | |-----------------------------|----------------------------------------| | ||
| + | | `transacciones.md` | ||
| + | | `templates/ | ||
| + | |||
| + | ## 1. Conceptos clave | ||
| + | < | ||
| + | |||
| + | ## 2. Convenciones del proyecto | ||
| + | <solo lo propio del proyecto, no lo del framework> | ||
| + | |||
| + | ## 3. Patrones recomendados | ||
| + | < | ||
| + | |||
| + | ## 4. Ejemplos ✅/❌ | ||
| + | <casos correctos e incorrectos, | ||
| + | |||
| + | ## 5. Anti-patrones | ||
| + | <lo que no se hace nunca y por qué> | ||
| + | </ | ||
| + | |||
| + | * **H1 igual que el '' | ||
| + | * **Frase de entrada**: qué cubre y **quién la usa**, para que el modelo sepa si es la que busca. | ||
| + | |||
| + | ==== Skill de procedimiento ==== | ||
| + | |||
| + | Sigue la estructura de los comandos de [[https:// | ||
| + | |||
| + | <sxh markdown; | ||
| + | --- | ||
| + | name: do-crear-servicio | ||
| + | description: | ||
| + | specs/. Usar cuando se pida crear, añadir o generar un servicio o una clase *Service. | ||
| + | --- | ||
| + | |||
| + | # do-crear-servicio | ||
| + | |||
| + | Eres un desarrollador del servidor: conviertes un requisito de `specs/` en un `*Service` con su test. | ||
| + | |||
| + | ## Índice | ||
| + | |||
| + | | Fichero | ||
| + | |-----------------------------|-----------------------------------------| | ||
| + | | `templates/ | ||
| + | | `agents/ | ||
| + | | `scripts/ | ||
| + | | `evals/ | ||
| + | |||
| + | ## Formato de entrada | ||
| + | |||
| + | ```text | ||
| + | $ARGUMENTS | ||
| + | ``` | ||
| + | |||
| + | You **MUST** consider the user input before proceeding (if not empty). Se espera el | ||
| + | identificador del requisito (`R-12`) y, opcionalmente, | ||
| + | |||
| + | ## Outline | ||
| + | |||
| + | 1. **Leer** el requisito (Fase 1). | ||
| + | 2. **Escribir** el servicio y su test (Fase 2). | ||
| + | 3. **Comprobar** que el requisito tiene test y pasa (Fase 3). | ||
| + | |||
| + | **STOP conditions**: | ||
| + | |||
| + | - No hay ningún requisito con ese identificador → **ERROR** y detente. | ||
| + | - El servicio ya existe → **STOP** y pregunta antes de sobrescribirlo. | ||
| + | |||
| + | ## 1. Fase 1 — Leer el requisito | ||
| + | |||
| + | 1. Busca el identificador en `specs/`. | ||
| + | 2. Carga la skill `k-servicios`. | ||
| + | |||
| + | ## 2. Fase 2 — Escribir el servicio | ||
| + | |||
| + | 1. Escribe el servicio con la plantilla de `k-servicios`. | ||
| + | 2. Copia `templates/ | ||
| + | |||
| + | ## 3. Fase 3 — Comprobar | ||
| + | |||
| + | 1. Ejecuta `python3 .claude/ | ||
| + | 2. Lanza un subagente con model: haiku que lea `agents/ | ||
| + | 3. Ejecuta `./mvnw -pl servidor test`. | ||
| + | |||
| + | **LIMIT**: máximo 3 vueltas de corrección; | ||
| + | |||
| + | ## Quick Guidelines | ||
| + | |||
| + | - Un servicio por agregado. | ||
| + | - Ningún requisito sin su test. | ||
| + | - Si el requisito es ambiguo, pregunta: no lo interpretes. | ||
| + | </ | ||
| + | |||
| + | Las secciones, en este orden: | ||
| + | |||
| + | * **Frase de entrada**: el **rol** que asume el modelo y **qué transforma en qué**. | ||
| + | * **''## | ||
| + | * **''## | ||
| + | * **Una sección por fase** del Outline, con sus pasos. | ||
| + | * **''## | ||
| + | |||
| + | ==== Palabras clave ==== | ||
| + | |||
| + | El cuerpo va en español, pero las palabras que marcan una orden van **en inglés y en negrita**: el modelo les da más peso que a «debes» o «es importante». | ||
| + | |||
| + | ^ Palabra ^ Para qué ^ | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | |||
| + | Solo en lo que de verdad no puede fallar. El resto, en imperativo y en segunda persona: «lee», «valida», no «podrías leer». | ||
| + | |||
| + | ==== Si genera un fichero: checklist y vueltas ==== | ||
| + | |||
| + | Una //skill// que escribe un fichero termina esa fase con un **checklist** que el modelo repasa antes de dar el fichero por bueno, y un **'' | ||
| + | |||
| + | <sxh markdown> | ||
| + | ### Checklist del servicio | ||
| + | |||
| + | - [ ] ¿Cada método público valida su entrada? | ||
| + | - [ ] ¿Cada requisito de `specs/` tiene un test con su identificador? | ||
| + | |||
| + | **MUST NOT** dar el servicio por terminado con algún punto sin cumplir. | ||
| + | **LIMIT**: máximo 3 vueltas de corrección; | ||
| + | </ | ||
| + | |||
| + | ==== agents/: los subagentes ==== | ||
| + | |||
| + | Si una fase delega en un subagente (comprobar, revisar, juzgar), su rol va en un fichero de '' | ||
| + | |||
| + | <sxh markdown> | ||
| + | ✅ Lanza un subagente con model: haiku que lea `agents/ | ||
| + | ❌ Lanza un subagente que lea `agents/ | ||
| + | </ | ||
| + | |||
| + | Todos los ficheros de '' | ||
| + | |||
| + | <sxh markdown; | ||
| + | # Verificador | ||
| + | |||
| + | Comprueba que un requisito tiene su test y que el test prueba lo que pide el requisito. | ||
| + | |||
| + | ## Rol | ||
| + | Revisas el trabajo de otro sin haberlo visto hacer. No le das la razón por haberlo intentado. | ||
| + | |||
| + | ## Entradas | ||
| + | Te llegan en el prompt: | ||
| + | - `requisito`: | ||
| + | - `ruta_test`: | ||
| + | |||
| + | ## Proceso | ||
| + | 1. Lee el requisito en `specs/`. | ||
| + | 2. Lee el test y busca el identificador en su nombre. | ||
| + | 3. Comprueba que cada condición del requisito tiene su aserción. | ||
| + | |||
| + | ## Criterios | ||
| + | - OK cuando: el test cita el requisito y comprueba todas sus condiciones. | ||
| + | - Fallo cuando: falta el identificador o alguna condición no tiene aserción. | ||
| + | - En la duda: fallo. | ||
| + | |||
| + | ## Salida | ||
| + | La primera línea es exactamente `PASS R-12` o `FAIL R-12`; debajo, una línea por condición sin probar. | ||
| + | ✅ `FAIL R-12` / `Sin aserción: el pedido enviado no se puede cancelar.` | ||
| + | ❌ `Parece que el test está bastante bien.` (el que lo lanza no puede comparar eso) | ||
| + | |||
| + | ## Pautas | ||
| + | - **MUST NOT** modificar el test: solo dice qué falta. | ||
| + | </ | ||
| + | |||
| + | * **Autocontenido**: | ||
| + | * **Criterios explícitos**: | ||
| + | * **Salida cerrada**: palabras literales ('' | ||
| + | * **Modelo barato si el rol es mecánico**: | ||
| + | |||
| + | <note warning> | ||
| + | |||
| + | ==== El siguiente paso lo lanzas tú ==== | ||
| + | |||
| + | Una //skill// de procedimiento **no lanza la siguiente** cuando decides tú cuándo se sigue: termina diciendo la orden exacta y para. | ||
| + | |||
| + | <sxh markdown> | ||
| + | ✅ Servicio creado. Siguiente paso: `/ | ||
| + | ❌ Servicio creado. Ahora lanzo do-revisar-pr. (te quita la revisión de lo generado) | ||
| + | </ | ||
| + | |||
| + | ===== 7. Argumentos de entrada ===== | ||
| + | |||
| + | Lo que escribes detrás de ''/ | ||
| + | |||
| + | <sxh bash> | ||
| + | /do-test unit create PedidoService | ||
| + | /do-test api create Pedido: alta válida, sin cliente, cliente que no existe | ||
| + | /do-test e2e repair | ||
| + | </ | ||
| + | |||
| + | En ese caso, el ''## | ||
| + | |||
| + | <sxh markdown; | ||
| + | --- | ||
| + | name: do-test | ||
| + | description: | ||
| + | Usar cuando se pida escribir tests, generarlos o arreglar los que fallan. | ||
| + | argument-hint: | ||
| + | --- | ||
| + | |||
| + | # do-test | ||
| + | |||
| + | Eres el responsable de los tests: los creas a partir del código o de los escenarios y reparas los que fallan. | ||
| + | |||
| + | ## Formato de entrada | ||
| + | |||
| + | ```text | ||
| + | $ARGUMENTS | ||
| + | ``` | ||
| + | |||
| + | You **MUST** consider the user input before proceeding (if not empty). El formato es | ||
| + | `< | ||
| + | |||
| + | - `tipo`: `unit`, `arch`, `api` o `e2e`. Obligatorio. | ||
| + | - `verbo`: `create` o `repair`. Obligatorio. | ||
| + | - `resto`: todo lo que va detrás del verbo, tal cual. | ||
| + | - `unit create`: una clase o un paquete. Si no hay, las clases de `domain` sin tests. | ||
| + | - `arch create`: las reglas de arquitectura, | ||
| + | - `api create` y `e2e create`: los escenarios. Obligatorio. | ||
| + | - `repair`: no lleva. | ||
| + | |||
| + | **STOP conditions**: | ||
| + | |||
| + | - Falta el tipo o el verbo, o no es uno de los valores → **ERROR** con la forma de uso | ||
| + | y detente. | ||
| + | - `api create` o `e2e create` sin escenarios → **STOP** y pide los escenarios. | ||
| + | </ | ||
| + | |||
| + | * **'' | ||
| + | * **'' | ||
| + | |||
| + | <note important> | ||
| + | |||
| + | <note important> | ||
| + | |||
| + | ===== 8. Formato de salida ===== | ||
| + | |||
| + | Cuando una //skill// o un [[# | ||
| + | |||
| + | * **'' | ||
| + | * **'' | ||
| + | |||
| + | Ahora lo normal es que el agente nos retorne la lista de problemas que nos ha encontrado. Esa lista obviamente debe ser texto, así que podría ser un JSON , un XML, etc. | ||
| + | Pero pensar que esos formatos son demasiado estrictos, por lo que se gastarán tokens en que tenga alguno de esos formato y además puede cometer errores. | ||
| + | Por ello es mejor un formato sencillo y facil de leer. | ||
| + | |||
| + | Mi recomendación es simplemente columnas separadas por ":" | ||
| + | |||
| + | |||
| + | Ejemplos de ellos podrían ser: | ||
| + | |||
| + | ^ Formato ^ Cuándo ^ | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | |||
| + | Según lo que haga cada agente debes elegir el formato que más se acople a tu problema. | ||
| + | |||
| + | Lo mismo pasa con el tipo. A modo de ejemplo te indico posibles valores: | ||
| + | |||
| + | ^ Agente ^ Valores ^ Qué miden ^ | ||
| + | | Codex ('' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | CodeRabbit | '' | ||
| + | | ::: | '' | ||
| + | | '' | ||
| + | |||
| + | |||
| + | Ahora que hemos visto el formato, veamos como decirselo al agente para que retorne ese formato.Hay que tener una sección titulada " | ||
| + | |||
| + | <sxh markdown; | ||
| + | ## Formato de Salida | ||
| + | |||
| + | La primera línea es `PASS` o `FAIL`. Con `PASS` no se escribe nada más. Con `FAIL`, | ||
| + | debajo, una línea por problema con el formato `fichero: | ||
| + | |||
| + | - `fichero` es donde se ha encontrado el problema. La ruta es relativa al proyecto. | ||
| + | - `linea` es un número (`42`) o un rango (`50-71`). Si el problema es del fichero | ||
| + | entero, no lleva `linea`: `fichero: | ||
| + | - `tipo` es `CRITICAL`, `MAJOR` o `MINOR`. | ||
| + | - `descripcion`es la descripción del problema que ha encontrado. Es texto libre pero si hay retornos de carro se deben escapar para que solo sea una línea. | ||
| + | |||
| + | |||
| + | **MUST NOT** escribir nada más antes ni después. | ||
| + | </ | ||
| + | |||
| + | ==== Ejemplos ==== | ||
| + | |||
| + | Una revisión sin problemas: | ||
| + | |||
| + | <sxh markdown> | ||
| + | PASS | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | |||
| + | <sxh markdown> | ||
| + | FAIL | ||
| + | src/ | ||
| + | src/ | ||
| + | specs/ | ||
| + | </ | ||
| + | |||
| + | Una //skill// que revisa los tests, sin '' | ||
| + | |||
| + | <sxh markdown> | ||
| + | FAIL | ||
| + | src/ | ||
| + | src/ | ||
| + | src/ | ||
| + | </ | ||
| + | |||
| + | Una //skill// que revisa el diseño de las clases, por método ('' | ||
| + | |||
| + | <sxh markdown> | ||
| + | FAIL | ||
| + | com.tienda.domain.PedidoService.crear: | ||
| + | com.tienda.domain.PedidoService: | ||
| + | R-12: | ||
| + | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| + | ===== Ejercicios ===== | ||
| + | |||
| + | ==== Ejercicio 1 ==== | ||
| + | |||
| + | Esta //skill// tiene cinco fallos de estructura. Encuéntralos y di cómo se arregla cada uno. | ||
| + | |||
| + | <sxh text; | ||
| + | .claude/ | ||
| + | ├── skill.md | ||
| + | ├── validacion/ | ||
| + | │ | ||
| + | ├── agents/ | ||
| + | │ | ||
| + | ├── templates/ | ||
| + | │ | ||
| + | └── examples/ | ||
| + | └── pedido-controller.md | ||
| + | </ | ||
| + | |||
| + | ==== Ejercicio 2 ==== | ||
| + | |||
| + | Escribe la //skill// de conocimiento '' | ||
| + | |||
| + | ==== Ejercicio 3 ==== | ||
| + | |||
| + | Escribe la //skill// de procedimiento '' | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
