Inicio / Artículos

Desarrollando una buena habilidad de agente Claude: lecciones de un proyecto de entrenador deportivo

Crear una habilidad para Claude Agent que sea fiable: descripciones precisas, evaluaciones antes de redactar el texto, SKILL.md como enrutador, scripts en lugar de texto y un límite de credenciales en CI.

Editor: REACTAPP.TOP13 min de lectura3097 palabras

Fuentes: I Missed My Running Goal Three Years Running. So I Built an Agent Skill.

Imagínese a un corredor que, durante tres años seguidos, se fijó como objetivo recorrer 1,000 km pero no lo logró en ninguna de las ocasiones, terminando esos tres años con un total de aproximadamente 2,500 km. El esfuerzo no era el problema: hubo lesiones, reanudaciones del entrenamiento y semanas muy ocupadas. Lo que faltaba era un plan, ya que la motivación funciona bien hasta el día en que deja de hacerlo.

Una solución es dejar de depender de la fuerza de voluntad y crear un sistema. Así surgió running-coach, una habilidad de Claude Agent que planifica las carreras individuales y las semanas completas a partir de la historia personal de cada persona, convierte cada semana en un resumen por correo electrónico al estilo editorial e incluso ajusta la duración de una lista de reproducción según la longitud de la carrera que se avecina.

Correr es solo el telón de fondo aquí. El tema más útil es lo que se necesita para desarrollar una buena habilidad, es decir, una que se active de manera fiable, utilice el contexto con moderación, se comporte de forma idéntica en todas las plataformas y no se deteriore con el tiempo. A continuación, cada una de las prácticas de creación publicadas por Anthropic se relaciona con la forma en que este proyecto las aplica.

Qué es una habilidad de agente

Una habilidad es una carpeta. En su raíz se encuentra un archivo SKILL.md que comienza con información preliminar en YAML que incluye un name y un description, y luego continúa con instrucciones en Markdown. Los documentos de referencia, scripts, plantillas y otros recursos pueden encontrarse junto a él.

Lo interesante es cómo se carga una habilidad, mediante un modelo de tres niveles llamado divulgación progresiva:

  • Nivel 1, metadatos. Se cargan siempre al iniciar, con aproximadamente 100 tokens por habilidad. Consisten únicamente en el nombre y la descripción.
  • Nivel 2, instrucciones. Se cargan solo cuando se activa la habilidad, y se mantienen por debajo de unos 5 mil tokens. Este es el contenido de SKILL.md.
  • Nivel 3, recursos. Se obtienen bajo demanda mediante bash, y permanecen disponibles hasta que se accede a ellos. Aquí se encuentran los archivos de referencia, los scripts y los recursos.

Anthropic compara una habilidad con una guía de incorporación escrita para un nuevo colega. El principio subyacente en todo lo demás es que la ventana de contexto es compartida, un bien público. Lo que consume una habilidad queda fuera del alcance de todo lo demás que el agente intenta tener en mente.

1. La descripción funciona como la API

En el Nivel 1, todo lo que el modelo ve de una habilidad es su descripción. Funciona más bien como una tabla de enrutamiento que como documentación, ya que el modelo compara una solicitud entrante con ella para decidir si activar la habilidad. Debe indicar tanto qué hace la habilidad como cuándo usarla, estar escrita en tercera persona y tener menos de 1,024 caracteres; el límite práctico es de unos 200 caracteres si se desea que se muestre sin truncar en el selector de claude.ai. Esta es la descripción que utiliza running-coach:

name: running-coach
description: >-
  Plans a run or a whole week as Google Calendar blocks, builds a weekly
  running digest email, and makes playlists — from Strava, Spotify, AccuWeather
  and Calendar. Use for pacing or planning a week.

Mira cómo está estructurado. Comienza indicando qué puede hacer la habilidad (planificar una carrera, crear un resumen, hacer listas de reproducción), luego explica cuándo utilizarla (para controlar el ritmo o planificar una semana), y detalla las fuentes de datos para que una pregunta al estilo de Strava enlace a esta habilidad. El nombre se escribe en minúsculas y es idéntico al nombre del directorio; se trata de una regla estricta y no de una preferencia estilística, y el proceso de compilación del proyecto la aplica, como se verá más adelante.

No se puede saber de antemano si una descripción funcionará. Es necesario probarla, y por eso lo primero en el repositorio es un conjunto de evaluaciones y no documentación.

2. Escribir las evaluaciones antes de pulir el texto

