El rendimiento de la optimización generativa del motor no se puede medir únicamente mediante el seguimiento de clasificación tradicional. En 2026, deberá realizar un seguimiento de tres superficies: citas de descripción general de IA, presencia de entidades de Knowledge Graph y captura de fragmentos destacados. Este tutorial crea un panel de rendimiento GEO que verifica las tres superficies en busca de una lista de consultas de destino, calcula una puntuación GEO compuesta y realiza un seguimiento de los cambios a lo largo del tiempo. Cada cheque de consulta cuesta un crédito Scavio a $0,005.
Requisitos previos
- Python 3.9+ instalado
- solicita biblioteca instalada
- Una clave API de Scavio de scavio.dev
- Una lista de consultas de destino para realizar un seguimiento
Guia paso a paso
Paso 1: Definir las métricas de desempeño GEO
Configure las tres superficies para verificar cada consulta: cita de descripción general de AI, presencia de Knowledge Graph y captura de fragmentos destacados.
import os, requests, json, time
from datetime import datetime
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
URL = 'https://api.scavio.dev/api/v1/search'
TARGET_DOMAIN = 'scavio.dev'
QUERIES = [
'search api for ai agents',
'web search mcp server',
'serp api pricing comparison',
'tiktok data api',
'google search api alternative',
]Paso 2: Verifique las tres superficies GEO por consulta
Para cada consulta, consulte la cita de la descripción general de AI, la mención del gráfico de conocimiento y la propiedad del fragmento destacado. Devuelve un resultado estructurado.
def measure_geo(query: str, domain: str) -> dict:
resp = requests.post(URL, headers=H,
json={'query': query, 'country_code': 'us', 'include_ai_overview': True})
data = resp.json()
# AI Overview
ai = data.get('ai_overview', {})
ai_sources = ai.get('sources', [])
ai_cited = any(domain in s.get('link', '') for s in ai_sources)
# Knowledge Graph
kg = data.get('knowledge_graph', {})
kg_present = domain in json.dumps(kg) if kg else False
# Featured Snippet
snippet = data.get('featured_snippet', {})
snippet_owned = domain in snippet.get('link', '') if snippet else False
# Organic position
organic = data.get('organic_results', [])
org_pos = next((r['position'] for r in organic if domain in r.get('link', '')), None)
# GEO score: 0-100
score = 0
if ai_cited: score += 40
if kg_present: score += 25
if snippet_owned: score += 25
if org_pos and org_pos <= 3: score += 10
return {
'query': query, 'ai_cited': ai_cited, 'kg_present': kg_present,
'snippet_owned': snippet_owned, 'organic_position': org_pos,
'geo_score': score,
}Paso 3: Ejecute el informe completo de rendimiento de GEO
Verifique todas las consultas y calcule métricas GEO agregadas. Guarde el informe para compararlo históricamente.
def geo_report(queries: list, domain: str) -> dict:
results = []
for q in queries:
r = measure_geo(q, domain)
results.append(r)
print(f'[{r["geo_score"]:3d}] {q} | AI:{r["ai_cited"]} KG:{r["kg_present"]} Snip:{r["snippet_owned"]} Org:#{r["organic_position"]}')
time.sleep(0.5)
avg_score = sum(r['geo_score'] for r in results) / len(results)
ai_rate = sum(1 for r in results if r['ai_cited']) / len(results)
kg_rate = sum(1 for r in results if r['kg_present']) / len(results)
snip_rate = sum(1 for r in results if r['snippet_owned']) / len(results)
report = {
'date': datetime.now().strftime('%Y-%m-%d'),
'domain': domain,
'queries_checked': len(results),
'avg_geo_score': round(avg_score, 1),
'ai_citation_rate': round(ai_rate * 100, 1),
'kg_presence_rate': round(kg_rate * 100, 1),
'snippet_capture_rate': round(snip_rate * 100, 1),
'results': results,
}
print(f'\nGEO Performance Summary')
print(f' Avg GEO Score: {avg_score:.1f}/100')
print(f' AI Citation Rate: {ai_rate:.0%}')
print(f' Knowledge Graph Rate: {kg_rate:.0%}')
print(f' Featured Snippet Rate: {snip_rate:.0%}')
return report
geo_report(QUERIES, TARGET_DOMAIN)Ejemplo en Python
import os, requests, time
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
H = {'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'}
def measure_geo(query, domain):
resp = requests.post('https://api.scavio.dev/api/v1/search', headers=H,
json={'query': query, 'country_code': 'us', 'include_ai_overview': True})
data = resp.json()
ai_cited = any(domain in s.get('link', '') for s in data.get('ai_overview', {}).get('sources', []))
snippet = data.get('featured_snippet', {})
snip_owned = domain in snippet.get('link', '') if snippet else False
score = (40 if ai_cited else 0) + (25 if snip_owned else 0)
print(f'[{score:3d}] {query} | AI:{ai_cited} Snip:{snip_owned}')
for q in ['search api for agents', 'serp api comparison']:
measure_geo(q, 'scavio.dev')
time.sleep(0.5)Ejemplo en JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
async function measureGeo(query, domain) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, country_code: 'us', include_ai_overview: true })
});
const data = await resp.json();
const aiCited = (data.ai_overview?.sources || []).some(s => (s.link || '').includes(domain));
const snipOwned = (data.featured_snippet?.link || '').includes(domain);
const score = (aiCited ? 40 : 0) + (snipOwned ? 25 : 0);
console.log(`[${score}] ${query} | AI:${aiCited} Snip:${snipOwned}`);
}
(async () => {
for (const q of ['search api for agents', 'serp api comparison']) {
await measureGeo(q, 'scavio.dev');
}
})();Salida esperada
[ 40] search api for ai agents | AI:True KG:False Snip:False Org:#4
[ 75] web search mcp server | AI:True KG:True Snip:True Org:#1
[ 0] serp api pricing comparison | AI:False KG:False Snip:False Org:#8
[ 40] tiktok data api | AI:True KG:False Snip:False Org:#5
[ 10] google search api alternative | AI:False KG:False Snip:False Org:#3
GEO Performance Summary
Avg GEO Score: 33.0/100
AI Citation Rate: 60%
Knowledge Graph Rate: 20%
Featured Snippet Rate: 20%