AutoPodAutoPod

AI atsaukšanās ietekmes mērīšana: analītika, žurnāli un paneļu ielasīšana

•22 min lasīšanai
Audio raksts
AI atsaukšanās ietekmes mērīšana: analītika, žurnāli un paneļu ielasīšana
0:00—:—
AI atsaukšanās ietekmes mērīšana: analītika, žurnāli un paneļu ielasīšana

AI atsaukšanās ietekmes mērīšana: analītika, žurnāli un paneļu ielasīšana

Ievads

Mākslīgā intelekta (MI) virzīta atklāšana tagad ir sadalīta vairākos mērījumu slāņos. Persona var redzēt uzņēmumu, kas citēts MI atbildē, noklikšķināt uz saites bez noderīga atsauces avota, apmeklēt vietni caur pārlūkprogrammu, kas noņem kampaņas datus, vai lasīt atbildi, vispār neklikšķinot. Tikmēr MI pārlūks (crawler) var pieprasīt uzņēmuma lapu, nepārstāvot cilvēku apmeklētāju.

Tādēļ noderīgai mērījumu sistēmai ir jānošķir četri jautājumi:

  1. Vai vietne tika pārlūkota vai izgūta?
  2. Vai vietne tika citēta MI atbildē?
  3. Vai persona apmeklēja vietni no šīs atbildes?
  4. Vai šis apmeklējums radīja jēgpilnu iesaisti vai ieņēmumus?

Sākot ar 2026. gada 22. septembri, pirmo pušu ziņošana uzlabojas. Google Search Console nodrošina ģeneratīvā MI veiktspējas pārskatu MI pārskatiem un MI režīmam, ieskaitot seansus, lapas, valstis, ierīces un datumus. Pārskats kļuva pieejams visā pasaulē 2026. gada 31. augustā. Google ģeneratīvā MI veiktspējas pārskats (support.google.com)

Microsoft arī nodrošina MI veiktspējas pārskatu Bing Webmaster Tools. Tā publiskais priekšskatījums ziņo par kopējām atsaucēm, citētajām lapām, pamatā esošajiem vaicājumiem un citātu tendencēm visās atbalstītajās Microsoft MI pieredzēs. Bing Webmaster Tools MI veiktspēja (blogs.bing.com)

Šie rīki ir jāuzskata par autoritatīviem savām virsmām, taču tie nerada pilnīgu starp-asistentu mērījumu sistēmu. Ieteicamā pieeja ir apvienot pirmo pušu pārskatus, serveru žurnālus, kontrolētas izsekošanas saites, analītikas eksportus un plānotus atbildes paneļu novērojumus.


1. Kāpēc MI atsauču mērīšana ir sarežģīta

Tradicionālā tīmekļa analītika lielā mērā ir atkarīga no Referer galvenes un kampaņas parametriem. Abi var būt trūkstoši vai nepilnīgi.

HTTP Referer galvene var saturēt iepriekšējo lapu, tikai iepriekšējās vietnes izcelsmi vai vispār nekādu vērtību. Pārlūkprogrammas atsauces politikas var apzināti ierobežot vai noņemt šo informāciju. MDN Referrer-Policy dokumentācija (developer.mozilla.org)

MI sistēmas rada papildu sarežģījumus:

  • Asistents var saistīt lapu, nesūtot atpazīstamu atsauces avotu.
  • Asistents var izmantot pāradresējošu vai pārrakstītu URL.
  • Asistents var ielādēt saturu servera pusē pirms atbildes parādīšanas.
  • MI pārlūks var apmeklēt lapu, to neredzot nevienam cilvēkam.
  • Atbilde var citēt kanonisko URL, nevis sākotnēji izgūto URL.
  • Atbilde var mainīties atkarībā no atrašanās vietas, ierīces, valodas, laika vai personalizācijas.

