Quay lại blog

Kích thước mẫu Độ hiển thị AI: Một số thực sự cần bao nhiêu lần chạy

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

11-Aug-2026

TL;DR:

  • Một lần ghi nhận câu trả lời của AI chỉ hiện lên 49,6% các miền đã được trích dẫn mà năm lần ghi nhận cùng một lệnh truy vấn đã hiện lên, đo lường qua ma trận 100 lần ghi nhận của năm bộ máy trả lời, bốn lệnh truy vấn và năm lần lặp lại với mọi đầu vào được giữ nguyên.
  • Các tập miền đã được trích dẫn chồng chéo qua các lần lặp lại với chỉ số Jaccard trung bình là 0,384, nhưng các ô riêng lẻ của bộ máy và lệnh truy vấn dao động từ 0,114 đến 0,956 — không có một con số ổn định duy nhất nào che phủ “khả năng nhìn thấy của AI.”
  • Các đề cập đến thương hiệu trong văn bản câu trả lời là lớp ít đáng tin cậy nhất: trong số 137 quan sát thương hiệu theo ô, 44,5% xuất hiện trong tất cả năm lần lặp lại và 24,8% xuất hiện trong chính xác một lần.
  • Các câu hỏi về thành viên tập hợp hội tụ nhanh chóng — ba lần lặp lại đã phục hồi 83,1% các miền đã được trích dẫn mà năm lần lặp lại tìm thấy — vì vậy một cuộc kiểm tra trích dẫn cần một vài lần chạy, không phải một phần tư của các lần ghi nhận hàng ngày.
  • Các câu hỏi về tỷ lệ hội tụ chậm: với tỷ lệ xuất hiện được quan sát là 40%, năm lần chạy mang lại một khoảng tin cậy 95% 65 điểm rộng, và việc đạt được ±10 điểm mất khoảng 100 lần chạy mỗi bộ máy mỗi lệnh truy vấn.
  • Toàn bộ ma trận hoạt động trong 4 phút 9 giây, vì vậy những con số này chỉ đo lường sự không xác định ở cấp độ mô hình; một chương trình lấy mẫu qua nhiều ngày nên mong đợi ít nhất sự di chuyển này, không bao giờ ít hơn.
  • Chạy cùng một ma trận với bộ lệnh truy vấn của riêng bạn trên kế hoạch miễn phí Scrapeless và lấy số của riêng bạn thay vì mượn số này.

Mỗi bảng điều khiển khả năng nhìn thấy của AI đều báo cáo một con số. Tỷ lệ trích dẫn, chia sẻ giọng nói, xếp hạng đề xuất, tâm trạng — mỗi con số đến như một con số sạch sẽ với một mũi tên xu hướng bên cạnh. Không ai trong số chúng đến với một thanh lỗi.

Sự thiếu sót đó quan trọng hơn ở đây so với tìm kiếm cổ điển, vì bề mặt được đo lường tái tạo câu trả lời của nó trong mỗi yêu cầu. Các nhà nghiên cứu đã gán năm mô hình vào các cài đặt định tính ổn định ở tám nhiệm vụ vẫn ghi lại độ chính xác dao động lên đến 15% giữa các lần chạy, với khoảng cách giữa lần chạy tốt nhất và tệ nhất có thể lên tới 70%. Một mô hình sẽ không lặp lại chính nó khi được yêu cầu sẽ không cho bạn một con số khả năng nhìn thấy có thể lặp lại từ một lần ghi nhận.

Phần còn lại của bài viết này bắn cùng một lệnh truy vấn vào cùng một bộ máy liên tục, giữ mọi đầu vào không thay đổi, và đo lường khoảng cách mà các câu trả lời thực sự di chuyển. Sự di chuyển được đo lường đó sau đó chuyển đổi thành đầu ra duy nhất mà một chương trình giám sát có thể hành động — một số lần ghi nhận.

Pipeline at a Glance

Pipeline có bốn giai đoạn, và giai đoạn cuối cùng là đầu ra:

ghi nhận ma trận lặp lại → giảm mỗi câu trả lời thành các lớp có thể so sánh → đánh giá độ ổn định cho mỗi ô → chuyển đổi độ ổn định thành kích thước mẫu cần thiết

Giai đoạn 1 yêu cầu một yêu cầu giống hệt vài lần cho mỗi bộ máy và lưu trữ mỗi phản hồi thô. Giai đoạn 2 tách mỗi phản hồi xuống còn ba điều có thể so sánh qua các lần lặp lại: tập hợp các miền mà nó đã trích dẫn, văn bản của câu trả lời, và tên danh sách theo dõi mà văn bản đề cập đến và theo thứ tự nào. Giai đoạn 3 đo lường mức độ mà mỗi trong ba lớp đó di chuyển giữa các lần lặp lại. Giai đoạn 4 lấy sự di chuyển đã được đo lường và trả lời câu hỏi mà một đội ngũ báo cáo thực sự có, đó là cần bao nhiêu lần ghi nhận cho một yêu cầu.

Điều này nằm ở một lớp cao hơn các pipeline ghi nhận mà nó phụ thuộc vào. Nếu bạn chưa xây dựng phần ghi nhận, pipeline chia sẻ trích dẫn qua sáu bộ máy trả lời AI là nền tảng; bài viết này đo lường xem liệu chuỗi mà pipeline này tạo ra có thể đọc được với kích thước mẫu mà bạn đang chạy hay không.

What This Measurement Answers

Bốn quyết định thay đổi tùy thuộc vào câu trả lời, và cả bốn quyết định này đều đang được đưa ra hôm nay mà không có nó.

Liệu sự di chuyển theo tuần có thực sự không. Một con số tỷ lệ trích dẫn giảm từ 40% xuống 25% trông giống như một sự thoái lui. Với năm lần chạy mỗi ô, cả hai con số đều nằm trong cùng một khoảng tin cậy, vì vậy sự giảm này không thể phân biệt với việc bộ máy tái tạo lại câu trả lời của nó.

