Guía práctica para construir agentes ADK con Skills y progressive disclosure
Cuando hablamos de un agente de IA bien hecho, no basta con que solo siga instrucciones. Un buen agente necesita poder cargar conocimiento bajo demanda y, en algunos casos, incluso crear nuevas instrucciones por sí mismo. Y es exactamente ahí donde entra el Agent Development Kit (ADK) de Google y su SkillToolset.
En lugar de intentar meter todo el conocimiento en el system prompt, el ADK trabaja con el concepto de Skills: bloques de especialización que el agente puede listar, cargar y combinar de forma dinámica. Con la configuración correcta, el propio agente consigue generar una nueva Skill en tiempo de ejecución, guardar el contenido y empezar a usar ese nuevo conocimiento en seguida.
El flujo queda simple:
- generar la Skill;
- cargar la Skill;
- usar la Skill en la tarea del usuario.
Da igual si quieres un checklist de seguridad, una rutina de auditoría de compliance o un validador de pipeline de datos: la arquitectura es la misma. La diferencia está solo en el tipo de instrucción que empaquetas dentro de cada Skill.
El problema de los prompts monolíticos
Mucha gente todavía construye agentes con un único prompt gigante. Junta todo en un solo bloque: reglas de compliance, guías de estilo, documentación de API, manual de troubleshooting, estándares de código, políticas internas y por ahí va.
Eso hasta se aguanta cuando el agente tiene dos o tres funciones bien simples. Pero, en el momento en que empiezas a escalar a diez, quince o veinte tareas distintas, ese modelo se rompe. Cada llamada al LLM pasa a cargar miles de tokens de instrucción, incluso cuando el usuario hace una pregunta trivial que no depende del 90% de ese contexto.
La especificación Agent Skills resuelve esto con un patrón de arquitectura llamado progressive disclosure. En vez de soltar todo de una vez, divide la carga de conocimiento en tres niveles bien definidos:
- L1 – Metadata (~100 tokens por Skill)
Nombre y descripción de la Skill. Este nivel se carga en la inicialización, para todas las Skills. Funciona como un menú que el agente consulta para decidir qué es relevante para cada pedido del usuario. - L2 – Instructions (< 5.000 tokens)
Cuerpo completo de la Skill, con pasos detallados y flujo de trabajo. Solo se carga cuando el agente activa explícitamente esa Skill. - L3 – Resources (bajo demanda)
Archivos externos: guías de estilo, especificaciones de API, anexos de referencia, ejemplos extensos. Solo entran en el contexto cuando la propia Skill lo pide, vía herramienta de carga de recursos.
En la práctica, un agente con 10 Skills deja de cargar algo del orden de 10.000 tokens en un super prompt y pasa a trabajar con cerca de 1.000 tokens de metadata de L1 al inicio, llamando L2 y L3 solo cuando los necesita. Eso representa algo cercano a un 90% de reducción de contexto base por llamada al LLM.
En el ADK, este patrón se implementa con la clase SkillToolset, que genera automáticamente tres herramientas alineadas con esos niveles:
list_skills– L1, lista de Skills disponibles;load_skill– L2, carga el cuerpo de la Skill;load_skill_resource– L3, carga recursos externos de la Skill.
Pattern 1: Inline skills (el post-it pegado en el código)
El primer patrón es el más simple: una Skill definida directamente en el código Python, en forma de objeto, con name, description e instructions. Funciona bien para reglas pequeñas, estables y que casi no cambian.
Un ejemplo clásico es una Skill de checklist de SEO para revisar posts de blog:
seo_skill = models.Skill(
frontmatter=models.Frontmatter(
name="seo-checklist",
description="SEO optimization checklist for blog posts. Covers title tags, meta descriptions, heading structure, and readability.",
),
instructions=(
"When optimizing a blog post for SEO, check each item:\n"
"1. Title: 50-60 chars, primary keyword near the start\n"
"2. Meta description: 150-160 chars, includes a call-to-action\n"
"3. Headings: H2/H3 hierarchy, keywords in 2-3 headings\n"
"4. First paragraph: Primary keyword in first 100 words\n"
"5. Images: Alt text with keywords, compressed, descriptive names\n"
"Review the content against each item and suggest improvements."
),
)
En este formato:
- el frontmatter (nombre y descripción) se convierte en L1, siempre visible como parte de la lista de Skills;
- las instructions se convierten en L2, cargadas solo cuando el agente decide que necesita esa Skill.
Si el usuario dice algo como Revisa mi post de blog para SEO, el agente consulta el L1, identifica que la Skill seo-checklist es relevante, llama a load_skill y pasa a aplicar el checklist paso a paso sobre el contenido recibido.
Pattern 2: File-based skills (la carpeta de referencia organizada)
La inline skill resuelve bastante, pero empieza a quedarse corta cuando esa competencia necesita documentación de apoyo: guías extensas, specs de API, playbooks internos, etc. En ese escenario, entra el segundo patrón: la Skill basada en archivos.
Cada Skill queda en su propio directorio, con un archivo central SKILL.md y subcarpetas opcionales para referencias, assets o scripts. La estructura mínima es así:
skills/blog-writer/
├── SKILL.md # L2: Instructions
└── references/
└── style-guide.md # L3: Loaded on demand
El SKILL.md empieza con frontmatter en YAML, seguido del cuerpo en Markdown con las instrucciones detalladas. Ya los archivos dentro de references/ traen el conocimiento denso, como guías de estilo completas o especificaciones largas.
La Skill se carga en el ADK de forma muy directa:
blog_writer_skill = load_skill_from_dir(
pathlib.Path(__file__).parent / "skills" / "blog-writer"
)
Cuando el agente activa esta Skill, trae el L2 a partir de SKILL.md. Si, dentro de las instrucciones, hay un paso que dice que debe leer la guía de estilo, el agente va a llamar load_skill_resource y buscar el archivo references/style-guide.md solo en ese momento.
Esta separación es poderosa por dos motivos:
- deja el L2 más ligero y objetivo, con foco en el flujo de acciones;
- saca documentos enormes del prompt principal, colocándolos detrás de L3, accesibles bajo demanda.
Como bonus, cualquier agente compatible con la especificación agentskills.io consigue consumir la misma carpeta. Escribes una vez, lo reaprovechas en varios agentes.
Pattern 3: External skills (el import de repositorios de comunidad)
El tercer patrón es básicamente la evolución natural del anterior. La arquitectura es la misma que una Skill basada en archivos, solo que, en lugar de escribir el SKILL.md desde cero, descargas una Skill lista de un repositorio externo.
Un ejemplo son colecciones como el repositorio awesome-claude-skills. Copias la Skill que te interesa al directorio de tu proyecto y la cargas con la misma llamada:
content_researcher_skill = load_skill_from_dir(
pathlib.Path(__file__).parent / "skills" / "content-research-writer"
)
Para el ADK, da igual si quien escribió el SKILL.md fuiste tú o la comunidad. La especificación Agent Skills define un formato de directorio universal. Si la carpeta sigue ese formato, la función load_skill_from_dir simplemente funciona.
El propio Google publica Skills oficiales de desarrollo para ADK en el mismo patrón, instalables vía línea de comandos, por ejemplo con:
npx skills add google/adk-docs -y -g
Con eso, puedes combinar:
- Skills que tú mismo escribiste;
- Skills internas de tu empresa;
- Skills abiertas de la comunidad y de Google.
Los tres primeros patterns cubren todo lo que ya existe: lo que creas, lo que importas desde archivo y lo que bajas de terceros. Falta un paso: dejar que el agente cree sus propias Skills.
Pattern 4: Meta skill (la fábrica de Skills en tiempo de ejecución)
El cuarto patrón cierra el ciclo. Aquí, creas una meta skill: una Skill cuyo objetivo es generar nuevas Skills, escribiendo archivos SKILL.md completos a partir de requisitos en lenguaje natural.
Con eso, el agente se vuelve autoextensible. Cuando surge una necesidad que ninguna Skill existente cubre bien, el propio agente consigue leer la especificación, generar una nueva Skill compatible con el ADK y usar ese nuevo recurso de inmediato.
Esta meta skill suele definirse como una Inline Skill, pero con un diferencial: viene con un conjunto de resources en L3, incluyendo:
- el texto de la especificación oficial de agentskills.io;
- un ejemplo de Skill bien formada, que sirve como modelo.
Queda más o menos así:
skill_creator = models.Skill(
frontmatter=models.Frontmatter(
name="skill-creator",
description=(
"Creates new ADK-compatible skill definitions from requirements."
" Generates complete SKILL.md files following the Agent Skills"
" specification at agentskills.io."
),
),
instructions=(
"When asked to create a new skill, generate a complete SKILL.md file.\n\n"
"Read `references/skill-spec.md` for the format specification.\n"
"Read `references/example-skill.md` for a working example.\n\n"
"Follow these rules:\n"
"1. Name must be kebab-case, max 64 characters\n"
"2. Description must be under 1024 characters\n"
"3. Instructions should be clear, step-by-step\n"
"4. Reference files in references/ for detailed domain knowledge\n"
"5. Keep SKILL.md under 500 lines, put details in references/\n"
"6. Output the complete file content the user can save directly\n"
),
resources=models.Resources(
references={
"skill-spec.md": "# Agent Skills Specification (agentskills.io)...",
"example-skill.md": "# Example: Code Review Skill...",
}
),
)
El campo resources usa models.Resources para incrustar la especificación y un ejemplo funcional como archivos lógicos de L3. Cuando el agente llama load_skill_resource("skill-creator", "references/skill-spec.md"), recibe el contenido completo de la spec y pasa a seguirla para generar el nuevo SKILL.md.
Buena práctica importante: por más tentador que sea automatizar todo, conviene mantener a alguien revisando las Skills generadas. Trata cada nuevo SKILL.md como si fuera una dependencia de código: revisa, prueba y solo después ponlo en producción. El propio ADK ofrece mecanismos de evaluación para validar el comportamiento de las Skills antes de liberarlas a lo grande.
La fábrica de Skills en acción
Imagina la siguiente petición: el usuario dice:
Necesito una Skill para revisar código Python en busca de vulnerabilidades de seguridad.
El agente activa la skill-creator, lee los recursos de L3 con la spec y el ejemplo, y genera un SKILL.md completo, con:
- nombre en kebab-case válido;
- instrucciones organizadas por tipo de riesgo (validación de entrada, autenticación, criptografía, etc.);
- formato de salida basado en severidad (baja, media, alta).
Esta nueva Skill sigue la misma especificación de agentskills.io. Resultado: no solo funciona en el ADK, sino también en cualquier otro agente compatible con el formato, como:
- Gemini CLI;
- Claude Code;
- Cursor;
- y decenas de otras herramientas que ya adoptaron el estándar.
Conectando todo con el SkillToolset
Después de definir las Skills (inline, basadas en archivo, externas y la meta skill), el último paso es empaquetar todo en un SkillToolset y entregarlo al agente.
skill_toolset = SkillToolset(
skills=[seo_skill, blog_writer_skill, content_researcher_skill, skill_creator]
)
root_agent = Agent(
model="gemini-2.5-flash",
name="blog_skills_agent",
description="A blog-writing agent powered by reusable skills.",
instruction=(
"You are a blog-writing assistant with specialized skills.\n"
"Load relevant skills to get detailed instructions.\n"
"Use load_skill_resource to access reference materials.\n"
"Follow each skill's step-by-step instructions.\n"
"Always explain which skill you're using and why."
),
tools=[skill_toolset],
)
En este ejemplo:
seo_skillse encarga del checklist de SEO;blog_writer_skilldefine cómo estructurar el texto;content_researcher_skillhace la parte de investigación de contenido;skill_creatores la fábrica, lista para crear nuevas Skills bajo demanda.
Si el usuario pide algo como Crea una Skill para escribir introducciones técnicas de blog, el agente usa la meta skill, genera un nuevo SKILL.md y responde con el contenido listo para guardarse en skills/blog-intro-writer/SKILL.md. En la próxima sesión, puedes cargar ese directorio con load_skill_from_dir y tratar esa Skill como cualquier otra.
Por debajo del capó, el SkillToolset sigue el mismo modelo de progressive disclosure, generando automáticamente:
list_skills– L1, siempre inyectado;load_skill– L2, llamado cuando es necesario;load_skill_resource– L3, para referencias específicas.
Consejos finales para diseñar Skills útiles
- Cuida bien la descripción
El campodescriptiones, en la práctica, la documentación de API que el LLM ve en L1. Textos como SEO optimization checklist for blog posts ayudan al agente a entender cuándo activar la Skill. En cambio, descripciones vagas dejan al modelo perdido. - Empieza inline, evoluciona a archivos cuando tenga sentido
No hace falta crear directorio y spec completa para todo. Si la Skill cabe en pocas líneas y no exige referencia externa, mantenla inline. Migra al formato basado en archivos cuando aparezca la necesidad de reutilizarla en varios agentes o incluir documentación mayor en L3. - Trata las Skills generadas como código en producción
Lo que genera la meta skill es, en la práctica, parte del comportamiento de tu agente. Vale la pena revisar, validar en escenarios reales y, si es posible, crear tests automatizados con las herramientas de evaluación del ADK antes de ponerlo en una ruta crítica.
Al final, la jugada del ADK con Skills y SkillToolset es simple: en lugar de un prompt gigante y difícil de mantener, ganas un conjunto de bloques de conocimiento modulares, cargados bajo demanda, que pueden ser escritos por ti, por la comunidad o por el propio agente en tiempo de ejecución. Menos tokens, más control y una arquitectura de agentes mucho más cercana a las buenas prácticas de ingeniería de software.
