Se mueve la documentación de issues/tasks de .claude/tasks/ a dev/issues/ para separar la planificación de desarrollo de la configuración de Claude. Se añade dev/README.md como índice de la carpeta de desarrollo. Los issues completados se mueven a dev/issues/completed/. Esto permite que dev/ sea el punto central de documentación interna del proyecto. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
11 KiB
016 — Sistema de Skills para agentes
Objetivo
Crear un sistema de skills reutilizables que los agentes puedan cargar y ejecutar. Las skills son paquetes de instrucciones, scripts y recursos que amplian las capacidades de un agente mas alla de las tools de function calling. Mientras las tools son funciones atomicas (clock, http_get, ssh_command), las skills son flujos completos de trabajo (deploy a produccion, analizar logs, generar reportes).
Contexto
- Las tools (
tools/) son funciones atomicas: reciben args, ejecutan, devuelven resultado. El LLM las invoca via function calling. - Las skills son paquetes de instrucciones + recursos que guian al agente para completar tareas complejas multi-paso. Son como "recetas" que el agente sigue.
- Ejemplo: una tool es
ssh_command. Una skill es "deploy-service" que usa ssh_command, http_get, y logica condicional para hacer un deploy completo.
Prerequisitos
- Ninguno estricto. El sistema de tools existente sigue funcionando igual.
Estructura de una skill
skills/<categoria>/<skill-name>/
├── SKILL.md ← obligatorio (frontmatter YAML + instrucciones markdown)
├── LICENSE.txt ← opcional
├── scripts/ ← opcional, codigo ejecutable (bash, python, etc.)
├── references/ ← opcional, docs de referencia
├── templates/ ← opcional, plantillas/assets
└── assets/ ← opcional, fuentes, iconos, etc.
SKILL.md — formato
---
name: skill-name
description: >
Descripcion clara de que hace la skill y cuando debe activarse.
Esta descripcion es el mecanismo principal de triggering.
---
# Instrucciones
Cuerpo markdown con las instrucciones completas.
Idealmente < 500 lineas.
Carga progresiva (3 niveles)
- Metadata (name + description) — siempre en contexto (~100 palabras). El agente la lee para decidir si activar la skill.
- Cuerpo del SKILL.md — se carga cuando la skill se activa. Instrucciones principales.
- Recursos bundled (scripts/, references/, etc.) — se cargan bajo demanda. El SKILL.md indica cuando leer cada archivo.
Carpetas opcionales
| Carpeta | Proposito |
|---|---|
scripts/ |
Codigo ejecutable que el agente corre (bash, python). Puede ejecutarlos sin cargarlos en contexto. |
references/ |
Documentacion extensa, leida solo cuando es relevante. Si > 300 lineas, agregar TOC al inicio. |
templates/ |
Plantillas que la skill usa como base para generar outputs. |
assets/ |
Archivos estaticos (fuentes, iconos, imagenes). |
Tareas
Fase 1: Estructura de directorios y skills iniciales
-
1.1 Crear la carpeta
skills/en la raiz del proyecto con subcategorias:skills/ ├── README.md ← documentacion del sistema de skills ├── devops/ ← skills de operaciones y deploy ├── analysis/ ← skills de analisis de datos/logs ├── communication/ ← skills de comunicacion y notificaciones ├── coding/ ← skills de desarrollo y code review └── system/ ← skills de administracion del sistema -
1.2 Crear skills iniciales de ejemplo:
skills/devops/deploy-service/SKILL.md— deploy de un servicio via SSHskills/analysis/log-analyzer/SKILL.md— analisis de logs con patronesskills/communication/daily-report/SKILL.md— generar y enviar reporte diarioskills/system/health-check/SKILL.md— verificar salud de servicios
Fase 2: Tipos puros en pkg/skills/
-
2.1 Crear
pkg/skills/types.gocon los tipos puros:// SkillMeta es la metadata extraida del frontmatter YAML del SKILL.md. type SkillMeta struct { Name string `yaml:"name"` Description string `yaml:"description"` Category string // derivado de la ruta del directorio } // Skill es la representacion completa de una skill cargada. type Skill struct { Meta SkillMeta Instructions string // cuerpo markdown del SKILL.md BasePath string // ruta al directorio de la skill Scripts []string // rutas relativas a scripts/ References []string // rutas relativas a references/ Templates []string // rutas relativas a templates/ } // SkillMatch indica si una skill es relevante para un contexto dado. type SkillMatch struct { Skill SkillMeta Confidence float64 // 0.0 - 1.0 } -
2.2 Crear
pkg/skills/match.go— funcion pura que dado un mensaje y una lista deSkillMeta, retorna las skills mas relevantes:func Match(query string, skills []SkillMeta) []SkillMatchImplementacion inicial: keyword matching simple contra name + description.
Fase 3: Loader en shell/skills/
-
3.1 Crear
shell/skills/loader.go— carga skills desde el filesystem:// Loader descubre y carga skills desde un directorio base. type Loader struct { basePath string } func NewLoader(basePath string) *Loader func (l *Loader) LoadAll() ([]skills.Skill, error) // carga todas las skills func (l *Loader) LoadMeta() ([]skills.SkillMeta, error) // solo metadata (nivel 1) func (l *Loader) LoadSkill(name string) (*skills.Skill, error) // skill completa (nivel 2) func (l *Loader) ReadResource(skill, path string) (string, error) // recurso (nivel 3) -
3.2 Implementar parsing del SKILL.md:
- Extraer frontmatter YAML entre
--- - Extraer cuerpo markdown
- Listar archivos en subcarpetas opcionales
- Extraer frontmatter YAML entre
Fase 4: Integracion con el runtime
-
4.1 Anadir
skillLoader *shellskills.Loaderal structAgentenagents/runtime.go -
4.2 Crear una tool
skill_searchentools/skills/que permita al LLM buscar skills relevantes:// Def: name="skill_search", params=[{name: "query", type: "string"}] // Exec: usa el loader para buscar skills por relevancia -
4.3 Crear una tool
skill_loadentools/skills/que cargue el contenido completo de una skill:// Def: name="skill_load", params=[{name: "skill_name", type: "string"}] // Exec: retorna las instrucciones completas del SKILL.md -
4.4 Crear una tool
skill_read_resourcepara cargar recursos bajo demanda:// Def: name="skill_read_resource", params=[{name: "skill_name"}, {name: "path"}] // Exec: lee un archivo de scripts/, references/, templates/, o assets/ -
4.5 Registrar las tools de skills en el builder de tools de
runtime.go -
4.6 Inyectar la lista de skills disponibles (nivel 1: metadata) en el system prompt del agente, para que sepa que skills tiene a disposicion.
Fase 5: Configuracion
-
5.1 Anadir seccion
skills:al config schema eninternal/config/schema.go:type SkillsCfg struct { Enabled bool `yaml:"enabled"` SkillsPath string `yaml:"path"` // default: "skills/" Categories []string `yaml:"categories"` // filtro opcional de categorias } -
5.2 Anadir
SkillsCfgalAgentConfigprincipal -
5.3 Respetar el filtro de categorias: si un agente solo tiene
categories: [devops, system], no carga skills deanalysis/ocommunication/
Fase 6: Ejecucion de scripts
-
6.1 Evaluar como ejecutar scripts de skills de forma segura:
- Los scripts viven en
skills/<cat>/<name>/scripts/ - El agente necesita permisos para ejecutarlos (similar a ssh_command)
- Opcion A: ejecutar via
os/execcon sandbox basico (allowlist de interpreters) - Opcion B: ejecutar via SSH contra localhost (reutiliza infra existente)
- Opcion C: solo permitir bash scripts con validacion previa
- Recomendacion: opcion A con allowlist configurable de interpreters
- Los scripts viven en
-
6.2 Crear
shell/skills/executor.gopara ejecutar scripts:type Executor struct { allowedInterpreters []string // ["bash", "python3", "sh"] timeout time.Duration } func (e *Executor) Run(ctx context.Context, scriptPath string, args []string) (string, error) -
6.3 Crear tool
skill_run_scriptentools/skills/:// Def: name="skill_run_script", params=[{name: "skill_name"}, {name: "script"}, {name: "args"}] // Exec: ejecuta un script de la skill con el executor
Fase 7: Tests
- 7.1 Unit tests para
pkg/skills/types.go— verificar parsing de metadata - 7.2 Unit tests para
pkg/skills/match.go— verificar matching de skills - 7.3 Unit tests para
shell/skills/loader.go— verificar carga desde filesystem (con directorio temporal) - 7.4 Unit tests para
shell/skills/executor.go— verificar ejecucion de scripts - 7.5 Integration test: un agente con skills habilitadas puede buscar, cargar y ejecutar una skill
Fase 8: Documentacion
- 8.1 Crear
skills/README.mdcon la guia completa del sistema de skills - 8.2 Actualizar
CLAUDE.md— anadirskills/,pkg/skills/,shell/skills/a la estructura - 8.3 Crear
.claude/rules/create_skill.md— regla para crear nuevas skills - 8.4 Actualizar
docs/creating-agents.mdcon la seccion de skills
Orden de ejecucion recomendado
- Fase 1 (estructura + skills de ejemplo) — valida el formato antes de escribir codigo
- Fase 2 (tipos puros) — base para el loader y matching
- Fase 3 (loader) — carga skills desde disco
- Fase 5 (config) — permite habilitar/configurar skills por agente
- Fase 4 (integracion runtime) — conecta skills al agente via tools
- Fase 6 (ejecucion scripts) — opcional, solo si hay scripts
- Fase 7 (tests) — validar todo
- Fase 8 (docs) — cuando todo este estable
Decisiones de diseno
- Skills vs Tools: las tools son atomicas (function calling). Las skills son flujos multi-paso que el agente sigue como instrucciones. Las skills USAN tools internamente.
- Carga progresiva: no cargar todo en contexto — solo metadata siempre, instrucciones cuando se activa, recursos bajo demanda.
- Skills como carpeta en raiz: viven en
skills/(no enpkg/nishell/) porque son contenido declarativo, no codigo Go. Similar a comoagents/tiene configs y prompts. - Subcategorias: organizadas por dominio (devops, analysis, etc.) como los tools por funcion (clock, http, ssh, etc.).
- Seguridad de scripts: los scripts de skills deben tener las mismas restricciones que ssh_command — allowlist de interpreters, timeout, sin acceso a secretos directos.
Analogia con el patron del proyecto
pkg/skills/ → PURE: tipos SkillMeta, Skill, SkillMatch + matching puro
shell/skills/ → IMPURE: Loader (filesystem), Executor (os/exec)
tools/skills/ → tools de function calling para que el LLM interactue con skills
skills/ → contenido declarativo (SKILL.md + recursos)
Riesgos
- Inflar el contexto del LLM si se cargan muchas skills de golpe — mitigado por carga progresiva
- Ejecucion de scripts arbitrarios — mitigado por allowlist de interpreters y timeout
- Complejidad innecesaria si los agentes actuales no necesitan skills — empezar con 2-3 skills simples y validar