Sistema de habilidades Skills
Responsabilidad
Una Skill es una unidad de capacidad de orden superior respecto a una Tool: un flujo reutilizable con frontmatter (similar a la especificación agentskills.io), clasificado por dominio en skills/<category>/. A diferencia de las herramientas (tool) («funciones estáticas»), las habilidades pueden ser creadas, reescritas y refinadas por el bucle de aprendizaje; son el soporte que hace al agent «más listo cuanto más se usa». Las habilidades se exponen al bucle principal a través de skills_tool.
Motivo de diseño
¿Por agrupar las habilidades por categoría en directorios en lugar de en una lista plana? La cantidad de habilidades crece con el uso (las que añade el usuario, las que sincroniza el hub, las que genera el bucle de aprendizaje — todo va a ~/.hermes/skills/); una lista plana convierte enseguida la salida de skills_list en ruido. La categoría permite que el progressive disclosure de primer nivel exponga solo «aquí hay un grupo de habilidades de research» en lugar de 50 nombres concretos. Cada SKILL.md es un archivo único que define la habilidad (con frontmatter); los subarchivos en skills/<category>/<skill>/references/ se cargan bajo demanda, para que los tokens no revienten de golpe.
El bundle es otra capa de envoltorio: carga varias habilidades con un único slash command, porque escenarios como «desarrollo backend» necesitan colgar a la vez tres habilidades (code review, TDD, PR); ir una por una con /skill es demasiado fragmentario.
Archivos clave
directorio skills/— agrupado por dominio (apple, computer-use, research, software-development, yuanbao…). Cada habilidad tiene esta forma:
skills/
├── my-skill/
│ ├── SKILL.md # instrucción principal (obligatorio)
│ ├── references/ # documentos de apoyo
│ │ ├── api.md
│ │ └── examples.md
│ ├── templates/ # plantillas de salida
│ └── assets/ # adjuntos (estándar agentskills.io)
└── category/
└── another-skill/
└── SKILL.mdLa cima de SKILL.md es YAML frontmatter (name/description/version/platforms/prerequisites…), el cuerpo son las instrucciones. name está limitado a 64 caracteres y description a 1024; son lo único que devuelve la primera capa de progressive disclosure en skills_list, para ahorrar tokens.
skills_tool— expone las habilidades como herramienta al bucle principal. Registra dos herramientas:
registry.register(
name="skills_list",
toolset="skills",
schema=SKILLS_LIST_SCHEMA,
handler=lambda args, **kw: skills_list(
category=args.get("category"), task_id=kw.get("task_id")
),
check_fn=check_skills_requirements,
emoji="📚",
)
registry.register(
name="skill_view",
toolset="skills",
schema=SKILL_VIEW_SCHEMA,
handler=_skill_view_with_bump,
check_fn=check_skills_requirements,
emoji="📚",
)skills_list solo devuelve name + description + category (primera capa de progressive disclosure); skill_view carga el SKILL.md completo (segunda capa); los archivos de apoyo (references, templates) se cargan bajo demanda con skill_view(name, file_path="references/api.md") (tercera capa). _skill_view_with_bump actualiza tras el éxito los contadores de uso (bump_view / bump_use); el stale timer del curator se apoya en ellos para limpiar habilidades que nadie usa.
skill_manager_tool— gestión de habilidades (listar/ver/activar)skills_hub— sincronización con el hub de habilidades (compatible con agentskills.io)skills_sync— sincronización local ↔ remotoskill_bundles— empaquetado de bundles de habilidades, inyectados en el prompt. Un bundle es un archivo pequeño en~/.hermes/skill-bundles/*.yaml:
name: backend-dev
description: Backend feature work — code review, testing, PR workflow.
skills:
- github-code-review
- test-driven-development
- github-pr-workflow
instruction: |
Optional extra guidance to inject above the skill bodies./<bundle-name> invoca build_bundle_invocation_message, que concatena los SKILL.md de todos los miembros en un único user message. Si un bundle y una habilidad comparten nombre, gana el bundle — el usuario que puso el mismo nombre quiere explícitamente sobrescribir la habilidad que cayera en la colisión. Las habilidades miembros que falten no provocan error; se añade al resultado un apunte de «cuáles se saltaron».
skill_preprocessing— preprocesado del contenido de habilidades. Sustituye las variables de plantilla${HERMES_SKILL_DIR}/${HERMES_SESSION_ID}y ejecuta snippets de shell inline del estilo!date +%Y-%m-%d``. Si un snippet falla, devuelve el marcador[inline-shell error: ...]en lugar de lanzar excepción; un snippet roto no tira el mensaje completo de la habilidad.nodos y aristas de habilidades:125-193—build_skill_nodes/build_edges, organiza las habilidades en un grafo de aprendizaje
Flujo de datos
- En el arranque,
skill_preprocessing(agent/skill_preprocessing.py) escaneaskills/<category>/y lee el frontmatter. skill_bundles(agent/skill_bundles.py) empaqueta las habilidades relevantes y las inyecta víabuild_turn_context:268en el prompt del turno (turn).- El provider decide invocar una habilidad →
tool_call: skills→tools/skills_tool.pycarga y ejecuta el flujo de esa habilidad. - El resultado de la ejecución se devuelve al bucle principal.
- El bucle de aprendizaje revisa el turno en segundo plano y puede:
- crear nuevas habilidades (
learning_mutations) - registrar la nueva habilidad en el grafo de aprendizaje
agent/learning_graph.py:125 - sincronizarla al hub vía
tools/skills_sync.py
- crear nuevas habilidades (
Límites y fallos
- Path traversal: el nombre de la habilidad se concatena a
~/.hermes/skills/para localizar el archivo;_skill_lookup_path_errorrechaza segmentos.., rutas absolutas y letras de unidad Windows. Sin esto,name="../outside"leería archivos fuera del directorio de habilidades. - Inyección de prompt: los
SKILL.mdque contienen patrones como «ignore previous instructions», «system prompt:» o]]>quedan marcados por_INJECTION_PATTERNS. Las habilidades de terceros (sincronizadas desde el hub) son contenido no fiable; el bucle principal las sanea al cargarlas. - Bundle con miembros faltantes:
build_bundle_invocation_messagepara los miembros ausentes o deshabilitados los anota en las listasmissing/disabledsin lanzar error — el bundle carga de forma indulgente; que falten algunos no afecta al resto. - Caché stale: escanear
skills/es O(#dirs) stat y la firma incluye mtime del directorio + conjunto de deshabilitadas + plataforma. Pero la edición in situ de unSKILL.mdsolo actualiza su propio mtime, invisible para la firma del directorio; por eso se añade un TTL de 30s como red de seguridad.
Resumen
Habilidad = flujo de orden superior evolutivo: el frontmatter lo describe, el archivo lo define, el bucle de aprendizaje lo puede reescribir. Relación con las herramientas: las herramientas son los átomos invocados dentro del flujo de una habilidad; las habilidades son el conocimiento de «cómo combinar herramientas para completar una clase de tareas». La evolución de las habilidades se describe en el bucle de aprendizaje.