Answer Engine Optimization (AEO) es la práctica de clasificar en las respuestas de ChatGPT, Perplexity y Claude, no solo en Google. Este tutorial explica la creación de un panel de AEO que ejecuta mensajes diarios, captura menciones de marca y visualiza tendencias a lo largo del tiempo utilizando Scavio para datos y Metabase para gráficos.
Requisitos previos
- Python 3.8+
- Una clave API de Scavio
- Una base de datos Postgres (el nivel gratuito de Supabase funciona)
- Metabase autohospedada o en la nube
Guia paso a paso
Paso 1: Configurar el esquema de la base de datos
Cree una tabla para registrar filas de mención de respuesta rápida.
CREATE TABLE aeo_log (
id SERIAL PRIMARY KEY,
run_date DATE,
engine TEXT,
prompt TEXT,
answer TEXT,
brand_mentions JSONB
);Paso 2: Escribe el script de seguimiento diario
Para cada motor y mensaje, consulte Scavio y registre el resultado.
ENGINES = ['chatgpt', 'perplexity']
PROMPTS = ['best SERP API 2026', 'top Claude Code alternatives']
def run_tracker():
for engine in ENGINES:
for prompt in PROMPTS:
resp = requests.post('https://api.scavio.dev/api/v1/ask',
headers={'x-api-key': API_KEY},
json={'platform': engine, 'prompt': prompt}).json()
mentions = count_brands(resp.get('answer', ''))
save_row(engine, prompt, resp['answer'], mentions)Paso 3: Programar con cron
Ejecute el rastreador diariamente a las 8 a. m. UTC.
0 8 * * * /usr/bin/python3 /path/to/aeo_tracker.pyPaso 4: Crear gráficos de metabase
Cree un gráfico de tendencias de menciones de marca a lo largo del tiempo, por motor.
-- In Metabase, use:
SELECT run_date, engine, brand_mentions->>'Scavio' AS scavio_count
FROM aeo_log
ORDER BY run_date;Paso 5: Configurar alertas
Configure Metabase para enviar un correo electrónico al equipo cuando el recuento de menciones de un competidor aumente más del 20 %.
// Metabase UI: Subscriptions > New alert on trend changeEjemplo en Python
import os, requests, psycopg2, json
API_KEY = os.environ['SCAVIO_API_KEY']
PG_URL = os.environ['POSTGRES_URL']
BRANDS = ['Scavio', 'SerpAPI', 'Tavily']
def count_brands(text):
return {b: text.lower().count(b.lower()) for b in BRANDS}
def run():
conn = psycopg2.connect(PG_URL)
cur = conn.cursor()
for engine in ['chatgpt', 'perplexity']:
for prompt in ['best SERP API 2026']:
r = requests.post('https://api.scavio.dev/api/v1/ask',
headers={'x-api-key': API_KEY},
json={'platform': engine, 'prompt': prompt}).json()
cur.execute('INSERT INTO aeo_log (run_date, engine, prompt, answer, brand_mentions) VALUES (CURRENT_DATE, %s, %s, %s, %s)',
(engine, prompt, r.get('answer', ''), json.dumps(count_brands(r.get('answer', '')))))
conn.commit()
run()Ejemplo en JavaScript
import { Client } from 'pg';
const API_KEY = process.env.SCAVIO_API_KEY;
const BRANDS = ['Scavio', 'SerpAPI', 'Tavily'];
const pg = new Client({ connectionString: process.env.POSTGRES_URL });
await pg.connect();
for (const engine of ['chatgpt', 'perplexity']) {
const r = await fetch('https://api.scavio.dev/api/v1/ask', {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ platform: engine, prompt: 'best SERP API 2026' })
});
const { answer } = await r.json();
const mentions = Object.fromEntries(BRANDS.map(b => [b, (answer.toLowerCase().match(new RegExp(b.toLowerCase(), 'g')) || []).length]));
await pg.query('INSERT INTO aeo_log (run_date, engine, prompt, answer, brand_mentions) VALUES (CURRENT_DATE, $1, $2, $3, $4)', [engine, 'best SERP API 2026', answer, mentions]);
}
await pg.end();Salida esperada
Daily rows appear in the aeo_log table, one per engine-prompt combination. Metabase charts display a 30-day trend line of brand mentions, and an alert fires when a competitor's count spikes.