Chương trình cần ngân sách ghi nhận bao nhiêu. Kích thước mẫu có chi phí. Một đội cần một ước lượng tỷ lệ và một đội cần một tổng hợp trích dẫn có yêu cầu khác nhau hơn một bậc độ lớn, và việc mua cái lớn hơn cho cả hai làm lãng phí hầu hết ngân sách.

Chỉ số nào để xây dựng một mục tiêu quanh. Một số lớp của câu trả lời AI đủ ổn định để đặt ra một mục tiêu. Những lớp khác thì không, và việc xây dựng một OKR trên lớp không ổn định sẽ tạo ra một phần tư tạp âm được diễn giải như là tiến bộ.

Bộ máy nào cần được cân nhắc. Độ ổn định của từng bộ máy dao động khoảng hai lần trong ma trận này. Một bộ máy mà các trích dẫn của nó hầu như không di chuyển sẽ cho bạn một số đọc sử dụng được từ vài lần ghi nhận; một bộ máy cần phải xáo trộn cần nhiều lần lấy mẫu để đạt được cùng một mức độ tin cậy.

The Sample Design, Stated Up Front

Ma trận này có năm bộ máy, bốn lệnh truy vấn, năm lần lặp lại: 100 lần ghi nhận, với 20 ô bộ máy và lệnh truy vấn mỗi ô giữ năm lần lặp lại.

Dimension Value
Động cơ Perplexity, Grok, Gemini, Google AI Mode, ChatGPT
Các câu lệnh 4 câu hỏi cấp độ danh mục trong một danh mục sản phẩm
Số lần lặp lại trên mỗi ô 5
Tổng số lần thu thập 100
Quốc gia Được gán cố định vào US trong mỗi cuộc gọi
Chế độ suy luận Grok Được gán cố định vào MODEL_MODE_FAST trong mỗi cuộc gọi
Thời gian thu thập 4 phút 9 giây, một phiên duy nhất
Dấu vân tay đầu vào riêng biệt 20 — một cái trên mỗi ô, chia sẻ bởi 5 lần lặp lại của nó

Hai lựa chọn thiết kế mang lại kết quả. Thứ nhất là mỗi đầu vào đều được gán cố định: cùng một chuỗi câu lệnh, cùng một quốc gia, cùng một chế độ suy luận, cùng một cờ tìm kiếm web. Việc thay đổi bất kỳ yếu tố nào trong số đó sẽ trộn lẫn sự khác biệt đầu vào vào biến đổi và làm cho việc đo lường trở nên vô nghĩa. Số lượng dấu vân tay trong Giai đoạn 1 tồn tại để chứng minh rằng việc gán cố định đã được giữ.

Thứ hai là cửa sổ nén. Tất cả 100 lần thu thập đều diễn ra trong bốn phút. Điều này là cố ý, và nó cũng là giới hạn chặt chẽ nhất của toàn bộ bài tập — xem phần giới hạn trước khi trích dẫn bất kỳ con số nào ở đây.

Điều kiện tiên quyết

  • Python 3.10 hoặc mới hơn, chỉ thư viện tiêu chuẩn.
  • Một khóa API Scrapeless được xuất ra dưới dạng SCRAPELESS_API_KEY. Các diễn viên LLM Chat Scraper dưới API Thu thập Dữ liệu Toàn cầu đã đặt cả năm động cơ phía sau một điểm cuối và một phong bì phản hồi, điều này làm cho một ma trận xuyên động cơ trở nên thực tế.
  • Một tệp watchlist.txt với một tên thương hiệu mỗi dòng — thương hiệu của bạn và những tên mà bạn mong đợi cạnh tranh trong danh mục. Giữ nó ra khỏi kiểm soát phiên bản nếu danh sách đó nhạy cảm.
  • Khoảng 100 cuộc gọi diễn viên với ngân sách cho một lần thử đầu tiên. Giá cả dựa trên mức sử dụng có trên trang trang giá Scrapeless.
bash Copy
export SCRAPELESS_API_KEY="your_scrapeless_api_key"
mkdir -p ai-visibility-variance && cd ai-visibility-variance
printf 'YourBrand\nRivalOne\nRivalTwo\n' > watchlist.txt

Giai đoạn 1 — Thu thập Ma trận Lặp lại

Giai đoạn 1 kích hoạt năm lần lặp lại của mỗi ô và ghi lại từng phản hồi thô vào đĩa mà không bị sửa đổi. Việc lưu trữ toàn bộ phong bì thay vì một bản tóm tắt đã phân tích là quan trọng, vì các lớp mà bạn muốn so sánh không rõ ràng cho đến khi bạn nhìn vào sự phân bổ.

Mỗi động cơ sử dụng cùng một promptcountry; chỉ có các yếu tố bổ sung yêu cầu của diễn viên khác nhau, và mỗi yếu tố bổ sung đều được gán cố định để không thể trôi dạt giữa các lần lặp lại. Các ô chạy song song vì một lượt chuyển tiếp qua 100 lần thu thập sẽ kéo dài cửa sổ và để sự trôi dạt thực tế rò rỉ vào một phép đo mà lẽ ra phải loại trừ nó.

python Copy
# capture.py — capture a fixed engine x prompt x repeat matrix
import hashlib
import json
import os
import time
import urllib.request
from concurrent.futures import ThreadPoolExecutor

API = "https://api.scrapeless.com/api/v2/scraper/execute"
KEY = os.environ["SCRAPELESS_API_KEY"]
OUT = "runs"
REPEATS = 5

PROMPTS = {
    "P1": "What are the best web scraping APIs for developers in 2026?",
    "P2": "Which services provide cloud browsers for automated data collection?",
    "P3": "What tools do developers use to collect Google search results programmatically?",
    "P4": "Recommend a proxy provider for large-scale public web data collection.",
}

