Lo esencial
El SEO en 2026 ya no es solo "salir en Google". Una parte de las búsquedas ahora la resuelven las respuestas de IA: el usuario le preguntó a ChatGPT por una agencia inmobiliaria en Cuenca y se fue con la respuesta sin entrar a ningún sitio. El juego nuevo: aparecer tanto en Google como en las respuestas de la IA. Claude Code permite automatizar casi todo el stack, desde el keyword research hasta la auditoría semanal, con un gasto pequeño en tokens.
Conceptos clave
- Google AI Overviews (antes se llamaban SGE): bloques de IA en los resultados de Google; en una parte de las búsquedas informativas les quitan clics a los resultados normales
- AEO (Answer Engine Optimization): optimizar para las respuestas de IA (ChatGPT, Claude, Gemini, Perplexity)
- Keyword Gap: las palabras clave con las que posiciona tu competencia y tú no
- Schema Markup: marcado legible por máquinas que ayuda a la IA a entender de qué trata la página
- Core Web Vitals: la velocidad y estabilidad de la página, un factor de posicionamiento de Google
- searchfit-seo:*: un plugin con skills de SEO para Claude Code (se instala con
/plugin)
Teoría
El SEO en 2026: qué cambió con la IA
Hasta 2024 la tarea era una sola: llegar a la primera página de Google. En 2026 el panorama es más complejo.
Qué cambió:
| Antes (hasta 2024) | Ahora (2026) |
|---|---|
| Meta: posición 1-3 en Google | Meta: posición en Google + mención en las respuestas de IA |
| Tráfico = clics desde el buscador | Tráfico = clics desde el buscador + búsquedas de marca después de la IA |
| Palabras clave → artículos | Preguntas y respuestas → autoridad de la fuente |
| Masa de enlaces = ranking | Masa de enlaces + menciones en fuentes con autoridad |
| SEO técnico | SEO técnico + datos estructurados |
Google AI Overviews (antes SGE) aparece encima de los resultados normales en una parte de las búsquedas informativas; la proporción depende del tema, la región y el idioma. Si no estás entre las fuentes del AI Overview, el tráfico de esas búsquedas baja.
ChatGPT, Claude y Gemini se apoyan más a menudo en fuentes que:
- Se citan seguido en materiales con autoridad
- Tienen una estructura clara de pregunta y respuesta
- Usan Schema Markup (Article y otros tipos)
- Tienen buen SEO técnico
Qué papel juega el marcado en cada servicio de IA, oficialmente no lo dicen. Tómalo como buena higiene, no como una palanca con efecto garantizado.
AEO vs. SEO: no se contradicen, se complementan. Un buen artículo de SEO = un buen artículo de AEO, si tiene la estructura correcta.
Las herramientas clave del stack
El plugin searchfit-seo agrega a Claude Code skills de SEO listas. Se instala con /plugin desde el marketplace; la lista de abajo es a octubre de 2026:
# Skills del plugin searchfit-seo (se instalan con /plugin desde el marketplace):
# searchfit-seo:seo-audit — auditoría completa del sitio
# searchfit-seo:keyword-clustering — agrupar palabras clave
# searchfit-seo:content-brief — brief para un artículo
# searchfit-seo:on-page-seo — optimizar una página
# searchfit-seo:schema-markup — marcado para la IA y para Google
# searchfit-seo:ai-visibility — revisar la visibilidad en respuestas de IA
# searchfit-seo:content-strategy — estrategia de contenido
# searchfit-seo:internal-linking — estrategia de enlaces internos
# searchfit-seo:technical-seo — auditoría técnica
# Herramientas externas (por API):
# Google Search Console API — posiciones, clics, impresiones (gratis)
# Ahrefs API — palabras clave de la competencia (de pago, precios en su sitio)
# Google PageSpeed API — Core Web Vitals (gratis)Para empezar basta con Google Search Console (gratis) + las skills de searchfit-seo. Ahrefs lo agregas cuando escales.
Keyword research automático
Buscamos dónde está la oportunidad: palabras clave con tráfico e intención comercial.
import anthropic
import os
import json
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
def find_keyword_opportunities(topic: str, our_domain: str) -> dict:
"""
Analiza las oportunidades de palabras clave para un tema.
Sin la API de Ahrefs: usa solo a Claude para generar hipótesis.
Con la API de Ahrefs: agregas volúmenes reales (ver el comentario abajo).
"""
response = "".join(b.text for b in client.messages.create(
model="claude-sonnet-5-5",
max_tokens=3000,
messages=[{
"role": "user",
"content": f"""Haz un keyword research para el tema: "{topic}"
Dominio: {our_domain}
Tarea: encontrar 30 palabras clave con potencial comercial.
Divídelas por categoría:
1. TRANSACCIONALES (la gente quiere comprar/contratar):
Ejemplos: "comprar departamento Cuenca", "agencia inmobiliaria Ecuador"
2. INFORMATIVAS (la gente busca información):
Ejemplos: "cómo compra un extranjero una propiedad en Ecuador", "vivir en Cuenca opiniones"
3. DE NAVEGACIÓN (la gente busca una marca/sitio concreto):
Ejemplos: "Acme Realty inmobiliaria", "agencia Cuenca para extranjeros"
4. LONG-TAIL (cola larga, menos competencia):
Ejemplos: "cómo compra departamento en Cuenca un jubilado extranjero", "zonas de Cuenca donde viven extranjeros"
Para cada palabra clave estima:
- Volumen de búsqueda probable (bajo/medio/alto)
- Nivel de competencia (bajo/medio/alto)
- Potencial comercial (1-5)
- Tipo de contenido a crear (artículo/FAQ/guía/comparación)
Formato de respuesta: una lista JSON de objetos:
{{
"keyword": "...",
"category": "transaccional/informativa/navegación/long-tail",
"estimated_volume": "bajo/medio/alto",
"competition": "bajo/medio/alto",
"commercial_potential": 1-5,
"content_type": "...",
"priority": "high/medium/low"
}}
Devuelve solo un arreglo JSON válido."""
}]
).content if b.type == "text")
keywords = json.loads(response)
# Filtramos las oportunidades prioritarias
high_priority = [k for k in keywords if k["priority"] == "high"]
print(f"Total de palabras clave: {len(keywords)}")
print(f"Prioritarias (high): {len(high_priority)}")
print("\nTop 10 por prioridad:")
for i, kw in enumerate(high_priority[:10], 1):
print(f" {i}. {kw['keyword']} | potencial: {kw['commercial_potential']}/5 | competencia: {kw['competition']}")
return {"all": keywords, "high_priority": high_priority}
def find_keyword_gap(our_keywords: list, competitor_keywords: list) -> list:
"""
Encuentra las palabras clave que tiene la competencia y nosotros no.
our_keywords / competitor_keywords: listas de cadenas (palabras clave).
"""
response = "".join(b.text for b in client.messages.create(
model="claude-sonnet-5-5",
max_tokens=2000,
messages=[{
"role": "user",
"content": f"""Haz un análisis de keyword gap.
Nuestras palabras clave: {json.dumps(our_keywords[:50], ensure_ascii=False)}
Palabras clave de la competencia: {json.dumps(competitor_keywords[:50], ensure_ascii=False)}
Encuentra:
1. Las 20 palabras clave principales de la competencia que no tenemos; priorízalas por intención comercial
2. Victorias rápidas: nuestras palabras en posiciones 11-30 (se pueden subir al top 10 en 2-4 semanas)
3. Palabras compartidas: donde competimos directamente; compara las posiciones potenciales
Formato: JSON con tres arreglos:
{{
"gap_keywords": [{{"keyword": "...", "why_valuable": "...", "urgency": "high/medium"}}],
"quick_wins": [{{"keyword": "...", "current_position_estimate": "11-30", "action": "..."}}],
"competitive": [{{"keyword": "...", "our_advantage": "...", "their_advantage": "..."}}]
}}"""
}]
).content if b.type == "text")
return json.loads(response)
# Ejemplo de uso
if __name__ == "__main__":
# Keyword research básico sin API
opportunities = find_keyword_opportunities(
topic="bienes raíces en Ecuador para extranjeros",
our_domain="acme-realty.example"
)
# Lo guardamos para seguir trabajando
with open("keyword-research.json", "w", encoding="utf-8") as f:
json.dump(opportunities, f, ensure_ascii=False, indent=2)
print("\nResultados guardados en keyword-research.json")Un content brief en 5 minutos
En lugar de escribir los briefs a mano, Claude los hace automáticamente.
Usa la skill searchfit-seo:content-brief directamente desde Claude Code:
Claude, usa la skill searchfit-seo:content-brief. Tema: "comprar departamento en Cuenca Ecuador" Nuestro público: inversionistas y personas que se mudan desde otros países, de 35-55 años Competidores a analizar: [URL del artículo del competidor 1, URL del artículo del competidor 2] Dame un content brief completo: - Palabra clave principal y palabras clave LSI - Título H1 (atractivo, con la palabra clave) - Estructura del artículo (H2, H3 con la descripción del contenido de cada sección) - Qué tiene la competencia y qué le falta (nuestra ventaja competitiva) - Largo recomendado (palabras) - Tipo de schema markup (Article / FAQ / HowTo / LocalBusiness) - CTA al final del artículo
O con Python, para automatizarlo en el flujo:
def generate_content_brief(keyword: str, audience: str, competitor_urls: list) -> str:
"""Genera un content brief para una palabra clave concreta"""
response = "".join(b.text for b in client.messages.create(
model="claude-sonnet-5-5",
max_tokens=2500,
messages=[{
"role": "user",
"content": f"""Crea un content brief para un artículo de SEO.
Palabra clave objetivo: "{keyword}"
Público: {audience}
Competidores: {', '.join(competitor_urls) if competitor_urls else 'no indicados'}
El brief debe incluir:
## Palabras clave
- Principal: {keyword}
- LSI (relacionadas semánticamente): [lista de 10-15 palabras]
- Variaciones long-tail: [lista de 5-7 frases]
## Título H1
[Título atractivo con la palabra clave principal, 50-60 caracteres]
## Meta Description
[155 caracteres, incluye la palabra clave y un llamado a la acción]
## Estructura del artículo
[Bloque H2 1: nombre]
- Qué incluir: ...
- Largo aproximado: ... palabras
[Bloque H2 2: nombre]
...
## Sección de FAQ
[5-7 preguntas que la gente realmente hace sobre el tema]
## Recomendaciones
- Largo: ... palabras
- Schema markup: ...
- Tipo de contenido: artículo/guía/comparación/FAQ
- Ángulo único (lo que nos distingue de la competencia): ...
Escribe en español."""
}]
).content if b.type == "text")
return response
# Generamos briefs para las 5 palabras clave prioritarias
priority_keywords = [
"comprar departamento en Cuenca",
"vivir en Ecuador siendo extranjero",
"bienes raíces Ecuador inversión",
"mudarse a Cuenca desde el extranjero",
"costo de vida en Cuenca 2026",
]
for kw in priority_keywords:
brief = generate_content_brief(
keyword=kw,
audience="personas de 35-55 años que piensan en mudarse o invertir",
competitor_urls=[]
)
# Guardamos cada brief en un archivo aparte
filename = kw.replace(" ", "-").replace("/", "-") + ".md"
with open(f"briefs/{filename}", "w", encoding="utf-8") as f:
f.write(f"# Content brief: {kw}\n\n")
f.write(brief)
print(f"Brief creado: briefs/{filename}")Schema markup automático
El marcado de Schema.org ayuda a los buscadores a entender la estructura del contenido. No garantiza aparecer en los resultados enriquecidos ni en los AI Overviews.
def add_schema_markup(page_content: str, page_type: str, business_info: dict) -> str:
"""
Genera el Schema markup JSON-LD para una página.
page_type: "article" / "faq" / "local_business" / "howto" / "product"
business_info: diccionario con los datos del negocio (nombre, dirección, teléfono, etc.)
"""
schema_prompt = f"""
Crea el marcado JSON-LD de schema.org para una página.
Tipo de página: {page_type}
Datos del negocio: {json.dumps(business_info, ensure_ascii=False)}
Contenido de la página (primeros 1500 caracteres):
{page_content[:1500]}
Requisitos:
1. Usa el tipo de schema.org más adecuado
2. Llena todos los campos obligatorios (required properties)
3. Agrega los campos recomendados (recommended properties) donde se pueda
4. Para páginas de FAQ: agrega el schema FAQPage con preguntas reales del contenido
5. Para artículos: agrega el schema Article con autor y fecha de publicación
6. Para negocios locales: agrega LocalBusiness + GeoCoordinates
7. Para instructivos: agrega el schema HowTo con los pasos
Devuelve solo un objeto JSON-LD válido (sin bloques de markdown).
"""
schema_json = "".join(b.text for b in client.messages.create(
model="claude-sonnet-5-5",
max_tokens=2000,
messages=[{"role": "user", "content": schema_prompt}]
).content if b.type == "text").strip()
# Lo envolvemos en una etiqueta para insertarlo en el HTML
html_tag = f'<script type="application/ld+json">\n{schema_json}\n</script>'
return html_tag
# Ejemplo: Schema para una agencia inmobiliaria
business_info = {
"name": "Acme Realty",
"url": "https://acme-realty.example",
"telephone": "+593-XX-XXX-XXXX",
"address": {
"city": "Cuenca",
"country": "Ecuador"
},
"description": "Agencia inmobiliaria en Cuenca para extranjeros",
"languages": ["es", "en"],
"priceRange": "$$"
}
faq_page_content = """
¿Cuánto cuesta un departamento en Cuenca? [respuesta con cifras reales de la agencia]...
¿Cómo compra una propiedad en Ecuador un extranjero? [respuesta revisada por un abogado]...
¿Hace falta visa para comprar una propiedad? [respuesta revisada por un abogado]...
"""
schema_html = add_schema_markup(
page_content=faq_page_content,
page_type="faq",
business_info=business_info
)
print("Schema markup creado:")
print(schema_html[:500] + "...")Qué cambió en los resultados enriquecidos. Google quitó los resultados enriquecidos de HowTo en 2023, y los de FAQ dejaron de mostrarse desde el 7 de mayo de 2026 (así lo dice la documentación de Google Search Central). El marcado FAQPage y HowTo en sí sigue siendo válido: describe la estructura de la página para las máquinas, pero no esperes "preguntas desplegables" en los resultados por usarlo. Revisa que el marcado sea válido y no armes expectativas de tráfico sobre él.
AI Visibility: aparecer en las respuestas de la IA
El AEO es una disciplina joven. La meta: que cuando alguien le pregunte a ChatGPT o a Claude sobre tu tema, tú aparezcas en la respuesta.
Usa la skill searchfit-seo:ai-visibility:
Claude, usa la skill searchfit-seo:ai-visibility. Nuestro sitio: acme-realty.example Tema: bienes raíces en Ecuador para extranjeros Revisa nuestra visibilidad en las respuestas de IA para estas búsquedas: - "Cómo compra una propiedad en Ecuador un extranjero" - "Agencia inmobiliaria en Cuenca que atienda a extranjeros" - "Vivir en Ecuador siendo extranjero: dónde vivir" - "Es seguro comprar una propiedad en Ecuador" Dame: 1. El nivel actual de visibilidad en IA (si aparecemos en las respuestas) 2. Qué le impide a la IA recomendarnos 3. Cambios concretos para mejorar la visibilidad en IA: - Qué páginas agregar o rehacer - Qué marcado agregar - Qué formato de contenido prefieren los motores de IA 4. Prioridad de las acciones (qué hacer primero)
O con código, para monitorear con regularidad. Es una revisión simplificada: Claude responde de memoria, sin buscar en la web, así que el script no reproduce las respuestas reales de ChatGPT, Gemini, Perplexity ni Google AI Mode. Para una medición real, abre esos servicios tú mismo o usa una herramienta de monitoreo de visibilidad en IA (por ejemplo, Peec AI u OtterlyAI; precios y condiciones en sus sitios).
def check_ai_visibility(brand_name: str, topics: list, test_queries: list) -> dict:
"""
Revisa qué tanto se menciona la marca en las respuestas de IA.
Simula las respuestas de la IA a las búsquedas indicadas y busca menciones de la marca.
"""
results = {}
for query in test_queries:
# Simulamos la respuesta de la IA a la búsqueda (sin una consulta real a ChatGPT)
response = "".join(b.text for b in client.messages.create(
model="claude-sonnet-5-5",
max_tokens=1000,
system=f"""Eres un asistente de búsqueda con IA que responde preguntas de los usuarios.
Responde con base en información que realmente existe en internet.
Si recomiendas recursos o empresas concretos, explica por qué.""",
messages=[{
"role": "user",
"content": query
}]
).content if b.type == "text")
# Revisamos si se menciona nuestra marca
brand_mentioned = brand_name.lower() in response.lower()
# Analizamos qué se recomienda
analysis = "".join(b.text for b in client.messages.create(
model="claude-haiku-4-5", # modelo ligero para etiquetar la respuesta de forma sencilla; nombres vigentes de modelos: página «Lo vigente»
max_tokens=300,
messages=[{
"role": "user",
"content": f"""Búsqueda del usuario: "{query}"
Respuesta de la IA: {response[:800]}
Nuestra marca: {brand_name}
Responde:
1. ¿Se menciona nuestra marca? (sí/no)
2. ¿A quién o qué se recomienda? (enuméralo)
3. ¿Por qué se mencionan esas fuentes? (una frase)
4. ¿Qué tenemos que hacer para aparecer en una respuesta así? (una frase)
Formato: JSON {{
"mentioned": true/false,
"recommended": ["...", "..."],
"why_they_rank": "...",
"our_action": "..."
}}"""
}]
).content if b.type == "text")
results[query] = {
"brand_mentioned": brand_mentioned,
"analysis": json.loads(analysis)
}
# Conclusión general
mention_rate = sum(1 for r in results.values() if r["brand_mentioned"]) / len(results)
print(f"\nAI Visibility Report de {brand_name}:")
print(f"Menciones en respuestas de IA: {mention_rate:.0%} ({sum(1 for r in results.values() if r['brand_mentioned'])}/{len(results)} búsquedas)")
print("\nPor búsqueda:")
for query, data in results.items():
status = "NOS MENCIONAN" if data["brand_mentioned"] else "no nos mencionan"
print(f" [{status}] {query[:60]}...")
return results
# Ejemplo de uso
visibility = check_ai_visibility(
brand_name="Acme Realty",
topics=["bienes raíces Ecuador", "vivienda Cuenca"],
test_queries=[
"¿Cómo compra un departamento en Cuenca un extranjero?",
"Agencia inmobiliaria en Cuenca para extranjeros",
"¿Es seguro comprar una propiedad en Ecuador en 2026?",
]
)Auditoría de SEO automática cada semana
En lugar de revisar a mano una vez al mes, una auditoría automática cada lunes.
#!/usr/bin/env python3
# weekly-seo-audit.py: ejecutar con cron cada lunes
import anthropic
import requests
import json
import os
from datetime import datetime, timedelta
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
# Google Search Console API (requiere configurar OAuth 2.0)
GSC_PROPERTY = os.environ.get("GSC_PROPERTY", "https://acme-realty.example/")
def get_gsc_data(days_back: int = 28) -> dict:
"""
Obtiene los datos de Google Search Console por API.
Requiere: google-auth-oauthlib, google-api-python-client
pip install google-auth-oauthlib google-api-python-client
Si GSC no está configurado, devuelve datos de muestra para la demo.
"""
try:
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
creds = Credentials.from_authorized_user_file(
os.environ.get("GSC_CREDENTIALS_FILE", "gsc-credentials.json")
)
service = build("searchconsole", "v1", credentials=creds)
end_date = datetime.now().strftime("%Y-%m-%d")
start_date = (datetime.now() - timedelta(days=days_back)).strftime("%Y-%m-%d")
request = {
"startDate": start_date,
"endDate": end_date,
"dimensions": ["query", "page"],
"rowLimit": 100,
# la API devuelve las filas ordenadas por clics de mayor a menor; no hace falta ordenar aparte
}
response = service.searchanalytics().query(
siteUrl=GSC_PROPERTY, body=request
).execute()
return response.get("rows", [])
except Exception as e:
# Datos de muestra si GSC no está configurado
print(f"GSC no está configurado ({e}). Usamos datos de muestra.")
return [
{"keys": ["comprar departamento cuenca", "acme-realty.example/"], "clicks": 45, "impressions": 890, "ctr": 0.051, "position": 8.2},
{"keys": ["bienes raices ecuador extranjeros", "acme-realty.example/blog/"], "clicks": 23, "impressions": 560, "ctr": 0.041, "position": 12.5},
{"keys": ["vivir en cuenca opiniones", "acme-realty.example/blog/life/"], "clicks": 18, "impressions": 340, "ctr": 0.053, "position": 6.1},
]
def check_page_speed(url: str) -> dict:
"""Revisa los Core Web Vitals con la API de Google PageSpeed Insights (gratis)"""
api_key = os.environ.get("PAGESPEED_API_KEY", "")
params = {
"url": url,
"strategy": "mobile", # para Google importa más el celular
}
if api_key:
params["key"] = api_key
try:
response = requests.get(
"https://www.googleapis.com/pagespeedonline/v5/runPagespeed",
params=params,
timeout=30
)
data = response.json()
# Extraemos las métricas principales
metrics = data.get("lighthouseResult", {}).get("audits", {})
return {
"lcp": metrics.get("largest-contentful-paint", {}).get("displayValue", "N/A"),
"cls": metrics.get("cumulative-layout-shift", {}).get("displayValue", "N/A"),
"tbt": metrics.get("total-blocking-time", {}).get("displayValue", "N/A"), # en laboratorio, en lugar de INP
"score": data.get("lighthouseResult", {}).get("categories", {}).get("performance", {}).get("score", 0) * 100,
}
except Exception as e:
return {"error": str(e)}
def run_weekly_audit(site_url: str, report_dir: str = "reports/seo") -> str:
"""Corre la auditoría de SEO semanal completa"""
today = datetime.now().strftime("%Y-%m-%d")
os.makedirs(report_dir, exist_ok=True)
print(f"Iniciando la auditoría de SEO de {site_url} ({today})")
# 1. Datos de GSC
print(" Obteniendo los datos de Google Search Console...")
gsc_data = get_gsc_data(days_back=28)
# 2. Core Web Vitals
print(" Revisando los Core Web Vitals...")
speed_data = check_page_speed(site_url)
# 3. Claude analiza todo y da recomendaciones
print(" Analizando con Claude...")
analysis = "".join(b.text for b in client.messages.create(
model="claude-sonnet-5-5",
max_tokens=3000,
messages=[{
"role": "user",
"content": f"""Analiza los datos de SEO y da recomendaciones.
Sitio: {site_url}
Fecha: {today}
Google Search Console (búsquedas principales de los últimos 28 días):
{json.dumps(gsc_data[:20], ensure_ascii=False, indent=2)}
Core Web Vitals:
{json.dumps(speed_data, ensure_ascii=False, indent=2)}
Haz el análisis:
## 1. Victorias rápidas (hacer en 1-2 semanas)
Búsquedas en posición 11-30 con posibilidad de subir al top 10.
Para cada una: qué hacer exactamente (¿reescribir el título? ¿agregar una sección? ¿mejorar los enlaces internos?)
## 2. Caída de posiciones
Si ves un CTR alto con una posición baja, la página es relevante pero no posiciona.
¿Qué hacer?
## 3. Lo técnico
Core Web Vitals: ¿hay problemas críticos de velocidad?
¿Qué arreglar primero?
## 4. Oportunidades de contenido
¿Qué temas vale la pena cubrir según los datos de GSC?
¿Qué búsquedas tienen muchas impresiones y pocos clics (problema del título o del meta)?
## 5. Plan prioritario de la semana
Las 5 tareas concretas principales con una estimación de tiempo (horas).
Escribe en español. Concreto, sin relleno."""
}]
).content if b.type == "text")
# 4. Guardamos el reporte
report_path = f"{report_dir}/seo-{today}.md"
with open(report_path, "w", encoding="utf-8") as f:
f.write(f"# Auditoría de SEO {today}\n\n")
f.write(f"**Sitio:** {site_url}\n\n")
f.write(f"**Core Web Vitals (mobile):** LCP {speed_data.get('lcp', 'N/A')} | Score {speed_data.get('score', 'N/A')}/100\n\n")
f.write("---\n\n")
f.write(analysis)
print(f"\nReporte guardado: {report_path}")
return analysis
# Ejecución
if __name__ == "__main__":
run_weekly_audit(
site_url="https://acme-realty.example",
report_dir="reports/seo"
)Lo agregamos a cron para que corra solo:
# Crontab: ejecutar cada lunes a las 09:00
# crontab -e → agregar la línea:
0 9 * * 1 cd /path/to/project && python weekly-seo-audit.py >> logs/seo-audit.log 2>&1
# O con Routines en Claude Code: una tarea programada en la nube (comando /schedule).
# A octubre de 2026 es un research preview en los planes de pago; las condiciones están en la documentación de Claude Code.Calculadora de SEO: cómo estimar si vale la pena invertir
Los números de la tabla son inventados, es un ejemplo didáctico. No es un pronóstico ni una promesa de ingresos: las cifras reales dependen del nicho, la competencia, la región y la calidad de los materiales. Pon tus propios datos.
| Paso del cálculo | Supuesto del ejemplo |
|---|---|
| Búsquedas al mes de la frase elegida | 500 |
| Porcentaje de clics (CTR) en la posición elegida | 28% (en la vida real depende mucho de la búsqueda y de los bloques de IA en los resultados) |
| Visitas al mes | 500 × 28% = 140 |
| Conversión del sitio a solicitud de contacto | 3% |
| Solicitudes al mes | 140 × 3% ≈ 4 |
| Porcentaje de solicitudes que llegan a una venta | 25% |
| Ingreso de la agencia por una venta | $3,000 |
| Ingreso al mes por una frase con estos supuestos | 4 × 25% × $3,000 = $3,000 |
Del otro lado calcula los gastos: tokens de Claude, tu tiempo, hosting y herramientas de pago, si las tienes. Nadie garantiza las posiciones en los resultados, así que calcula también un escenario malo, por ejemplo la mitad de visitas y la mitad de conversión. Si aun así el cálculo se ve razonable, el artículo vale el esfuerzo.
Práctica
Tarea: poner en marcha la máquina de SEO para un sitio real o un dominio de prueba.
Paso 1: configurar Google Search Console (15 min)
- Entra a search.google.com/search-console
- Agrega tu sitio y verifícalo por DNS o con un archivo HTML
- Espera 2-3 días a que se junten datos (o usa los datos de muestra del script)
Paso 2: keyword research con Claude (10 min)
# Corre el script de keyword research
python keyword-research.py
# Abre keyword-research.json
# Elige las 3 palabras clave prioritarias para tus primeros artículosPaso 3: content brief con la skill de searchfit-seo (5 min)
# En Claude Code usa la skill: Claude, usa la skill searchfit-seo:content-brief. Tema: [tu palabra clave del paso 2] Público: [descripción de tu público]
Paso 4: schema markup para la página principal (10 min)
# Corre el script de schema markup
python add-schema.py --page-type local_business --url https://tu-sitio.com
# Copia el JSON-LD que obtuviste y pégalo en el <head> del sitioPaso 5: configurar la auditoría semanal (10 min)
# Configura cron:
crontab -e
# Agrega la línea:
0 9 * * 1 cd /path/to/project && python weekly-seo-audit.py
# O córrelo a mano para el primer reporte:
python weekly-seo-audit.pyPaso 6: revisión de AI Visibility (5 min)
# Revisa la visibilidad en las respuestas de IA:
python check-ai-visibility.py
# Compara con los resultados 4 semanas después de hacer los cambiosResultado: al terminar la práctica tienes una lista de palabras clave, tus primeros content briefs, el marcado de schema y una auditoría semanal automática.
Herramientas y recursos
- Google Search Console: analítica gratuita de posiciones y tráfico
- Google PageSpeed Insights API: Core Web Vitals (gratis)
- Schema.org: referencia de todos los tipos de marcado
- Rich Results Test: la herramienta de Google para revisar el schema markup
- Ahrefs: herramienta de pago para keyword gap (precios en su sitio; para tu propio sitio existe el gratuito Ahrefs Webmaster Tools)
- Screaming Frog: auditoría técnica de SEO (hay una versión gratis con un límite de URL; los detalles están en su sitio)
- searchfit-seo:*: un plugin con skills y comandos de SEO para Claude Code
- Google Search Console Python API: documentación oficial
- Modelos de Claude: los nombres en el código son a octubre de 2026; precios y versiones vigentes: Lo vigente
Conclusiones clave
El SEO en 2026 es un juego doble: Google + motores de IA. Las técnicas son distintas, el contenido es el mismo: respuestas estructuradas a las preguntas reales de tu público.
El AEO (Answer Engine Optimization) no reemplaza al SEO, se monta encima. Una estructura clara de pregunta y respuesta y un Schema bien hecho aumentan las posibilidades de aparecer tanto en Google como en las respuestas de ChatGPT, Claude y Gemini, pero no lo garantizan.
Automatizar la máquina de SEO: keyword research (Claude) → content brief (5 min) → artículo → schema markup → auditoría semanal (automática). Una vez configurada, la rutina corre sola, pero los reportes y los textos hay que leerlos y revisarlos de todos modos.
Los resultados del SEO no llegan de inmediato: normalmente son meses, no días, y dependen del nicho, la competencia y la calidad del material. No hay posiciones garantizadas. A cambio, un buen artículo que se mantiene actualizado sigue siendo un activo que trabaja.
Siguiente lección
→ Publicidad con IA: generación de creativos, pruebas A/B, pujas inteligentes
La marca se guarda solo en este navegador y no se envía a ningún sitio. Mi progreso