Tamaño de la Muestra de Visibilidad de IA: ¿Cuántas Ejecuciones Necesita Realmente un Número?
Senior Web Scraping Engineer
TL;DR:
- Una sola captura de una respuesta de IA reveló solo el 49.6% de los dominios citados que cinco capturas del mismo aviso revelaron, medido a través de una matriz de 100 capturas de cinco motores de respuesta, cuatro avisos y cinco repeticiones con cada entrada mantenida constante.
- Los conjuntos de dominios citados se superpusieron a través de repeticiones con un Jaccard pareado medio de 0.384, pero las celdas individuales de motor y aviso varían de 0.114 a 0.956 — no hay una sola cifra de estabilidad que cubra la "visibilidad de IA".
- Las menciones de marcas dentro del texto de la respuesta fueron la capa menos confiable: de 137 observaciones de marca por celda, 44.5% aparecieron en las cinco repeticiones y 24.8% aparecieron en exactamente una.
- Las preguntas de pertenencia a conjuntos convergen rápidamente: tres repeticiones recuperaron 83.1% de los dominios citados que cinco repeticiones encontraron — por lo que una auditoría de citas necesita un puñado de ejecuciones, no un cuarto de las capturas diarias.
- Las preguntas de tasa convergen lentamente: con una tasa de aparición observada del 40%, cinco ejecuciones dan un intervalo del 95% de 65 puntos de ancho, y alcanzar ±10 puntos requiere aproximadamente 100 ejecuciones por motor por aviso.
- La matriz completa se ejecutó en 4 minutos y 9 segundos, por lo que estas cifras miden solo la no determinación a nivel modelo; un programa que muestrea a través de días debería esperar al menos este movimiento, nunca menos.
- Ejecuta la misma matriz contra tu propio conjunto de avisos en el plan gratuito de Scrapeless y obtén tu propio número en lugar de tomar prestado este.
Cada panel de visibilidad de IA informa un número. Participación en citas, participación de voz, clasificación de recomendaciones, sentimiento — cada uno llega como una cifra limpia con una flecha de tendencia al lado. Ninguno de ellos llega con un intervalo de error.
Esa omisión importa más aquí que en la búsqueda clásica, porque la superficie que se mide regenera su respuesta en cada solicitud. Los investigadores que fijaron cinco modelos en configuraciones nominalmente deterministas en ocho tareas aún registraron variaciones de precisión de hasta el 15% entre ejecuciones, con la brecha entre la mejor y la peor ejecución posible alcanzando el 70%. Un modelo que no se repetirá cuando se le indique, tampoco te dará un número de visibilidad repetible de una captura.
El resto de esta publicación dispara los mismos avisos a los mismos motores repetidamente, mantiene cada entrada constante, y mide cuánto se mueven realmente las respuestas. Ese movimiento medido se convierte luego en la única salida sobre la que un programa de monitoreo puede actuar — un número de ejecuciones.
Pipeline a Vista de Pájaro
El pipeline tiene cuatro etapas, y la última es el entregable:
capturar la matriz de repeticiones → reducir cada respuesta a capas comparables → puntuar la estabilidad por celda → convertir la estabilidad en un tamaño de muestra requerido
La Etapa 1 dispara una solicitud idéntica muchas veces por motor y almacena cada respuesta en bruto. La Etapa 2 reduce cada respuesta a tres cosas que se pueden comparar a través de repeticiones: el conjunto de dominios que citó, el texto de la respuesta y qué nombres de listas de vigilancia menciona el texto y en qué orden. La Etapa 3 mide cuánto se mueve cada una de esas tres capas entre repeticiones. La Etapa 4 toma el movimiento medido y responde a la pregunta que tiene realmente un equipo de informes, que es cuántas capturas necesita detrás de una afirmación.
Esto se sitúa un nivel por encima de los pipelines de captura de los que depende. Si no has construido aún el lado de captura, el pipeline de participación de citas a través de seis motores de respuesta de IA es la base; esta publicación mide si la serie que produce ese pipeline es legible en el tamaño de muestra que estás utilizando.
Qué Responde Esta Medición
Cuatro decisiones cambian dependiendo de la respuesta, y las cuatro se están tomando hoy sin ella.
Si un movimiento semana a semana es real. Una cifra de participación en citas que cae del 40% al 25% se ve como una regresión. Con cinco ejecuciones por celda, ambas cifras se sitúan dentro del mismo intervalo de confianza, por lo que la caída es indistinguible de la regeneración de la respuesta por parte del motor.
Cuánto presupuesto de captura necesita un programa. Los tamaños de muestra tienen un costo. Un equipo que necesita una estimación de tasas y un equipo que necesita un inventario de citas tienen requisitos que difieren en más de un orden de magnitud, y comprar el más grande para ambos desperdicia la mayor parte del presupuesto.
Qué métrica construir alrededor de un objetivo. Algunas capas de una respuesta de IA son lo suficientemente estables como para establecer un objetivo. Otras no lo son, y construir un OKR sobre la inestable produce un cuarto de ruido interpretado como progreso.
Qué motor ponderar. La estabilidad por motor varía aproximadamente por un factor de dos en esta matriz. Un motor cuyas citas apenas se mueven te da una lectura utilizable de unas pocas capturas; un motor que reorganiza necesita varias veces el muestreo para la misma confianza.
El Diseño de la Muestra, Declarado Desde el Principio
La matriz consiste en cinco motores, cuatro avisos, cinco repeticiones: 100 capturas, con 20 celdas de motor y aviso que sostienen cinco repeticiones cada una.
| Dimensión | Valor |
|---|---|
| Motores | Perplexity, Grok, Gemini, Google AI Mode, ChatGPT |
| Prompts | 4 preguntas a nivel de categoría en una categoría de productos |
| Repeticiones por celda | 5 |
| Total de capturas | 100 |
| País | Fijado en US en cada llamada |
| Modo de razonamiento de Grok | Fijado en MODEL_MODE_FAST en cada llamada |
| Ventana de captura | 4 minutos 9 segundos, sesión única |
| Huellas digitales de entrada distintas | 20 — una por celda, compartida por sus 5 repeticiones |
Dos decisiones de diseño llevan el resultado. La primera es que cada entrada está fijada: mismo string de prompt, mismo país, mismo modo de razonamiento, mismo flag de búsqueda web. Variar cualquiera de esos mezclaría diferencias de entrada en la variación y haría que la medición careciera de sentido. La cuenta de huellas digitales en la Fase 1 existe para probar que la fijación se mantuvo.
La segunda es la ventana comprimida. Todas las 100 capturas se realizaron en menos de cuatro minutos. Eso es deliberado, y también es la limitación más aguda de todo el ejercicio — consulta la sección de límites antes de citar cualquier cifra aquí.
Prerrequisitos
- Python 3.10 o más reciente, solo biblioteca estándar.
- Una clave API de Scrapeless exportada como
SCRAPELESS_API_KEY. Los actores del LLM Chat Scraper bajo la API de Extracción Universal ponen los cinco motores detrás de un único endpoint y un solo sobre de respuesta, que es lo que hace práctico un matriz entre motores cruzados. - Un archivo
watchlist.txtcon un nombre de marca por línea — tu propia marca y los nombres con los que esperas competir en la categoría. Mantenlo fuera del control de versiones si la lista es sensible. - Aproximadamente 100 llamadas de actores de presupuesto para un primer intento. La tarificación basada en el uso está en la página de precios de Scrapeless.
bash
export SCRAPELESS_API_KEY="your_scrapeless_api_key"
mkdir -p ai-visibility-variance && cd ai-visibility-variance
printf 'YourBrand\nRivalOne\nRivalTwo\n' > watchlist.txt
Fase 1 — Captura de la Matriz de Repetición
La Fase 1 dispara las cinco repeticiones de cada celda y escribe cada respuesta cruda en el disco sin tocar. Almacenar el sobre completo en lugar de un resumen analizado es importante, porque las capas que deseas comparar no son obvias hasta que has mirado la dispersión.
Cada motor toma el mismo prompt y country; solo los extras requeridos por el actor difieren, y cada extra está fijado para que no pueda desviarse entre repeticiones. Las celdas se ejecutan simultáneamente porque un paso en serie sobre 100 capturas estiraría la ventana y dejaría escapar la desviación del mundo real en una medición que pretende excluirla.
python
# capture.py — capture a fixed engine x prompt x repeat matrix
import hashlib
import json
import os
import time
import urllib.request
from concurrent.futures import ThreadPoolExecutor
API = "https://api.scrapeless.com/api/v2/scraper/execute"
KEY = os.environ["SCRAPELESS_API_KEY"]
OUT = "runs"
REPEATS = 5
PROMPTS = {
"P1": "What are the best web scraping APIs for developers in 2026?",
"P2": "Which services provide cloud browsers for automated data collection?",
"P3": "What tools do developers use to collect Google search results programmatically?",
"P4": "Recommend a proxy provider for large-scale public web data collection.",
}
# Same prompt and country everywhere. Only actor-required extras differ, and
# every one of them is pinned: an input that moves between repeats would be
# measured as engine variance.
ENGINES = {
"perplexity": ("scraper.perplexity", {}),
"grok": ("scraper.grok", {"mode": "MODEL_MODE_FAST"}),
"gemini": ("scraper.gemini", {}),
"aimode": ("scraper.aimode", {}),
"chatgpt": ("scraper.chatgpt", {"web_search": True, "shopping": False}),
}
def execute(actor, payload, timeout=300):
request = urllib.request.Request(
API,
data=json.dumps({"actor": actor, "input": payload}).encode(),
headers={"Content-Type": "application/json", "x-api-token": KEY},
method="POST",
)
started = time.time()
with urllib.request.urlopen(request, timeout=timeout) as response:
return json.loads(response.read().decode()), round(time.time() - started, 1)
def capture(job):
engine, prompt_id, repeat = job
actor, extra = ENGINES[engine]
payload = {"prompt": PROMPTS[prompt_id], "country": "US", **extra}
# Hash the actor with the payload. Three of these engines take an identical
# payload, so a payload-only hash would collapse them into one fingerprint
# and stop proving that each cell repeated the same request.
fingerprint = hashlib.sha256(
json.dumps({"actor": actor, **payload}, sort_keys=True).encode()).hexdigest()[:16]
try:
body, elapsed = execute(actor, payload)
except Exception as exc:
# A cell that returns nothing is logged as missing, never dropped.
# A silent hole would bias every statistic computed downstream.
return {"ok": False, "note": f"{engine} {prompt_id} r{repeat}: {type(exc).__name__}"}
with open(f"{OUT}/{engine}__{prompt_id}__r{repeat}.json", "w") as handle:
json.dump({
"engine": engine, "prompt_id": prompt_id, "repeat": repeat,
"elapsed_s": elapsed, "input_fingerprint": fingerprint,
"captured_utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
"response": body,
}, handle)
return {"ok": True, "fingerprint": fingerprint}
os.makedirs(OUT, exist_ok=True)
jobs = [(e, p, r) for e in ENGINES for p in PROMPTS for r in range(1, REPEATS + 1)]
print(f"{len(jobs)} captures = {len(ENGINES)} engines"
f" x {len(PROMPTS)} prompts x {REPEATS} repeats")
with ThreadPoolExecutor(max_workers=12) as pool:
results = list(pool.map(capture, jobs))
stored = [r for r in results if r["ok"]]
print(f"stored {len(stored)} captures in {OUT}/")
print(f"missing cells: {[r['note'] for r in results if not r['ok']] or 'none'}")
print(f"{len({r['fingerprint'] for r in stored})} distinct input fingerprints "
f"across {len(stored)} captures")
La línea de huellas digitales es la verificación de honestidad. Veinte huellas digitales distintas a través de 100 capturas significa que las cinco repeticiones de cada celda fueron solicitudes idénticas en bytes, por lo que cualquier cosa que difiera en las respuestas provino del motor.
Fase 2 — Reducir Cada Captura a Tres Capas Comparables
La Fase 2 aplana cinco sobres de respuesta diferentes en una forma de fila con tres capas de medición, porque "visibilidad de IA" no es una cantidad y tratarla como tal es donde comienza el error.
Las tres capas responden a diferentes preguntas y, como muestran los resultados, necesitan tamaños de muestra diferentes:
| Capa | Lo que contiene | La familia métrica que alimenta |
|---|---|---|
| L1 citas | Conjunto de dominios registrables que citó el motor | Participación de citas, brecha de dominio citado |
| L2 prosa | El texto de respuesta, como caracteres y como conjunto de tokens | Sentimiento, resumir, diferencias de texto |
| L3 marcas | Qué nombres de la lista de vigilancia menciona el texto, en orden de primera mención | Participación de voz, rango de recomendación |
Cada motor informa sus fuentes bajo su propia clave — Perplexity utiliza web_results, Grok clave footnotes por ID de cita, tanto Gemini como AI Mode utilizan citations, y el panel de búsqueda de ChatGPT llega como search_result. Normalizar al host registrable elimina la diferencia entre una URL de artículo profundo y un enlace a la página de inicio, que es lo que en realidad cuenta una métrica de participación de citas.
python
# layers.py — reduce every capture to three comparable measurement layers
import json
import os
import re
from urllib.parse import urlparse
WATCHLIST = [line.strip() for line in open("watchlist.txt") if line.strip()]
CITATIONS = {
"perplexity": lambda r: [c.get("url") for c in r.get("web_results") or []],
"grok": lambda r: [c.get("url") for c in (r.get("footnotes") or {}).values()],
"gemini": lambda r: [c.get("url") for c in r.get("citations") or []],
"aimode": lambda r: [c.get("url") for c in r.get("citations") or []],
"chatgpt": lambda r: [c.get("url") for c in r.get("search_result") or []],
}
ANSWER_KEY = {
"perplexity": "result_text", "grok": "full_response", "gemini": "result_text",
"aimode": "result_text", "chatgpt": "result_text",
}
def registrable(url):
netloc = urlparse(url).netloc.lower()
return netloc[4:] if netloc.startswith("www.") else netloc
def mentions(text):
"""Watchlist names present in the answer, keyed by first-mention offset."""
lowered = text.lower()
found = {}
for name in WATCHLIST:
hit = re.search(rf"(?<![a-z0-9]){re.escape(name.lower())}(?![a-z0-9])", lowered)
if hit:
found[name] = hit.start()
return found
rows = []
for filename in sorted(os.listdir("runs")):
record = json.load(open(f"runs/{filename}"))
result = record["response"].get("task_result") or {}
engine = record["engine"]
answer = result.get(ANSWER_KEY[engine]) or ""
found = mentions(answer)
rows.append({
"engine": engine,
"prompt_id": record["prompt_id"],
"repeat": record["repeat"],
"cited_hosts": sorted({
host for url in CITATIONS[engine](result)
if url and (host := registrable(url))
}),
"answer_chars": len(answer),
"answer_tokens": sorted(set(re.findall(r"[a-z0-9]+", answer.lower()))),
# Ordered by first mention, so list position survives into stage 3.
"brands_present": sorted(found, key=found.get),
})
with open("layers.jsonl", "w") as handle:
for row in rows:
handle.write(json.dumps(row) + "\n")
cited = sum(len(r["cited_hosts"]) for r in rows)
print(f"reduced {len(rows)} captures -> layers.jsonl")
print(f"L1 citations: {cited} cited hosts, {cited / len(rows):.1f} per capture")
print(f"L2 prose: {sum(r['answer_chars'] for r in rows) / len(rows):.0f} chars per answer")
print(f"L3 brands: {sum(len(r['brands_present']) for r in rows)} watchlist hits total")
Fase 3 — Puntuar Estabilidad por Motor y Prompt
La Fase 3 mide el movimiento dentro de cada celda, y reporta por motor en lugar de agrupar, porque la cifra agrupada oculta lo que más necesitas saber.
Tres estadísticas hacen el trabajo. Para las capas de citas y prosa, el índice Jaccard medio par a par a través de las cinco repeticiones — el tamaño de la intersección sobre el tamaño de la unión, promediado sobre los diez pares en una celda. Para la longitud de respuesta, el coeficiente de variación, que expresa la desviación estándar de una dispersión medida como un porcentaje de la media para que las respuestas de diferentes longitudes se mantengan comparables. Para marcas, la participación de nombres que aparecieron en las cinco repeticiones en lugar de en algunas de ellas.
python
# stability.py — how far each layer moves inside a cell
import json
import statistics as stats
from collections import defaultdict
from itertools import combinations
cells = defaultdict(dict)
for line in open("layers.jsonl"):
row = json.loads(line)
cells[(row["engine"], row["prompt_id"])][row["repeat"]] = row
def jaccard(left, right):
union = left | right
return len(left & right) / len(union) if union else None
def mean_pairwise(sets):
scores = [j for a, b in combinations(sets, 2) if (j := jaccard(a, b)) is not None]
return stats.mean(scores) if scores else None
per_engine = defaultdict(lambda: defaultdict(list))
brands = defaultdict(lambda: {"stable": 0, "flipping": 0})
for (engine, _prompt), reps in sorted(cells.items()):
keys = sorted(reps)
hosts = [set(reps[k]["cited_hosts"]) for k in keys]
tokens = [set(reps[k]["answer_tokens"]) for k in keys]
lengths = [reps[k]["answer_chars"] for k in keys]
per_engine[engine]["cite"].append(mean_pairwise(hosts))
per_engine[engine]["prose"].append(mean_pairwise(tokens))
per_engine[engine]["cv"].append(stats.pstdev(lengths) / stats.mean(lengths) * 100)
per_engine[engine]["union"].append(len(set().union(*hosts)))
per_engine[engine]["core"].append(len(set.intersection(*hosts)))
for brand in set().union(*[set(reps[k]["brands_present"]) for k in keys]):
seen = sum(1 for k in keys if brand in reps[k]["brands_present"])
brands[engine]["stable" if seen == len(keys) else "flipping"] += 1
header = f"{'engine':<12}{'citeJaccard':>12}{'proseJaccard':>13}{'lengthCV%':>11}"
print(header + f"{'hostsEveryRun':>15}{'brandsStable%':>15}")
for engine, series in per_engine.items():
core, union = sum(series["core"]), sum(series["union"])
counts = brands[engine]
stable_pct = counts["stable"] / (counts["stable"] + counts["flipping"]) * 100
print(f"{engine:<12}{stats.mean(series['cite']):>12.3f}"
f"{stats.mean(series['prose']):>13.3f}{stats.mean(series['cv']):>11.1f}"
f"{f'{core}/{union}':>15}{stable_pct:>14.1f}%")
Fase 4 — Convertir Estabilidad en un Tamaño de Muestra
La etapa 4 convierte la dispersión en un conteo de ejecuciones, y lo hace dos veces porque los dos tipos de preguntas se comportan de manera completamente diferente.
Para una pregunta de pertenencia a un conjunto — ¿qué dominios cita este motor para mi categoría? — la salida útil es una curva de cobertura: qué proporción de los dominios que cinco ejecuciones presentan, una ejecución presenta, o dos, o tres. Eso se calcula directamente a partir de las capturas al hacer muestreo de cada combinación de repeticiones.
Para una pregunta de tasa — ¿qué proporción de respuestas menciona mi marca? — la salida es un intervalo de confianza sobre una proporción. El intervalo de puntuación de Wilson es la herramienta adecuada en estos tamaños de muestra: la implementación de referencia de NIST lo convierte en el método por defecto para límites de confianza de proporción, y una comparación sistemática de tamaños de muestra de 1 a 1,000 encontró que el intervalo de Wilson supera al intervalo de Wald del libro de texto, particularmente en n pequeños y en proporciones cercanas a 0 o 1. Ambas condiciones describen exactamente datos de menciones de marca.
python
# samplesize.py — measured stability -> a required number of runs
import json
import math
import statistics as stats
from collections import Counter, defaultdict
from itertools import combinations
cells = defaultdict(dict)
for line in open("layers.jsonl"):
row = json.loads(line)
cells[(row["engine"], row["prompt_id"])][row["repeat"]] = row
def wilson(hits, runs, z=1.96):
proportion = hits / runs
denominator = 1 + z * z / runs
centre = (proportion + z * z / (2 * runs)) / denominator
half = z * math.sqrt(
proportion * (1 - proportion) / runs + z * z / (4 * runs * runs)) / denominator
return max(0.0, centre - half) * 100, min(1.0, centre + half) * 100
coverage = defaultdict(list)
for reps in cells.values():
keys = sorted(reps)
universe = set().union(*[set(reps[k]["cited_hosts"]) for k in keys])
if not universe:
continue
for n in range(1, len(keys) + 1):
coverage[n].append(stats.mean([
len(set().union(*[set(reps[k]["cited_hosts"]) for k in combo])) / len(universe)
for combo in combinations(keys, n)
]))
print("SET QUESTION — share of the 5-run cited-domain union that n runs surface")
for n in sorted(coverage):
print(f" n={n}: {stats.mean(coverage[n]) * 100:5.1f}%")
observed = Counter()
for reps in cells.values():
keys = sorted(reps)
for brand in set().union(*[set(reps[k]["brands_present"]) for k in keys]):
observed[sum(1 for k in keys if brand in reps[k]["brands_present"])] += 1
total = sum(observed.values())
print(f"\nRATE QUESTION — {total} brand-by-cell observations at n=5")
for seen in sorted(observed):
low, high = wilson(seen, 5)
print(f" seen {seen}/5 in {observed[seen]:>3} cases ({observed[seen] / total * 100:4.1f}%)"
f" 95% interval {low:5.1f}%-{high:5.1f}% width {high - low:4.1f}pt")
print("\nRATE QUESTION — interval width at a 40% appearance rate, by run count")
for n in (1, 5, 10, 20, 30, 50, 100, 200):
low, high = wilson(round(0.4 * n), n)
print(f" n={n:<4} {low:5.1f}%-{high:5.1f}% width {high - low:4.1f}pt")
Lo que la Matriz Realmente Mostró
Todo se movió, y los motores no se movieron en la misma cantidad.
| Motor | Jaccard de dominio citado | Jaccard de token de prosa | CV de longitud de respuesta | Hosts citados en cada ejecución | Menciones de marca estables |
|---|---|---|---|---|---|
| Perplexity | 0.534 | 0.446 | 28.7% | 8 de 34 | 47.6% |
| Gemini | 0.511 | 0.361 | 16.3% | 6 de 29 | 40.6% |
| Grok | 0.366 | 0.392 | 10.2% | 6 de 61 | 45.5% |
| Google AI Mode | 0.282 | 0.333 | 15.9% | 11 de 182 | 50.0% |
| ChatGPT | 0.228 | 0.342 | 9.4% | 1 de 80 | 40.0% |
Agrupado a través de todas las 20 celdas, el Jaccard promedio pareado en dominios citados fue 0.384. La dispersión a nivel de celda es la cifra más útil: 0.114 en el extremo inferior y 0.956 en el extremo superior. Una afirmación de estabilidad tomada de un motor en un aviso puede caer en cualquier lugar dentro de ese rango, que es precisamente por qué una prueba de tres ejecuciones en un solo motor es una pista y no un hallazgo.
La curva de cobertura es el número más digno de apuntar:
| Ejecuciones | Proporción de la unión de dominios citados en cinco ejecuciones |
|---|---|
| 1 | 49.6% |
| 2 | 70.3% |
| 3 | 83.1% |
| 4 | 92.3% |
| 5 | 100% |
Una captura te muestra alrededor de la mitad de los dominios que cinco capturas te muestran. Por motor en n=1, el rango va desde el 73.6% en Perplexity hasta el 35.1% en ChatGPT, por lo que una auditoría de citas de captura única en el motor menos estable está perdiendo aproximadamente dos tercios de lo que se supone que debe inventariar. La curva también se aplana rápidamente: la tercera ejecución añade 12.8 puntos, la cuarta añade 9.2. Para un inventario de citas, de tres a cuatro repeticiones se obtiene la mayor parte de lo que está disponible.
Google AI Mode produjo de lejos la unión de dominios más amplia — 182 hosts distintos a través de cuatro avisos, con solo 11 apareciendo en todas las cinco repeticiones de su celda. La propia guía de Google explica el mecanismo: tanto AI Mode como AI Overviews pueden utilizar una técnica de difusión de consultas que emite múltiples búsquedas relacionadas a través de subtemas y, por lo tanto, pueden mostrar un conjunto de enlaces más amplio y variado que la búsqueda clásica. Cuando un motor está diseñado para distribuir sus citas a través de subtemas, una captura muestrea solo una parte de esa dispersión.
La capa de tasa cuenta la historia opuesta. A través de 137 observaciones de marca por celda, solo el 44.5% estaban presentes en las cinco repeticiones. El 24.8% apareció en exactamente una de cinco — un nombre que una captura única informaría ya sea como una presencia confiable o una ausencia confiable, dependiendo completamente de qué captura tomaste.
| Visto en | Casos | Proporción | Intervalo del 95% sobre la tasa verdadera | Ancho |
|---|---|---|---|---|
| 1 de 5 | 34 | 24.8% | 3.6% – 62.4% | 58.8 pt |
| 2 de 5 | 16 | 11.7% | 11.8% – 76.9% | 65.2 pt |
| 3 de 5 | 14 | 10.2% | 23.1% – 88.2% | 65.2 pt |
| 4 de 5 | 12 | 8.8% | 37.6% – 96.4% | 58.8 pt |
| 5 de 5 | 61 | 44.5% | 56.6% – 100% | 43.4 pt |
Una marca vista dos veces en cinco ejecuciones tiene una tasa de aparición verdadera en algún lugar entre el 12% y el 77%, lo que es demasiado amplio para respaldar cualquier declaración en la que un interesado actuaría. Ampliar la muestra la reduce lentamente:
| Ejecuciones por celda | Intervalo del 95% a una tasa observada del 40% | Ancho |
|---|---|---|
| 1 | 0.0% – 79.3% | 79.3 pt |
| 5 | 11.8% – 76.9% | 65.2 pt |
| 10 | 16.8% – 68.7% | 51.9 pt |
| 20 | 21.9% – 61.3% | 39.5 pt |
| 30 | 24.6% – 57.7% | 33.1 pt |
| 50 | 27.6% – 53.8% | 26.2 pt |
| 100 | 30.9% – 49.8% | 18.9 pt |
| 200 | 33.5% – 46.9% | 13.5 pt |
| Así que la respuesta a "cuántas ejecuciones" es: depende de qué capa estés reportando, y las dos respuestas difieren por más de un orden de magnitud. Un inventario de citas es legible en tres a cuatro repeticiones. Una tasa que pretendes comparar semana a semana necesita alrededor de 100 capturas por motor por aviso antes de que el intervalo se ajuste a ±10 puntos. Las capturas diarias durante dos a tres semanas se sitúan entre aproximadamente 14 y 21 — suficientemente cómodas para la pregunta establecida, y alrededor de cinco veces más cortas para la pregunta de tasa. |
Dos resultados más pequeños merecen ser registrados. El rango se movió menos que la mención: entre los nombres presentes en más de una repetición, la posición de primera mención se trasladó en un promedio de 0.89 lugares en ChatGPT y 1.95 en Grok, por lo que una métrica de seguimiento de rango hereda la inestabilidad de la mención pero añade solo un poco de la suya. Y una celda — un único motor en el aviso de navegador en la nube — no nombró ninguna marca de la lista de vigilancia en ninguna de sus cinco repeticiones, respondiendo en categorías de capacidad en lugar de proveedores. Una ausencia consistente también es una lectura estable, y un monitor que trata un resultado vacío como una captura fallida desechará una señal real.
La dispersión medida también coincide con la investigación publicada en lugar de contradecirla. Un estudio de componentes de varianza que descompuso 12,933 respuestas de marcas LLM a través de 20 marcas, 8 idiomas y 3 modelos encontró que el remuestreo solo representaba el 34.8% de la varianza total, con la confiabilidad de una sola respuesta situada cerca de 0.01. Ese estudio utilizó un corpus diferente y un método estadístico diferente y aun así llegó al mismo lugar: una respuesta lleva casi ninguna señal que discrimine marcas.
Si ya estás ejecutando el pipeline de sentimiento de marca por motor o el rastreador de rango de recomendación de IA, ambos leen la capa de prosa, y ambos, por lo tanto, heredan el tamaño de muestra de convergencia lenta en lugar del rápido.
Obtener tu propia versión de esta tabla toma alrededor de cien llamadas. Comienza con el plan gratuito de Scrapeless y ejecuta la matriz contra tus propios avisos antes de establecer un objetivo en cualquiera de estas métricas.
Lo Que Esta Medición No Puede Decirte
La ventana de captura comprimida es la limitación que rige cada cifra anterior. Todas las 100 capturas ocurrieron en 4 minutos y 9 segundos en un solo día. Eso aísla una fuente de movimiento de manera limpia — el modelo regenerando su respuesta — y excluye varias otras por completo: actualizaciones de índices, ciclos de noticias, contenido que publicas, cambios de versión del modelo y cualquier auténtico desplazamiento diario en lo que los motores recuperan.
La consecuencia corre en una dirección solamente. Estos números son un suelo, no una estimación de la varianza total. Un programa que muestrea los mismos avisos a lo largo de las semanas está expuesto a la no determinación a nivel de modelo más todo lo que la ventana de cuatro minutos mantuvo constante. Por lo tanto, los tamaños de muestra requeridos para un programa de monitoreo real son al menos de este tamaño, y la brecha entre una cifra de cuatro minutos y una cifra de cuatro semanas es en sí misma una medición que nadie aquí ha realizado.
Cuatro límites más estrechos se aplican:
- Veinte celdas es un diseño pequeño. Las cifras por motor son medias sobre cuatro avisos, por lo que el número de un motor no es una estimación precisa de ese motor. El rango a nivel de celda de 0.114 a 0.956 es el resumen honesto de cuánto puede diferir una sola celda.
- Una categoría, un idioma, un país. Todos los avisos estaban en una categoría de producto, en inglés, vinculados a
US. El trabajo de componentes de varianza citado anteriormente encontró que el idioma de consulta llevaba el 26.5% de la varianza total, por lo que no se debe asumir que un idioma diferente se comporte como este. - El intervalo de Wilson asume muestras independientes. Cinco solicitudes disparadas simultáneamente en una sesión pueden compartir un estado superior, lo que haría que la muestra efectiva fuera más pequeña que la nominal y que los verdaderos intervalos fueran más amplios de lo que la tabla muestra.
- La capa de marca depende de la lista de vigilancia. Solo se cuentan los nombres en la lista, por lo que un competidor que no enumeraste es invisible para L3 mientras que sigue siendo completamente visible para L1 si el motor cita su dominio.
Ninguno de estos infringe el resultado principal, que es una comparación entre capas medidas bajo condiciones idénticas. Sin embargo, significan que los porcentajes específicos pertenecen a esta matriz, no a las respuestas de IA en general.
Colocando el Número en un Programa de Monitoreo
Programa los dos tipos de preguntas por separado, porque ejecutar una cadencia para ambos sobrepaga la pregunta establecida y subutiliza la pregunta de tasa.
Para el inventario de citas, tres a cuatro repeticiones por motor por solicitud, semanalmente. Eso recupera entre el 83% y el 92% del universo de dominios citados por ronda de captura, y la diferencia semana a semana en ese conjunto es legible. Almacene la unión por ronda en lugar de una lista de una sola ejecución; comparar dos ejecuciones individuales genera cambios que son en su mayoría re-muestreo.
Para las métricas de tasa — cuota de menciones, cuota de voz, cuota de sentimiento, rango — acumule en lugar de tomar instantáneas. Veinte capturas por celda por semana dan un intervalo cercano a ±20 puntos en una cifra semanal y una cifra mensual agrupada cercana a ±10. Informe el intervalo junto al número cada vez. Un panel que muestra el 42% sin mostrar el 31%–50% está afirmando una precisión que el diseño de captura no支持.
Cualquiera que sea la cadencia que elija, fije todo. Mismas cadenas de solicitud, mismo país, mismo modo de razonamiento. La huella de entrada de la Etapa 1 pertenece a sus filas almacenadas, para que un analista futuro pueda distinguir un cambio real de una solicitud que alguien editó.
Re-mida cuando un motor cambia. La estabilidad es una propiedad del modelo actual y la pila de recuperación, no una constante. Cuando un motor lanza un cambio visible, el conteo de ejecuciones que fue suficiente el trimestre pasado es una hipótesis nuevamente. La misma disciplina se aplica aquí que en cualquier evaluación de modelo, donde la curaduría de un conjunto de datos representativo y la elección de una metodología significativa vienen antes de la métrica, no después de ella.
Conclusión: Informe el Intervalo, No Solo el Número
El hallazgo útil no es que las respuestas de IA cambien. Cada guía ya dice eso. El hallazgo útil es que cambian por diferentes cantidades en diferentes capas, y que el tamaño de muestra requerido se divide en consecuencia: un puñado de ejecuciones para un inventario de citas, alrededor de cien para una tasa que pretende defender en una reunión.
El diseño detrás de esa división son cuatro archivos y cien llamadas. Captura con las entradas fijadas, reduce a capas comparables, puntúa el movimiento, convierte a un conteo de ejecuciones. Ejecútalo una vez contra tu propio conjunto de solicitudes y dejarás de adivinar una cadencia, porque tendrás el único número que actualmente falta en cada panel de visibilidad de IA: la barra de error.
¿Listo para Medir tu Propia Variación de Visibilidad de IA?
Cinco motores de respuesta se encuentran detrás de un solo punto final y un sobre de respuesta en el API de Raspado Universal Scrapeless, que es lo que hace que una matriz de cien capturas sea una sola tarde en lugar de cinco integraciones separadas. Los parámetros y las formas de respuesta para cada actor utilizado aquí están en la documentación de la API de Scrapeless.
Crea una cuenta gratuita en Scrapeless y coloca una barra de error en tus números de visibilidad.
FAQ
P: ¿Cuántas ejecuciones necesita realmente un número de visibilidad de IA?
Depende de la capa, y las dos respuestas difieren en más de un orden de magnitud. En esta matriz, tres a cuatro repeticiones por motor por solicitud recuperaron entre el 83% y el 92% de los dominios citados que cinco repeticiones mostraron, por lo que un inventario de citas es legible a ese tamaño de muestra. Una métrica de tasa como la cuota de menciones necesita aproximadamente 100 capturas por motor por solicitud antes de que un intervalo del 95% se reduzca a alrededor de ±10 puntos, y cinco capturas lo dejan alrededor de 65 puntos de ancho.
P: ¿Por qué cambian las respuestas de IA cuando la solicitud y los ajustes son idénticos?
Los modelos muestrean de una distribución de probabilidad y la capa de recuperación que los alimenta tampoco está fija, por lo que las entradas idénticas no garantizan salidas idénticas. El trabajo que fijó cinco modelos en configuraciones nominalmente deterministas a través de ocho tareas todavía registró fluctuaciones de precisión de hasta el 15% entre ejecuciones, y atribuyó el efecto a cómo se procesan los lotes de inferencia en lugar de a un error de configuración.
P: ¿Son las fuentes citadas más estables que el texto de respuesta?
No de manera confiable, y no por suficiente para omitir el muestreo repetido en cualquiera de las capas. Los conjuntos de dominios citados en esta matriz se superpusieron a una media par Jaccard de 0.384, mientras que una sola captura reveló solo el 49.6% de los dominios que cinco capturas revelaron, por lo que la capa de citas se mueve sustancialmente en términos absolutos. Converge más rápido que una métrica de tasa, lo cual es una afirmación diferente de ser estable.
P: ¿El motor que sigo cambia cuántas ejecuciones necesito?
Sí, aproximadamente por un factor de dos en la capa de citas. Una captura única mostró el 73.6% de la unión de dominios de cinco ejecuciones en el motor más estable de esta matriz y el 35.1% en el menos estable, así que un conteo de ejecuciones elegido para un motor será incorrecto para otro. Calcula la curva de cobertura por motor en lugar de aplicar una cifra en todos los casos.
P: ¿Este medida también evalúa la deriva día a día?
No. Las 100 capturas se realizaron en 4 minutos y 9 segundos, lo que aísla el no determinismo a nivel de modelo y excluye las actualizaciones de índice, ciclos de noticias, cambios de contenido y versiones de modelo. Trata cada cifra aquí como un mínimo: un programa que muestrea a lo largo de semanas lleva esta variabilidad más todo lo que la ventana corta mantuvo constante.
P: ¿Es legal capturar respuestas de IA de esta manera?
Capturar respuestas de IA públicamente disponibles a los mensajes que tú autoras es una recopilación ordinaria de datos de la web pública, y los mensajes y respuestas aquí no contienen datos personales. Mantén el volumen limitado y proporcional a la medición, almacena solo lo que el análisis necesita y verifica los términos que aplican a tu propia jurisdicción y caso de uso antes de ejecutar un programa a gran escala.
P: ¿Puedo ejecutar esto sin un agente de IA o SDK?
Sí. Cada script aquí es de la biblioteca estándar de Python contra un extremo HTTPS, así que todo el proceso se ejecuta desde un trabajo cron o un cronograma de CI sin nada instalado más allá de Python. La única dependencia externa es la clave API.
En Scrapeless, solo accedemos a datos disponibles públicamente y cumplimos estrictamente con las leyes, regulaciones y políticas de privacidad del sitio web aplicables. El contenido de este blog es sólo para fines de demostración y no implica ninguna actividad ilegal o infractora. No ofrecemos garantías y renunciamos a toda responsabilidad por el uso de la información de este blog o enlaces de terceros. Antes de realizar cualquier actividad de scraping, consulte a su asesor legal y revise los términos de servicio del sitio web de destino u obtenga los permisos necesarios.