# Same prompt and country everywhere. Only actor-required extras differ, and
# every one of them is pinned: an input that moves between repeats would be
# measured as engine variance.
ENGINES = {
    "perplexity": ("scraper.perplexity", {}),
    "grok":       ("scraper.grok",       {"mode": "MODEL_MODE_FAST"}),
    "gemini":     ("scraper.gemini",     {}),
    "aimode":     ("scraper.aimode",     {}),
    "chatgpt":    ("scraper.chatgpt",    {"web_search": True, "shopping": False}),
}


def execute(actor, payload, timeout=300):
    request = urllib.request.Request(
        API,
        data=json.dumps({"actor": actor, "input": payload}).encode(),
        headers={"Content-Type": "application/json", "x-api-token": KEY},
        method="POST",
    )
    started = time.time()
    with urllib.request.urlopen(request, timeout=timeout) as response:
        return json.loads(response.read().decode()), round(time.time() - started, 1)


def capture(job):
    engine, prompt_id, repeat = job
    actor, extra = ENGINES[engine]
    payload = {"prompt": PROMPTS[prompt_id], "country": "US", **extra}
    # Hash the actor with the payload. Three of these engines take an identical
    # payload, so a payload-only hash would collapse them into one fingerprint
    # and stop proving that each cell repeated the same request.
    fingerprint = hashlib.sha256(
        json.dumps({"actor": actor, **payload}, sort_keys=True).encode()).hexdigest()[:16]
    try:
        body, elapsed = execute(actor, payload)
    except Exception as exc:
        # A cell that returns nothing is logged as missing, never dropped.
        # A silent hole would bias every statistic computed downstream.
        return {"ok": False, "note": f"{engine} {prompt_id} r{repeat}: {type(exc).__name__}"}
    with open(f"{OUT}/{engine}__{prompt_id}__r{repeat}.json", "w") as handle:
        json.dump({
            "engine": engine, "prompt_id": prompt_id, "repeat": repeat,
            "elapsed_s": elapsed, "input_fingerprint": fingerprint,
            "captured_utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
            "response": body,
        }, handle)
    return {"ok": True, "fingerprint": fingerprint}


os.makedirs(OUT, exist_ok=True)
jobs = [(e, p, r) for e in ENGINES for p in PROMPTS for r in range(1, REPEATS + 1)]
print(f"{len(jobs)} captures = {len(ENGINES)} engines"
      f" x {len(PROMPTS)} prompts x {REPEATS} repeats")

with ThreadPoolExecutor(max_workers=12) as pool:
    results = list(pool.map(capture, jobs))

stored = [r for r in results if r["ok"]]
print(f"stored {len(stored)} captures in {OUT}/")
print(f"missing cells: {[r['note'] for r in results if not r['ok']] or 'none'}")
print(f"{len({r['fingerprint'] for r in stored})} distinct input fingerprints "
      f"across {len(stored)} captures")

Dòng dấu vân tay là kiểm tra sự trung thực. Hai mươi dấu vân tay riêng biệt qua 100 lần thu thập có nghĩa là năm lần lặp lại của mỗi ô là các yêu cầu giống hệt nhau, vì vậy bất kỳ sự khác biệt nào trong các phản hồi đều đến từ động cơ.

Giai đoạn 2 — Giảm Mỗi Lần Thu Thập Thành Ba Lớp Có Thể So Sánh

Giai đoạn 2 làm phẳng năm phong bì phản hồi khác nhau thành một hình dạng hàng với ba lớp đo lường, vì "khả năng nhìn thấy AI" không phải là một số lượng và việc xem xét nó như một là nơi mà lỗi bắt đầu.

Ba lớp trả lời các câu hỏi khác nhau và, như kết quả cho thấy, cần các kích thước mẫu khác nhau:

Lớp Nó chứa gì Gia đình chỉ số mà nó nuôi dưỡng
L1 trích dẫn Tập hợp các miền có thể đăng ký mà động cơ đã trích dẫn Tỷ lệ trích dẫn, khoảng cách giữa miền đã trích dẫn
L2 văn xuôi Nội dung trả lời, dưới dạng ký tự và dưới dạng tập hợp token Cảm xúc, tóm tắt, sự khác biệt văn bản
L3 thương hiệu Những tên trong danh sách theo dõi mà văn bản đã đề cập, theo thứ tự đề cập đầu tiên Thị phần giọng nói, thứ hạng đề xuất

Mỗi động cơ báo cáo nguồn của nó dưới khóa riêng — Perplexity sử dụng web_results, Grok khóa footnotes theo ID trích dẫn, cả Gemini và AI Mode đều sử dụng citations, và bảng tìm kiếm của ChatGPT xuất hiện dưới dạng search_result. Việc chuẩn hóa đến máy chủ có thể đăng ký loại bỏ sự khác biệt giữa URL bài báo sâu và liên kết trang chủ, điều mà một chỉ số tỷ lệ trích dẫn thực sự đếm.

python Copy
# layers.py — reduce every capture to three comparable measurement layers
import json
import os
import re
from urllib.parse import urlparse

WATCHLIST = [line.strip() for line in open("watchlist.txt") if line.strip()]

CITATIONS = {
    "perplexity": lambda r: [c.get("url") for c in r.get("web_results") or []],
    "grok":       lambda r: [c.get("url") for c in (r.get("footnotes") or {}).values()],
    "gemini":     lambda r: [c.get("url") for c in r.get("citations") or []],
    "aimode":     lambda r: [c.get("url") for c in r.get("citations") or []],
    "chatgpt":    lambda r: [c.get("url") for c in r.get("search_result") or []],
}
ANSWER_KEY = {
    "perplexity": "result_text", "grok": "full_response", "gemini": "result_text",
    "aimode": "result_text", "chatgpt": "result_text",
}


def registrable(url):
    netloc = urlparse(url).netloc.lower()
    return netloc[4:] if netloc.startswith("www.") else netloc


