Tabla de Contenidos
9. Skills, agentes y subagentes
En Skills y agentes vimos lo que dan las herramientas: la skill, que se carga en tu conversación, y el agente, que trabaja en un contexto vacío y devuelve un resultado. Aquí vamos a ver qué hacemos nosotros con eso: en este curso hablaremos de skills, agentes y subagentes, y los tres se escriben como skill. Cómo se organiza cada una por dentro (carpetas, secciones del SKILL.md) está en Estructura de un skill.
Más información:
- Specification - Agent Skills: el estándar de las skills: una carpeta con su
SKILL.mdy los ficheros que use. - Claude Code: subagents: qué es un subagente y cómo se le pasa el prompt.
1. Lo que da la herramienta
Dos ficheros con instrucciones, que se distinguen solo en dónde se carga su contenido (Skill o agente):
- Skill: su fichero se añade a tu conversación. Lo que lee y hace se queda en tu contexto.
- Agente: su fichero va a un contexto nuevo y vacío, junto con el prompt que le pasa el principal. A tu conversación solo vuelve su respuesta.
Y la frontera es más fina de lo que parece: una skill lanzada en una conversación recién abierta que cierras al terminar es un agente (el caso especial del tema 8). Claude Code lo hace explícito: una skill con context: fork en el frontmatter se ejecuta como agente, en un contexto aparte, sin cambiar nada más del fichero.
context: fork en las skills que lo necesiten, que es lo que ha acabado haciendo Claude Code.
2. Lo que hacemos nosotros: tres tipos
En este curso vamos a usar tres palabras, y conviene fijar desde ahora qué quiere decir cada una:
- Skill: lo que todo el mundo entiende por skill: conocimiento que se carga en la conversación. Cómo son los servicios, cómo se escriben los tests.
- Agente: lo que todo el mundo entiende por agente: le encargas un trabajo y lo hace. Pero lo implementamos como skill, por las razones de abajo. En Claude Code, con
context: forken el frontmatter, pasa a ser un agente de verdad: se ejecuta en su propio contexto. - Subagente: un agente que lanza nuestro agente para partir su tarea en trozos más pequeños: comprobar el test, revisar el fichero generado. Es también un agente, con su contexto vacío y su respuesta cerrada; lo que cambia es quién lo lanza.
Y cada uno se escribe y se nombra de una forma:
- Las skills se llaman
k-, de knowledge:k-servicios,k-tests. Detrás del prefijo, el tema. - Los agentes se llaman
do-, «hacer» en inglés:do-crear-servicio,do-revisar-pr. Detrás del prefijo, un verbo. Son skills para la herramienta, así que viven en.claude/skills/con las demás. - Los subagentes son un fichero markdown con su prompt en la carpeta
subagents/del agente que los lanza:do-crear-servicio/subagents/verificador.md. Sin prefijo: el nombre es su rol.
Todo en kebab-case.
.claude/skills/
├── k-servicios/
│ └── SKILL.md
└── do-crear-servicio/
├── SKILL.md
└── subagents/
└── verificador.md
Skill (k-) | Agente (do-) | Subagente | |
|---|---|---|---|
| Qué es | Lo que hay que saber: las convenciones del proyecto | Lo que hay que hacer: un proceso por fases | Una comprobación cerrada dentro de una fase del agente |
| Quién lo lanza | Un agente, o el modelo cuando la necesita | Tú, con / | El agente, en una de sus fases |
| Dónde se carga | En tu conversación | En tu conversación (o en una nueva con context: fork) | En un contexto nuevo y vacío |
| Qué devuelve | Nada: se queda cargada | El trabajo hecho y un mensaje final | Una respuesta cerrada: PASS o FAIL y una línea por problema |
| Dónde vive | .claude/skills/k-servicios/ | .claude/skills/do-crear-servicio/ | .claude/skills/do-crear-servicio/subagents/ |
Ventajas del prefijo:
- No chocan con los comandos de Claude Code, que también se lanzan con
/. Una skill llamadainitocontextse confunde con/inito/context;/do-revisar-prno coincide con ningún comando. - Escribiendo
/do-sale todo lo que se puede lanzar: el autocompletado enseña solo los agentes, sin las skills de conocimiento, que no se lanzan a mano.
Skill: k-
Describe cómo se hace algo en el proyecto: cómo son los servicios, cómo se escriben los tests, cómo se nombran los commits. No hace nada sola: la cargan los agentes («carga k-servicios») o el modelo cuando ve en su description que la necesita.
Es el ejemplo 1 del tema 8, el repository JPA: conocimiento que tiene que quedarse en la conversación para que valga en el siguiente mensaje. Por eso es una skill y nunca un agente.
Agente: do-
Ejecuta un proceso por fases: crear un servicio, revisar un PR, generar los tests. La lanzas tú con /do-crear-servicio R-12 y al terminar te dice qué ha hecho.
Es el ejemplo 2 del tema 8, generar los tests: el trabajo de un agente. Pero lo escribimos como skill, no como agente de la herramienta (por qué). Lo que aporta el agente, empezar con el contexto vacío, se consigue lanzando la skill en una conversación limpia, con /clear antes. Y si quieres que se ejecute como agente de verdad, mientras tú sigues en tu conversación, en Claude Code basta con context: fork en el frontmatter:
--- name: do-crear-servicio description: Crea un servicio de Pedidos con su test a partir de un requisito de specs/. Usar cuando se pida crear, añadir o generar un servicio o una clase *Service. context: fork ---
Subagente
Un subagente es un trabajo cerrado dentro de una fase de un agente: comprobar que el test cubre el requisito, revisar el fichero generado, juzgar si cumple el checklist. Lo lanza el agente, no tú, y su respuesta la lee el agente para decidir si sigue o corrige.
Su prompt es un fichero .md en la carpeta subagents/ del agente. Para la herramienta ese fichero no existe: no está en .claude/agents/ ni tiene frontmatter. Es el SKILL.md del agente el que dice cuándo se lanza, qué fichero lee y qué le pasa, y Claude Code arranca un subagente genérico con ese prompt:
✅ Lanza un subagente con model: haiku que lea `subagents/verificador.md` y pásale `requisito` y `ruta_test`. ❌ Lanza un subagente que lea `subagents/verificador.md`. (no dice qué le pasa ni con qué modelo)
Es el agente del tema 8 (El fichero del agente), con las mismas tres secciones, Entradas, Proceso y Salida, y las mismas razones:
- Empieza vacío, así que todo lo que necesita le llega en
Entradas. «Revisa lo que hemos hecho» no funciona. - Lo que lee muere con él: la clase, el test, la salida de
mvn test. Al agente solo le vuelve la respuesta. - La respuesta es cerrada,
PASSoFAILen la primera línea, para que el agente la compare tal cual.
Por qué va dentro del agente y no en .claude/agents/ ni en su propia carpeta do-, en la sección 4.
fork. El fork hereda toda la conversación: el verificador ve razonar al que escribió el código y le da la razón. Además ignora el model.
3. Cuál de los tres
Tres preguntas, en este orden:
- ¿Son reglas o es una tarea? Si son reglas (cómo se hace algo), skill
k-. Si es una tarea, sigue. - ¿La lanzas tú? Si la pides tú y quieres ver cómo avanza, agente
do-. Si la lanza un agente en medio de su proceso, sigue. - ¿El resultado es una comprobación cerrada que el agente compara? Entonces subagente. Si el agente necesita que lo que se ha leído siga en el contexto, no es un subagente: es una fase más del
do-.
Con el ejemplo del curso:
- Cómo son los servicios →
k-servicios. - Crear un servicio a partir de un requisito →
do-crear-servicio. - Comprobar que el test del servicio cubre el requisito, dentro de
do-crear-servicio→subagents/verificador.md.
4. Por qué esta separación
La herramienta ya trae skills y agentes. Tenerlos de otra manera, los agentes como skill y los subagentes como un fichero dentro del agente, es una decisión, y estas son las razones.
Por qué los agentes son skills
- Un agente de la herramienta no tiene carpeta propia. Es un único fichero en
.claude/agents/. Nuestros agentes llevan plantillas, scripts, ejemplos, subagentes y evals (la estructura), y todo eso tiene que ir junto para poder mantenerlo. Una skill es una carpeta. - Lanzarlo cuesta más. En Claude Code un agente se lanza con
agent-delante del nombre y una skill directamente, y/do-autocompleta solo lo que se puede lanzar:
@agent-crear-servicio R-12 /do-crear-servicio R-12
- Un agente se lanza solo en su conversación. Lo normal con un trabajo cerrado es abrir una conversación, lanzar
/do-crear-servicio R-12, mirar el resultado y cerrarla. Eso ya es un agente (el caso especial del tema 8): el contexto vacío lo da/clear, no hace falta otro proceso. Y el día que quieras seguir hablando mientras trabaja,context: forklo convierte en agente de la herramienta sin tocar el resto del fichero. - Vale para las dos herramientas. OpenCode lee
.claude/skills/pero no.claude/agents/, y su frontmatter de agente es otro (tema 3). Un agente escrito como skill funciona igual en Claude Code y en OpenCode; escrito como agente, hay que mantener dos ficheros. - Un solo formato que aprender. Skill y agente tienen el mismo
SKILL.md, el mismo frontmatter y la misma forma de organizar la carpeta. Lo que cambia entre uno y otro es el cuerpo, no la mecánica.
El único inconveniente: el modelo. Un agente de la herramienta elige su modelo en el frontmatter (model: haiku para un revisor mecánico, el modelo grande para el que diseña). Una skill no: se ejecuta con el modelo de la conversación en la que se carga. La excepción es Claude Code, cuyo frontmatter de skill también admite model, así que ahí el inconveniente desaparece:
--- name: do-revisar-pr description: Revisa un PR y deja la lista de problemas. Usar cuando se pida revisar un PR o una rama. context: fork model: haiku ---
context: fork y model, dice por dónde va el camino: unificar agentes y skills en una sola carpeta y un solo formato. Es lo que hacemos en este curso.
Por qué los subagentes van dentro del agente
- No son reutilizables. El verificador de
do-crear-serviciocomprueba lo que genera ese agente, con las entradas que ese agente le pasa. Fuera de él nadie lo lanza, así que no tiene sentido que esté donde se buscan las cosas que se lanzan. Lo que solo usa uno va con ese uno. - En
.claude/agents/estorbaría. Aparecería en la lista de agentes de la herramienta y en el autocompletado de@, como si fuera para lanzarlo tú. Y en OpenCode, además, no existiría. - Se mantiene con el agente. Si cambia la fase que lo lanza, cambian sus
Entradasy suSalida: están en la misma carpeta y se cambian a la vez. Quien leedo-crear-serviciolo ve entero sin salir de su carpeta. - Sí tiene que ser un agente de verdad, con contexto vacío, porque el resultado lo necesita el agente que sigue trabajando, no tú, y porque lo que lee (la clase, el test, la salida de
mvn test) no tiene que llenar el contexto del agente. Un fichero desubagents/da justo eso: un prompt que se lanza en un contexto nuevo y devuelve una línea.
Y la señal de que algo está mal clasificado: si un fichero de subagents/ acaba lanzándose desde dos agentes, es que es un agente. Pasa a su propia carpeta do- y los dos lo cargan desde allí.
Ejercicios
Ejercicio 1
Di si cada cosa es una skill, un agente o un subagente, y por qué:
| Tarea | Tipo | Por qué |
|---|---|---|
| Las convenciones de los controladores REST del proyecto | ||
| Crear el controlador de un agregado a partir de su especificación | ||
| Comprobar que ningún controlador devuelve una entidad JPA, al final de crear uno | ||
| Cómo se escribe un mensaje de commit en el equipo | ||
| Revisar un PR entero y dejar la lista de problemas | ||
Contar cuántos requisitos de specs/ no tienen test, dentro de la revisión del PR |
Ejercicio 2
do-revisar-pr tiene estas fases: leer el PR, comprobar las convenciones de los servicios, comprobar que cada requisito tiene test, comprobar la cobertura y escribir el informe. Di qué skills k- carga el agente, qué fases se hacen con un subagente y qué le pasa a cada uno en Entradas.
