Herramientas de usuario

Herramientas del sitio


cursos:sdd:08-skills-agentes

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
Próxima revisión
Revisión previa
cursos:sdd:08-skills-agentes [2026/11/05 23:51] – Apartado 3: árbol con los cuatro ficheros y su contenido (mismo cuerpo, distinto frontmatter); el prompt es el cuerpo del fichero claudecursos:sdd:08-skills-agentes [2026/11/06 08:37] (actual) – Renumerar el curso: Estructura de un skill pasa al 10 y los temas siguientes suben un número claude
Línea 1: Línea 1:
 ====== 8. Skills y agentes ====== ====== 8. Skills y agentes ======
  
-Las //skills// y los agentes son los dos ficheros markdown con instrucciones, pero sirven para cosas distintas y por eso se escriben distinto. Vamos a ver qué es cada uno, cuándo se usa cada uno, dónde se guardan en OpenCode y qué partes lleva cada fichero.+Las //skills// y los agentes son los dos ficheros markdown con instrucciones, pero sirven para cosas distintas y por eso se escriben distinto. Vamos a ver qué es cada uno, dónde se guardan en OpenCode, qué lleva su frontmatter, cuándo se usa cada uno y qué partes lleva el cuerpo de cada fichero.
  
 Más información: Más información:
Línea 23: Línea 23:
 El subagente **empieza con el contexto vacío**: solo tiene su fichero y el prompt que le escribe el principal. Al terminar, al principal solo le vuelve su respuesta. El subagente **empieza con el contexto vacío**: solo tiene su fichero y el prompt que le escribe el principal. Al terminar, al principal solo le vuelve su respuesta.
  