Piemēram, OpenAI atšķir OAI-SearchBot meklēšanas atklāšanai, GPTBot iespējamai apmācībai un ChatGPT-User lietotāja ierosinātām darbībām. Perplexity atsevišķi identificē PerplexityBot un Perplexity-User. Anthropic identificē ClaudeBot, Claude-SearchBot un Claude-User. Šie pieprasījumi nedrīkst tikt apvienoti vienā vispārīgā “MI datplūsmas” skaitlī. OpenAI pārlūka dokumentācija (openai.com) Perplexity pārlūka dokumentācija (docs.perplexity.ai) Anthropic pārlūka dokumentācija (support.anthropic.com)

Centrālais noteikums ir:

Pārlūka aktivitāte nav novirzīšanas datplūsma, citātu redzamība nav datplūsma, un datplūsma nav biznesa ietekme.


2. Mērījumu sistēma

Izmantojiet piecus mērījumu slāņus.

SlānisGalvenais jautājumsIeteicamie dati
PiekļuveVai MI sistēma pieprasīja lapu?Tīmekļa servera žurnāli, ugunsmūra žurnāli
RedzamībaVai lapa tika parādīta vai citēta?Google Search Console, Bing Webmaster Tools, atbildes paneļu novērojumi
IegūšanaVai persona ieradās no MI virsmas?Atsauces avots, kampaņas parametri, īso saišu klikšķi, analītika
IesaisteVai apmeklētājs jēgpilni mijiedarbojās?Analītikas notikumi, lapu skatījumi, iesaistes laiks
VērtībaVai apmeklējums radīja vēlamo rezultātu?Reģistrācijas, potenciālie klienti, pirkumi, abonementi

Ieteicamā patiesības avota hierarhija

Izmantojiet spēcīgāko pieejamo signālu katram jautājumam:

  1. Pirmo pušu platformu pārskati par seansiem un atsaucēm.
  2. Atbildes paneļu novērojumi par redzamību pamudinājuma līmenī un konkurences salīdzinājumiem.
  3. Pāradresācijas žurnāli kontrolētiem saišu klikšķiem.
  4. Tīmekļa analītika sesijām, iesaistei un konversijām.
  5. Serveru žurnāli pārlūka un izguvēja aktivitātēm.
  6. Modelētas aplēses tikai tad, ja tieši pierādījumi nav pieejami.

Nekombinējiet visus signālus vienā skaitlī, nesaglabājot avotu un pārliecības līmeni.


3. Pamatdatu modelis

Izveidojiet datu noliktavu ar atsevišķām tabulām neapstrādātiem novērojumiem un atvasinātām metrikām.

panel_runs

Viena rinda katrai pamudinājuma un virsmas pārbaudei.

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

Viena rinda katrai atbildes panelī novērotajai saitei.

text run_id surface topic prompt_id cited_url cited_domain citation_position link_scope target_domain target_cited

ai_crawler_requests

Apkopoti servera žurnālu dati.

text date bot_name bot_role path requests successful_requests error_requests unique_ip_count

shortener_clicks

Viena rinda katram kontrolētās saites pieprasījumam.

text click_id occurred_at slug surface topic prompt_id asset_id referrer_host user_agent_family ip_hmac destination_path

ai_sessions

Normalizēta analītikas tabula.

text session_id date surface topic prompt_id landing_page attribution_method confidence engaged engagement_time_seconds key_event revenue

confidence lauks ir svarīgs. Ieteicamās vērtības ir:

  • A — Tieši: kontrolēts īssaites klikšķis vai uzticams kampaņas parametrs.
  • B — Spēcīgi: zināms asistenta atsauces avots vai verificēts lietotāja izgūšanas pieprasījums.
  • C — Iespējami: kampaņas vai galvenās lapas pierādījumi bez pilnīga atsauces avota.
  • D — Modelēti: secināti no laika, paneļu novērojumiem vai kopējām izmaiņām.

Ziņojiet par A un B atsevišķi no C un D.


4. Metriku definīcijas

Atsauču daļa pēc tēmas

Atsauču daļa pēc tēmas mēra, cik bieži mērķa domēns parādās starp tēmai novērotajiem avotiem.

