Az AI hivatkozási hatásának mérése: Analitika, naplók és panelkaparások
Bevezetés
Az AI-vezérelt felfedezés ma már több mérési réteg között oszlik meg. Egy személy láthat egy céget, amelyet egy AI-válaszban hivatkoznak, kattinthat egy linkre hasznos hivatkozó nélkül, látogathat egy kampányadatokat eltávolító böngészőn keresztül, vagy elolvashat egy választ anélkül, hogy rákattintana. Eközben egy AI-feltérképező kérheti a cég oldalát anélkül, hogy emberi látogatót képviselne.
Egy hasznos mérési rendszernek tehát négy kérdést kell elkülönítenie:
- Az oldalt feltérképezték vagy lekérdezték?
- Az oldalt hivatkozták egy AI-válaszban?
- Valaki meglátogatta az oldalt ebből a válaszból?
- Ez a látogatás értelmes elkötelezettséget vagy bevételt eredményezett?
2026. szeptember 22-től az elsődleges jelentések javulnak. A Google Search Console generatív AI teljesítményjelentést biztosít az AI áttekintésekhez és az AI módhoz, beleértve a megjelenítéseket, oldalakat, országokat, eszközöket és dátumokat. A jelentés 2026. augusztus 31-én vált elérhetővé világszerte. A Google generatív AI teljesítményjelentése (support.google.com)
A Microsoft is biztosít egy AI Teljesítmény jelentést a Bing Webmaster Tools-ban. Nyilvános előnézete összegzi az összes hivatkozást, hivatkozott oldalakat, alapozó lekérdezéseket és hivatkozási trendeket a támogatott Microsoft AI élmények között. Bing Webmaster Tools AI Teljesítmény (blogs.bing.com)
Ezeket az eszközöket saját felületeikre nézve hitelesnek kell tekinteni, de nem hoznak létre teljes, asszisztensen átívelő mérési rendszert. Az ajánlott megközelítés az elsődleges jelentések, szervernaplók, ellenőrzött nyomkövető linkek, analitikai exportok és ütemezett válaszpanel-megfigyelések kombinálása.
1. Miért nehéz az AI hivatkozási mérése
A hagyományos webanalitika nagymértékben függ a Referer fejléctől és a kampányparaméterektől. Mindkettő hiányozhat vagy hiányos lehet.
Az HTTP Referer fejléc tartalmazhatja az előző oldalt, csak az előző weboldal eredetét, vagy egyáltalán semmilyen értéket. A böngésző hivatkozó irányelvei szándékosan korlátozhatják vagy eltávolíthatják ezeket az információkat. MDN Referrer-Policy dokumentáció (developer.mozilla.org)
Az AI rendszerek további bonyodalmakat okoznak:
- Egy asszisztens hivatkozhat egy oldalra anélkül, hogy felismerhető hivatkozót küldene.
- Egy asszisztens átirányító vagy átírt URL-t használhat.
- Egy asszisztens szerveroldalról lekérheti a tartalmat, mielőtt választ mutatna.
- Egy AI feltérképező meglátogathat egy oldalt anélkül, hogy ember látná.
- A válasz kanonikus URL-t hivatkozhat az eredetileg lekérdezett URL helyett.
- A válasz változhat a hely, eszköz, nyelv, idő vagy személyre szabás függvényében.
Például az OpenAI megkülönbözteti az OAI-SearchBot-ot a keresési felfedezéshez, a GPTBot-ot a lehetséges képzési felhasználáshoz, és a ChatGPT-User-t a felhasználó által kezdeményezett műveletekhez. A Perplexity külön azonosítja a PerplexityBot-ot és a Perplexity-User-t. Az Anthropic azonosítja a ClaudeBot-ot, a Claude-SearchBot-ot és a Claude-User-t. Ezeket a kéréseket nem szabad egy általános „AI-forgalom” számba vonni. OpenAI feltérképező dokumentáció (openai.com) Perplexity feltérképező dokumentáció (docs.perplexity.ai) Anthropic feltérképező dokumentáció (support.anthropic.com)
A központi szabály a következő:
A feltérképező tevékenység nem hivatkozási forgalom, a hivatkozási láthatóság nem forgalom, és a forgalom nem üzleti hatás.
2. A mérési keretrendszer
Öt mérési réteget használjon.
| Réteg | Fő kérdés | Ajánlott adatok |
|---|---|---|
| Hozzáférés | Egy AI rendszer kérte az oldalt? | Webszerver naplók, tűzfal naplók |
| Láthatóság | Megjelent vagy hivatkozták az oldalt? | Google Search Console, Bing Webmaster Tools, válaszpanel-megfigyelések |
| Bevonás | Egy személy AI felületről érkezett? | Hivatkozó, kampányparaméterek, rövidített link kattintások, analitika |
| Elkötelezettség | Értelmesen interakcióba lépett a látogató? | Analitikai események, oldalmegtekintések, elkötelezettségi idő |
| Érték | A látogatás elérte a kívánt eredményt? | Feliratkozások, leadek, vásárlások, előfizetések |
Ajánlott „igazságforrás” hierarchia
Minden kérdésre a legerősebb elérhető jelet használja:
- Elsődleges platformjelentések a megjelenítésekhez és hivatkozásokhoz.
- Válaszpanel-megfigyelések a prompt-szintű láthatósághoz és versenytársi összehasonlításokhoz.
- Átirányítási naplók az ellenőrzött linkkattintásokhoz.
- Webanalitika a munkamenetekhez, elkötelezettséghez és konverziókhoz.
- Szervernaplók a feltérképező és lekérdező tevékenységhez.
- Modellezett becslések csak akkor, ha közvetlen bizonyíték nem áll rendelkezésre.
Ne kombinálja az összes jelet egyetlen számba anélkül, hogy megőrizné a forrást és a megbízhatósági szintet.
3. Alapvető adatmodell
Hozzon létre egy adattárat külön táblákkal a nyers megfigyelések és a származtatott metrikák számára.
panel_runs
Egy sor minden prompt és felület ellenőrzéshez.
text run_id observed_at surface topic prompt_id query_text locale country device panel_present panel_type answer_hash raw_html_path screenshot_path collector_version status
panel_citations
Egy sor minden válaszpanelben megfigyelt linkhez.
text run_id surface topic prompt_id cited_url cited_domain citation_position link_scope target_domain target_cited
ai_crawler_requests
Összesített szervernapló adatok.
text date bot_name bot_role path requests successful_requests error_requests unique_ip_count
shortener_clicks
Egy sor minden ellenőrzött link kéréshez.
text click_id occurred_at slug surface topic prompt_id asset_id referrer_host user_agent_family ip_hmac destination_path
ai_sessions
Normalizált analitikai táblázat.
text session_id date surface topic prompt_id landing_page attribution_method confidence engaged engagement_time_seconds key_event revenue
A confidence mező fontos. Ajánlott értékek:
- A — Közvetlen: ellenőrzött rövidített linkre kattintás vagy megbízható kampányparaméter.
- B — Erős: ismert asszisztens hivatkozó vagy ellenőrzött felhasználói lekérdezési kérés.
- C — Valószínű: kampány- vagy céloldal-bizonyíték teljes hivatkozó nélkül.
- D — Modellezett: időzítésből, panelmegfigyelésekből vagy aggregált változásokból következtetve.
Jelentse az A és B kategóriát külön C-től és D-től.
4. Metrika definíciók
Hivatkozási részesedés téma szerint
A témánkénti hivatkozási részesedés azt méri, hogy egy cél domain milyen gyakran jelenik meg az adott témához megfigyelt források között.
[ \text{Citation Share}_{topic}
\frac{\text{Target-domain citation occurrences}} {\text{All citation occurrences}} ]
Példa:
- 100 összes hivatkozás megfigyelve a „projektmenedzsment szoftverek” témában
- 12 hivatkozás mutat az Ön domainjére
- Hivatkozási részesedés téma szerint = 12%
Ez a metrika a forrás részesedését méri, nem azt, hogy egy válasz legalább egyszer tartalmazta-e az Ön oldalát.
Hivatkozási lefedettség
Használjon egy második metrikát a válaszszintű jelenlétre:
[ \text{Citation Coverage}_{topic}
\frac{\text{Answer runs containing a target citation}} {\text{Answer runs where a panel was present}} ]
A hivatkozási lefedettséget gyakran könnyebb megérteni a nem technikai közönség számára:
„Oldalunk az adott témára vonatkozó megfigyelt AI-válaszok 34%-ában jelent meg.”
Hivatkozási pozíció
Rögzítse egy hivatkozás pozícióját a válaszon belül:
1= első megfigyelt forrás2= második megfigyelt forrás3= harmadik megfigyelt forrás
Mivel az AI felületek gyakran csoportosítják vagy újrarendezik a forrásokat, a pozíciót leíró megfigyelésként kezelje, nem univerzális rangsorolásként.
Asszisztens Hivatkozási Arány
Az Asszisztens Hivatkozási Arány azt méri, hogy az emberi weboldal-munkamenetek hányad része tulajdonítható egy AI felületnek.
[ \text{Assistant Referral Rate}
\frac{\text{AI-attributed human sessions}} {\text{All human sessions}} ]
Jelentjen legalább két verziót:
text Confirmed Assistant Referral Rate = A-confidence AI sessions / all human sessions
Expanded Assistant Referral Rate = A + B + C-confidence AI sessions / all human sessions
A megerősített verzió konzervatívabb. A kibővített verzió hasznos a trendelemzéshez, de nem szabad teljes mértékben megfigyelt forgalomként bemutatni.
Ne használjon panel futásokat megjelenítésként
Ha 500 promptot kapar le, az nem jelenti azt, hogy 500 ember látta azokat a válaszokat. A kaparója a válaszállapotok ellenőrzött mintáját méri. Használjon elsődleges platform megjelenítési jelentéseket, amikor azok elérhetők.
Hivatkozás Utáni Elkötelezettség
A hivatkozás utáni elkötelezettség azt méri, hogy az AI hivatkozáson keresztül érkezett emberek tettek-e értelmes lépést.
[ \text{Post-Citation Engagement}
\frac{\text{Engaged AI sessions}} {\text{AI-attributed sessions}} ]
A Google Analytics 4 esetében egy elkötelezett munkamenet több mint 10 másodpercig tart, tartalmaz egy kulcseseményt, vagy legalább két oldal- vagy képernyőmegtekintést. Google Analytics elkötelezettségi arány dokumentáció (support.google.com)
Jelentse még:
text Post-Citation Engagement Time = median engaged seconds per AI session
Post-Citation Conversion Rate = AI sessions with a key event / AI-attributed sessions
Post-Citation Revenue per Session = revenue from AI sessions / AI-attributed sessions
A medián elkötelezettségi idő általában stabilabb, mint az átlagos elkötelezettségi idő, mert egy kis számú nagyon hosszú munkamenet torzíthatja az átlagot.
További hasznos metrikák
AI feltérképező sikerességi aránya
[ \text{Crawler Success Rate}
\frac{\text{AI crawler requests returning 2xx or 3xx}} {\text{AI crawler requests}} ]
Bontsa le bot és útvonal szerint. A magas hivatkozási csökkenés, növekvő feltérképező hibaaránnyal kombinálva, tárhely-, tűzfal- vagy robots konfigurációs problémát jelezhet.
Hivatkozásból kattintásra váltási arány
Ellenőrzött válaszpanel-megfigyelésekhez:
[ \text{Observed Citation-to-Click Rate}
\frac{\text{Confirmed short-link clicks}} {\text{Observed target citations}} ]
Ez nem valódi felhasználói átkattintási arány, hacsak a nevező nem a tényleges felhasználói megjelenítéseket képviseli. Egyértelműen címkézze meg megfigyelt működési metrikaként.
Hivatkozási frissesség
Mérje meg, hogy milyen gyakran tükrözi a hivatkozott URL az oldal aktuális verzióját.
text Citation Freshness = cited pages with current content hash / cited pages
Ez hasznos a gyakran változó dokumentációk, árazási, termék- és szabályzatoldalak esetében.
5. Szervernapló elemzés
Strukturált hozzáférési naplók konfigurálása
A strukturált naplók könnyebben elemezhetők, mint a hagyományos, szóközzel elválasztott naplók.
Példa Nginx konfiguráció:
nginx log_format ai_json escape=json '{' '"ts":"$time_iso8601",' '"remote_addr":"$remote_addr",' '"request":"$request",' '"status":$status,' '"bytes":$body_bytes_sent,' '"referer":"$http_referer",' '"user_agent":"$http_user_agent",' '"host":"$host"' '}';
access_log /var/log/nginx/ai-access.jsonl ai_json;
Tárolja a naplófájlokat korlátozott helyen. Ne küldjön nyers IP-címeket általános analitikai táblázatba, hacsak nincs világos működési oka.
AI kérés típusok azonosítása
Minimum különítse el:
text OpenAI:
- OAI-SearchBot
- ChatGPT-User
- GPTBot
Anthropic:
- Claude-SearchBot
- Claude-User
- ClaudeBot
Perplexity:
- PerplexityBot
- Perplexity-User
Search engines:
- Googlebot
- Bingbot
A Google AI keresési funkciói általában a meglévő Google Keresés feltérképezési vezérlőit használják, nem pedig egy külön univerzális „AI Overview botot”. A Google kijelenti, hogy a Googlebot vezérli a keresési hozzáférést, beleértve az AI funkciókat is. Google AI funkciók és weboldalak (developers.google.com)
A felhasználói ügynök (user-agent) stringek hamisíthatóak. Működési döntésekhez kombinálja a felhasználói ügynök egyeztetést a szolgáltató által közzétett IP-tartományokkal vagy ellenőrzött fordított DNS-sel, ahol elérhető. Az OpenAI és a Perplexity közzétesz IP-információkat releváns feltérképezőikhez és lekérdezőikhez. (openai.com)
Reprodukálható naplóösszegző
Mentse a következőket ai_log_summary.py néven.
python #!/usr/bin/env python3
import csv import hashlib import hmac import json import os import re import sys from collections import Counter, defaultdict from datetime import datetime from urllib.parse import urlsplit
BOT_PATTERNS = { "OAI-SearchBot": ("openai", re.compile(r"\bOAI-SearchBot\b", re.I)), "ChatGPT-User": ("openai_user", re.compile(r"\bChatGPT-User\b", re.I)), "GPTBot": ("openai_training", re.compile(r"\bGPTBot\b", re.I)), "Claude-SearchBot": ("anthropic", re.compile(r"\bClaude-SearchBot\b", re.I)), "Claude-User": ("anthropic_user", re.compile(r"\bClaude-User\b", re.I)), "ClaudeBot": ("anthropic_training", re.compile(r"\bClaudeBot\b", re.I)), "PerplexityBot": ("perplexity", re.compile(r"\bPerplexityBot\b", re.I)), "Perplexity-User": ("perplexity_user", re.compile(r"\bPerplexity-User\b", re.I)), "Googlebot": ("google_search", re.compile(r"\bGooglebot\b", re.I)), "Bingbot": ("bing_search", re.compile(r"\bbingbot\b", re.I)), }
SECRET = os.environ.get("HMAC_SECRET", "replace-this-in-production").encode()
def hmac_ip(ip): return hmac.new(SECRET, ip.encode(), hashlib.sha256).hexdigest()[:16]
def classify_bot(user_agent): for bot_name, (role, pattern) in BOT_PATTERNS.items(): if pattern.search(user_agent or ""): return bot_name, role return None, None
def parse_path(request_line): try: parts = request_line.split() return urlsplit(parts[1]).path except Exception: return "/"
def main(input_path): totals = defaultdict(lambda: { "requests": 0, "success": 0, "errors": 0, "ips": set(), "paths": Counter(), })
with open(input_path, "r", encoding="utf-8") as source:
for line in source:
try:
record = json.loads(line)
except json.JSONDecodeError:
continue
bot_name, bot_role = classify_bot(record.get("user_agent", ""))
if not bot_name:
continue
timestamp = record.get("ts", "")
date = datetime.fromisoformat(
timestamp.replace("Z", "+00:00")
).date().isoformat()
status = int(record.get("status", 0))
path = parse_path(record.get("request", ""))
key = (date, bot_name, bot_role)
totals[key]["requests"] += 1
totals[key]["ips"].add(hmac_ip(record.get("remote_addr", "")))
totals[key]["paths"][path] += 1
if 200 <= status < 400:
totals[key]["success"] += 1
else:
totals[key]["errors"] += 1
writer = csv.writer(sys.stdout)
writer.writerow([
"date",
"bot_name",
"bot_role",
"requests",
"successful_requests",
"error_requests",
"unique_ip_count",
"top_paths",
])
for (date, bot_name, bot_role), values in sorted(totals.items()):
top_paths = values["paths"].most_common(10)
writer.writerow([
date,
bot_name,
bot_role,
values["requests"],
values["success"],
values["errors"],
len(values["ips"]),
json.dumps(top_paths),
])
if name == "main": if len(sys.argv) != 2: print("Usage: python ai_log_summary.py /path/to/access.jsonl") sys.exit(1)
main(sys.argv[1])
Futtassa a következővel:
bash
HMAC_SECRET='a-long-random-secret'
python ai_log_summary.py /var/log/nginx/ai-access.jsonl \
data/ai_crawler_daily.csv
Ez lekérdezési tevékenységről szolgáltat működési bizonyítékokat, nem emberi forgalomról.
6. Egyedi linkrövidítők AI-közeli összefoglalókhoz
Egy elsődleges linkrövidítő ellenőrzött mérési pontot biztosít, amikor olyan összefoglalókat vagy forrásanyagokat tesz közzé, amelyekre AI rendszerek hivatkozhatnak.
Használjon egy Ön által ellenőrzött domaint, például:
text https://go.example.com/ai-docs
A célállomásnak tartalmaznia kell kampányparamétereket, például:
text utm_source=perplexity utm_medium=ai_answer utm_campaign=product_documentation utm_content=pricing_summary_v3
A Google kampányparamétereket ajánl a forgalmi források és kampányok azonosítására. Google Analytics kampány URL dokumentáció (support.google.com)
Ajánlott link mezők
text surface topic prompt_id asset_id content_version destination_path
Ne tegyen személyes adatokat, e-mail címeket vagy felhasználói keresési lekérdezéseket a linkbe. A kampányazonosítóknak a közzétett eszközt kell leírniuk, nem egy személyt azonosítani.
Fontos korlátozások
A rövidített link egy kalibrációs eszköz, nem univerzális megoldás:
- Az asszisztens átírhatja a cél URL-t.
- Az asszisztens helyette a kanonikus URL-t hivatkozhatja.
- A link megjelenhet, de soha nem kattintanak rá.
- Egy böngésző vagy adatvédelmi eszköz eltávolíthatja a hivatkozót.
- Egyes rendszerek szerveroldalról kérhetik le a célállomást.
- Egy rövidített link nem méri azokat a felhasználókat, akik emlékeznek a márkára és később visszatérnek.
Ne használjon rövidítőt a célállomás elrejtésére, biztonsági rendszerek megkerülésére vagy hivatkozások manipulálására. Használjon egyértelmű átirányítást egy releváns, kanonikus oldalra.
Minimális elsődleges rövidítő
Az alábbi példa FastAPI-t és SQLite-ot használ. Védje a linkkészítési végpontot hitelesítéssel, mielőtt éles környezetben használná.
python
shortener.py
import hashlib import hmac import os import secrets import sqlite3 from datetime import datetime, timezone from urllib.parse import parse_qsl, urlencode, urlsplit, urlunsplit
from fastapi import FastAPI, HTTPException, Request from fastapi.responses import RedirectResponse from pydantic import BaseModel
DB_PATH = os.environ.get("SHORTENER_DB", "shortener.db") HMAC_SECRET = os.environ.get( "HMAC_SECRET", "replace-this-in-production" ).encode()
ALLOWED_HOST = "www.example.com"
app = FastAPI()
def db(): connection = sqlite3.connect(DB_PATH) connection.row_factory = sqlite3.Row return connection
def init_db(): connection = db() connection.execute(""" CREATE TABLE IF NOT EXISTS links ( slug TEXT PRIMARY KEY, destination TEXT NOT NULL, surface TEXT NOT NULL, topic TEXT, prompt_id TEXT, asset_id TEXT, created_at TEXT NOT NULL ) """) connection.execute(""" CREATE TABLE IF NOT EXISTS clicks ( id INTEGER PRIMARY KEY AUTOINCREMENT, occurred_at TEXT NOT NULL, slug TEXT NOT NULL, surface TEXT, topic TEXT, prompt_id TEXT, referrer_host TEXT, user_agent TEXT, ip_hmac TEXT ) """) connection.commit() connection.close()
def append_query(url, params): parsed = urlsplit(url) query = dict(parse_qsl(parsed.query, keep_blank_values=True)) query.update(params) return urlunsplit(( parsed.scheme, parsed.netloc, parsed.path, urlencode(query), parsed.fragment, ))
def hash_ip(ip): return hmac.new( HMAC_SECRET, (ip or "").encode(), hashlib.sha256 ).hexdigest()[:16]
class LinkRequest(BaseModel): destination_path: str surface: str topic: str | None = None prompt_id: str | None = None asset_id: str | None = None
@app.on_event("startup") def startup(): init_db()
@app.post("/links") def create_link(payload: LinkRequest): destination = f"https://{ALLOWED_HOST}{payload.destination_path}"
if not payload.destination_path.startswith("/"):
raise HTTPException(400, "destination_path must be a site-relative path")
slug = secrets.token_urlsafe(7).replace("_", "-").replace("/", "-")
target = append_query(destination, {
"utm_source": payload.surface,
"utm_medium": "ai_answer",
"utm_campaign": "citation_measurement",
"utm_content": payload.asset_id or "unspecified",
})
connection = db()
connection.execute("""
INSERT INTO links
(slug, destination, surface, topic, prompt_id, asset_id, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (
slug,
target,
payload.surface,
payload.topic,
payload.prompt_id,
payload.asset_id,
datetime.now(timezone.utc).isoformat(),
))
connection.commit()
connection.close()
return {"slug": slug, "url": f"https://go.example.com/{slug}"}
@app.get("/{slug}") def redirect(slug: str, request: Request): connection = db() row = connection.execute( "SELECT * FROM links WHERE slug = ?", (slug,) ).fetchone()
if not row:
connection.close()
raise HTTPException(404, "Unknown link")
referrer = request.headers.get("referer", "")
referrer_host = urlsplit(referrer).hostname or ""
connection.execute("""
INSERT INTO clicks
(occurred_at, slug, surface, topic, prompt_id,
referrer_host, user_agent, ip_hmac)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
""", (
datetime.now(timezone.utc).isoformat(),
slug,
row["surface"],
row["topic"],
row["prompt_id"],
referrer_host,
request.headers.get("user-agent", "")[:300],
hash_ip(request.client.host if request.client else ""),
))
connection.commit()
connection.close()
return RedirectResponse(row["destination"], status_code=302)
Futtassa a következővel:
bash pip install fastapi uvicorn uvicorn shortener:app --host 0.0.0.0 --port 8080
Használjon 302-es átirányítást a mérési linkekhez, hogy a böngészők és a köztes rendszerek kisebb valószínűséggel gyorsítótárazzák az átirányítást véglegesen.
7. AI válaszpanelek ütemezett kaparása
A panelkaparás hasznos olyan kérdések megválaszolásához, amelyeket az elsődleges analitika nem feltétlenül tár fel:
- Melyik versengő forrásokat hivatkozzák?
- Melyik oldalt hivatkozzák egy adott prompt esetén?
- Változik-e a válasz ország vagy eszköz szerint?
- A hivatkozás megjelenik a válaszban, a forráslistában vagy mindkettőben?
- Mennyire stabil a válasz idővel?
- Az asszisztens rövidített linket vagy a kanonikus URL-t hivatkozza?
A kaparást azonban óvatosan kell végezni.
Felelősségteljes gyűjtés szabályai
- Előnyben részesítse a hivatalos API-t, licencelt keresési adatszolgáltatót vagy elsődleges jelentést.
- Tekintse át a szolgáltató feltételeit, mielőtt automatizálná a kéréseket.
- Tartsa tiszteletben a robots utasításokat, ahol alkalmazható.
- Ne kerülje meg a CAPTCHA-kat, bejelentkezési akadályokat, sebességkorlátokat vagy botvédelmet.
- Használjon kis, rögzített promptkészletet.
- Alacsony gyakorisággal futtassa.
- Mentse a választ és az időbélyeget, hogy az eredmények ellenőrizhetők legyenek.
- Álljon le, ha egy szolgáltató kihívást vagy hozzáférés megtagadása választ ad vissza.
A Robots Kizárási Protokoll egy feltérképező preferenciamechanizmus, nem biztonsági rendszer. Nem jogosít fel védett tartalomhoz való hozzáférésre. RFC 9309: Robots Kizárási Protokoll (rfc-editor.org)
Prompt Manifest készítése
csv prompt_id,topic,query,locale,surface,target_domain pm_001,project-management,"best project management software for remote teams",en-US,google,example.com pm_001,project-management,"best project management software for remote teams",en-US,bing,example.com pm_002,analytics,"how to measure AI referral traffic",en-US,google,example.com
Tartsa stabilan a promptokat. Ha a promptok változnak, a trendösszehasonlítások kevésbé lesznek megbízhatóak.
Tárolja még:
- ország
- nyelv
- eszköz típusa
- böngésző verziója
- prompt verziója
- tartalom verziója
- gyűjtési idő UTC-ben
A Google megjegyzi, hogy az AI Overview és az AI Mode válaszok eltérőek lehetnek, mert különböző rendszereket használnak, és kapcsolódó kereséseket vagy „lekérdezés szétterjedést” alkalmazhatnak. Google AI funkciók és weboldal dokumentáció (developers.google.com)
Playwright gyűjtő szkript
Az alábbi szkript egy általános célú kutatási eszköz. Rögzíti a renderelt oldalt, képernyőképet, oldallinkeket és válaszszöveget. Szándékosan nem kerüli meg a kihívásokat, és nem próbálja meg áthágni a hozzáférési vezérlőket.
python
scrape_panels.py
import asyncio import csv import hashlib import json import os import re from datetime import datetime, timezone from pathlib import Path from urllib.parse import quote_plus, urljoin, urlsplit
from playwright.async_api import async_playwright
DATA_DIR = Path("data/panels") DATA_DIR.mkdir(parents=True, exist_ok=True)
SURFACE_URLS = { "google": "https://www.google.com/search?q={query}&hl=en&gl=us", "bing": "https://www.bing.com/search?q={query}&setlang=en-us", }
PANEL_MARKERS = { "google": ["AI Overview", "AI Mode"], "bing": ["Copilot", "Generative search"], }
BLOCK_MARKERS = [ "captcha", "unusual traffic", "verify you are human", "access denied", ]
def clean_text(value): return re.sub(r"\s+", " ", value or "").strip()
def host_matches(url, target_domain): host = (urlsplit(url).hostname or "").lower() target = target_domain.lower().lstrip("www.") return host == target or host.endswith("." + target)
def page_hash(text): normalized = clean_text(text).encode("utf-8") return hashlib.sha256(normalized).hexdigest()
async def collect_one(page, row): surface = row["surface"] query = row["query"] target_domain = row["target_domain"]
search_url = SURFACE_URLS[surface].format(
query=quote_plus(query)
)
await page.goto(
search_url,
wait_until="domcontentloaded",
timeout=45_000,
)
await page.wait_for_timeout(2500)
text = await page.locator("body").inner_text()
lowered = text.lower()
if any(marker in lowered for marker in BLOCK_MARKERS):
return {
**row,
"observed_at": datetime.now(timezone.utc).isoformat(),
"status": "blocked_or_challenged",
"panel_present": False,
"links": [],
}
links = await page.locator("a").evaluate_all("""
anchors => anchors.map(a => ({
href: a.href || "",
text: (a.innerText || "").trim()
})).filter(x => x.href)
""")
panel_present = any(
marker.lower() in lowered
for marker in PANEL_MARKERS.get(surface, [])
)
observed_at = datetime.now(timezone.utc)
run_id = hashlib.sha256(
f"{surface}|{row['prompt_id']}|{observed_at.isoformat()}".encode()
).hexdigest()[:20]
html_path = DATA_DIR / f"{run_id}.html"
screenshot_path = DATA_DIR / f"{run_id}.png"
await page.screenshot(path=str(screenshot_path), full_page=True)
html_path.write_text(await page.content(), encoding="utf-8")
output_links = []
for position, link in enumerate(links, start=1):
output_links.append({
"href": urljoin(search_url, link["href"]),
"text": clean_text(link["text"])[:300],
"position": position,
"target_cited": host_matches(
link["href"],
target_domain
),
})
return {
**row,
"run_id": run_id,
"observed_at": observed_at.isoformat(),
"status": "ok",
"panel_present": panel_present,
"answer_hash": page_hash(text),
"answer_text": clean_text(text)[:50_000],
"html_path": str(html_path),
"screenshot_path": str(screenshot_path),
"link_scope": "page_fallback",
"links": output_links,
}
async def main(manifest_path): rows = [] with open(manifest_path, newline="", encoding="utf-8") as source: rows = list(csv.DictReader(source))
output_path = DATA_DIR / (
datetime.now(timezone.utc).strftime("%Y-%m-%d") + ".jsonl"
)
async with async_playwright() as playwright:
browser = await playwright.chromium.launch(headless=True)
context = await browser.new_context(
locale="en-US",
timezone_id="UTC",
)
page = await context.new_page()
with open(output_path, "w", encoding="utf-8") as output:
for row in rows:
try:
result = await collect_one(page, row)
except Exception as exc:
result = {
**row,
"observed_at": datetime.now(timezone.utc).isoformat(),
"status": f"error:{type(exc).__name__}",
"panel_present": False,
"links": [],
}
output.write(json.dumps(result) + "\\n")
output.flush()
# Keep request volume low.
await asyncio.sleep(8)
await browser.close()
if name == "main": asyncio.run(main("prompts.csv"))
Telepítse és futtassa:
bash pip install playwright playwright install chromium python scrape_panels.py
Ütemezze egy zárral, hogy két futás ne fedje át egymást:
cron
15 3 * * * flock -n /tmp/ai-panel.lock
/usr/bin/python3 /opt/ai-measure/scrape_panels.py
Pontosság javítása felületadapterekkel
A visszavonási szkript oldal szintű linkeket rögzít. Ez hasznos a felfedezéshez, de tartalmazhatja a szokásos keresési eredmények linkjeit is. Éles használatra:
- Használjon licencelt válaszpanel API-t, ha elérhető.
- Hozzon létre külön selector adaptert minden felülethez.
- Tárolja a selector verziót.
- Tárolja a nyers HTML-t és képernyőképet.
- Jelöljön meg minden rekordot
link_scope = "panel_selector"vagylink_scope = "page_fallback"értékkel.
Csak akkor számítsa ki a hivatkozási részesedést a panel_selector adatokból, ha megbízhatóan azonosítani tudja a panelt. A visszavonási megfigyeléseket tartsa külön, feltáró jellegű jelentésben.
8. Google Analytics és BigQuery Integráció
A Google Analytics 4 nyers eseményadatokat exportálhat a BigQuerybe. A napi exportok stabil táblázatokat biztosítanak, mint például az events_YYYYMMDD; a streaming exportok hasznosak a közel valós idejű monitorozáshoz, de hiányosak lehetnek, amíg a napi táblázat véglegesítésre nem kerül. Google Analytics BigQuery Export (support.google.com)
Egy egyszerűsített munkamenet-lekérdezés így nézhet ki:
sql WITH page_events AS ( SELECT event_date, user_pseudo_id,
(
SELECT value.int_value
FROM UNNEST(event_params)
WHERE key = 'ga_session_id'
) AS session_id,
(
SELECT value.string_value
FROM UNNEST(event_params)
WHERE key = 'page_location'
) AS page_location,
(
SELECT value.string_value
FROM UNNEST(event_params)
WHERE key = 'session_engaged'
) AS session_engaged,
event_name
FROM PROJECT.analytics_PROPERTY.events_*
WHERE _TABLE_SUFFIX BETWEEN '20260901' AND '20260921'
),
session_rollup AS ( SELECT event_date, user_pseudo_id, session_id,
MAX(
CASE
WHEN REGEXP_CONTAINS(
LOWER(page_location),
r'[?&]utm_medium=ai_answer'
)
THEN 1 ELSE 0
END
) AS ai_session,
MAX(
CASE
WHEN session_engaged = '1'
THEN 1 ELSE 0
END
) AS engaged_session,
MAX(
CASE
WHEN event_name IN ('purchase', 'generate_lead', 'sign_up')
THEN 1 ELSE 0
END
) AS key_event
FROM page_events GROUP BY event_date, user_pseudo_id, session_id )
SELECT event_date, COUNTIF(ai_session = 1) AS ai_sessions, COUNTIF(ai_session = 1 AND engaged_session = 1) AS engaged_ai_sessions, COUNTIF(ai_session = 1 AND key_event = 1) AS ai_key_events, SAFE_DIVIDE( COUNTIF(ai_session = 1 AND engaged_session = 1), COUNTIF(ai_session = 1) ) AS post_citation_engagement_rate FROM session_rollup GROUP BY event_date ORDER BY event_date;
Érett megvalósításhoz adja hozzá a surface, topic és prompt_id mezőket a kampánystruktúrához, vagy csatlakoztassa őket a rövidített link kattintási táblázatból.
Ne hozzon létre magas kardinalitású analitikai dimenziót minden egyes felhasználóhoz vagy munkamenethez. A Google figyelmeztet, hogy a túlzottan magas kardinalitású egyéni dimenziók csökkenthetik a jelentéskészítés minőségét. Google Analytics egyéni dimenziók és metrikák (support.google.com)
9. Irányítópult tervezés
Egy praktikus irányítópultnak öt nézetet kell tartalmaznia.
Vezetői összefoglaló
Megjelenítés:
- Hivatkozási részesedés téma szerint
- Hivatkozási lefedettség téma szerint
- Megerősített asszisztens hivatkozási arány
- Kiterjesztett asszisztens hivatkozási arány
- Hivatkozás Utáni Elkötelezettség
- AI feltérképező sikerességi aránya
- AI-nak tulajdonítható kulcsesemények vagy bevétel
Hivatkozási részesedés trend
Vonaldiagram:
text Date × Topic × Surface
Mutassa mindkettőt:
- cél domain hivatkozási előfordulásai
- összes megfigyelt hivatkozási előfordulás
Asszisztens forgalom tölcsér
text Observed citations ↓ Controlled-link clicks ↓ AI-attributed sessions ↓ Engaged AI sessions ↓ Key events
Minden szakaszban meg kell jeleníteni az attribúciós megbízhatóságot.
Feltérképező állapot
Táblázat bot szerint:
text bot_name requests successful_requests error_rate unique_ip_count top_paths
Riasztás, ha:
- a hibaarány meghaladja a 2 százalékot
- egy bot hirtelen eltűnik
- egy korábban elérhető tartalmi rész 403-at vagy 429-et ad vissza
- a feltérképező kérések egy nem szándékolt privát útvonalra koncentrálódnak
Tartalmi lehetőség táblázat
Rangsorolja az oldalakat és témákat a következő szerint:
text high citation share + low referral rate high impressions + low citation coverage high engagement + low citation visibility high crawler errors + high business importance
Ezek a kombinációk általában jobb döntéseket eredményeznek, mint kizárólag a forgalom volumenének vizsgálata.
Minimális Streamlit irányítópult
Mentse dashboard.py néven.
python import glob import json from pathlib import Path
import pandas as pd import streamlit as st
st.set_page_config( page_title="AI Citation Impact", layout="wide", )
@st.cache_data(ttl=300) def load_panel_rows(): rows = []
for filename in glob.glob("data/panels/*.jsonl"):
with open(filename, encoding="utf-8") as source:
for line in source:
record = json.loads(line)
run_id = record.get("run_id")
for link in record.get("links", []):
hostname = link.get("href", "").split("/")[2]
rows.append({
"run_id": run_id,
"observed_at": record.get("observed_at"),
"surface": record.get("surface"),
"topic": record.get("topic"),
"prompt_id": record.get("prompt_id"),
"panel_present": record.get("panel_present"),
"target_domain": record.get("target_domain"),
"cited_domain": hostname,
"target_cited": link.get("target_cited", False),
"position": link.get("position"),
"link_scope": record.get("link_scope"),
})
return pd.DataFrame(rows)
panels = load_panel_rows()
st.title("AI Citation Impact Dashboard")
if panels.empty: st.warning("No panel observations found.") st.stop()
panels["date"] = pd.to_datetime( panels["observed_at"], errors="coerce" ).dt.date
citation_share = ( panels.groupby("topic") .apply( lambda group: group["target_cited"].sum() / max(len(group), 1) ) .reset_index(name="citation_share") )
coverage = ( panels.groupby(["topic", "run_id"], dropna=False) .agg( panel_present=("panel_present", "max"), target_cited=("target_cited", "max"), ) .reset_index() )
coverage = ( coverage[coverage["panel_present"] == True] .groupby("topic") .apply(lambda group: group["target_cited"].mean()) .reset_index(name="citation_coverage") )
col1, col2 = st.columns(2)
with col1: st.subheader("Citation Share by Topic") st.dataframe(citation_share, use_container_width=True) st.bar_chart( citation_share.set_index("topic")["citation_share"] )
with col2: st.subheader("Citation Coverage by Topic") st.dataframe(coverage, use_container_width=True) st.bar_chart( coverage.set_index("topic")["citation_coverage"] )
st.subheader("Citation Position") st.dataframe( panels.groupby(["topic", "surface"], dropna=False) .agg( citations=("target_cited", "sum"), median_position=("position", "median"), observations=("run_id", "nunique"), ) .reset_index(), use_container_width=True, )
st.subheader("Daily Observations") daily = ( panels.groupby(["date", "surface"], dropna=False) .agg( citations=("target_cited", "sum"), observed_links=("cited_domain", "count"), ) .reset_index() )
st.line_chart( daily.pivot( index="date", columns="surface", values="citations" ).fillna(0) )
Futtassa a következővel:
bash pip install streamlit pandas streamlit run dashboard.py
Éles környezetben normalizált táblákat töltsön be DuckDB, BigQuery, Snowflake vagy PostgreSQL adatbázisokba a nyers fájlok közvetlen olvasása helyett.
10. Minőségellenőrzés
Egy mérési rendszer pontosnak tűnő, de félrevezető számokat produkálhat. Adja hozzá ezeket az ellenőrzéseket.
Bots és emberek elkülönítése
Soha ne számolja az OAI-SearchBot, GPTBot, ClaudeBot vagy PerplexityBot robotokat emberi munkamenetként. Ezek feltérképező vagy lekérdezési jelek.
Nyers bizonyítékok megőrzése
Minden panel futtatáshoz őrizze meg:
- nyers HTML
- képernyőfelvétel
- válasz szövege
- időbélyeg
- böngésző és gyűjtő verziója
- prompt és területi beállítás
- válasz hash
Ez lehetővé teszi annak magyarázatát, hogy egy metrika miért változott meg.
Panel hiányának nyomon követése
Egy hiányzó AI panel nem azonos egy olyan válasszal, amely nem tartalmazza az Ön hivatkozását.
Használja:
text panel_not_present panel_present_no_target panel_present_target_cited blocked_or_challenged collection_error
Mintavételi torzítás ellenőrzése
Az ütemezett kaparást befolyásolja:
- hely
- eszköz
- nyelv
- idő
- személyre szabás
- böngésző állapota
- prompt megfogalmazása
Használjon rögzített alap promptkészletet és egy forgó jellegű feltáró promptkészletet. Tartsa a két csoportot külön a jelentésekben.
Hamis pontosság elkerülése
Jelentse a konfidencia intervallumokat vagy minimális mintaméreteket kis témacsoportok esetén. Egy három megfigyeléssel rendelkező témát nem szabad közvetlenül összehasonlítani egy 300 megfigyelést tartalmazó témával.
Hasonlót hasonlóval összehasonlítani
Felületek összehasonlításakor tartsa állandóan:
- prompt
- területi beállítás
- ország
- eszköz
- gyűjtés órája
- cél domain szabályai
- hivatkozás elemző verziója
11. Ajánlott bevezetési terv
1. hét: Eszközölés
- Strukturált szervernaplók konfigurálása.
- Botregiszter létrehozása.
- Rövidítő domain létrehozása.
- Kampány elnevezési szabályok hozzáadása.
- Téma taxonómia definiálása.
- Google Analytics 4 BigQuery export engedélyezése.
2. hét: Ellenőrzött linkek
- Tegyen közzé öt-tíz nyomon követett összefoglalót.
- Hozzon létre linkeket különböző témákhoz és tartalmi verziókhoz.
- Érvényesítse az átirányítási naplókat az analitikai munkamenetekkel szemben.
- Győződjön meg róla, hogy személyes adatok nem kerülnek URL-ekbe vagy analitikai paraméterekbe.
3. hét: Panelmegfigyelések
- Hozzon létre egy prompt manifestet.
- Kezdje két felülettel és 20-50 stabil prompttal.
- Futtassa naponta egyszer.
- Mentse a képernyőképeket és a HTML-t.
- Mérje a gyűjtési hibákat külön a hivatkozások hiányától.
4. hét: Irányítópult és irányítás
- Építsen téma- és felületirányítópultokat.
- Adjon hozzá feltérképező állapotriasztásokat.
- Határozza meg a megbízhatósági szabályokat.
- Hasonlítsa össze az elsődleges jelentéseket a panelmegfigyelésekkel.
- Dokumentálja az adatmegőrzési, hozzáférési és törlési szabályzatokat.
Összefoglalás
Az AI hivatkozásmérést többjeles attribúciós rendszerként kell felépíteni, nem pedig egyetlen hivatkozási jelentésként.
A legmegbízhatóbb keretrendszer egyesíti:
- Google és Bing elsődleges láthatósági jelentések
- szervernaplók a feltérképező és lekérdező tevékenységhez
- elsődleges rövidített linkek az ellenőrzött kattintásméréshez
- ütemezett, szabályszerű válaszpanel-megfigyelések
- analitikai és konverziós adatok a későbbi értékhez
A három legfontosabb metrika:
- Hivatkozási részesedés téma szerint — a megfigyelt forrástér mekkora része tartozik az Ön domainjéhez.
- Asszisztens Hivatkozási Arány — mennyi emberi forgalom tulajdonítható AI felületeknek.
- Hivatkozás Utáni Elkötelezettség — tesznek-e értelmes lépéseket az AI-ról érkezett látogatók.
A rendszer akkor válik hasznossá, ha minden szám tartalmazza a felületét, időszakát, nevezőjét, attribúciós módszerét és megbízhatósági szintjét. Ez a fegyelem megakadályozza, hogy a feltérképező találatokat felhasználóknak, a kapart válaszokat megjelenítéseknek, és a hivatkozásokat üzleti eredményeknek tévesszék.
Auto