AutoPodAutoPod

Yapay Zeka Atıf Etkisini Ölçme: Analizler, Loglar ve Panel Kazımaları

•22 dk okuma
Sesli Makale
Yapay Zeka Atıf Etkisini Ölçme: Analizler, Loglar ve Panel Kazımaları
0:00—:—
Yapay Zeka Atıf Etkisini Ölçme: Analizler, Loglar ve Panel Kazımaları

Yapay Zeka Atıf Etkisini Ölçme: Analizler, Loglar ve Panel Kazımaları

Giriş

Yapay zeka destekli keşif artık birden fazla ölçüm katmanına yayılmış durumda. Bir kişi yapay zeka yanıtında alıntılanan bir şirket görebilir, yararlı bir yönlendirici (referrer) olmayan bir bağlantıya tıklayabilir, kampanya verilerini kaldıran bir tarayıcı aracılığıyla ziyaret edebilir veya hiç tıklamadan bir yanıtı okuyabilir. Bu arada, bir yapay zeka tarayıcısı insan bir ziyaretçiyi temsil etmeden şirketin sayfasını isteyebilir.

Faydalı bir ölçüm sistemi bu nedenle dört soruyu birbirinden ayırmalıdır:

  1. Site tarandı mı yoksa alındı mı?
  2. Site bir yapay zeka yanıtında alıntılandı mı?
  3. Bir kişi o yanıttan siteyi ziyaret etti mi?
  4. Bu ziyaret anlamlı bir etkileşim veya gelir sağladı mı?

22 Eylül 2026 itibarıyla, birinci taraf raporlaması gelişmektedir. Google Search Console, gösterimler, sayfalar, ülkeler, cihazlar ve tarihler dahil olmak üzere Yapay Zeka Genel Bakışları ve Yapay Zeka Modu için bir Üretken Yapay Zeka performansı raporu sunmaktadır. Rapor 31 Ağustos 2026 tarihinde dünya çapında kullanıma sunulmuştur. Google'ın Üretken Yapay Zeka performansı raporu (support.google.com)

Microsoft ayrıca Bing Webmaster Tools'ta bir Yapay Zeka Performansı raporu sunmaktadır. Genel önizlemesi, desteklenen Microsoft yapay zeka deneyimlerinde toplam atıfları, alıntılanan sayfaları, temel sorguları ve atıf eğilimlerini raporlar. Bing Webmaster Tools Yapay Zeka Performansı (blogs.bing.com)

Bu araçlar kendi yüzeyleri için yetkili kabul edilmelidir, ancak eksiksiz bir asistanlar arası ölçüm sistemi oluşturmazlar. Önerilen yaklaşım, birinci taraf raporları, sunucu logları, kontrollü takip bağlantıları, analiz dışa aktarımları ve planlanmış yanıt-panel gözlemlerini birleştirmektir.


1. Yapay Zeka Yönlendirme Ölçümü Neden Zordur

Geleneksel web analizleri, Referer başlığına ve kampanya parametrelerine büyük ölçüde bağlıdır. Her ikisi de eksik veya eksik olabilir.

HTTP Referer başlığı, önceki sayfayı, yalnızca önceki web sitesi kaynağını veya hiçbir değeri içermeyebilir. Tarayıcı yönlendirici politikaları bu bilgiyi kasıtlı olarak sınırlayabilir veya kaldırabilir. MDN Referrer-Policy belgeleri (developer.mozilla.org)

Yapay zeka sistemleri ek komplikasyonlar yaratır:

  • Bir asistan, tanınabilir bir yönlendirici göndermeden bir sayfaya bağlantı verebilir.
  • Bir asistan, yönlendiren veya yeniden yazılan bir URL kullanabilir.
  • Bir asistan, bir yanıt göstermeden önce içeriği sunucu tarafında çekebilir.
  • Bir yapay zeka tarayıcısı, herhangi bir insan görmeden bir sayfayı ziyaret edebilir.
  • Yanıt, orijinal olarak alınan URL yerine bir kanonik URL'yi alıntılayabilir.
  • Yanıt, konuma, cihaza, dile, zamana veya kişiselleştirmeye bağlı olarak değişebilir.