El consejo de Anthropic es crear primero las evaluaciones, de modo que se resuelvan los problemas reales y no aquellos que se han imaginado. El proyecto contiene cuatro archivos de escenarios en la carpeta evals/, uno por cada capacidad. No se trata de pruebas unitarias, sino de contratos de comportamiento redactados en lenguaje sencillo. Este es el correspondiente a la planificación de una ejecución:

{
  "skills": ["running-coach"],
  "query": "I'm heading out for 8k this evening, how long is that going to take me?",
  "expected_behavior": [
    "Triggers the running-coach skill without being named, and routes to the planning capability",
    "Reads references/run-planning.md and does not read the digest or playlist references",
    "Runs scripts/cache.py status before projecting…",
    "Executes scripts/planning/plan_run.py 8 rather than reading its source or reimplementing Riegel inline",
    "Reports the projected finish time, the pace, and the recommended effort band…",
    "Never asks for or uses a Strava access token"
  ]
}

Cada afirmación codifica una buena práctica. Ejecutar pruebas sin que tengan nombre pone a prueba la calidad de la descripción de las mismas. Leer únicamente las pruebas de referencia relevantes representa una divulgación progresiva. Ejecutar el script sin volver a implementarlo verifica la preferencia por los scripts sobre el texto narrativo. No tocar nunca un token comprueba los límites de las credenciales. Juntos, convierten toda la filosofía de diseño en comportamientos observables, y el resto del proceso de construcción consiste en hacer que estos se cumplan.

3. Mantener SKILL.md como enrutador

La forma más común de agotar el presupuesto de contexto de una habilidad es incluir todo en SKILL.md. Un enfoque mejor es tratar ese archivo como un índice que apunte a material más detallado cuando sea necesario. Manténgalo breve y las referencias a un nivel de profundidad, ya que los agentes tienden a leer archivos profundamente anidados solo parcialmente y terminan teniendo una visión incompleta.

Cuatro capacidades aquí requerirían una página entera para explicarlas, por lo que SKILL.md no explica ninguna de ellas. Redirige a:

| Capability     | Reference                        | Entry point                       |
| -------------- | -------------------------------- | --------------------------------- |
| Plan a run     | references/run-planning.md       | scripts/planning/plan_run.py      |
| Plan the week  | references/week-planning.md      | scripts/planning/plan_week.py     |
| Weekly digest  | references/weekly-digest.md      | scripts/digest/run_pipeline.py    |
| Run playlist   | references/run-playlist.md       | scripts/playlist/build_playlist.py|

Work out which one is wanted, then read only that capability's reference.

Pide una lista de reproducción y el agente abre run-playlist.md y nada más. La especificación del flujo de trabajo del resumen, sus trampas y las notas de la plantilla nunca entran en el contexto, ya que el contenido empaquetado no utilizado no cuesta nada. El Nivel 2 se mantiene sencillo y el Nivel 3 aporta exactamente un archivo. La línea “lee X, no lee Y” en la evaluación verifica precisamente esto.

4. Scripts en lugar de prosa: úsalos, no los leas

Esta podría ser la idea más valiosa en el diseño de habilidades. Cuando el agente ejecuta un script mediante bash, solo la salida entra en el contexto y nunca el código fuente. Los scripts preescritos también son más fiables que el código generado al momento, y dan siempre el mismo resultado.

Por lo tanto, la lógica de running-coach está en Python, y las instrucciones indican explícitamente al agente que deje el código fuente intacto:

**Run the scripts, don't read them.** They print everything needed; every one
takes --help and most take --json. Reading their source wastes context.

La proyección del tiempo de finalización de Riegel, el cálculo de la banda de esfuerzo y el análisis resumido se ejecutan todos mediante Python determinista y devuelven una respuesta compacta. El agente coordina el proceso sin volver a calcular. Compare un agente que razona sobre su ritmo, el cual es lento, variable y consume muchos recursos, con uno que utiliza un calculador de ritmo y muestra un número, el cual es rápido e idéntico en cada ocasión.

5. Cada script es una CLI adecuada con convenciones comunes