[ \text{Citation Share}_{topic}

\frac{\text{Target-domain citation occurrences}} {\text{All citation occurrences}} ]

Piemērs:

  • 100 kopējās atsauces, kas novērotas par “projektu vadības programmatūru”
  • 12 atsauces norāda uz jūsu domēnu
  • Atsauču daļa pēc tēmas = 12%

Šī metrika mēra avotu daļu, nevis to, vai atbilde vismaz vienreiz saturēja jūsu vietni.

Atsauču aptvērums

Izmantojiet otru metriku atbildes līmeņa klātbūtnei:

[ \text{Citation Coverage}_{topic}

\frac{\text{Answer runs containing a target citation}} {\text{Answer runs where a panel was present}} ]

Atsauču aptvērums bieži ir vieglāk saprotams netehniskai auditorijai:

“Mūsu vietne parādījās 34% no novērotajām MI atbildēm par šo tēmu.”

Atsauces pozīcija

Ierakstiet atsauces pozīciju atbildē:

  • 1 = pirmais novērotais avots
  • 2 = otrais novērotais avots
  • 3 = trešais novērotais avots

Tā kā MI saskarnes bieži grupē vai pārkārto avotus, pozīcija jāuztver kā aprakstošs novērojums, nevis universāls rangs.


Asistenta novirzīšanas likme

Asistenta novirzīšanas likme mēra to cilvēku vietnes sesiju proporciju, ko var attiecināt uz MI virsmu.

[ \text{Assistant Referral Rate}

\frac{\text{AI-attributed human sessions}} {\text{All human sessions}} ]

Ziņojiet vismaz divas versijas:

text Apstiprināta asistenta novirzīšanas likme = A-pārliecības MI sesijas / visas cilvēku sesijas

Paplašināta asistenta novirzīšanas likme = A + B + C-pārliecības MI sesijas / visas cilvēku sesijas

Apstiprinātā versija ir konservatīvāka. Paplašinātā versija ir noderīga tendenču analīzei, taču to nevajadzētu pasniegt kā pilnībā novērotu datplūsmu.

Neizmantojiet paneļu palaišanas reizes kā seansus

Ja jūs ielasāt 500 pamudinājumus, tas nenozīmē, ka 500 cilvēki redzēja šīs atbildes. Jūsu ielasītājs mēra kontrolētu atbilžu stāvokļu paraugu. Izmantojiet pirmo pušu platformu seansu pārskatus, kad tie ir pieejami.


Iesaiste pēc citēšanas

Iesaiste pēc citēšanas mēra, vai cilvēki, kuri ieradās caur MI atsauci, veica jēgpilnu darbību.

[ \text{Post-Citation Engagement}

\frac{\text{Engaged AI sessions}} {\text{AI-attributed sessions}} ]

Google Analytics 4 gadījumā iesaistīta sesija ilgst vairāk nekā 10 sekundes, ietver galveno notikumu vai vismaz divus lapu vai ekrāna skatījumus. Google Analytics iesaistes likmes dokumentācija (support.google.com)

Ziņojiet arī:

text Iesaistes laiks pēc citēšanas = vidējais iesaistes sekunžu skaits vienā MI sesijā

Konversijas likme pēc citēšanas = MI sesijas ar galveno notikumu / MI attiecinātās sesijas

Ieņēmumi no sesijas pēc citēšanas = ieņēmumi no MI sesijām / MI attiecinātās sesijas

Vidējais iesaistes laiks parasti ir stabilāks nekā vidējais iesaistes laiks, jo neliels skaits ļoti garu sesiju var sagrozīt vidējo.


Papildu noderīgas metrikas

MI pārlūka veiksmes likme

[ \text{Crawler Success Rate}

\frac{\text{AI crawler requests returning 2xx or 3xx}} {\text{AI crawler requests}} ]

Sadalīt to pēc robota un ceļa. Liels atsauču samazinājums apvienojumā ar pieaugošu pārlūka kļūdu līmeni var norādīt uz mitināšanas, ugunsmūra vai robotu konfigurācijas problēmu.

