Tabla de Contenidos
¡Esta es una revisión vieja del documento!
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.
Más información:
- OpenCode: skills: dónde busca las skills y qué campos lleva su frontmatter.
- OpenCode: agents: agentes principales y subagentes, y todos los campos del frontmatter.
- Specification - Agent Skills: el estándar de las skills.
1. Qué es una skill
Una skill es un fichero SKILL.md con lo que el agente tiene que saber o hacer para una tarea concreta: cómo son los servicios, cómo se revisa un PR, cómo se crea un endpoint o como se hacen los test.
Se carga dentro de tu conversación: el agente lee el skill y sigue trabajando con esas instrucciones. Es decir, llamar a un skill añade más prompt a tu conversación (contexto).,
2. Agente principal y subagentes
Un agente es un fichero con las instrucciones para hacer un trabajo cerrado y devolver un resultado. En OpenCode, Plan y Build son los agentes principales, los que hablan contigo; los que escribimos nosotros son casi siempre subagentes: los lanza el principal (qué es un subagente).
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
| Skill | Agente | |
|---|---|---|
| Dónde trabaja | En tu conversación | En un contexto nuevo, vacío |
| Qué ve | Todo lo que habéis hablado | Solo su fichero y el prompt que le pasan |
| Qué queda en tu contexto | Todo lo que lee y hace | Solo su respuesta |
| Para qué | Saber cómo se hace algo en el proyecto o seguir un procedimiento contigo | Encargar un trabajo y recibir un veredicto |
Por defecto, skill. Se usa un agente cuando el trabajo necesita un contexto limpio:
- Revisar lo que se acaba de escribir: un revisor que ha visto razonar al que escribió el código le da la razón. Sin la conversación, solo ve el código.
- Leer mucho para contestar poco: comprobar cuarenta tests y decir cuáles fallan. Los cuarenta ficheros se quedan en su contexto; al tuyo solo vuelve la lista.
4. Dónde se guardan
En OpenCode, dentro de .opencode/ del proyecto (y en ~/.config/opencode/ para todos los proyectos: skills y agentes en el tema 3):
.opencode
├── skills
│ ├── servicios
│ │ └── SKILL.md
│ └── revisar-pr
│ ├── SKILL.md
│ └── checklist.md
└── agents
├── revisor-tests.md
└── verificador-spec.md
- 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.mdpor agente. El nombre del agente es el del fichero:revisor-tests.mdes el agenterevisor-tests.
.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.
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.
--- name: servicios description: Convenciones de los servicios de Pedidos (transacciones, validación, errores de negocio). Usar al escribir, revisar o probar una clase *Service. ---
--- 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 ---
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:subagentpara que solo lo lance otro agente. Si no se pone, también aparece entre los principales al pulsarTab.permission: lo que no puede hacer. Un revisor conedit: 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:
# ✅ 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.
6. El SKILL.md
Una skill no lleva entradas ni salida: trabaja dentro de tu conversación, así que ya ve lo que has pedido, y lo que hace se queda ahí. El cuerpo es solo lo que tiene que saber o hacer:
---
name: servicios
description: Convenciones de los servicios de Pedidos (transacciones, validación,
errores de negocio). Usar al escribir, revisar o probar una clase *Service.
---
# servicios
Reglas de las clases `*Service` del servidor.
## Convenciones
- Un servicio por agregado: `PedidoService`, no `PedidoLineaService`.
- Valida al entrar y lanza `ErrorDeNegocio` con el código del requisito de `specs/`.
- No devuelve entidades: devuelve DTOs.
## Ejemplos
- ✅ `throw new ErrorDeNegocio("R-12", "El pedido ya está enviado")`
- ❌ `throw new IllegalStateException("No se puede")` (no dice qué requisito incumple)
Cómo se organiza por dentro una skill grande está en Estructura de un skill.
7. El fichero del agente
Un agente sí necesita entradas y salida, porque no ve tu conversación y lo que devuelve lo lee otro agente. Así que su cuerpo lleva siempre estas tres secciones, en este orden:
## Entradas: lo que le llega en el prompt, con nombre. Es todo lo que sabe de la tarea.## Proceso: lo que tiene que hacer, en pasos numerados.## Salida: qué devuelve y con qué formato exacto.
--- 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 --- # Revisor de tests Revisas los tests de una clase. No arreglas nada: solo dices qué está mal. ## Entradas Te llegan en el prompt: - `clase`: ruta de la clase que se prueba. - `test`: ruta de su clase de test. ## Proceso 1. Lee `clase` y apunta sus métodos públicos. 2. Lee `test` y busca al menos un test por cada método público. 3. Comprueba que cada test tiene aserciones y que no copia valores del código de producción (el IVA escrito a mano en vez de leerlo). 4. En la duda, cuéntalo como problema. ## Salida La primera línea es exactamente `PASS` o `FAIL`. Con `PASS` no se escribe nada más. Con `FAIL`, debajo, una línea por problema con el formato `fichero:inicio-fin:descripcion`: - `fichero`: ruta relativa a la raíz del proyecto. - `inicio-fin`: las líneas donde está el problema. Si es una sola, `42-42`. - `descripcion`: qué está mal, en una sola línea.
Entradas el agente no lo sabe. «Revisa lo que hemos hecho» no funciona; el principal tiene que pasarle clase y test con sus rutas.
La salida: PASS o FAIL
El agente termina con una sola palabra en la primera línea: PASS si todo está bien, FAIL si no. El principal compara esa palabra tal cual para decidir qué hace; con «parece que los tests están bastante bien» no puede.
Con FAIL, una línea por problema con el formato fichero:inicio-fin:descripcion, que dice dónde ir a arreglarlo:
FAIL src/test/java/com/tienda/PedidoServiceTest.java:28-28:el nombre del test no cita el requisito src/test/java/com/tienda/PedidoServiceTest.java:30-45:escribe 21 en vez de leer el IVA del código de producción src/main/java/com/tienda/PedidoService.java:52-60:cancelar() no tiene ningún test
PASS
Ejercicios
Ejercicio 1
Di si cada tarea se hace con una skill o con un agente, y por qué:
| Tarea | Skill o agente | Por qué |
|---|---|---|
| Las convenciones de los controladores REST del proyecto | ||
Comprobar que cada requisito de specs/pedidos.md tiene un test | ||
| Cómo se escribe un mensaje de commit en el equipo | ||
| Revisar el servicio que acaba de escribir Build |
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.