def mentions(text):
    """Watchlist names present in the answer, keyed by first-mention offset."""
    lowered = text.lower()
    found = {}
    for name in WATCHLIST:
        hit = re.search(rf"(?<![a-z0-9]){re.escape(name.lower())}(?![a-z0-9])", lowered)
        if hit:
            found[name] = hit.start()
    return found


rows = []
for filename in sorted(os.listdir("runs")):
    record = json.load(open(f"runs/{filename}"))
    result = record["response"].get("task_result") or {}
    engine = record["engine"]
    answer = result.get(ANSWER_KEY[engine]) or ""
    found = mentions(answer)
    rows.append({
        "engine": engine,
        "prompt_id": record["prompt_id"],
        "repeat": record["repeat"],
        "cited_hosts": sorted({
            host for url in CITATIONS[engine](result)
            if url and (host := registrable(url))
        }),
        "answer_chars": len(answer),
        "answer_tokens": sorted(set(re.findall(r"[a-z0-9]+", answer.lower()))),
        # Ordered by first mention, so list position survives into stage 3.
        "brands_present": sorted(found, key=found.get),
    })

with open("layers.jsonl", "w") as handle:
    for row in rows:
        handle.write(json.dumps(row) + "\n")

cited = sum(len(r["cited_hosts"]) for r in rows)
print(f"reduced {len(rows)} captures -> layers.jsonl")
print(f"L1 citations: {cited} cited hosts, {cited / len(rows):.1f} per capture")
print(f"L2 prose:     {sum(r['answer_chars'] for r in rows) / len(rows):.0f} chars per answer")
print(f"L3 brands:    {sum(len(r['brands_present']) for r in rows)} watchlist hits total")

Giai đoạn 3 — Đo Sự Ổn Định Cho Từng Động Cơ và Câu Lệnh

Giai đoạn 3 đo lường chuyển động bên trong mỗi ô, và nó báo cáo theo từng động cơ thay vì gộp lại, vì con số gộp che giấu điều mà bạn cần biết nhất.

Ba chỉ số thực hiện công việc. Đối với lớp trích dẫn và văn xuôi, chỉ số Jaccard cặp trung bình qua năm lần lặp lại — kích thước của giao điểm trên kích thước của hợp nhất, được trung bình qua tất cả mười cặp trong một ô. Đối với độ dài câu trả lời, hệ số biến thiên, thể hiện độ lệch chuẩn của một trải nghiệm được đo lường dưới dạng một phần trăm của trung bình để các câu trả lời có độ dài khác nhau vẫn có thể so sánh được. Đối với các thương hiệu, tỷ lệ tên xuất hiện trong cả năm lần lặp lại thay vì chỉ một số trong số chúng.

python Copy
# stability.py — how far each layer moves inside a cell
import json
import statistics as stats
from collections import defaultdict
from itertools import combinations

cells = defaultdict(dict)
for line in open("layers.jsonl"):
    row = json.loads(line)
    cells[(row["engine"], row["prompt_id"])][row["repeat"]] = row


def jaccard(left, right):
    union = left | right
    return len(left & right) / len(union) if union else None


def mean_pairwise(sets):
    scores = [j for a, b in combinations(sets, 2) if (j := jaccard(a, b)) is not None]
    return stats.mean(scores) if scores else None


per_engine = defaultdict(lambda: defaultdict(list))
brands = defaultdict(lambda: {"stable": 0, "flipping": 0})

for (engine, _prompt), reps in sorted(cells.items()):
    keys = sorted(reps)
    hosts = [set(reps[k]["cited_hosts"]) for k in keys]
    tokens = [set(reps[k]["answer_tokens"]) for k in keys]
    lengths = [reps[k]["answer_chars"] for k in keys]

    per_engine[engine]["cite"].append(mean_pairwise(hosts))
    per_engine[engine]["prose"].append(mean_pairwise(tokens))
    per_engine[engine]["cv"].append(stats.pstdev(lengths) / stats.mean(lengths) * 100)
    per_engine[engine]["union"].append(len(set().union(*hosts)))
    per_engine[engine]["core"].append(len(set.intersection(*hosts)))

    for brand in set().union(*[set(reps[k]["brands_present"]) for k in keys]):
        seen = sum(1 for k in keys if brand in reps[k]["brands_present"])
        brands[engine]["stable" if seen == len(keys) else "flipping"] += 1

header = f"{'engine':<12}{'citeJaccard':>12}{'proseJaccard':>13}{'lengthCV%':>11}"
print(header + f"{'hostsEveryRun':>15}{'brandsStable%':>15}")
for engine, series in per_engine.items():
    core, union = sum(series["core"]), sum(series["union"])
    counts = brands[engine]
    stable_pct = counts["stable"] / (counts["stable"] + counts["flipping"]) * 100
    print(f"{engine:<12}{stats.mean(series['cite']):>12.3f}"
          f"{stats.mean(series['prose']):>13.3f}{stats.mean(series['cv']):>11.1f}"
          f"{f'{core}/{union}':>15}{stable_pct:>14.1f}%")

Giai đoạn 4 — Chuyển Đổi Sự Ổn Định Thành Một Kích Thước Mẫu

Giai đoạn 4 chuyển đổi sự phân bố thành một số lượng chạy, và điều này được thực hiện hai lần vì hai loại câu hỏi hoạt động hoàn toàn khác nhau.

Đối với một câu hỏi thành viên tập hợp — miền nào mà động cơ này trích dẫn cho danh mục của tôi — đầu ra hữu ích là một đường cong bao phủ: phần trăm các miền mà năm lần chạy hiển thị được một lần chạy hiển thị, hoặc hai, hoặc ba. Điều này được tính toán trực tiếp từ các lần nắm bắt bằng cách lấy mẫu mọi sự kết hợp của các lần lặp lại.