Para que funcione el principio de “ejecútalo, no lo leas”, el agente debe hacer funcionar un script cuyo contenido le está prohibido abrir. Esto depende de una interfaz uniforme y autodescriptiva, por lo que cada script sigue las mismas convenciones:

  • un argumento posicional para todo lo que siempre es necesario (distancia, para la planificación y listas de reproducción);
  • --data DIR en todas partes, de modo que cualquier script puede apuntar a un caché diferente, lo que permite las pruebas sin conexión y los entornos aislados por sesión;
  • --json en casi todos ellos, para que la salida de un script pueda alimentar al siguiente;
  • --help en cada uno, la opción de respaldo del agente cuando no está seguro acerca de una opción. Lee el texto de ayuda, lo cual es sencillo, y no el código fuente, que es costoso y está prohibido.

Aquí se presentan las funcionalidades, una por una.

Planificación de una ejecución utiliza plan_run.py:

python3 scripts/planning/plan_run.py 8                 # 8 km, defaults
python3 scripts/planning/plan_run.py 8 --band steady   # force an effort band
python3 scripts/planning/plan_run.py 8 --start-in 3    # start 3h from now (weather-aware)
python3 scripts/planning/plan_run.py 8 --json          # machine-readable plan

El único argumento requerido es distance_km. Las opciones opcionales son --exp, que ajusta el exponente de fatiga de Riegel, y --band, que fuerza un rango específico de esfuerzo. Si no se especifica nada, se determina el rango a partir de la carga de entrenamiento previa del corredor. La parte heurística ofrece libertad, mientras que la proyección exacta sigue siendo determinista.

La lista de reproducción es gestionada por build_playlist.py, el cual imita deliberadamente la estructura del planificador:

python3 scripts/playlist/build_playlist.py 8                    # size to the 8 km finish
python3 scripts/playlist/build_playlist.py 8 --genre "lo-fi"
python3 scripts/playlist/build_playlist.py 8 --minutes 55       # size by time instead
python3 scripts/playlist/build_playlist.py 8 --band hard

Dado que ambos ocupan la misma distancia posicional, estas dos capacidades se combinan: el tiempo de finalización que proyecta plan_run corresponde a la duración para la cual build_playlist ajusta la lista de reproducción. El script emite una solicitud y no una lista de reproducción, y el agente transmite dicha solicitud al conector de Spotify. Aquí vuelve a aparecer la distinción entre funciones, ya que el script se encarga de los cálculos matemáticos mientras que el agente se ocupa de las operaciones de entrada/salida.

El resumen semanal es un pipeline pequeño y no un sistema monolítico. run_pipeline.py valida la caché y luego ejecuta dos etapas:

python3 scripts/digest/run_pipeline.py                 # validate → analyse → render
python3 scripts/digest/run_pipeline.py --plan-km 8     # lead the digest with a planned run
python3 scripts/digest/run_pipeline.py --seed 3        # pin the masthead title choice
python3 scripts/digest/run_pipeline.py --skip-validate # skip the pre-flight cache check

Debajo de él, analyze.py agrega la semana almacenada en caché en un único archivo digest_data.json, y build_email.py convierte ese JSON en un correo electrónico en HTML autónomo. Al separar el análisis de la generación del formato, el correo puede ser rediseñado sin afectar el análisis, y la opción --seed permite que la única elección aleatoria, que es el título del encabezado, sea reproducible, lo cual es útil para tomar capturas de pantalla de la misma semana dos veces.

Planning the week es la CLI más interesante, ya que representa un proceso de planificación, validación y ejecución expresado como subcomandos que el agente sigue en orden:

python3 scripts/planning/plan_week.py goal       # show the weekly goal in force
python3 scripts/planning/plan_week.py propose    # propose the split of runs (as JSON)
python3 scripts/planning/plan_week.py draft   --split -   # lay the split across the days
python3 scripts/planning/plan_week.py brief   --draft -   # hand the agent a per-run contract
python3 scripts/planning/plan_week.py events  --draft - --content -   # emit calendar blocks

Cada etapa imprime JSON que la siguiente consume por stdin. Allí donde es aplicable, las etapas también aceptan sobrescrituras comunes (--km, --runs) y opciones de programación como --start-date, --time, --weekend-time, --location y --tz. La guía recomienda este formato de “resultados intermedios verificables” para trabajos frágiles: el agente nunca escribe libremente una semana entera. Emite un plan estructurado, el script lo verifica y lo modifica, y solo después se convierte en eventos de calendario.

