Guía técnica Agent Skills: Arquitectura y Patrones
Para la introducción conceptual con video, visita la guía de Agent Skills.
Concepto
Sección titulada «Concepto»Un Agent Skill es una capacidad acotada, reutilizable y segura que un agente puede invocar. El agente razona libremente con Gemini, pero solo puede ejecutar lo que sus skills le permiten. Si un skill no existe, la acción es arquitectónicamente imposible.
Distinción de términos
Sección titulada «Distinción de términos»| Término | Nivel | En este repo |
|---|---|---|
| Skill (patrón) | Diseño | Idea universal — separar razonamiento de ejecución |
| Tool / Function | Ejecución | Función Python registrada en SkillAgent o ADK |
| Claude Skill (SKILL.md) | Conocimiento | Carpeta .claude/skills/dns-management/ |
| AgentSkill (A2A) | Descubrimiento | Declaración en agent.json para descubrimiento entre agentes |
Las dos capas de un agente
Sección titulada «Las dos capas de un agente»| Capa | Qué es | Cómo se implementa aquí |
|---|---|---|
| Capa 1 — Instrucciones | System prompt, guías en markdown | instructions= en SkillAgent, SKILL.md en Claude Code |
| Capa 2 — Capacidades | Tools registradas (funciones ejecutables) | Lista skills=[...] en SkillAgent, tools=[...] en ADK |
Capa 1 guía el razonamiento — el agente puede ignorarla. Capa 2 es restricción real — si el tool no existe, la acción es imposible.
skill_engine.py — Motor universal
Sección titulada «skill_engine.py — Motor universal»SkillAgent es la clase base que conecta Gemini con el catálogo de skills usando automatic_function_calling.
Constructor:
agent = SkillAgent( skills=[list_dns_records, create_dns_record, ...], # Capa 2: funciones ejecutables instructions="...", # Capa 1: system prompt model="gemini-2.5-flash", # default name="DNS Agent")| Parámetro | Tipo | Descripción |
|---|---|---|
skills | list[callable] | Funciones Python que el agente puede invocar |
instructions | str | System prompt — guía el razonamiento |
model | str | Modelo Gemini. Default: gemini-2.5-flash |
name | str | Nombre del agente para el output en terminal |
Métodos:
agent.run("Crea api.nicolasneira.dev apuntando a 203.0.113.50")# → Gemini razona, ejecuta skills encadenados, retorna respuesta final
agent.show_catalog()# → Lista los skills disponibles con sus docstringsFlujo interno:
Usuario → Gemini (razona) → SkillAgent (busca en catálogo) → Función Python (ejecuta) → Gemini (interpreta resultado) → Respuesta finalMáximo 20 llamadas a funciones por solicitud. Cada llamada se muestra en terminal con ✅/⚠️/❌.
dns_skills.py — 6 Skills de DNS
Sección titulada «dns_skills.py — 6 Skills de DNS»Skills contra la API de Cloudflare. Requiere CLOUDFLARE_API_TOKEN, CLOUDFLARE_ZONE_ID y CLOUDFLARE_DOMAIN en .env.
list_dns_records(domain)
Sección titulada «list_dns_records(domain)»Lista todos los registros DNS activos del dominio.
list_dns_records("nicolasneira.dev")# → Lista de registros con id, tipo, nombre, valor, TTLcreate_dns_record(domain, type, name, value)
Sección titulada «create_dns_record(domain, type, name, value)»Crea un nuevo registro DNS. Solo acepta tipos seguros.
create_dns_record( domain="nicolasneira.dev", type="A", # Solo: A, CNAME, MX, TXT name="api", value="203.0.113.50")Tipos rechazados: NS, SOA, SRV — el skill valida internamente y rechaza.
find_dns_record(domain, type, name)
Sección titulada «find_dns_record(domain, type, name)»Busca un registro específico y retorna su record_id (necesario para actualizar).
find_dns_record("nicolasneira.dev", "A", "mail")# → { "record_id": "abc123", "value": "1.2.3.4", ... }update_dns_record(record_id, value)
Sección titulada «update_dns_record(record_id, value)»Actualiza el valor de un registro existente usando su record_id.
update_dns_record(record_id="abc123", value="5.6.7.8")validate_dns(domain, expected_value)
Sección titulada «validate_dns(domain, expected_value)»Valida que el registro DNS resuelve al valor esperado.
validate_dns("api.nicolasneira.dev", "203.0.113.50")# → ✅ Resuelve correctamente / ❌ No resuelve aúncheck_propagation(domain)
Sección titulada «check_propagation(domain)»Verifica propagación en múltiples servidores DNS públicos (Google, Cloudflare, OpenDNS).
check_propagation("api.nicolasneira.dev")# → Estado en 8.8.8.8, 1.1.1.1, 208.67.222.222Skills que NO existen (restricción por diseño):
- ❌
delete_dns_record— no se puede borrar - ❌
modify_nameservers— no se pueden cambiar nameservers - ❌
create_for_other_domain— restringido a la zona configurada
monitoring_skills.py — 3 Skills de Monitoreo
Sección titulada «monitoring_skills.py — 3 Skills de Monitoreo»Skills de solo lectura. No requieren API keys — usan HTTP, SSL y WHOIS públicos.
check_url_status(url)
Sección titulada «check_url_status(url)»HTTP GET al URL. Retorna status code, tiempo de respuesta y headers relevantes.
check_url_status("https://nicolasneira.com")# → { "status": 200, "response_time_ms": 234, "server": "cloudflare" }check_ssl_certificate(domain)
Sección titulada «check_ssl_certificate(domain)»Consulta el certificado SSL. Retorna emisor, fecha de expiración y días restantes.
check_ssl_certificate("nicolasneira.com")# → { "issuer": "Let's Encrypt", "expires": "2025-06-01", "days_remaining": 87 }check_domain_whois(domain)
Sección titulada «check_domain_whois(domain)»Consulta WHOIS. Retorna registrar, nameservers y fecha de expiración del dominio.
check_domain_whois("nicolasneira.com")# → { "registrar": "Cloudflare, Inc.", "expires": "2026-01-15", ... }Skills que NO existen (restricción por diseño):
- ❌
restart_service— solo observa, no modifica - ❌
send_alert— no tiene capacidad de notificar - ❌
modify_config— cero escritura
Patrones de seguridad
Sección titulada «Patrones de seguridad»Seguridad por SCOPE — DNS Agent
Sección titulada «Seguridad por SCOPE — DNS Agent»El agente está restringido al dominio configurado en CLOUDFLARE_DOMAIN. Cualquier solicitud sobre otro dominio es rechazada en las instrucciones (Capa 1) y en las validaciones internas del skill (Capa 2).
# Si el usuario pide: "Crea un registro en google.com"# El skill valida domain == CLOUDFLARE_DOMAIN → rechazaSeguridad por CAPABILITY — Monitoring Agent
Sección titulada «Seguridad por CAPABILITY — Monitoring Agent»El agente puede observar cualquier dominio sin restricción de scope, pero no tiene ningún skill de escritura. La seguridad viene de la ausencia de capacidad, no de instrucciones.