Atsauces uz klikšķu likme

Kontrolētiem atbildes paneļu novērojumiem:

[ \text{Observed Citation-to-Click Rate}

\frac{\text{Confirmed short-link clicks}} {\text{Observed target citations}} ]

Šī nav patiesa lietotāju klikšķu caurlūkošanas likme, ja vien saucējs nepārstāv faktiskos lietotāju seansus. Skaidri apzīmējiet to kā novērotu operatīvo metriku.

Atsauču aktualitāte

Mēriet, cik bieži citētais URL atspoguļo pašreizējo lapas versiju.

text Citation Freshness = cited pages with current content hash / cited pages

Tas ir noderīgi dokumentācijai, cenu, produktu un politikas lapām, kas bieži mainās.


5. Servera žurnālu analīze

Konfigurēt strukturētus piekļuves žurnālus

Strukturētie žurnāli ir vieglāk analizējami nekā tradicionālie ar atstarpēm atdalītie žurnāli.

Piemērs Nginx konfigurācija:

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;

Glabājiet žurnālu failus ierobežotā vietā. Nesūtiet neapstrādātas IP adreses uz vispārēju analītikas tabulu, ja vien jums nav skaidra operatīva iemesla.

Identificēt MI pieprasījumu veidus

Minimāli, atdalīt:

text OpenAI:

  • OAI-SearchBot
  • ChatGPT-User
  • GPTBot

Anthropic:

  • Claude-SearchBot
  • Claude-User
  • ClaudeBot

Perplexity:

  • PerplexityBot
  • Perplexity-User

Meklētājprogrammas:

  • Googlebot
  • Bingbot

Google MI meklēšanas funkcijas parasti izmanto esošās Google meklēšanas pārlūkošanas vadības ierīces, nevis atsevišķu universālu “MI pārskatu robotu”. Google apgalvo, ka Googlebot kontrolē piekļuvi meklēšanai, tostarp MI funkcijām. Google MI funkcijas un vietnes (developers.google.com)

Lietotāja aģenta virknes var viltot. Operatīviem lēmumiem apvienojiet lietotāja aģenta saskaņošanu ar pakalpojumu sniedzēju publicētajiem IP diapazoniem vai verificētu apgriezto DNS, ja pieejams. OpenAI un Perplexity publicē IP informāciju par saviem attiecīgajiem pārlūkiem un izguvējiem. (openai.com)

Atkārtojams žurnālu apkopotājs

Saglabājiet sekojošo kā ai_log_summary.py.

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", "aizstājiet-šo-ražošanā").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("Lietojums: python ai_log_summary.py /ceļš/uz/access.jsonl") sys.exit(1)

main(sys.argv[1])

Palaidiet to ar:

bash HMAC_SECRET='garš-nejaušs-slepenais-teksts'
python ai_log_summary.py /var/log/nginx/ai-access.jsonl \

data/ai_crawler_daily.csv

Tas rada operatīvus pierādījumus par izguves aktivitāti, nevis cilvēku datplūsmu.


6. Pielāgoti saišu saīsinātāji MI vērstiem kopsavilkumiem

Pirmās puses saišu saīsinātājs nodrošina kontrolētu mērījumu punktu, publicējot kopsavilkumus vai avota materiālus, uz kuriem var atsaukties MI sistēmas.

Izmantojiet domēnu, ko kontrolējat, piemēram:

text https://go.example.com/ai-docs

Galamērķim jāietver kampaņas parametri, piemēram:

text utm_source=perplexity utm_medium=ai_answer utm_campaign=product_documentation utm_content=pricing_summary_v3

Google iesaka kampaņas parametrus datplūsmas avotu un kampaņu identificēšanai. Google Analytics kampaņas URL dokumentācija (support.google.com)

Ieteicamie saišu lauki

text surface topic prompt_id asset_id content_version destination_path

Neievietojiet personisko informāciju, e-pasta adreses vai lietotāju meklēšanas vaicājumus saitē. Kampaņas identifikatoriem jāapraksta publicētais resurss, nevis jāidentificē persona.