En algún punto intermedio se produce una transferencia deliberada de responsabilidades. En la fase de brief, el script calcula la distancia, el rango de ritmo y el día, y luego entrega al agente un contrato para cada ejecución. El agente escribe las palabras que imitan el estilo humano para completarlo, de modo que las descripciones de las ejecuciones no sean idénticas entre sí. El script se encarga de lo que debe ser preciso, mientras que el modelo se ocupa de lo que debe sonar como si estuviera escrito por un humano. La poca libertad en los cálculos matemáticos delicados y la alta libertad en la prosa constituyen el principio de los “grados adecuados de libertad” en una sola instrucción.

6. Resuelve los problemas, no los ignores

Una habilidad deficiente obliga al agente a lidiar con casos complejos mediante instrucciones vagas como “si los datos parecen obsoletos, encuentra una solución”. La formulación de Anthropic es resolver los problemas y no ignorarlos: se deben manejar las condiciones de error en el script y no delegarlas. running-coach aplica esto a través de un modelo de frescura; para cada dato almacenado en caché registra cuán antiguo es, y status indica la llamada MCP específica que permitiría subsanar cada deficiencia:

python3 scripts/cache.py status                 # what's cached, how stale, what to call
python3 scripts/cache.py put streams --file -    # ingest an MCP response from stdin
python3 scripts/cache.py show week --json        # a compact summary, not the raw blob
python3 scripts/cache.py validate --for digest   # shape-check before a run

cache.py cuenta con cuatro funciones (status, put, show, validate), cada una representando un escalón en el proceso de actualización. status enumera todas las claves junto con su límite de vigencia: este límite es ajustado para la semana actual, ya que cambia con cada ejecución, y se establece a nivel semanal para las semanas completadas y los datos de los atletas; además, si hay información obsoleta o faltante, indica qué herramienta MCP utilizar. El agente realiza la llamada correspondiente y envía directamente la respuesta a put. Luego, validate --for <capability> verifica que el resultado sea utilizable antes de que se ejecute un script posterior, de modo que una obtención defectuosa se detiene de inmediato con un error, en lugar de manifestarse más tarde como un resumen incorrecto.

Medidas adicionales de seguridad: put solo acepta claves de una lista permitida fija, show muestra un resumen y no el JSON en bruto, de modo que al inspeccionar la caché no se descargan megabytes de datos GPS en el contexto, y al agente se le indica que no edite manualmente esos archivos JSON. Como resultado, el agente no tiene que decidir si volver a obtener datos o qué datos obtener, ya que lo indica el script. Un juicio subjetivo (“¿Es lo suficientemente reciente?”) se convierte en una instrucción determinista, que es exactamente lo que significa ejecutar cache.py status antes de procesar los datos.

7. Los límites de las credenciales

Esta es la elección arquitectónica central y también una práctica de seguridad: realizar auditorías de llamadas de red e patrones de acceso a archivos inesperados. Esta herramienta hace que dichas auditorías sean sencillas por diseño, ya que nada dentro de ella almacena credenciales ni abre conexiones de red.

agent --(Strava / Spotify / AccuWeather MCP)--> cache.py put --> the cache
the cache --> plan_run.py / run_pipeline.py / build_playlist.py --> output

El agente es el único que se comunica con los conectores MCP, y cache.py es el único que escribe en la caché. Todos los demás scripts simplemente transforman los datos en caché de forma offline, sin ningún cliente HTTP, sin claves de API y sin tokens de acceso en ningún lugar del paquete.

# cache.py — the only gateway to the running-coach data cache.
# The agent is the only thing that talks to MCP; this script is the only thing
# that reads or writes the cache. Nothing here needs an access token.

Siguen tres ventajas. En cuanto a la seguridad, no hay nada que pueda filtrarse y la superficie de red a auditar está vacía. En cuanto a la portabilidad, la habilidad no se preocupa por si los conectores son locales, remotos o faltan, ya que solo consume una caché. En cuanto a la practicabilidad de pruebas, una caché poblada permite que cada script posterior se ejecute completamente sin conexión a Internet, lo que hace posible una prueba básica de CI.

8. Un requisito de ejecución: Python 3.10

Las habilidades no se sincronizan entre diferentes entornos, y cada entorno tiene sus propios límites de ejecución. La API de Claude no ofrece acceso a redes ni instalación de paquetes de ejecución, mientras que Claude Code lo tiene todo. Para poder ejecutar una habilidad en cualquier lugar, hay que diseñarla para el entorno más restringido.

Por eso running-coach no requiere nada externo. No existe un requirements.txt, ni virtualenv, ni etapa de instalación. Sus instrucciones indican que solo se necesita Python 3.10 o una versión más reciente, y el simple python3 funciona tal como está, incluso en un entorno sandbox alojado donde es imposible instalar paquetes.

