Tamanho da Amostra de Visibilidade da IA: Quantas Execuções um Número Realmente Necessita
Senior Web Scraping Engineer
TL;DR:
- Uma única captura de uma resposta da IA revelou apenas 49,6% dos domínios citados que cinco capturas do mesmo prompt revelaram, medidas em uma matriz de 100 capturas de cinco motores de resposta, quatro prompts e cinco repetições com cada entrada mantida constante.
- Os conjuntos de domínios citados se sobrepuseram entre repetições com uma média de Jaccard par a par de 0,384, mas as células de motor-e-prompt individuais variaram de 0,114 a 0,956 — não existe um único número de estabilidade que cobre a "visibilidade da IA".
- As menções de marcas dentro do texto da resposta foram a camada menos confiável: de 137 observações de marca-por-célula, 44,5% apareceram em todas as cinco repetições e 24,8% apareceram em exatamente uma.
- As perguntas de pertencimento a conjuntos convergem rapidamente — três repetições recuperaram 83,1% dos domínios citados que cinco repetições encontraram — então uma auditoria de citação precisa de um punhado de execuções, não um quarto de capturas diárias.
- As perguntas de taxa convergem lentamente: com uma taxa de aparecimento observada de 40%, cinco execuções dão um intervalo de 95% 65 pontos de largura, e alcançar ±10 pontos leva aproximadamente 100 execuções por motor por prompt.
- A matriz inteira rodou dentro de 4 minutos e 9 segundos, então esses números medem apenas o não determinismo em nível de modelo; um programa que amostra ao longo dos dias deve esperar pelo menos esse tanto de movimento, nunca menos.
- Execute a mesma matriz contra seu próprio conjunto de prompts no plano gratuito do Scrapeless e obtenha seu próprio número em vez de pegar este.
Cada painel de visibilidade da IA relata um número. Participação de citação, participação de voz, rank de recomendação, sentimento — cada um chega como um número limpo com uma seta de tendência ao lado. Nenhum deles chega com uma barra de erro.
Essa omissão é mais importante aqui do que na busca clássica, porque a superfície que está sendo medida regenera sua resposta em cada solicitação. Pesquisadores que fixaram cinco modelos em configurações nominalmente determinísticas em oito tarefas ainda registraram oscilações de precisão de até 15% entre execuções, com a diferença entre a melhor e a pior execução possível alcançando 70%. Um modelo que não se repetirá quando solicitado também não lhe dará um número de visibilidade repetível a partir de uma captura.
O resto deste post dispara os mesmos prompts nos mesmos motores repetidamente, mantém cada entrada constante e mede quão longe as respostas realmente se movem. Esse movimento medido se converte então na única saída sobre a qual um programa de monitoramento pode agir — um número de execuções.
Pipeline em um Relance
O pipeline tem quatro estágios, e o último é o entregável:
capturar a matriz de repetição → reduzir cada resposta a camadas comparáveis → pontuar a estabilidade por célula → converter a estabilidade em um tamanho de amostra necessário
O Estágio 1 dispara um pedido idêntico muitas vezes por motor e armazena cada resposta bruta. O Estágio 2 despoja cada resposta em três coisas que podem ser comparadas entre repetições: o conjunto de domínios que citou, o texto da resposta, e quais nomes de lista de vigilância o texto menciona e em que ordem. O Estágio 3 mede quanto cada uma dessas três camadas se move entre repetições. O Estágio 4 pega o movimento medido e responde à pergunta que uma equipe de relatórios realmente tem, que é quantas capturas uma reivindicação precisa por trás dela.
Isso se assenta em um nível acima dos pipelines de captura dos quais depende. Se você ainda não construiu o lado de captura, o pipeline de participação de citação em seis motores de resposta da IA é a fundação; este post mede se a série que esse pipeline produz é legível no tamanho de amostra que você está utilizando.
O Que Essa Medida Responde
Quatro decisões mudam dependendo da resposta, e todas as quatro estão sendo tomadas hoje sem ela.
Se um movimento semana a semana é real. Um número de participação de citação que cai de 40% para 25% parece uma regressão. Com cinco execuções por célula, ambos os números estão dentro do mesmo intervalo de confiança, então a queda é indistinguível do motor regenerando sua resposta.
Quanto orçamento de captura um programa precisa. Tamanhos de amostra têm custos. Uma equipe que precisa de uma estimativa de taxa e uma equipe que precisa de um inventário de citações têm requisitos que diferem por mais de uma ordem de magnitude, e comprar o maior para ambos desperdiça a maior parte do orçamento.
Qual métrica construir em torno de um alvo. Algumas camadas de uma resposta da IA são estáveis o suficiente para definir um objetivo. Outras não são, e construir um OKR naquelas instáveis produz um quarto de ruído interpretado como progresso.
Qual motor ponderar. A estabilidade por motor varia em aproximadamente um fator de dois nesta matriz. Um motor cujas citações mal se movem oferece uma leitura utilizável a partir de algumas capturas; um motor que reordena precisa de várias vezes a amostragem para a mesma confiança.
O Design da Amostra, Declarado Desde o Começo
A matriz é composta por cinco motores, quatro prompts, cinco repetições: 100 capturas, com 20 células de motor-e-prompt contendo cinco repetições cada.
| Dimensão | Valor |
|---|---|
| Motores | Perplexity, Grok, Gemini, Google AI Mode, ChatGPT |
| Prompts | 4 perguntas de nível de categoria em uma categoria de produto |
| Repetições por célula | 5 |
| Capturas totais | 100 |
| País | Fixo em US em cada chamada |
| Modo de raciocínio Grok | Fixo em MODEL_MODE_FAST em cada chamada |
| Janela de captura | 4 minutos 9 segundos, sessão única |
| Impressões digitais de entrada distintas | 20 — uma por célula, compartilhada por suas 5 repetições |
Duas escolhas de design carregam o resultado. A primeira é que cada entrada é fixada: mesma string de prompt, mesmo país, mesmo modo de raciocínio, mesma bandeira de busca na web. Variar qualquer uma dessas misturaria as diferenças de entrada na variação e tornaria a medição sem sentido. A contagem de impressões digitais na Fase 1 existe para provar que a fixação se manteve.
A segunda é a janela comprimida. Todas as 100 capturas ocorreram dentro de quatro minutos. Isso é deliberado, e também é a limitação mais aguda de todo o exercício — veja a seção de limites antes de citar qualquer figura aqui.
Pré-requisitos
- Python 3.10 ou mais recente, apenas biblioteca padrão.
- Uma chave de API Scrapeless exportada como
SCRAPELESS_API_KEY. Os atores LLM Chat Scraper sob a API Universal Scraping colocam todos os cinco motores atrás de um único ponto final e um envelope de resposta, o que torna uma matriz entre motores prática. - Um arquivo
watchlist.txtcom um nome de marca por linha — sua própria marca e os nomes que você espera competir na categoria. Mantenha-o fora do controle de versão se a lista for sensível. - Aproximadamente 100 chamadas de ator com orçamento para uma primeira passada. O preço baseado no uso está na página de preços do 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 — Capturar a Matriz de Repetição
A Fase 1 dispara as cinco repetições de cada célula e escreve cada resposta bruta no disco sem alterações. Armazenar o envelope completo em vez de um resumo analisado é importante, porque as camadas que você deseja comparar não são óbvias até que você olhe a dispersão.
Cada motor recebe o mesmo prompt e country; apenas os extras exigidos pelo ator diferem, e cada extra é fixado para que não possa se desviar entre as repetições. As células são executadas simultaneamente porque uma passada serial sobre 100 capturas esticaria a janela e deixaria a deriva do mundo real vazar em uma medição que deveria excluí-la.
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")
A linha de impressões digitais é o cheque de honestidade. Vinte impressões digitais distintas em 100 capturas significam que as cinco repetições de cada célula foram solicitações idênticas em bytes, portanto, qualquer coisa que difira nas respostas veio do motor.
Fase 2 — Reduzir Cada Captura a Três Camadas Comparáveis
A Fase 2 achata cinco envelopes de resposta diferentes em uma forma de linha com três camadas de medição, porque "visibilidade de IA" não é uma quantidade e tratá-la como uma é onde o erro começa.
As três camadas respondem a perguntas diferentes e, como os resultados mostram, precisam de tamanhos de amostra diferentes:
| Camada | O que contém | A família métrica que alimenta |
|---|---|---|
| L1 citações | Conjunto de domínios registráveis que o motor citou | Participação da citação, gap de domínio citado |
| L2 prosa | O texto da resposta, como caracteres e como um conjunto de tokens | Sentimento, sumarização, diferenças de texto |
| L3 marcas | Quais nomes da lista de monitoramento o texto menciona, na ordem da primeira menção | Participação de voz, classificação de recomendação |
Cada motor relata suas fontes sob sua própria chave — Perplexity usa web_results, Grok chaves footnotes por ID de citação, Gemini e AI Mode usam citations, e o painel de pesquisa do ChatGPT chega como search_result. Normalizar para o host registrável elimina a diferença entre uma URL de artigo profundo e um link de homepage, que é o que uma métrica de participação de citação realmente conta.
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 — Medir a Estabilidade por Motor e Prompt
A Fase 3 mede o movimento dentro de cada célula e relata por motor em vez de agrupar, porque a figura agrupada oculta a coisa que você mais precisa saber.
Três estatísticas fazem o trabalho. Para as camadas de citação e prosa, o índice de Jaccard médio par a par nas cinco repetições — o tamanho da interseção sobre o tamanho da união, média sobre todos os dez pares em uma célula. Para o comprimento da resposta, o coeficiente de variação, que expressa o desvio padrão de uma dispersão medida como uma porcentagem da média para que respostas de diferentes comprimentos permaneçam comparáveis. Para marcas, a participação de nomes que apareceram em todas as cinco repetições em vez de algumas delas.
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 — Converter Estabilidade em um Tamanho de Amostra
A Fase 4 transforma a distribuição em uma contagem de execuções, e faz isso duas vezes porque os dois tipos de perguntas se comportam de maneira completamente diferente.
Para uma pergunta de membros do conjunto — quais domínios este mecanismo cita para a minha categoria — a saída útil é uma curva de cobertura: qual porcentagem dos domínios que cinco execuções revelam uma execução revela, ou duas, ou três. Isso é computado diretamente a partir das capturas ao subamostrar cada combinação de repetições.
Para uma pergunta de taxa — qual porcentagem de respostas menciona minha marca — a saída é um intervalo de confiança sobre uma proporção. O intervalo de Wilson é a ferramenta certa nesses tamanhos de amostra: a implementação de referência do NIST torna-o o método padrão para limites de confiança de proporção, e uma comparação sistemática entre tamanhos de amostra de 1 a 1.000 encontrou que o intervalo de Wilson supera o intervalo de Wald do livro didático, particularmente em n pequeno e em proporções próximas a 0 ou 1. Ambas as condições descrevem dados de menção de marca exatamente.
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")
O que a Matriz Realmente Mostrou
Tudo se moveu, e os mecanismos não se moveram na mesma medida.
| Mecanismo | Jaccard de domínio citado | Jaccard de token em prosa | CV de comprimento da resposta | Hosts citados em cada execução | Menções de marca estáveis |
|---|---|---|---|---|---|
| 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% |
Agrupando todos os 20 células, o Jaccard médio pareado em domínios citados foi 0.384. A dispersão em nível celular é a figura mais útil: 0.114 na extremidade baixa e 0.956 na extremidade alta. Uma reivindicação de estabilidade tirada de um mecanismo sobre um prompt pode cair em qualquer lugar nesse intervalo, que é precisamente o motivo pelo qual uma sondagem de três execuções em um único mecanismo é uma pista e não uma descoberta.
A curva de cobertura é o número que mais vale a pena ser registrado:
| Execuções | Parte da união de domínios citados de cinco execuções revelados |
|---|---|
| 1 | 49.6% |
| 2 | 70.3% |
| 3 | 83.1% |
| 4 | 92.3% |
| 5 | 100% |
Uma captura mostra cerca da metade dos domínios que cinco capturas mostram. Por mecanismo em n=1, o intervalo varia de 73.6% no Perplexity até 35.1% no ChatGPT, então uma auditoria de citação de captura única no mecanismo menos estável está perdendo cerca de dois terços do que se supõe inventariar. A curva também se achata rapidamente: a terceira execução adiciona 12.8 pontos, a quarta adiciona 9.2. Para um inventário de citações, três a quatro repetições compram a maior parte do que está disponível.
O Google AI Mode produziu de longe a maior união de domínios — 182 hosts distintos em quatro prompts, com apenas 11 aparecendo em todas as cinco repetições de sua célula. As próprias orientações do Google explicam o mecanismo: tanto o AI Mode quanto os AI Overviews podem usar uma técnica de dispersão de consulta que emite várias pesquisas relacionadas em subtemas e, portanto, podem revelar um conjunto de links mais amplo e variado do que a busca clássica. Quando um mecanismo é feito para espalhar suas citações em subtemas, uma captura amostra apenas parte dessa dispersão.
A camada de taxa conta uma história oposta. Em 137 observações por célula de marca, apenas 44.5% estavam presentes em todas as cinco repetições. 24.8% apareceram em exatamente uma das cinco — um nome que uma única captura relataría como uma presença confiante ou uma ausência confiante, dependendo inteiramente de qual captura você fez.
| Visto em | Casos | Parte | Intervalo de 95% sobre a taxa verdadeira | Largura |
|---|---|---|---|---|
| 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 |
Uma marca vista duas vezes em cinco execuções tem uma taxa de aparência verdadeira em algum lugar entre 12% e 77%, o que é largo demais para apoiar qualquer declaração em que um interessado possa agir. Ampliar a amostra a estreita lentamente:
| Execuções por célula | Intervalo de 95% a uma taxa observada de 40% | Largura |
|---|---|---|
| 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 |
| Assim, a resposta para "quantas execuções" é: depende de qual camada você está relatando, e as duas respostas diferem por mais de uma ordem de magnitude. Um inventário de citações é legível em três a quatro repetições. Uma taxa que você pretende comparar semana a semana precisa na ordem de 100 capturas por motor por prompt antes que o intervalo se estreite para ±10 pontos. Capturas diárias por duas a três semanas ficam em torno de 14 a 21 — confortavelmente suficiente para a pergunta definida, e cerca de cinco vezes abaixo para a pergunta de taxa. |
Dois resultados menores valem a pena serem registrados. O ranking mudou menos do que a menção: entre os nomes presentes em mais de uma repetição, a posição da primeira menção mudou em média 0,89 lugares no ChatGPT e 1,95 no Grok, portanto, uma métrica de rastreamento de ranking herda a instabilidade da menção, mas adiciona apenas um pouco da sua própria. E uma célula — um único motor no prompt do navegador em nuvem — não nomeou nenhuma marca da lista de vigilância em nenhuma de suas cinco repetições, respondendo em categorias de capacidade em vez de fornecedores. Uma ausência consistente é uma leitura estável também, e um monitor que trata um resultado vazio como uma captura falhada descartará sinal real.
A dispersão medida também alinha-se com pesquisas publicadas, em vez de contradizê-las. Um estudo sobre componentes de variância que decompôs 12.933 respostas de marcas LLM entre 20 marcas, 8 idiomas e 3 modelos descobriu que a reamostragem sozinha respondeu por 34,8% da variância total, com a confiabilidade de uma única resposta situada perto de 0,01. Esse estudo usou um corpus diferente e um método estatístico diferente e ainda assim chegou ao mesmo lugar: uma resposta carrega quase nenhum sinal que discrimine marcas.
Se você já está executando o pipeline de sentimento de marca por motor ou o rastreador de classificação de recomendações AI, ambos leem a camada de prosa e, portanto, herdam o tamanho de amostra que converge lentamente em vez do rápido.
Obter sua própria versão desta tabela leva cerca de cem chamadas. Comece no plano gratuito do Scrapeless e execute a matriz contra seus próprios prompts antes de definir um alvo em qualquer uma dessas métricas.
O Que Esta Medição Não Pode Dizer
A janela de captura comprimida é a limitação que governa todos os números acima. Todas as 100 capturas ocorreram dentro de 4 minutos e 9 segundos em um único dia. Isso isola uma fonte de movimento de forma limpa — o modelo regenerando sua resposta — e exclui várias outras completamente: atualizações de índice, ciclos de notícias, conteúdo que você publica, mudanças de versão do modelo e qualquer deriva genuína de dia para dia no que os motores recuperam.
A consequência corre em uma única direção. Esses números são um limite inferior, não uma estimativa da variância total. Um programa amostrando os mesmos prompts ao longo de semanas está exposto ao não determinismo em nível de modelo mais tudo o que a janela de quatro minutos manteve constante. Os tamanhos de amostra necessários para um programa de monitoramento real são, portanto, pelo menos deste tamanho, e a diferença entre um número de quatro minutos e um número de quatro semanas é, ela mesma, uma medição que ninguém aqui fez.
Quatro limites mais estreitos se aplicam:
- Vinte células é um design pequeno. Os números por motor são médias de quatro prompts, então o número de um motor não é uma estimativa precisa desse motor. A variação a nível de célula de 0,114 a 0,956 é o resumo honesto de quanto uma única célula pode diferir.
- Uma categoria, um idioma, um país. Todos os prompts estavam em uma categoria de produto, em inglês, vinculados a
US. O trabalho com componentes de variância citado acima descobriu que a linguagem da consulta carregava 26,5% da variância total, então não se deve assumir que uma linguagem diferente se comportará como esta. - O intervalo de Wilson assume sorteios independentes. Cinco solicitações disparadas simultaneamente em uma sessão podem compartilhar estado avançado, o que tornaria a amostra efetiva menor do que a nominal e os verdadeiros intervalos mais amplos do que a tabela mostra.
- A camada de marca depende da lista de vigilância. Apenas os nomes na lista são contados, portanto, um concorrente que você não listou é invisível para o L3, enquanto continua plenamente visível para o L1 se o motor cita seu domínio.
Nenhum desses quebra o resultado principal, que é uma comparação entre camadas medidas sob condições idênticas. Isso significa que as porcentagens específicas pertencem a esta matriz, não às respostas da IA em geral.
Colocando o Número em um Cronograma de Monitoramento
Programe os dois tipos de perguntas separadamente, pois executar uma cadência para ambos paga demais pela pergunta definida e não fornece energia suficiente para a pergunta de taxa.
Para inventário de citações, três a quatro repetições por motor por prompt, semanalmente. Isso recupera de 83% a 92% do universo de domínios citados por rodada de captura, e a diferença de semana para semana nesse conjunto é legível. Armazene a união por rodada em vez de uma lista de uma única execução; comparar duas execuções únicas gera mudanças que são principalmente reamostragens.
Para métricas de taxa — participação, participação de voz, participação de sentimento, classificação — acumule em vez de fazer um instantâneo. Vinte capturas por célula por semana fornecem um intervalo próximo a ±20 pontos em um número semanal e um número mensal agrupado próximo a ±10. Informe o intervalo próximo ao número toda vez. Um painel que mostra 42% sem mostrar 31%–50% está afirmando uma precisão que o design de captura não suporta.
Qualquer que seja a cadência que você escolher, fixe tudo. Mesmos strings de prompt, mesmo país, mesmo modo de raciocínio. A impressão digital de entrada da Fase 1 pertence às suas linhas armazenadas, para que um analista futuro possa distinguir uma mudança real de um prompt que alguém editou.
Re-meça quando um motor muda. A estabilidade é uma propriedade do modelo atual e do stack de recuperação, não uma constante. Quando um motor envia uma mudança visível, a contagem de execuções que foi suficiente no último trimestre torna-se uma hipótese novamente. A mesma disciplina se aplica aqui como em qualquer avaliação de modelo, onde curar um conjunto de dados representativo e escolher uma metodologia significativa vem antes da métrica, não depois.
Conclusão: Informe o Intervalo, Não Apenas o Número
A descoberta útil não é que as respostas de IA mudam. Todo guia já diz isso. A descoberta útil é que elas mudam em diferentes quantidades em diferentes camadas, e que o tamanho da amostra necessário se divide de acordo: um punhado de execuções para um inventário de citações, cerca de cem para uma taxa que você pretende defender em uma reunião.
O design por trás dessa divisão é quatro arquivos e cem chamadas. Capture com as entradas fixadas, reduza para camadas comparáveis, pontue o movimento, converta em uma contagem de execuções. Execute uma vez contra seu próprio conjunto de prompts e você para de adivinhar uma cadência, porque você terá o único número que cada painel de visibilidade de IA atualmente está perdendo — a barra de erro.
Pronto para Medir a Sua Própria Variação de Visibilidade de IA?
Cinco motores de resposta estão por trás de um único ponto de extremidade e uma única envelope de resposta na API de Extração Universal Scrapeless, que é o que torna uma matriz de cem capturas uma única tarde ao invés de cinco integrações separadas. Parâmetros e formas de resposta para cada ator usado aqui estão na documentação da API Scrapeless.
Crie uma conta gratuita no Scrapeless e coloque uma barra de erro em seus números de visibilidade.
FAQ
Q: Quantas execuções um número de visibilidade de IA realmente precisa?
Isso depende da camada, e as duas respostas diferem em mais de uma ordem de magnitude. Nesta matriz, três a quatro repetições por motor por prompt recuperaram 83% a 92% dos domínios citados que cinco repetições apareceram, então um inventário de citações é legível nesse tamanho de amostra. Uma métrica de taxa, como participação, precisa de aproximadamente 100 capturas por motor por prompt antes que um intervalo de 95% se estreite para cerca de ±10 pontos, e cinco capturas a deixam em torno de 65 pontos de largura.
Q: Por que as respostas de IA mudam quando o prompt e as configurações são idênticos?
Os modelos amostram de uma distribuição de probabilidade e a camada de recuperação que os alimenta também não está fixa, então entradas idênticas não garantem saídas idênticas. O trabalho que fixou cinco modelos em configurações nominalmente determinísticas em oito tarefas ainda registrou oscilações de precisão de até 15% entre execuções, e atribuiu o efeito a como os lotes de inferência são processados, em vez de a um erro de configuração.
Q: As fontes citadas são mais estáveis do que o texto da resposta?
Não de forma confiável, e não o suficiente para pular a reamostragem em qualquer camada. Os conjuntos de domínios citados nesta matriz se sobrepuseram com uma média pareada de Jaccard de 0.384, enquanto uma única captura trouxe apenas 49,6% dos domínios que cinco capturas trouxeram, então a camada de citação se move substancialmente em termos absolutos. Ela converge mais rápido do que uma métrica de taxa, o que é uma afirmação diferente de ser estável.
Q: O motor que acompanho muda quantas execuções eu preciso?
Sim, por aproximadamente um fator de dois na camada de citação. Uma única captura surfou 73,6% da união de domínio de cinco execuções no motor mais estável nesta matriz e 35,1% no menos estável, então uma contagem de execuções escolhida para um motor estará errada para outro. Calcule a curva de cobertura por motor em vez de aplicar uma figura uniformemente.
Q: Esta medida também avalia a variação dia a dia?
Não. Todas as 100 capturas foram realizadas dentro de 4 minutos e 9 segundos, o que isola a não determinismo em nível de modelo e exclui atualizações de índice, ciclos de notícias, mudanças de conteúdo e versões de modelo. Trate cada figura aqui como um valor mínimo: um programa amostrando ao longo de semanas carrega essa variação mais tudo o que a janela curta manteve constante.
Q: Capturar respostas de IA dessa forma é legal?
Capturar respostas de IA publicamente disponíveis para solicitações que você autoriza é uma coleta de dados ordinária da web pública, e as solicitações e respostas aqui não contêm dados pessoais. Mantenha o volume limitado e proporcional à medida, armazene apenas o que a análise necessita e verifique os termos que se aplicam à sua própria jurisdição e caso de uso antes de executar um programa em grande escala.
Q: Posso executar isso sem um agente de IA ou SDK?
Sim. Todos os scripts aqui utilizam a biblioteca padrão do Python contra um endpoint HTTPS, então todo o pipeline roda a partir de um trabalho cron ou um cronograma de CI sem nada instalado além do Python. A única dependência externa é a chave da API.
Na Scorretless, acessamos apenas dados disponíveis ao público, enquanto cumprem estritamente as leis, regulamentos e políticas de privacidade do site aplicáveis. O conteúdo deste blog é apenas para fins de demonstração e não envolve atividades ilegais ou infratoras. Não temos garantias e negamos toda a responsabilidade pelo uso de informações deste blog ou links de terceiros. Antes de se envolver em qualquer atividade de raspagem, consulte seu consultor jurídico e revise os termos de serviço do site de destino ou obtenha as permissões necessárias.