Svarīgi ierobežojumi

Īsa saite ir kalibrēšanas ierīce, nevis universāls risinājums:

  • Asistents var pārrakstīt mērķa URL.
  • Asistents tā vietā var citēt kanonisko URL.
  • Saite var tikt parādīta, bet nekad netikt noklikšķināta.
  • Pārlūkprogramma vai privātuma rīks var noņemt atsauces avotu.
  • Dažas sistēmas var izgūt galamērķi servera pusē.
  • Īsa saite nemēra lietotājus, kuri atceras zīmolu un atgriežas vēlāk.

Neizmantojiet saīsinātāju, lai paslēptu galamērķi, apietu drošības sistēmas vai manipulētu ar atsaucēm. Izmantojiet skaidru pāradresāciju uz atbilstošu, kanonisko lapu.

Minimāls pirmās puses saīsinātājs

Šis piemērs izmanto FastAPI un SQLite. Pirms lietošanas ražošanā aizsargājiet saišu izveides galapunktu ar autentifikāciju.

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", "aizstājiet-šo-ražošanā" ).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 jābūt vietnes relatīvam ceļam")

slug = secrets.token_urlsafe(7).replace("_", "-").replace("/", "-")

target = append_query(destination, {
    "utm_source": payload.surface,
    "utm_medium": "ai_answer",
    "utm_campaign": "atsauču_mērīšana",
    "utm_content": payload.asset_id or "nenorādīts",
})

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, "Nezināma saite")

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)

Palaidiet to ar:

bash pip install fastapi uvicorn uvicorn shortener:app --host 0.0.0.0 --port 8080

Izmantojiet 302 pāradresāciju mērījumu saitēm, lai pārlūkprogrammas un starpsistēmas retāk pastāvīgi kešotu pāradresāciju.


7. MI atbildes paneļu plānota ielasīšana

Paneļu ielasīšana ir noderīga, lai atbildētu uz jautājumiem, ko pirmo pušu analītika var neatklāt:

  • Kādi konkurējošie avoti tiek citēti?
  • Kura lapa tiek citēta konkrētam pamudinājumam?
  • Vai atbilde mainās atkarībā no valsts vai ierīces?
  • Vai atsauce parādās atbildē, avotu sarakstā vai abos?
  • Cik stabila ir atbilde laika gaitā?
  • Vai asistents citē īsu saiti vai kanonisko URL?

Tomēr ielasīšana jāveic uzmanīgi.

Atbildīgas datu vākšanas noteikumi

  1. Dodiet priekšroku oficiālai API, licencētam meklēšanas datu pakalpojumu sniedzējam vai pirmās puses pārskatam.
  2. Pirms pieprasījumu automatizēšanas pārskatiet pakalpojumu sniedzēja noteikumus.
  3. Ievērojiet robotu norādījumus, ja tie ir piemērojami.
  4. Neapiejiet CAPTCHA, pieteikšanās barjeras, likmju ierobežojumus vai botu aizsardzību.
  5. Izmantojiet nelielu, fiksētu pamudinājumu kopu.
  6. Palaidiet ar zemu frekvenci.
  7. Saglabājiet atbildi un laika zīmogu, lai rezultātus varētu pārbaudīt.
  8. Apstājieties, kad pakalpojumu sniedzējs atgriež izaicinājumu vai piekļuves lieguma atbildi.

Robots izslēgšanas protokols ir pārlūka preferenču mehānisms, nevis drošības sistēma. Tas neatļauj piekļuvi aizsargātam saturam. RFC 9309: Robots izslēgšanas protokols (rfc-editor.org)

Izveidot pamudinājumu manifestu

csv prompt_id,topic,query,locale,surface,target_domain pm_001,projektu-vadība,"labākā projektu vadības programmatūra attālinātām komandām",en-US,google,example.com pm_001,projektu-vadība,"labākā projektu vadības programmatūra attālinātām komandām",en-US,bing,example.com pm_002,analītika,"kā mērīt MI novirzīšanas datplūsmu",en-US,google,example.com