Đối với một câu hỏi tỉ lệ — phần trăm câu trả lời đề cập đến thương hiệu của tôi — đầu ra là một khoảng tin cậy về một tỷ lệ. Khoảng tin cậy Wilson là công cụ phù hợp cho các kích thước mẫu này: triển khai tham khảo của NIST làm cho nó trở thành phương pháp mặc định cho các giới hạn tin cậy tỷ lệ, và một so sánh có hệ thống trên các kích thước mẫu từ 1 đến 1.000 đã tìm thấy khoảng Wilson vượt trội hơn khoảng Wald trong sách giáo khoa, đặc biệt là tại n nhỏ và tại các tỷ lệ gần 0 hoặc 1. Cả hai điều kiện đều mô tả dữ liệu đề cập đến thương hiệu một cách chính xác.

python Copy
# samplesize.py — measured stability -> a required number of runs
import json
import math
import statistics as stats
from collections import Counter, defaultdict
from itertools import combinations

cells = defaultdict(dict)
for line in open("layers.jsonl"):
    row = json.loads(line)
    cells[(row["engine"], row["prompt_id"])][row["repeat"]] = row


def wilson(hits, runs, z=1.96):
    proportion = hits / runs
    denominator = 1 + z * z / runs
    centre = (proportion + z * z / (2 * runs)) / denominator
    half = z * math.sqrt(
        proportion * (1 - proportion) / runs + z * z / (4 * runs * runs)) / denominator
    return max(0.0, centre - half) * 100, min(1.0, centre + half) * 100


coverage = defaultdict(list)
for reps in cells.values():
    keys = sorted(reps)
    universe = set().union(*[set(reps[k]["cited_hosts"]) for k in keys])
    if not universe:
        continue
    for n in range(1, len(keys) + 1):
        coverage[n].append(stats.mean([
            len(set().union(*[set(reps[k]["cited_hosts"]) for k in combo])) / len(universe)
            for combo in combinations(keys, n)
        ]))

print("SET QUESTION — share of the 5-run cited-domain union that n runs surface")
for n in sorted(coverage):
    print(f"  n={n}: {stats.mean(coverage[n]) * 100:5.1f}%")

observed = Counter()
for reps in cells.values():
    keys = sorted(reps)
    for brand in set().union(*[set(reps[k]["brands_present"]) for k in keys]):
        observed[sum(1 for k in keys if brand in reps[k]["brands_present"])] += 1

total = sum(observed.values())
print(f"\nRATE QUESTION — {total} brand-by-cell observations at n=5")
for seen in sorted(observed):
    low, high = wilson(seen, 5)
    print(f"  seen {seen}/5 in {observed[seen]:>3} cases ({observed[seen] / total * 100:4.1f}%)"
          f"  95% interval {low:5.1f}%-{high:5.1f}%  width {high - low:4.1f}pt")

print("\nRATE QUESTION — interval width at a 40% appearance rate, by run count")
for n in (1, 5, 10, 20, 30, 50, 100, 200):
    low, high = wilson(round(0.4 * n), n)
    print(f"  n={n:<4} {low:5.1f}%-{high:5.1f}%  width {high - low:4.1f}pt")

Những gì Ma trận thực sự cho thấy

Mọi thứ đều di chuyển, và các động cơ không di chuyển cùng một lượng.

Động cơ Jaccard miền đã trích dẫn Jaccard token văn xuôi CV độ dài câu trả lời Các máy chủ được trích dẫn trong mỗi lần chạy Các đề cập đến thương hiệu ổn định
Perplexity 0.534 0.446 28.7% 8 trong 34 47.6%
Gemini 0.511 0.361 16.3% 6 trong 29 40.6%
Grok 0.366 0.392 10.2% 6 trong 61 45.5%
Google AI Mode 0.282 0.333 15.9% 11 trong 182 50.0%
ChatGPT 0.228 0.342 9.4% 1 trong 80 40.0%

Tổng hợp trên tất cả 20 ô, giá trị Jaccard trung bình theo cặp trên các miền đã trích dẫn là 0.384. Sự phân bố ở cấp độ ô là con số hữu ích hơn: 0.114 ở đầu thấp và 0.956 ở đầu cao. Một tuyên bố về sự ổn định được lấy từ một động cơ trên một gợi ý có thể xuất hiện ở bất kỳ đâu trong khoảng đó, đó chính xác là lý do tại sao một bài kiểm tra ba lần trên một động cơ đơn lẻ là một manh mối và không phải là một phát hiện.

Đường cong bao phủ là số đáng để viết ra nhất:

Số lần chạy Phần trăm của liên minh miền đã trích dẫn năm lần chạy được hiển thị
1 49.6%
2 70.3%
3 83.1%
4 92.3%
5 100%

Một lần nắm bắt cho bạn khoảng một nửa các miền mà năm lần nắm bắt hiển thị cho bạn. Theo từng động cơ tại n=1, khoảng này chạy từ 73.6% trên Perplexity xuống còn 35.1% trên ChatGPT, vì vậy một cuộc kiểm toán trích dẫn với một lần nắm bắt trên động cơ ít ổn định nhất đang thiếu khoảng hai phần ba những gì nó dự kiến sẽ tổng hợp. Đường cong cũng phẳng dần: lần chạy thứ ba thêm 12.8 điểm, lần thứ tư thêm 9.2. Đối với một tổng hợp trích dẫn, ba đến bốn lần lặp mua hầu hết những gì có sẵn.

Google AI Mode đã sản xuất liên minh miền rộng nhất — 182 máy chủ khác nhau trên bốn gợi ý, với chỉ 11 xuất hiện trong cả năm lần lặp lại của ô của họ. Hướng dẫn của chính Google giải thích cơ chế: cả AI Mode và AI Overviews có thể sử dụng một kỹ thuật fan-out truy vấn phát ra nhiều tìm kiếm liên quan across subtopics và do đó có thể xuất hiện một bộ liên kết rộng và đa dạng hơn so với tìm kiếm cổ điển. Khi một động cơ được xây dựng để phân bổ các trích dẫn của nó qua các tiểu thuộc đề, một lần nắm bắt chỉ lấy mẫu một phần của sự phân bổ đó.