Örneğin, OpenAI arama keşfi için OAI-SearchBot'u, olası eğitim kullanımı için GPTBot'u ve kullanıcı tarafından başlatılan eylemler için ChatGPT-User'ı birbirinden ayırır. Perplexity, PerplexityBot ve Perplexity-User'ı ayrı ayrı tanımlar. Anthropic, ClaudeBot, Claude-SearchBot ve Claude-User'ı tanımlar. Bu istekler tek bir genel “Yapay Zeka trafiği” sayısına birleştirilmemelidir. OpenAI tarayıcı belgeleri (openai.com) Perplexity tarayıcı belgeleri (docs.perplexity.ai) Anthropic tarayıcı belgeleri (support.anthropic.com)

Merkezi kural şudur:

Tarayıcı etkinliği yönlendirme trafiği değildir, atıf görünürlüğü trafik değildir ve trafik iş etkisi değildir.


2. Ölçüm Çerçevesi

Beş ölçüm katmanı kullanın.

KatmanAna soruÖnerilen veri
ErişimBir yapay zeka sistemi sayfayı istedi mi?Web sunucusu logları, güvenlik duvarı logları
GörünürlükSayfa gösterildi mi yoksa alıntılandı mı?Google Search Console, Bing Webmaster Tools, yanıt paneli gözlemleri
EdinmeBir kişi bir yapay zeka yüzeyinden mi geldi?Yönlendirici, kampanya parametreleri, kısa bağlantı tıklamaları, analizler
EtkileşimZiyaretçi anlamlı bir şekilde etkileşim kurdu mu?Analiz olayları, sayfa görüntülemeleri, etkileşim süresi
DeğerZiyaret istenen bir sonuç verdi mi?Kayıtlar, potansiyel müşteriler, satın almalar, abonelikler

Önerilen doğruluk kaynağı hiyerarşisi

Her soru için mevcut en güçlü sinyali kullanın:

  1. Gösterimler ve atıflar için birinci taraf platform raporları.
  2. İstem düzeyinde görünürlük ve rekabetçi karşılaştırmalar için yanıt paneli gözlemleri.
  3. Kontrollü bağlantı tıklamaları için yönlendirme logları.
  4. Oturumlar, etkileşim ve dönüşümler için web analizleri.
  5. Tarayıcı ve getirme etkinliği için sunucu logları.
  6. Yalnızca doğrudan kanıt bulunmadığında modellenmiş tahminler.

Tüm sinyalleri, kaynak ve güven düzeyini korumadan tek bir sayıda birleştirmeyin.


3. Temel Veri Modeli

Ham gözlemler ve türetilmiş metrikler için ayrı tablolar içeren bir veri ambarı oluşturun.

panel_runs

Her istem ve yüzey kontrolü için bir satır.

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

Bir yanıt panelinde gözlemlenen her bağlantı için bir satır.

text run_id surface topic prompt_id cited_url cited_domain citation_position link_scope target_domain target_cited

ai_crawler_requests

Toplu sunucu logu verileri.

text date bot_name bot_role path requests successful_requests error_requests unique_ip_count

shortener_clicks

Her kontrollü bağlantı isteği için bir satır.

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

ai_sessions

Normalleştirilmiş bir analiz tablosu.

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

confidence alanı önemlidir. Önerilen değerler şunlardır:

  • A — Doğrudan: kontrollü kısa bağlantı tıklaması veya güvenilir kampanya parametresi.
  • B — Güçlü: bilinen asistan yönlendirici veya doğrulanmış kullanıcı getirme isteği.
  • C — Muhtemel: eksiksiz bir yönlendirici olmadan kampanya veya açılış sayfası kanıtı.
  • D — Modellenmiş: zamanlamadan, panel gözlemlerinden veya toplu değişikliklerden çıkarılmıştır.

A ve B'yi C ve D'den ayrı olarak raporlayın.


4. Metrik Tanımları

Konuya Göre Atıf Payı

Konuya Göre Atıf Payı, hedeflenen bir alan adının bir konu için gözlemlenen kaynaklar arasında ne sıklıkta göründüğünü ölçer.