Uzturiet pamudinājumus stabilus. Ja pamudinājumi mainās, tendenču salīdzinājumi kļūst mazāk uzticami.

Saglabājiet arī:

  • valsts
  • valoda
  • ierīces tips
  • pārlūkprogrammas versija
  • pamudinājuma versija
  • satura versija
  • vākšanas laiks UTC

Google norāda, ka MI Pārskats un MI Režīms atbildes var atšķirties, jo tie izmanto dažādas sistēmas un var izmantot saistītus meklējumus vai “vaicājumu izvērsumu”. Google MI funkcijas un vietnes dokumentācija (developers.google.com)

Playwright vākšanas skripts

Šis skripts ir vispārējas nozīmes pētījumu rīks. Tas ieraksta renderēto lapu, ekrānuzņēmumu, lapas saites un atbildes tekstu. Tas apzināti neapiet izaicinājumus un nemēģina pārvarēt piekļuves kontroli.

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", "neparasta datplūsma", "pārbaudiet, vai esat cilvēks", "piekļuve liegta", ]

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()

            # Uzturēt zemu pieprasījumu apjomu.
            await asyncio.sleep(8)

    await browser.close()

if name == "main": asyncio.run(main("prompts.csv"))

Instalējiet un palaidiet:

bash pip install playwright playwright install chromium python scrape_panels.py

Ieplānojiet to ar bloķētāju, lai divi palaidieni nevarētu pārklāties:

cron 15 3 * * * flock -n /tmp/ai-panel.lock
/usr/bin/python3 /opt/ai-measure/scrape_panels.py

Uzlabojiet precizitāti ar virsmas adapteriem

Atkrituma skripts ieraksta lapas līmeņa saites. Tas ir noderīgi atklāšanai, bet var ietvert parastās meklēšanas rezultātu saites. Ražošanas vajadzībām:

  • Izmantojiet licencētu atbildes paneļa API, ja tā ir pieejama.
  • Izveidojiet atsevišķu selektora adapteri katrai virsmai.
  • Glabājiet selektora versiju.
  • Glabājiet neapstrādātu HTML un ekrānuzņēmumu.
  • Atzīmējiet katru ierakstu ar link_scope = "panel_selector" vai link_scope = "page_fallback".

Aprēķiniet atsauču daļu tikai no panel_selector datiem, ja varat droši identificēt paneli. Glabājiet atkrituma novērojumus atsevišķā izpētes ziņojumā.


8. Google Analytics un BigQuery integrācija

Google Analytics 4 var eksportēt neapstrādātus notikumu datus uz BigQuery. Ikdienas eksporti nodrošina stabilas tabulas, piemēram, events_YYYYMMDD; straumēšanas eksporti ir noderīgi gandrīz reāllaika uzraudzībai, taču tie var būt nepilnīgi, līdz ikdienas tabula ir pabeigta. Google Analytics BigQuery eksports (support.google.com)

Vienkāršots sesijas vaicājums varētu izskatīties šādi:

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;

Nobriedušai implementācijai pievienojiet surface, topic un prompt_id kampaņas struktūrai vai apvienojiet tos no saišu saīsinātāja klikšķu tabulas.

Neveidojiet augstas kardinalitātes analītikas dimensiju katram atsevišķam lietotājam vai sesijai. Google brīdina, ka pārmērīgas augstas kardinalitātes pielāgotās dimensijas var samazināt ziņošanas kvalitāti. Google Analytics pielāgotās dimensijas un metrikas (support.google.com)


9. Paneļa dizains

Praktiskam panelim jāsatur pieci skati.

Kopsavilkums vadībai

Parādīt:

  • Atsauču daļa pēc tēmas
  • Atsauču aptvērums pēc tēmas
  • Apstiprināta asistenta novirzīšanas likme
  • Paplašināta asistenta novirzīšanas likme
  • Iesaiste pēc citēšanas
  • MI pārlūka veiksmes likme
  • MI attiecinātie galvenie notikumi vai ieņēmumi