-===== 3. Skill o agente =====+===== 3. Dónde se guardan ===== 
 + 
 +En OpenCode, dentro de ''.opencode/'' del proyecto (y en ''~/.config/opencode/'' para todos los proyectos: [[cursos:sdd:03-opencode#donde_se_guardan1|skills]] y [[cursos:sdd:03-opencode#donde_se_guardan|agentes]] en el tema 3): 
 + 
 +<sxh text;gutter:false> 
 +.opencode 
 +├── skills 
 +│   ├── servicios 
 +│   │   └── SKILL.md 
 +│   └── revisar-pr 
 +│       ├── SKILL.md 
 +│       └── checklist.md 
 +└── agents 
 +    ├── revisor-tests.md 
 +    └── verificador-spec.md 
 +</sxh> 
 + 
 +  * **Cada //skill// va en su propia carpeta**, con el nombre de la //skill//, y dentro el fichero se llama siempre ''SKILL.md''. La carpeta es suya: puede llevar al lado los ficheros que use (''checklist.md''). 
 +  * **Todos los agentes van en una única carpeta**, ''.opencode/agents/'', un fichero ''.md'' por agente. **El nombre del agente es el del fichero**: ''revisor-tests.md'' es el agente ''revisor-tests''. 
 + 
 +<note warning>**En ''.opencode/agents/'' no se deja ningún otro ''.md''.** OpenCode convierte en agente todo ''.md'' que haya ahí, también en subcarpetas: una plantilla ''agents/plantillas/informe.md'' aparece como el agente ''plantillas/informe''.</note> 
 + 
 +---- 
 + 
 +===== 4. El frontmatter ===== 
 + 
 +Los dos ficheros empiezan con una **cabecera en YAML entre dos líneas ''%%---%%''**, el //frontmatter//. Detrás va el cuerpo en markdown. 
 + 
 +<sxh yaml;title:.opencode/skills/servicios/SKILL.md> 
 +--- 
 +name: servicios 
 +description: Convenciones de los servicios de Pedidos (transacciones, validación, 
 +  errores de negocio). Usar al escribir, revisar o probar una clase *Service. 
 +--- 
 +</sxh> 
 + 
 +<sxh yaml;title:.opencode/agents/revisor-tests.md> 
 +--- 
 +description: Revisa los tests de una clase de servicio y dice qué falta o está mal. 
 +  Usar después de escribir o cambiar los tests de una clase *Service, antes del commit. 
 +mode: subagent 
 +permission: 
 +  edit: deny 
 +--- 
 +</sxh> 
 + 
 +En la //skill//: 
 + 
 +  * ''name'': obligatorio, el mismo que el nombre de la carpeta. 
 +  * ''description'': obligatoria. 
 + 
 +En el agente no hay ''name'', porque lo da el fichero: 
 + 
 +  * ''description'': obligatoria. 
 +  * ''mode'': ''subagent'' para que solo lo lance otro agente. Si no se pone, también aparece entre los principales al pulsar ''Tab''. 
 +  * ''permission'': lo que no puede hacer. Un revisor con ''edit: deny'', porque si puede editar acaba arreglando en vez de revisar. 
 + 
 +==== La descripción ==== 
 + 
 +**La ''description'' es lo único que el LLM lee siempre.** De todas las //skills// y agentes tiene en contexto solo el nombre y la descripción; el cuerpo no lo ve hasta que decide usarlo. Así que, si la descripción no dice **cuándo** usarlo, no lo usa nunca. 
 + 
 +Tiene que decir **qué hace y cuándo usarlo**, con las palabras con las que se pedirá la tarea: 
 + 
 +<sxh yaml> 
 +# ✅ qué cubre, cuándo usarla y con qué palabras se pide 
 +description: Convenciones de los servicios de Pedidos (transacciones, validación, 
 +  errores de negocio). Usar al escribir, revisar o probar una clase *Service. 
 + 
 +# ❌ no dice cuándo: no se carga nunca 
 +description: Utilidades para servicios. 
 + 
 +# ❌ cuenta el proceso, que va en el cuerpo, y no dice cuándo 
 +description: Primero lee el servicio, luego revisa las transacciones y lanza los tests. 
 +</sxh> 
 + 
 +---- 
 + 
 +===== 5. Skill o agente =====
  
 ^  ^ Skill ^ Agente ^ ^  ^ Skill ^ Agente ^
Línea 53: Línea 130:
 **Ejemplo 1: cómo se hace un ''Repository'' con JPA.** El fichero dice **cómo se hace algo** en el proyecto. Es conocimiento que se usa mientras se programa. La //skill// y el agente llevan el mismo cuerpo; solo cambia el frontmatter: **Ejemplo 1: cómo se hace un ''Repository'' con JPA.** El fichero dice **cómo se hace algo** en el proyecto. Es conocimiento que se usa mientras se programa. La //skill// y el agente llevan el mismo cuerpo; solo cambia el frontmatter:
  
-<sxh markdown;title:.opencode/skills/repository-jpa/SKILL.md>+<sxh yaml;title:.opencode/skills/repository-jpa/SKILL.md>
 --- ---
 name: repository-jpa name: repository-jpa
Línea 69: Línea 146:
 </sxh> </sxh>
  
-<sxh markdown;title:.opencode/agents/repository-jpa.md>+<sxh yaml;title:.opencode/agents/repository-jpa.md>
 --- ---
 description: Cómo se escriben los repositorios JPA de este proyecto. Usar al crear description: Cómo se escriben los repositorios JPA de este proyecto. Usar al crear
Línea 87: Línea 164:
 **Ejemplo 2: generar los tests de una clase.** El fichero dice **cómo hacer un trabajo cerrado** del que interesa el resultado: el test terminado y si pasa. Otra vez el mismo cuerpo en los dos: **Ejemplo 2: generar los tests de una clase.** El fichero dice **cómo hacer un trabajo cerrado** del que interesa el resultado: el test terminado y si pasa. Otra vez el mismo cuerpo en los dos:
  
-<sxh markdown;title:.opencode/skills/generar-tests/SKILL.md>+<sxh yaml;title:.opencode/skills/generar-tests/SKILL.md>
 --- ---
 name: generar-tests name: generar-tests
Línea 104: Línea 181:
 </sxh> </sxh>
  
-<sxh markdown;title:.opencode/agents/generar-tests.md>+<sxh yaml;title:.opencode/agents/generar-tests.md>
 --- ---
 description: Genera la clase de test de una clase de servicio con JUnit 5 y Mockito description: Genera la clase de test de una clase de servicio con JUnit 5 y Mockito
Línea 129: Línea 206:
 ==== Ejemplo 1 como agente ==== ==== Ejemplo 1 como agente ====
  
-No pasa absolutamente nada útil. El principal lanza el agente, que arranca con el contexto vacío, lee su fichero con las reglas de JPA, hace el repository en su contexto y devuelve el código. Las reglas **no han llegado a tu conversación**: tu agente principal sigue sin saber cómo se hace un repository en este proyecto. En cuanto pidas el de ''Cliente'' o retoques el de ''Pedido'' a mano con él, hará lo que le parezca, o tendrá que lanzar el agente otra vez para que vuelva a leer el mismo fichero.+No pasa absolutamente nada. El principal lanza el agente, que arranca con el contexto vacío y lee su fichero. Y en ese fichero **no se le dice que haga nada**: son cuatro reglas sobre cómo son los repositorios, ni una tarea. El agente no puede crear ''PedidoRepository'' ni devolver código, porque nadie se lo ha pedido a él; lo único que puede hacer es contestar con lo que sabe, es decir, repetir sus reglas, o decir que no tiene nada que hacer. Y al terminar, las reglas **mueren con él**: a tu conversación no ha llegado nada, y tu agente principal sigue sin saber cómo se hace un repository en este proyecto.
  
-Lo único que se ha conseguido es gastar tokens en que un proceso aparte lea unas reglas que luego mueren con él. Conocimiento en un agente es conocimiento que nadie conserva.+En el mejor de los casos, el agente devuelve las reglas en su respuesta y el principal las usa: has pagado un proceso aparte para traer al contexto el mismo texto que la //skill// habría puesto directamente. En el peor, cada vez que el principal necesite saber cómo va un repository tendrá que lanzarlo otra vez para que vuelva a leer el mismo fichero. Conocimiento en un agente es conocimiento que nadie conserva.
  
 ==== Ejemplo 2 como agente ==== ==== Ejemplo 2 como agente ====
Línea 141: Línea 218:
 El trabajo también se hace, y se hace igual de bien: el principal carga el fichero y hace lo mismo que haría el agente. La diferencia es **dónde se queda todo eso**: la clase leída, el test escrito, la salida de ''mvn test'' con su traza de error, el test corregido, la segunda salida... todo en tu conversación, cuando a ti solo te interesaba el resultado. Y ese relleno **se paga en cada mensaje que viene después**: en cada turno se vuelve a enviar el contexto entero, así que cuantos más tokens hay dentro, más caro sale cada mensaje nuevo y antes se llena el contexto, que es lo que hace que el modelo empiece a olvidar lo del principio. El trabajo también se hace, y se hace igual de bien: el principal carga el fichero y hace lo mismo que haría el agente. La diferencia es **dónde se queda todo eso**: la clase leída, el test escrito, la salida de ''mvn test'' con su traza de error, el test corregido, la segunda salida... todo en tu conversación, cuando a ti solo te interesaba el resultado. Y ese relleno **se paga en cada mensaje que viene después**: en cada turno se vuelve a enviar el contexto entero, así que cuantos más tokens hay dentro, más caro sale cada mensaje nuevo y antes se llena el contexto, que es lo que hace que el modelo empiece a olvidar lo del principio.
  
-<note important>**La regla:** si el fichero dice **cómo se hace algo** que vas a seguir usando, es una //skill//: en un agente ese conocimiento no llega a tu conversación. Si el fichero describe **un trabajo del que solo quieres el resultado**, es un agente: como //skill// funciona, pero deja en tu contexto todo lo que ha tenido que leer y hacer.</note> 
  
 ==== Resumen ==== ==== Resumen ====
  
 ^  ^ Como skill ^ Como agente ^ ^  ^ Como skill ^ Como agente ^
-| Ejemplo 1: cómo se hace un repository JPA | ✓ Las reglas se quedan y valen para el resto de la conversación | Las reglas mueren con el agente: tu conversación sigue sin saberlas | +| Ejemplo 1: cómo se hace un repository JPA | ✓ Las reglas se quedan y valen para el resto de la conversación | No hay nada que hacer: el fichero son reglas, no una tarea. Como mucho las recita, y mueren con él | 
-| Ejemplo 2: generar los tests de una clase | Funciona, pero los ficheros leídos, las salidas de ''mvn test'' y los reintentos se quedan en tu contexto | ✓ Solo vuelve el resultado |+| Ejemplo 2: generar los tests de una clase | Funciona, pero los ficheros leídos, las salidas de ''mvn test'' y los reintentos se quedan en tu contexto y se gastan más tokens (Más dinero) | ✓ Se hace la misma tareas y solo devuelve el resultado al contexto principal |
  
 ==== Un caso especial ==== ==== Un caso especial ====
Línea 154: Línea 230:
  
 Piensa qué tienes: un contexto vacío al que se le añade el fichero y tu mensaje, trabaja, y lo que haya acumulado desaparece al cerrar porque nadie sigue hablando ahí. **Es exactamente un agente**, con la diferencia de que el resultado se lo has dado tú al principal en vez de leerlo él. La //skill// no ha llenado nada que vayas a pagar después. Así que la pregunta de fondo no es «¿esto es una skill o un agente?», sino «**¿voy a seguir trabajando en esta conversación con lo que quede en el contexto?**». Si no, da igual cuál de los dos uses. Piensa qué tienes: un contexto vacío al que se le añade el fichero y tu mensaje, trabaja, y lo que haya acumulado desaparece al cerrar porque nadie sigue hablando ahí. **Es exactamente un agente**, con la diferencia de que el resultado se lo has dado tú al principal en vez de leerlo él. La //skill// no ha llenado nada que vayas a pagar después. Así que la pregunta de fondo no es «¿esto es una skill o un agente?», sino «**¿voy a seguir trabajando en esta conversación con lo que quede en el contexto?**». Si no, da igual cuál de los dos uses.
- 
----- 
- 
-===== 4. Dónde se guardan ===== 
- 
-En OpenCode, dentro de ''.opencode/'' del proyecto (y en ''~/.config/opencode/'' para todos los proyectos: [[cursos:sdd:03-opencode#donde_se_guardan1|skills]] y [[cursos:sdd:03-opencode#donde_se_guardan|agentes]] en el tema 3): 
- 
-<sxh text;gutter:false> 
-.opencode 
-├── skills 
-│   ├── servicios 
-│   │   └── SKILL.md 
-│   └── revisar-pr 
-│       ├── SKILL.md 
-│       └── checklist.md 
-└── agents 
-    ├── revisor-tests.md 
-    └── verificador-spec.md 
-</sxh> 
- 
-  * **Cada //skill// va en su propia carpeta**, con el nombre de la //skill//, y dentro el fichero se llama siempre ''SKILL.md''. La carpeta es suya: puede llevar al lado los ficheros que use (''checklist.md''). 
-  * **Todos los agentes van en una única carpeta**, ''.opencode/agents/'', un fichero ''.md'' por agente. **El nombre del agente es el del fichero**: ''revisor-tests.md'' es el agente ''revisor-tests''. 
- 
-<note warning>**En ''.opencode/agents/'' no se deja ningún otro ''.md''.** OpenCode convierte en agente todo ''.md'' que haya ahí, también en subcarpetas: una plantilla ''agents/plantillas/informe.md'' aparece como el agente ''plantillas/informe''.</note> 
- 
----- 
- 
-===== 5. El frontmatter ===== 
- 
-Los dos ficheros empiezan con una **cabecera en YAML entre dos líneas ''%%---%%''**, el //frontmatter//. Detrás va el cuerpo en markdown. 
- 
-<sxh yaml;title:.opencode/skills/servicios/SKILL.md> 
---- 
-name: servicios 
-description: Convenciones de los servicios de Pedidos (transacciones, validación, 
-  errores de negocio). Usar al escribir, revisar o probar una clase *Service. 
---- 
-</sxh> 
- 
-<sxh yaml;title:.opencode/agents/revisor-tests.md> 
---- 
-description: Revisa los tests de una clase de servicio y dice qué falta o está mal. 
-  Usar después de escribir o cambiar los tests de una clase *Service, antes del commit. 
-mode: subagent 
-permission: 
-  edit: deny 
---- 
-</sxh> 
- 
-En la //skill//: 
- 
-  * ''name'': obligatorio, el mismo que el nombre de la carpeta. 
-  * ''description'': obligatoria. 
- 
-En el agente no hay ''name'', porque lo da el fichero: 
- 
-  * ''description'': obligatoria. 
-  * ''mode'': ''subagent'' para que solo lo lance otro agente. Si no se pone, también aparece entre los principales al pulsar ''Tab''. 
-  * ''permission'': lo que no puede hacer. Un revisor con ''edit: deny'', porque si puede editar acaba arreglando en vez de revisar. 
- 
-==== La descripción ==== 
- 
-**La ''description'' es lo único que el LLM lee siempre.** De todas las //skills// y agentes tiene en contexto solo el nombre y la descripción; el cuerpo no lo ve hasta que decide usarlo. Así que, si la descripción no dice **cuándo** usarlo, no lo usa nunca. 
- 
-Tiene que decir **qué hace y cuándo usarlo**, con las palabras con las que se pedirá la tarea: 
- 
-<sxh yaml> 
-# ✅ qué cubre, cuándo usarla y con qué palabras se pide 
-description: Convenciones de los servicios de Pedidos (transacciones, validación, 
-  errores de negocio). Usar al escribir, revisar o probar una clase *Service. 
- 
-# ❌ no dice cuándo: no se carga nunca 
-description: Utilidades para servicios. 
- 
-# ❌ cuenta el proceso, que va en el cuerpo, y no dice cuándo 
-description: Primero lee el servicio, luego revisa las transacciones y lanza los tests. 
-</sxh> 
  
 ---- ----
Línea 261: Línea 260:
 </sxh> </sxh>
  
-Cómo se organiza por dentro una //skill// grande está en [[cursos:sdd:09-creando-skills|Estructura de un skill]].+Cómo se organiza por dentro una //skill// grande está en [[cursos:sdd:10-creando-skills|Estructura de un skill]].
  
 ---- ----
Línea 340: Línea 339:
 | Comprobar que cada requisito de ''specs/pedidos.md'' tiene un test | | | | Comprobar que cada requisito de ''specs/pedidos.md'' tiene un test | | |
 | Cómo se escribe un mensaje de commit en el equipo | | | | Cómo se escribe un mensaje de commit en el equipo | | |
-| Revisar el servicio que acaba de escribir Build | | |+| Revisar el servicio que se acaba de escribir | | |
  
 ==== Ejercicio 2 ==== ==== Ejercicio 2 ====
  
-Escribe el agente ''.opencode/agents/revisor-dtos.md'', que comprueba que ningún controlador devuelve una entidad JPA. Tiene que tener el frontmatter con ''description'', ''mode'' y ''permission'', y las secciones ''Entradas'', ''Proceso'' y ''Salida'' con ''PASS''/''FAIL'' y el formato ''fichero:inicio-fin:descripcion''. Lánzalo desde Build con ''@revisor-dtos'' sobre un controlador que devuelva una entidad y comprueba que responde ''FAIL'' con la línea correcta.+Escribe la //skill// ''.opencode/skills/controladores-rest/SKILL.md'' con las convenciones de los controladores REST del proyecto: un controlador por agregado, rutas en plural (''/pedidos''), nunca devuelve una entidad JPA sino un DTO, y los errores de negocio se devuelven con ''409'' y el código del requisito. Pon una ''description'' que diga cuándo usarla. 
 + 
 +Abre **una conversación nueva** y pide «crea el controlador de ''Cliente''», sin nombrar la //skill//. Comprueba que la ha cargado y que el controlador cumple las cuatro reglas. 
 + 
 +==== Ejercicio 3 ==== 
 + 
 +Escribe el agente ''.opencode/agents/revisor-dtos.md'', que comprueba que ningún controlador devuelve una entidad JPA. Tiene que tener el frontmatter con ''description'', ''mode'' y ''permission'', y las secciones ''Entradas'', ''Proceso'' y ''Salida'' con ''PASS''/''FAIL'' y el formato ''fichero:inicio-fin:descripcion''. 
 + 
 +Abre **una conversación nueva** y lánzalo con ''@revisor-dtos'' sobre un controlador que devuelva una entidad. Comprueba que responde ''FAIL'' con la línea correcta y que en tu conversación solo ha quedado esa respuesta, no el controlador que ha leído.
  
cursos/sdd/08-skills-agentes.1793919072.txt.gz · Última modificación: por claude