Lớp tỷ lệ kể một câu chuyện ngược lại. Trên 137 quan sát thương hiệu theo ô, chỉ 44.5% xuất hiện trong cả năm lần lặp. 24.8% xuất hiện chính xác trong một trong năm — một cái tên mà một lần nắm bắt duy nhất sẽ báo cáo hoặc là có mặt một cách tự tin hoặc là không có một cách tự tin, tùy thuộc hoàn toàn vào lần nắm bắt mà bạn đã thực hiện.

Xuất hiện tại Trường hợp Phần Khoảng 95% trên tỷ lệ thực tế Độ rộng
1 trong 5 34 24.8% 3.6% – 62.4% 58.8 pt
2 trong 5 16 11.7% 11.8% – 76.9% 65.2 pt
3 trong 5 14 10.2% 23.1% – 88.2% 65.2 pt
4 trong 5 12 8.8% 37.6% – 96.4% 58.8 pt
5 trong 5 61 44.5% 56.6% – 100% 43.4 pt

Một thương hiệu xuất hiện hai lần trong năm lần chạy có tỷ lệ xuất hiện thực sự nằm giữa 12% và 77%, điều này quá rộng để hỗ trợ bất kỳ tuyên bố nào mà một bên liên quan có thể hành động. Mở rộng mẫu thu hẹp điều đó từ từ:

Số lần chạy mỗi ô Khoảng 95% tại tỷ lệ được quan sát 40% Độ rộng
1 0.0% – 79.3% 79.3 pt
5 11.8% – 76.9% 65.2 pt
10 16.8% – 68.7% 51.9 pt
20 21.9% – 61.3% 39.5 pt
30 24.6% – 57.7% 33.1 pt
50 27.6% – 53.8% 26.2 pt
100 30.9% – 49.8% 18.9 pt
200 33.5% – 46.9% 13.5 pt
Vậy câu trả lời cho "bao nhiêu lần" là: nó phụ thuộc vào lớp nào bạn đang báo cáo, và hai câu trả lời khác nhau hơn một bậc. Một danh mục trích dẫn có thể đọc được ở ba đến bốn lần lặp. Một tỷ lệ bạn dự định so sánh hàng tuần cần khoảng 100 lần ghi nhận mỗi động cơ mỗi lời nhắc trước khi khoảng thời gian được thu hẹp xuống ±10 điểm. Các lần ghi nhận hàng ngày trong hai đến ba tuần đạt khoảng 14 đến 21 — đủ thoải mái cho câu hỏi đã đặt, và khoảng năm lần ngắn cho câu hỏi tỷ lệ.

Hai kết quả nhỏ hơn đáng ghi nhận. Xếp hạng đã di chuyển ít hơn sự đề cập: trong số các tên có mặt trong nhiều lần lặp, vị trí lần đầu tiên đề cập đã thay đổi với trung bình 0.89 vị trí trên ChatGPT và 1.95 trên Grok, vì vậy một chỉ số theo dõi xếp hạng thừa hưởng sự không ổn định của việc đề cập nhưng chỉ thêm một chút vào của riêng nó. Và một ô — một động cơ duy nhất trên lời nhắc trình duyệt đám mây — không đề cập đến bất kỳ thương hiệu danh sách theo dõi nào trong bất kỳ năm lần lặp nào của nó, thay vào đó trả lời trong các danh mục khả năng thay vì nhà cung cấp. Một sự vắng mặt nhất quán cũng là một phép đọc ổn định, và một thiết bị theo dõi mà coi một kết quả trống như một lần ghi nhận thất bại sẽ đánh mất tín hiệu thực sự.

Sự phân tán được đo lường cũng phù hợp với nghiên cứu công bố thay vì mâu thuẫn với nó. Một nghiên cứu thành phần biến thể đã phân tách 12,933 phản hồi thương hiệu LLM qua 20 thương hiệu, 8 ngôn ngữ và 3 mô hình đã tìm thấy việc lấy mẫu đơn độc chiếm 34.8% tổng biến thể, với độ tin cậy của một phản hồi đơn ngồi gần 0.01. Nghiên cứu đó đã sử dụng một tập dữ liệu khác và một phương pháp thống kê khác mà vẫn có kết quả tương tự: một câu trả lời gần như không mang tín hiệu phân biệt thương hiệu.

Nếu bạn đã chạy quy trình cảm xúc thương hiệu theo động cơ hoặc trình theo dõi xếp hạng khuyến nghị AI, cả hai đều đọc lớp văn xuôi, và cả hai do đó đều thừa hưởng kích thước mẫu chậm hội tụ hơn thay vì nhanh.

Để có phiên bản riêng của bảng này mất khoảng một trăm cuộc gọi. Bắt đầu với gói miễn phí Scrapeless và chạy ma trận đối với các lời nhắc của riêng bạn trước khi bạn đặt mục tiêu cho bất kỳ chỉ số nào trong số này.

Điều gì mà phép đo này không thể cho bạn biết

Cửa ghi nhận nén là sự hạn chế điều khiển mọi con số ở trên. Tất cả 100 lần ghi nhận đều nằm trong 4 phút 9 giây trong một ngày duy nhất. Điều đó tách biệt một nguồn chuyển động rõ ràng — mô hình tái tạo lại câu trả lời của nó — và nó hoàn toàn loại trừ một số nguồn khác: cập nhật chỉ mục, chu kỳ tin tức, nội dung bạn xuất bản, thay đổi phiên bản mô hình và bất kỳ sự trôi dạt ngày qua ngày nào mà các động cơ thu được.