Atsauču daļas tendence

Līniju diagramma:

text Datums × Tēma × Virsma

Parādīt abus:

  • mērķa domēna atsauču gadījumi
  • visi novērotie atsauču gadījumi

Asistenta datplūsmas piltuve

text Novērotās atsauces ↓ Kontrolēto saišu klikšķi ↓ MI attiecinātās sesijas ↓ Iesaistītās MI sesijas ↓ Galvenie notikumi

Katram posmam jārāda tā atribūcijas pārliecība.

Pārlūka veselība

Tabula pēc robota:

text bot_name requests successful_requests error_rate unique_ip_count top_paths

Brīdināt, ja:

  • kļūdu līmenis pārsniedz 2 procentus
  • bots pēkšņi pazūd
  • iepriekš pieejama satura sadaļa atgriež 403 vai 429
  • pārlūka pieprasījumi koncentrējas uz neparedzētu privātu ceļu

Satura iespēju tabula

Rindojiet lapas un tēmas pēc:

text augsta atsauču daļa + zema novirzīšanas likme augsti seansi + zems atsauču aptvērums augsta iesaiste + zema atsauču redzamība augsts pārlūka kļūdu skaits + augsta biznesa nozīme

Šīs kombinācijas parasti nodrošina labākus lēmumus nekā tikai datplūsmas apjoma aplūkošana.

Minimāls Streamlit panelis

Saglabāt kā dashboard.py.

python import glob import json from pathlib import Path

import pandas as pd import streamlit as st

st.set_page_config( page_title="MI Atsauču Ietekme", 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("MI Atsauču Ietekmes Panelis")

if panels.empty: st.warning("Nav atrasti paneļu novērojumi.") 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("Atsauču daļa pēc tēmas") st.dataframe(citation_share, use_container_width=True) st.bar_chart( citation_share.set_index("topic")["citation_share"] )

with col2: st.subheader("Atsauču aptvērums pēc tēmas") st.dataframe(coverage, use_container_width=True) st.bar_chart( coverage.set_index("topic")["citation_coverage"] )

st.subheader("Atsauces pozīcija") 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("Ikdienas novērojumi") 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) )

Palaidiet to ar:

bash pip install streamlit pandas streamlit run dashboard.py

Ražošanā ielādējiet normalizētās tabulas DuckDB, BigQuery, Snowflake vai PostgreSQL, nevis lasiet neapstrādātus failus tieši.


10. Kvalitātes kontrole

Mērījumu sistēma var radīt precīzus, bet maldinošus skaitļus. Pievienojiet šīs kontroles.

Atdalīt robotus no cilvēkiem

Nekad neskaitiet OAI-SearchBot, GPTBot, ClaudeBot vai PerplexityBot kā cilvēku sesijas. Tie ir pārlūka vai izguves signāli.

Saglabāt neapstrādātus pierādījumus

Katram paneļa palaidienam saglabājiet:

  • neapstrādātu HTML
  • ekrānuzņēmumu
  • atbildes tekstu
  • laika zīmogu
  • pārlūkprogrammas un vācēja versiju
  • pamudinājumu un lokalizāciju
  • atbildes jaucējkodu

Tas ļauj izskaidrot, kāpēc metrika mainījās.

Izsekot paneļa neesamību

Trūkstošs MI panelis nav tas pats, kas atbilde bez jūsu atsauces.

Izmantojiet:

text panel_not_present panel_present_no_target panel_present_target_cited blocked_or_challenged collection_error

Kontrolēt izlases novirzes

Plānotu ielasīšanu ietekmē:

  • atrašanās vieta
  • ierīce
  • valoda
  • laiks
  • personalizācija
  • pārlūkprogrammas stāvoklis
  • pamudinājuma formulējums

Izmantojiet fiksētu pamata pamudinājumu kopu un rotējošu izpētes pamudinājumu kopu. Abas grupas atskaitēs saglabājiet atsevišķi.