Todo lo necesario para esta habilidad se encuentra dentro de la carpeta skills/running-coach/. Al colocar esa carpeta en ~/.claude/skills/ se hace disponible para Claude Code, y una subida en formato ZIP funciona igualmente en Cowork o claude.ai, con un comportamiento idéntico. Las rutas utilizan barras diagonales en todo momento, evitando así un problema común entre plataformas. Los archivos de caché y de salida se guardan en una ubicación fuera de la carpeta de la habilidad, manteniendo la copia instalada en modo solo lectura, y nunca se guardan en git, ya que el caché contiene polilíneas GPS reales que se decodifican en rutas que comienzan en la puerta principal de alguien.

9. Verificaciones del empaquetado y pruebas integradas que respaldan las afirmaciones

El empaquetado es el paso que la gente suele omitir. Una habilidad instalada incorrectamente parece defectuosa de maneras que no son obvias: un archivo comprimido con archivos sueltos en su raíz es rechazado silenciosamente al subirlo. Por eso el proyecto incluye package.py, un validador sin dependencias que repite las verificaciones que se encuentran en el repositorio de habilidades de Anthropic. Este validador verifica las claves de frontmatter permitidas, un name en formato kebab-case que coincida con el directorio, la longitud de la descripción dentro de los límites especificados (con una advertencia al alcanzar el límite aproximado de 200 caracteres de claude.ai), y un archivo comprimido que contenga exactamente un directorio de nivel superior con SKILL.md en su raíz.

Luego, GitHub Actions bloquea cada lanzamiento según esas verificaciones. Cuando se publica una etiqueta v*, el flujo de trabajo:

  1. compila cada script en bytecode (python -m compileall) para detectar errores de sintaxis;
  2. verifica el frontmatter según las especificaciones;
  3. ejecuta cada punto de entrada con --help, lo que demuestra al menos que cada script se importa y se analiza en una versión limpia de Python 3.10;
  4. confirma que running-coach/SKILL.md se encuentre en la raíz del archivo archivado;
  5. y solo después de todo esto, publica el archivo zip.
# 3.10 is the version the skill claims to support, so building on it is
# also how that claim stays honest.
- uses: actions/setup-python@v5
  with:
    python-version: "3.10"

Lecciones que se generalizan

Algunos puntos destacan del proceso de desarrollo:

Una descripción de unos 100 tokens es suficiente para hacer el 90% del trabajo. Como es la única parte que siempre se carga, si no se activa, todo lo demás pierde relevancia. Hay que prestarle una atención especial y añadir pruebas que verifiquen su activación sin mencionar el nombre de la habilidad.

Transfiera la lógica de los prompts a scripts deterministas. El texto que lee el agente varía y consume tokens, mientras que un script que ejecuta es económico y da siempre la misma respuesta. El lema es ejecutar, no leer.

Confíe en un límite que pueda expresarse en una sola oración. Frases como “Solo el agente habla con MCP, un script escribe en la caché, todo lo demás está fuera de línea” valen más que montones de código defensivo, ya que clases enteras de errores y fugas se vuelven estructuralmente imposibles.

Haga que la herramienta de compilación verifique sus afirmaciones. Una habilidad que promete usar Python 3.10 y cero dependencias debe compilarse exactamente de esa manera en los entornos CI en cada lanzamiento. Sin eso, la promesa no es más que una esperanza.

El objetivo de correr en sí sigue abierto, pero ahora existe un asistente que planifica la semana, ofrece una evaluación honesta cada lunes por la mañana y vuelve a calcular la meta según la distancia recorrida cada semana. Correr se convirtió en un problema de ingeniería resoluble en cuanto se trató como tal.

Cualquiera que instale una habilidad de este tipo necesita tener habilitada la ejecución de código y su propio conector Strava, ya que la habilidad no contiene credenciales. Lo mismo aplica a las fuentes útiles para leer: la descripción general de las Agent Skills de Anthropic y su página de buenas prácticas para crear habilidades, ambas en los documentos de la plataforma Claude.

Leer más

  • Hermes y Obsidian: Un depósito de conocimiento con tres agentes y revisión humana — Se configura un orquestador, un investigador y un bibliotecario en Hermes que transfieren las notas de Bronce a Plata y luego a Oro en un depósito de Obsidian, con aislamiento mediante Docker y revisión posterior.