Hệ quả chỉ diễn ra theo một hướng. Những con số này là mức sàn, không phải là ước lượng tổng biến thể. Một chương trình lấy mẫu cùng các lời nhắc qua các tuần bị tiếp xúc với sự không xác định ở cấp độ mô hình cộng với mọi thứ mà khoảng thời gian bốn phút giữ nguyên. Do đó, kích thước mẫu cần thiết cho một chương trình giám sát thực sự ít nhất phải lớn như vậy, và khoảng cách giữa một con số bốn phút và một con số bốn tuần là một phép đo mà không ai ở đây đã thực hiện.

Bốn giới hạn hẹp hơn áp dụng:

  • Hai mươi ô là một thiết kế nhỏ. Các con số theo động cơ là trung bình trên bốn lời nhắc, vì vậy con số của một động cơ không phải là ước lượng chính xác của động cơ đó. Phạm vi cấp ô từ 0.114 đến 0.956 là tóm tắt chân thực về mức độ mà một ô đơn có thể khác biệt.
  • Một danh mục, một ngôn ngữ, một quốc gia. Tất cả các lời nhắc đều nằm trong một danh mục sản phẩm, bằng tiếng Anh, gán cho US. Công trình thành phần biến thể đã đề cập ở trên cho thấy ngôn ngữ truy vấn chiếm 26.5% tổng biến thể, vì vậy một ngôn ngữ khác không nên được giả định hành xử giống như ngôn ngữ này.
  • Khoảng cách Wilson giả định các rút thăm độc lập. Năm yêu cầu thực hiện đồng thời trong một phiên có thể chia sẻ trạng thái phía trên, điều này sẽ làm cho mẫu hiệu quả nhỏ hơn so với mẫu danh nghĩa và các khoảng thực tế rộng hơn so với bảng cho thấy.
  • Lớp thương hiệu phụ thuộc vào danh sách theo dõi. Chỉ có các tên trong danh sách mới được tính, vì vậy một đối thủ mà bạn không đưa vào danh sách sẽ không nhìn thấy ở L3 trong khi vẫn hoàn toàn nhìn thấy ở L1 nếu động cơ trích dẫn miền của nó.

Không có điều nào trong số này phá vỡ kết quả tiêu đề, đó là một so sánh giữa các lớp được đo lường dưới cùng một điều kiện. Chúng có nghĩa là các tỷ lệ phần trăm cụ thể thuộc về ma trận này, chứ không phải cho các câu trả lời AI nói chung.

Đưa số vào lịch trình giám sát

Lập lịch cho hai loại câu hỏi riêng biệt, vì chạy một nhịp cho cả hai sẽ trả giá quá cao cho câu hỏi đã đặt và làm yếu câu hỏi tỷ lệ.
Đối với kho lưu trữ trích dẫn, ba đến bốn lần lặp lại mỗi máy tìm kiếm cho mỗi gợi ý, hàng tuần. Điều đó phục hồi từ 83% đến 92% của vũ trụ miền đã trích dẫn cho mỗi vòng thu thập, và sự khác biệt hàng tuần trên tập hợp đó là có thể đọc được. Lưu trữ liên hiệp cho mỗi vòng thay vì danh sách của một lần chạy đơn lẻ; so sánh hai lần chạy đơn lẻ tạo ra những thay đổi mà chủ yếu là tái lấy mẫu.

Đối với các chỉ số tỷ lệ — tỷ lệ đề cập, tỷ lệ giọng nói, tỷ lệ cảm xúc, hạng — tích lũy thay vì chụp nhanh. Hai mươi lần thu thập cho mỗi ô mỗi tuần tạo ra một khoảng gần ±20 điểm trên một con số hàng tuần và một con số hàng tháng tổng hợp gần ±10. Báo cáo khoảng bên cạnh số mỗi lần. Một bảng điều khiển cho thấy 42% mà không cho thấy 31%–50% đang khẳng định một độ chính xác mà thiết kế thu thập không hỗ trợ.

Bất kỳ nhịp điệu nào bạn chọn, hãy ghim mọi thứ. Cùng chuỗi gợi ý, cùng quốc gia, cùng chế độ lý luận. Dấu vân tay đầu vào từ Giai đoạn 1 thuộc về các hàng đã lưu của bạn, để một nhà phân tích trong tương lai có thể phân biệt một sự thay đổi thực sự với một gợi ý mà ai đó đã chỉnh sửa.

Đo lại khi một máy tìm kiếm thay đổi. Sự ổn định là một thuộc tính của mô hình hiện tại và ngăn xếp lấy lại, không phải là một hằng số. Khi một máy tìm kiếm gửi một sự thay đổi rõ rệt, số lần chạy đã đủ trong quý trước lại trở thành một giả thuyết. Cùng một kỷ luật áp dụng ở đây như trong bất kỳ đánh giá mô hình nào, nơi biên soạn một tập dữ liệu đại diện và chọn một phương pháp có ý nghĩa diễn ra trước chỉ số, không phải sau nó.

Kết luận: Báo cáo Khoảng, Không Chỉ là Số

Phát hiện hữu ích không phải là câu trả lời của AI thay đổi. Mỗi hướng dẫn đều đã nói điều đó. Phát hiện hữu ích là chúng thay đổi với những mức độ khác nhau ở các lớp khác nhau, và kích thước mẫu cần thiết được chia tách theo đó: một vài lần chạy cho kho lưu trữ trích dẫn, khoảng một trăm cho một tỷ lệ bạn dự định bảo vệ trong một cuộc họp.

Thiết kế phía sau sự phân chia đó là bốn tệp và một trăm cuộc gọi. Thu thập với các đầu vào đã ghim, giảm xuống các lớp có thể so sánh, đánh giá sự chuyển động, chuyển đổi sang số lần chạy. Chạy nó một lần chống lại bộ gợi ý của riêng bạn và bạn ngừng đoán một nhịp điệu, vì bạn sẽ có một số duy nhất mà mỗi bảng điều khiển khả năng nhìn thấy AI hiện đang thiếu — thanh sai số.

Sẵn Sàng Đo Biến Đổi Khả Năng Nhìn Thấy AI Của Bạn?