Izvairīties no viltus precizitātes

Ziņojiet par ticamības intervāliem vai minimālajiem izlases lielumiem mazām tēmu grupām. Tēma ar trim novērojumiem nevajadzētu tieši salīdzināt ar tēmu, kas satur 300 novērojumus.

Salīdzināt līdzīgo ar līdzīgo

Salīdzinot virsmas, saglabājiet nemainīgus:

  • pamudinājums
  • lokalizācija
  • valsts
  • ierīce
  • vākšanas stunda
  • mērķa domēna noteikumi
  • atsauču parsētāja versija

11. Ieteicamais ieviešanas plāns

1. nedēļa: Instrumentēšana

  • Konfigurēt strukturētus servera žurnālus.
  • Izveidot robotu reģistru.
  • Izveidot saišu saīsinātāja domēnu.
  • Pievienot kampaņas nosaukšanas noteikumus.
  • Definēt tēmu taksonomiju.
  • Iespējot Google Analytics 4 BigQuery eksportu.

2. nedēļa: Kontrolētās saites

  • Publicēt piecus līdz desmit izsekotus kopsavilkumus.
  • Izveidot saites dažādām tēmām un satura versijām.
  • Validēt pāradresācijas žurnālus pret analītikas sesijām.
  • Apstiprināt, ka personiskā informācija netiek ievietota URL vai analītikas parametros.

3. nedēļa: Paneļu novērojumi

  • Izveidot pamudinājumu manifestu.
  • Sākt ar divām virsmām un 20 līdz 50 stabilām pamudinājumiem.
  • Palaist vienreiz dienā.
  • Saglabāt ekrānuzņēmumus un HTML.
  • Mērīt vākšanas kļūmes atsevišķi no atsauču neesamības.

4. nedēļa: Panelis un pārvaldība

  • Izveidot tēmu un virsmu paneļus.
  • Pievienot pārlūka veselības brīdinājumus.
  • Definēt pārliecības noteikumus.
  • Salīdzināt pirmo pušu pārskatus ar paneļu novērojumiem.
  • Dokumentēt datu saglabāšanas, piekļuves un dzēšanas politikas.

Secinājums

MI atsauču mērīšana jāveido kā daudzsignālu atribūcijas sistēma, nevis kā vienots novirzīšanas pārskats.

Visuzticamākā sistēma apvieno:

  • Google un Bing pirmo pušu redzamības pārskati
  • serveru žurnāli pārlūka un izguvēja aktivitātēm
  • pirmo pušu īsās saites kontrolētai klikšķu mērīšanai
  • plānoti, atbilstoši atbildes paneļu novērojumi
  • analītikas un konversiju dati par turpmāko vērtību

Trīs vissvarīgākās metrikas ir:

  1. Atsauču daļa pēc tēmas — cik liela daļa no novērotā avotu laukuma pieder jūsu domēnam.
  2. Asistenta novirzīšanas likme — cik liela cilvēku datplūsmas daļa var tikt attiecināta uz MI virsmām.
  3. Iesaiste pēc citēšanas — vai MI novirzītie apmeklētāji veic jēgpilnas darbības.

Sistēma kļūst noderīga, ja katrs skaitlis ietver tā virsmu, laika periodu, saucēju, atribūcijas metodi un pārliecības līmeni. Šāda disciplīna novērš to, ka pārlūka apmeklējumi tiek sajaukti ar lietotājiem, ielasītās atbildes — ar seansiem, un atsauces — ar biznesa rezultātiem.

Saistītie raksti

Patīk šis saturs?

Abonējiet mūsu biļetenu, lai saņemtu jaunākos satura mārketinga ieskatus un izaugsmes ceļvežus.

Šis raksts ir paredzēts tikai informatīviem nolūkiem. Saturs un stratēģijas var atšķirties atkarībā no jūsu specifiskajām vajadzībām.
AI atsaukšanās ietekmes mērīšana: analītika, žurnāli un paneļu ielasīšana | AutoPod