\[ \text{Citation Share}_{topic}

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

Örnek:

  • "proje yönetim yazılımı" için gözlemlenen toplam 100 atıf
  • 12 atıf alan adınıza işaret ediyor
  • Konuya Göre Atıf Payı = %12

Bu metrik, bir yanıtın sitenizi en az bir kez içerip içermediğini değil, kaynak payını ölçer.

Atıf Kapsamı

Yanıt düzeyinde varlık için ikinci bir metrik kullanın:

\[ \text{Citation Coverage}_{topic}

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

Atıf Kapsamı genellikle teknik olmayan kitleler için anlaşılması daha kolaydır:

“Sitemiz, bu konu için gözlemlenen yapay zeka yanıtlarının %34'ünde yer aldı.”

Atıf Konumu

Bir atıfın yanıttaki konumunu kaydedin:

  • 1 = ilk gözlemlenen kaynak
  • 2 = ikinci gözlemlenen kaynak
  • 3 = üçüncü gözlemlenen kaynak

Yapay zeka arayüzleri genellikle kaynakları gruplandırdığı veya yeniden sıraladığı için, konumu evrensel bir sıralama değil, açıklayıcı bir gözlem olarak ele alın.


Asistan Yönlendirme Oranı

Asistan Yönlendirme Oranı, yapay zeka yüzeylerine atfedilebilen insan site oturumlarının oranını ölçer.

\[ \text{Assistant Referral Rate}

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

En az iki sürüm raporlayın:

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

Onaylanmış sürüm daha muhafazakârdır. Genişletilmiş sürüm, trend analizi için yararlıdır ancak tam olarak gözlemlenmiş trafik olarak sunulmamalıdır.

Panel çalıştırmalarını gösterim olarak kullanmayın

500 istemi kazımanız, 500 kişinin bu yanıtları gördüğü anlamına gelmez. Kazıyıcınız, yanıt durumlarının kontrollü bir örneğini ölçer. Birinci taraf platform gösterim raporları mevcut olduğunda bunları kullanın.


Atıf Sonrası Etkileşim

Atıf Sonrası Etkileşim, bir yapay zeka atıfı aracılığıyla gelen kişilerin anlamlı bir eylemde bulunup bulunmadığını ölçer.

\[ \text{Post-Citation Engagement}

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

Google Analytics 4 için, etkileşimli bir oturum 10 saniyeden uzun sürer, önemli bir olay içerir veya en az iki sayfa veya ekran görüntülemesi içerir. Google Analytics etkileşim oranı belgeleri (support.google.com)

Ayrıca raporlayın:

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

Medyan etkileşim süresi, ortalama etkileşim süresinden genellikle daha kararlıdır, çünkü çok uzun süreli az sayıda oturum ortalamayı bozabilir.


Ek Faydalı Metrikler

Yapay Zeka Tarayıcısı Başarı Oranı

\[ \text{Crawler Success Rate}

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

Bunu bot ve yola göre ayırın. Yüksek atıf düşüşü ile artan bir tarayıcı hata oranı, bir barındırma, güvenlik duvarı veya robots yapılandırma sorununu işaret edebilir.

Atıftan Tıklama Oranı

Kontrollü yanıt paneli gözlemleri için:

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

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

Bu, payda gerçek kullanıcı gösterimlerini temsil etmediği sürece gerçek bir kullanıcı tıklama oranı değildir. Bunu açıkça gözlemlenmiş bir operasyonel metrik olarak etiketleyin.

Atıf Güncelliği

Alıntılanan URL'nin mevcut sayfa sürümünü ne sıklıkla yansıttığını ölçün.

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

Bu, sık sık değişen dokümantasyon, fiyatlandırma, ürün ve politika sayfaları için faydalıdır.


5. Sunucu Logu Analizi

Yapılandırılmış Erişim Loglarını Yapılandırma

Yapılandırılmış loglar, geleneksel boşlukla ayrılmış loglardan daha kolay analiz edilir.

Örnek Nginx yapılandırması:

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;

Log dosyalarını kısıtlı bir konumda saklayın. Açık bir operasyonel nedeniniz yoksa ham IP adreslerini genel bir analiz tablosuna göndermeyin.

Yapay Zeka İstek Türlerini Belirleme

En azından şunları ayırın:

text OpenAI:

  • OAI-SearchBot
  • ChatGPT-User
  • GPTBot

Anthropic:

  • Claude-SearchBot
  • Claude-User
  • ClaudeBot

Perplexity:

  • PerplexityBot
  • Perplexity-User

Search engines:

  • Googlebot
  • Bingbot

Google'ın Yapay Zeka Arama özellikleri genellikle ayrı bir evrensel "Yapay Zeka Genel Bakış botu" yerine mevcut Google Arama tarama kontrollerini kullanır. Google, Googlebot'un yapay zeka özelliklerini içeren Arama'ya erişimi kontrol ettiğini belirtir. Google Yapay Zeka özellikleri ve web siteleri (developers.google.com)

Kullanıcı-aracı (User-agent) dizeleri sahte olabilir. Operasyonel kararlar için, kullanıcı-aracı eşleştirmesini sağlayıcı tarafından yayınlanan IP aralıkları veya mevcut olduğunda doğrulanmış ters DNS ile birleştirin. OpenAI ve Perplexity, ilgili tarayıcıları ve getiricileri için IP bilgilerini yayınlar. (openai.com)

Tekrarlanabilir Log Özetleyici

Aşağıdakini ai_log_summary.py olarak kaydedin.

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

Şu şekilde çalıştırın:

bash HMAC_SECRET='a-long-random-secret' \ python ai_log_summary.py /var/log/nginx/ai-access.jsonl \

data/ai_crawler_daily.csv

Bu, insan trafiği hakkında değil, getirme etkinliği hakkında operasyonel kanıt üretir.


6. Yapay Zeka Odaklı Özetler için Özel Bağlantı Kısaltıcılar

Birinci taraf bağlantı kısaltıcı, yapay zeka sistemleri tarafından referans alınabilecek özetler veya kaynak materyaller yayınladığınızda kontrollü bir ölçüm noktası sağlar.

Kontrol ettiğiniz bir alan adı kullanın, örneğin:

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

Hedef, aşağıdaki gibi kampanya parametrelerini içermelidir:

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

Google, trafik kaynaklarını ve kampanyaları belirlemek için kampanya parametrelerini önermektedir. Google Analytics kampanya URL belgeleri (support.google.com)

Önerilen bağlantı alanları

text surface topic prompt_id asset_id content_version destination_path

Kişisel bilgileri, e-posta adreslerini veya kullanıcı arama sorgularını bağlantıya koymayın. Kampanya tanımlayıcıları, yayınlanan varlığı tanımlamalı, bir kişiyi tanımlamamalıdır.

Önemli sınırlamalar

Kısa bir bağlantı, evrensel bir çözüm değil, bir kalibrasyon aracıdır:

  • Asistan, hedef URL'yi yeniden yazabilir.
  • Asistan, bunun yerine kanonik URL'yi alıntılayabilir.
  • Bağlantı görüntülenebilir ancak asla tıklanmayabilir.
  • Bir tarayıcı veya gizlilik aracı yönlendiriciyi kaldırabilir.
  • Bazı sistemler hedefi sunucu tarafında çekebilir.
  • Kısa bir bağlantı, markayı hatırlayan ve daha sonra geri dönen kullanıcıları ölçmez.

Hedefi gizlemek, güvenlik sistemlerini atlatmak veya atıfları manipüle etmek için bir kısaltıcı kullanmayın. İlgili, kanonik bir sayfaya açık bir yönlendirme kullanın.

Minimal Birinci Taraf Kısaltıcı

Aşağıdaki örnek FastAPI ve SQLite kullanır. Üretimde kullanmadan önce bağlantı oluşturma uç noktasını kimlik doğrulama ile koruyun.

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)

Şu şekilde çalıştırın:

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

Ölçüm bağlantıları için 302 yönlendirmesi kullanın, böylece tarayıcılar ve ara sistemler yönlendirmeyi kalıcı olarak önbelleğe alma olasılıkları daha düşük olur.


7. Yapay Zeka Yanıt Panellerinin Planlanmış Kazıması

Panel kazıması, birinci taraf analizlerinin ortaya koyamayabileceği soruları yanıtlamak için kullanışlıdır:

  • Hangi rakip kaynaklar alıntılanıyor?
  • Belirli bir istem için hangi sayfa alıntılanıyor?
  • Yanıt ülkeye veya cihaza göre değişiyor mu?
  • Atıf yanıtta mı, kaynak listesinde mi yoksa her ikisinde mi görünüyor?
  • Yanıt zaman içinde ne kadar kararlı?
  • Asistan kısa bir bağlantıyı mı yoksa kanonik URL'yi mi alıntılıyor?

Ancak, kazıma dikkatli yapılmalıdır.

Sorumlu toplama kuralları

  1. Resmi bir API'yi, lisanslı bir arama veri sağlayıcısını veya birinci taraf raporunu tercih edin.
  2. İstekleri otomatikleştirmeden önce sağlayıcının koşullarını inceleyin.
  3. Uygulanabilir olduğunda robots talimatlarına uyun.
  4. CAPTCHA'ları, oturum açma engellerini, hız sınırlamalarını veya bot korumalarını atlatmayın.
  5. Küçük, sabit bir istem seti kullanın.
  6. Düşük frekansta çalıştırın.
  7. Sonuçların denetlenebilmesi için yanıtı ve zaman damgasını kaydedin.
  8. Bir sağlayıcı bir meydan okuma veya erişim reddi yanıtı döndürdüğünde durun.

Robots Hariç Tutma Protokolü, bir tarayıcı tercih mekanizmasıdır, bir güvenlik sistemi değildir. Korunan içeriğe erişimi yetkilendirmez. RFC 9309: Robots Hariç Tutma Protokolü (rfc-editor.org)

Bir İstem Manifestosu Oluşturun

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

İstemleri sabit tutun. İstemler değişirse, trend karşılaştırmaları daha az güvenilir hale gelir.

Ayrıca şunları da saklayın:

  • ülke
  • dil
  • cihaz türü
  • tarayıcı sürümü
  • istem sürümü
  • içerik sürümü
  • UTC cinsinden toplama zamanı

Google, Yapay Zeka Genel Bakışı ve Yapay Zeka Modu yanıtlarının, farklı sistemler kullandıkları ve ilgili aramaları veya “sorgu yayılımını” kullanabilecekleri için değişebileceğini belirtiyor. Google Yapay Zeka özellikleri ve web sitesi belgeleri (developers.google.com)

Playwright Toplama Betiği

Aşağıdaki betik genel amaçlı bir araştırma aracıdır. Oluşturulan sayfayı, ekran görüntüsünü, sayfa bağlantılarını ve yanıt metnini kaydeder. Kasıtlı olarak zorlukları atlatmaz veya erişim kontrollerini aşmaya çalışmaz.

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) + "\

") output.flush()

            # Keep request volume low.
            await asyncio.sleep(8)

    await browser.close()

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

Yükleyin ve çalıştırın:

bash pip install playwright playwright install chromium python scrape_panels.py

İki çalıştırmanın çakışmaması için kilitleyin:

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

Yüzey adaptörleriyle doğruluğu artırma

Yedek betik, sayfa düzeyindeki bağlantıları kaydeder. Bu, keşif için kullanışlıdır ancak sıradan arama sonucu bağlantılarını içerebilir. Üretim kullanımı için:

  • Mümkün olduğunda lisanslı bir yanıt paneli API'si kullanın.
  • Her yüzey için ayrı bir seçici adaptör oluşturun.
  • Seçici sürümünü saklayın.
  • Ham HTML ve bir ekran görüntüsü saklayın.
  • Her kaydı link_scope = "panel_selector" veya link_scope = "page_fallback" ile işaretleyin.

Atıf Payını yalnızca paneli güvenilir bir şekilde tanımlayabildiğinizde panel_selector verilerinden hesaplayın. Yedek gözlemleri ayrı bir keşif raporunda tutun.


8. Google Analytics ve BigQuery Entegrasyonu

Google Analytics 4, ham olay verilerini BigQuery'ye aktarabilir. Günlük dışa aktarımlar, events_YYYYMMDD gibi kararlı tablolar sağlar; akışlı dışa aktarımlar neredeyse gerçek zamanlı izleme için kullanışlıdır ancak günlük tablo kesinleşene kadar eksik olabilir. Google Analytics BigQuery Dışa Aktarımı (support.google.com)

Basitleştirilmiş bir oturum sorgusu şöyle görünebilir:

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;

Olgun bir uygulama için, kampanya yapısına surface, topic ve prompt_id ekleyin veya bunları kısaltıcı tıklama tablosundan birleştirin.

Her bir kullanıcı veya oturum için yüksek kardinaliteli bir analiz boyutu oluşturmayın. Google, aşırı yüksek kardinaliteli özel boyutların raporlama kalitesini düşürebileceği konusunda uyarıyor. Google Analytics özel boyutları ve metrikleri (support.google.com)


9. Kontrol Paneli Tasarımı

Pratik bir kontrol paneli beş görünüm içermelidir.

Yönetici Özeti

Göster:

  • Konuya Göre Atıf Payı
  • Konuya Göre Atıf Kapsamı
  • Onaylanmış Asistan Yönlendirme Oranı
  • Genişletilmiş Asistan Yönlendirme Oranı
  • Atıf Sonrası Etkileşim
  • Yapay zeka tarayıcısı başarı oranı
  • Yapay zeka atfedilen anahtar olaylar veya gelir

Atıf Payı Eğilimi

Çizgi grafik:

text Date × Topic × Surface

Herk ikisini de gösterin:

  • hedef alan adı atıf oluşumları
  • tüm gözlemlenen atıf oluşumları

Asistan Trafik Hunisi

text Observed citations ↓ Controlled-link clicks ↓ AI-attributed sessions ↓ Engaged AI sessions ↓ Key events

Her aşama, atıf güvenini göstermelidir.

Tarayıcı Sağlığı

Bota göre tablo:

text bot_name requests successful_requests error_rate unique_ip_count top_paths

Şunlar olduğunda uyarı ver:

  • hata oranı %2'yi aşarsa
  • bir bot aniden kaybolursa
  • daha önce erişilebilir olan bir içerik bölümü 403 veya 429 döndürürse
  • tarayıcı istekleri istenmeyen özel bir yola yoğunlaşırsa

İçerik Fırsat Tablosu

Sayfaları ve konuları şunlara göre sıralayın:

text high citation share + low referral rate high impressions + low citation coverage high engagement + low citation visibility high crawler errors + high business importance

Bu kombinasyonlar, genellikle sadece trafik hacmine bakmaktan daha iyi kararlar üretir.

Minimal Streamlit Kontrol Paneli

dashboard.py olarak kaydedin.

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

Şu şekilde çalıştırın:

bash pip install streamlit pandas streamlit run dashboard.py

Üretim için, normalize edilmiş tabloları doğrudan ham dosyaları okumak yerine DuckDB, BigQuery, Snowflake veya PostgreSQL'e yükleyin.


10. Kalite Kontrolleri

Bir ölçüm sistemi, hassas görünen ancak yanıltıcı sayılar üretebilir. Bu kontrolleri ekleyin.

Botları insanlardan ayırın

OAI-SearchBot, GPTBot, ClaudeBot veya PerplexityBot'u asla insan oturumu olarak saymayın. Bunlar tarayıcı veya alma sinyalleridir.

Ham kanıtı koruyun

Her panel çalışması için şunları saklayın:

  • ham HTML
  • ekran görüntüsü
  • yanıt metni
  • zaman damgası
  • tarayıcı ve toplayıcı sürümü
  • istem ve yerel ayar
  • yanıt karması

Bu, bir metriğin neden değiştiğini açıklayabilmeyi mümkün kılar.

Panel yokluğunu takip et

Eksik bir yapay zeka paneli, atıfınız olmayan bir yanıtla aynı şey değildir.

Kullanın:

text panel_not_present panel_present_no_target panel_present_target_cited blocked_or_challenged collection_error

Örnekleme yanlılığını kontrol et

Planlanmış bir kazıma şunlardan etkilenir:

  • konum
  • cihaz
  • dil
  • zaman
  • kişiselleştirme
  • tarayıcı durumu
  • istem ifadesi

Sabit bir temel istem seti ve değişen bir keşifsel istem seti kullanın. İki grubu raporlarda ayrı tutun.

Yanlış kesinlikten kaçının

Küçük konu grupları için güven aralıklarını veya minimum örneklem büyüklüklerini raporlayın. Üç gözlem içeren bir konu, 300 gözlem içeren bir konuyla doğrudan karşılaştırılmamalıdır.

Benzeri benzeriyle karşılaştırın

Yüzeyleri karşılaştırırken şunları sabit tutun:

  • istem
  • yerel ayar
  • ülke
  • cihaz
  • toplama saati
  • hedef alan adı kuralları
  • atıf ayrıştırıcı sürümü

11. Önerilen Uygulama Planı

Hafta 1: Enstrümantasyon

  • Yapılandırılmış sunucu loglarını yapılandırın.
  • Bot kaydını oluşturun.
  • Kısaltıcı alan adını oluşturun.
  • Kampanya adlandırma kurallarını ekleyin.
  • Konu taksonomisini tanımlayın.
  • Google Analytics 4 BigQuery dışa aktarımını etkinleştirin.

Hafta 2: Kontrollü bağlantılar

  • Beş ila on takip edilen özeti yayınlayın.
  • Farklı konular ve içerik sürümleri için bağlantılar oluşturun.
  • Yönlendirme loglarını analiz oturumlarıyla doğrulayın.
  • URL'lere veya analiz parametrelerine hiçbir kişisel bilginin girmediğini onaylayın.

Hafta 3: Panel gözlemleri

  • Bir istem manifestosu oluşturun.
  • İki yüzey ve 20 ila 50 kararlı istemle başlayın.
  • Günde bir kez çalıştırın.
  • Ekran görüntülerini ve HTML'yi kaydedin.
  • Toplama hatalarını atıf yokluğundan ayrı olarak ölçün.

Hafta 4: Kontrol paneli ve yönetişim

  • Konu ve yüzey kontrol panelleri oluşturun.
  • Tarayıcı sağlık uyarıları ekleyin.
  • Güven kurallarını tanımlayın.
  • Birinci taraf raporlarını panel gözlemleriyle karşılaştırın.
  • Veri saklama, erişim ve silme politikalarını belgeleyin.

Sonuç

Yapay zeka atıf ölçümü, tek bir yönlendirme raporu olarak değil, çok sinyalli bir ilişkilendirme sistemi olarak oluşturulmalıdır.

En güvenilir çerçeve şunları birleştirir:

  • Google ve Bing birinci taraf görünürlük raporları
  • tarayıcı ve getirici etkinliği için sunucu logları
  • kontrollü tıklama ölçümü için birinci taraf kısa bağlantılar
  • planlanmış, uyumlu yanıt-panel gözlemleri
  • aşağı akış değeri için analiz ve dönüşüm verileri

En önemli üç metrik şunlardır:

  1. Konuya Göre Atıf Payı — gözlemlenen kaynak alanının ne kadarının alan adınıza ait olduğu.
  2. Asistan Yönlendirme Oranı — ne kadar insan trafiğinin yapay zeka yüzeylerine atfedilebileceği.
  3. Atıf Sonrası Etkileşim — yapay zeka tarafından yönlendirilen ziyaretçilerin anlamlı eylemler yapıp yapmadığı.

Sistem, her sayının yüzeyi, zaman dilimi, paydası, ilişkilendirme yöntemi ve güven düzeyini içerdiğinde kullanışlı hale gelir. Bu disiplin, tarayıcı isabetlerinin kullanıcılarla karıştırılmasını, kazınmış yanıtların gösterimlerle karıştırılmasını ve atıfların iş sonuçlarıyla karıştırılmasını önler.

İlgili Makaleler

Bu içeriği beğendiniz mi?

En son içerik pazarlama içgörüleri ve büyüme rehberleri için bültenimize abone olun.

Bu makale sadece bilgilendirme amaçlıdır. İçerik ve stratejiler özel ihtiyaçlarınıza göre değişiklik gösterebilir.
Yapay Zeka Atıf Etkisini Ölçme: Analizler, Loglar ve Panel Kazımaları | AutoPod