Năm động cơ trả lời nằm sau một điểm cuối và một phong bì phản hồi trên API Thu Thập Toàn Cầu Scrapeless, điều này làm cho ma trận thu thập một trăm trở thành một buổi chiều duy nhất thay vì năm tích hợp riêng biệt. Các tham số và hình dạng phản hồi cho mọi tác nhân được sử dụng ở đây có trong tài liệu API Scrapeless.

Tạo một tài khoản Scrapeless miễn phí và đặt một thanh sai số lên các số khả năng nhìn thấy của bạn.

Câu hỏi thường gặp

Hỏi: Một số liệu khả năng nhìn thấy AI thực sự cần bao nhiêu lần chạy?

Điều đó phụ thuộc vào lớp, và hai câu trả lời khác biệt hơn một bậc số học. Trong ma trận này, ba đến bốn lần lặp lại mỗi máy tìm kiếm cho mỗi gợi ý phục hồi 83% đến 92% các miền đã trích dẫn mà năm lần lặp lại hiện ra, vì vậy một kho lưu trữ trích dẫn là có thể đọc được ở kích thước mẫu đó. Một chỉ số tỷ lệ như tỷ lệ đề cập cần khoảng 100 lần thu thập cho mỗi máy tìm kiếm cho mỗi gợi ý trước khi một khoảng 95% thu hẹp xuống khoảng ±10 điểm, và năm lần thu thập để lại nó rộng khoảng 65 điểm.

Hỏi: Tại sao câu trả lời AI thay đổi khi gợi ý và cài đặt là giống nhau?

Các mô hình lấy mẫu từ một phân phối xác suất và lớp lấy lại cung cấp cho chúng cũng không cố định, vì vậy các đầu vào giống nhau không đảm bảo các đầu ra giống nhau. Công việc đã ghim năm mô hình vào các cài đặt xác định về mặt nominal qua tám nhiệm vụ vẫn ghi nhận sự dao động độ chính xác lên tới 15% giữa các lần chạy, và gán hiệu ứng này cho cách mà các lô suy diễn được xử lý chứ không phải do lỗi cấu hình.

Hỏi: Các nguồn đã trích dẫn có ổn định hơn văn bản câu trả lời không?

Không một cách đáng tin cậy, và không đủ để bỏ qua việc lấy mẫu lặp lại trên bất kỳ lớp nào. Các tập hợp miền đã trích dẫn trong ma trận này chồng chéo với một Jaccard trung bình cặp là 0.384 trong khi một lần thu thập duy nhất chỉ hiển thị 49.6% các miền mà năm lần thu thập hiện ra, vì vậy lớp trích dẫn di chuyển đáng kể về mặt tuyệt đối. Nó hội tụ nhanh hơn so với một chỉ số tỷ lệ, điều này là một tuyên bố khác với việc ổn định.

Hỏi: Liệu động cơ mà tôi theo dõi có thay đổi số lần chạy tôi cần không?
Có, theo một yếu tố khoảng hai trên lớp trích dẫn. Một lần thu thập duy nhất đã thu được 73,6% liên minh miền năm lượt trên động cơ ổn định nhất trong ma trận này và 35,1% trên động cơ kém ổn định nhất, vì vậy số lần chạy được chọn cho một động cơ sẽ không chính xác cho động cơ khác. Tính toán đường bao phủ theo từng động cơ thay vì áp dụng một con số cho tất cả.

H: Biện pháp này có đo lường độ trôi dạt hàng ngày không?

Không. Tất cả 100 lần thu thập đều diễn ra trong vòng 4 phút 9 giây, điều này cô lập tính không xác định ở cấp độ mô hình và loại trừ việc cập nhật chỉ mục, chu kỳ tin tức, thay đổi nội dung và các phiên bản mô hình. Xem mọi con số ở đây như một đáy: một chương trình lấy mẫu trong nhiều tuần sẽ mang theo độ biến đổi này cộng với mọi thứ mà khoảng thời gian ngắn đã giữ nguyên.

H: Việc ghi lại câu trả lời của AI theo cách này có hợp pháp không?

Ghi lại các câu trả lời AI công khai có sẵn cho những gợi ý bạn tạo ra là việc thu thập dữ liệu web công khai thông thường, và các gợi ý cũng như phản hồi ở đây không chứa dữ liệu cá nhân. Giữ cho thể tích bị giới hạn và tỷ lệ với phép đo, chỉ lưu trữ những gì phân tích cần, và kiểm tra các điều khoản áp dụng cho khu vực pháp lý và trường hợp sử dụng của bạn trước khi chạy một chương trình ở quy mô lớn.

H: Tôi có thể chạy điều này mà không cần tác nhân AI hoặc SDK không?

Có. Mọi kịch bản ở đây đều là thư viện tiêu chuẩn Python đối với một điểm cuối HTTPS, vì vậy toàn bộ quy trình chạy từ một tác vụ cron hoặc một lịch trình CI mà không cần cài đặt gì ngoài Python. Phụ thuộc bên ngoài duy nhất là khóa API.

Tại Scrapless, chúng tôi chỉ truy cập dữ liệu có sẵn công khai trong khi tuân thủ nghiêm ngặt các luật, quy định và chính sách bảo mật trang web hiện hành. Nội dung trong blog này chỉ nhằm mục đích trình diễn và không liên quan đến bất kỳ hoạt động bất hợp pháp hoặc vi phạm nào. Chúng tôi không đảm bảo và từ chối mọi trách nhiệm đối với việc sử dụng thông tin từ blog này hoặc các liên kết của bên thứ ba. Trước khi tham gia vào bất kỳ hoạt động cạo nào, hãy tham khảo ý kiến ​​cố vấn pháp lý của bạn và xem xét các điều khoản dịch vụ của trang web mục tiêu hoặc có được các quyền cần thiết.

Bài viết phổ biến nhất

Danh mục