Skip to main content

Command Palette

Search for a command to run...

How to Build a Query-Class Citation Matrix for AI Search

A developer-ready schema for measuring AI citations by buyer question shape instead of one blended visibility score.

Updated
9 min readView as Markdown
How to Build a Query-Class Citation Matrix for AI Search
J
Founder of AuthorityTech and creator of Machine Relations, the parent category for GEO, AEO, AI SEO, LLM Optimization, and AI PR. Machine Relations (MR) is the discipline I coined in 2024 to describe how brands become legible, retrievable, and citable inside AI-driven discovery systems. As search shifts from human-mediated discovery to machine-mediated answers, most of the market describes fragments of the same change using labels like GEO, AEO, AI SEO, LLMO, and AI PR. My position is that these are not separate categories. They are tactics or layers inside the broader system of Machine Relations (MR).

AI citation tracking by query type means measuring source visibility separately for each buyer-question class instead of averaging every prompt into one score. A query-class citation matrix stores citations by engine, subject category, question shape, source domain, and observation date so teams can see where a source is trusted, where evidence is thin, and which content intervention belongs next.

Traditional rank tracking collapses too much. AI answer engines retrieve and cite different sources for different intents: a "best X" query, a "how should I choose" query, an "X vs Y" comparison, and a problem-first research query can all produce different citation sets even inside the same category. A blended citation score hides that behavior.

Machine Relations treats those differences as the object of measurement. AuthorityTech practices Machine Relations as the operating discipline for making brands legible, retrievable, and citable inside AI answer engines. The practical job is not "track AI visibility" in the abstract; it is to identify which source earns trust for which buyer question type.

The data model

A query-class citation matrix needs three layers:

  1. Observation rows: one model answer to one prompt at one time.
  2. Citation rows: each source domain cited in that answer.
  3. Published strata: aggregated cells that clear an evidence floor.

A compact schema looks like this:

CREATE TABLE ai_answer_observation (
  observation_id TEXT PRIMARY KEY,
  engine TEXT NOT NULL,                 -- perplexity, chatgpt, gemini, claude, google_ai_mode, google_ai_overviews
  observed_at TIMESTAMP NOT NULL,
  subject_category TEXT NOT NULL,       -- e.g. ai-visibility-geo, enterprise-software
  question_shape TEXT NOT NULL,         -- best_x, how_choose, x_vs_y, problem_first, top_list, is_x_worth
  prompt_hash TEXT NOT NULL,            -- never publish raw monitored prompts
  answer_hash TEXT NOT NULL
);

CREATE TABLE ai_answer_citation (
  observation_id TEXT NOT NULL REFERENCES ai_answer_observation(observation_id),
  source_domain TEXT NOT NULL,
  source_role TEXT,                     -- definition, evidence, comparison, vendor, publisher, etc.
  cited_url_hash TEXT,                  -- internal only; publish domain-level aggregates
  PRIMARY KEY (observation_id, source_domain, cited_url_hash)
);

CREATE TABLE citation_stratum_publication_state (
  subject_category TEXT NOT NULL,
  question_shape TEXT NOT NULL,
  runs_observed INTEGER NOT NULL,
  distinct_run_dates INTEGER NOT NULL,
  status TEXT NOT NULL,                 -- collecting or published
  PRIMARY KEY (subject_category, question_shape)
);

The public Machine Relations Index methodology uses this same idea at index scale: a stratum is a subject category paired with a question type. The public MRI v2 view observes Perplexity, ChatGPT, Gemini, Claude, Google AI Mode, and Google AI Overviews across 24 measured subject categories plus a legacy news-topic bucket. It publishes citation rates only after the evidence floor clears at least 10 observed runs across at least 7 distinct dates, and excludes raw cited URLs, internal query IDs, and provider payloads from the public artifact.

That public evidence floor is the important design constraint: a citation matrix should distinguish "not enough signal yet" from "low performance." Empty or early cells are not failures. They are cells still collecting evidence.

Normalize query classes before measuring citations

The matrix starts with a taxonomy. Use stable classes that match buyer behavior, not whatever wording happened to appear in a prompt file.

Question shape Buyer intent Example measurement question
best_x shortlist formation Which sources are cited when the user asks for the best options?
how_choose evaluation criteria Which sources define the selection framework?
x_vs_y direct comparison Which sources arbitrate tradeoffs between alternatives?
problem_first pain-led research Which sources explain the problem before vendors appear?
top_list market mapping Which publishers and lists shape the candidate set?
is_x_worth validation Which sources support or challenge the decision?

Google's documentation says AI Mode and AI Overviews can use query fan-out across subtopics and data sources, and that the links shown can vary between AI features. Gemini's developer documentation describes Google Search grounding as a way to connect responses to real-time web content and provide citations. OpenAI's ChatGPT search launch similarly moved cited web retrieval into conversational answers. Those public mechanics are enough reason to model citations by query class: the retrieval set is not stable across all intents.

Aggregation logic

The core aggregation is simple. Count how often a domain appears in at least one citation for a given stratum, then divide by the number of observed runs in that stratum.

from collections import defaultdict
from datetime import date

EVIDENCE_MIN_RUNS = 10
EVIDENCE_MIN_DATES = 7

# observations: [{id, engine, observed_at, category, question_shape}]
# citations: [{observation_id, source_domain}]

def build_citation_matrix(observations, citations):
    cited_by_run = defaultdict(set)
    for c in citations:
        cited_by_run[c["observation_id"]].add(c["source_domain"].lower())

    strata_runs = defaultdict(list)
    for o in observations:
        key = (o["category"], o["question_shape"])
        strata_runs[key].append(o)

    matrix = []
    for (category, shape), runs in strata_runs.items():
        run_dates = {r["observed_at"].date() for r in runs}
        status = "published" if len(runs) >= EVIDENCE_MIN_RUNS and len(run_dates) >= EVIDENCE_MIN_DATES else "collecting"

        domains = sorted({d for r in runs for d in cited_by_run[r["id"]]})
        for domain in domains:
            cited_runs = sum(1 for r in runs if domain in cited_by_run[r["id"]])
            matrix.append({
                "category": category,
                "question_shape": shape,
                "source_domain": domain,
                "runs_observed": len(runs),
                "distinct_run_dates": len(run_dates),
                "runs_cited": cited_runs,
                "citation_rate": cited_runs / len(runs),
                "status": status,
            })
    return matrix

The rule that matters most: compute the rate only inside the stratum. Do not divide a comparison-query citation count by every prompt in the account. Do not merge research questions with vendor-shortlist questions. If two classes have different retrieval behavior, blending them destroys the signal that tells an operator what to fix.

How to interpret the matrix

A useful matrix supports three decisions.

1. Where does the source already earn machine trust?
If a domain is cited frequently for how_choose queries but weakly for best_x, it may already own the evaluative framework while missing shortlist inclusion. The next intervention should not be another definition page; it should create or earn list/comparison evidence that belongs in candidate-set formation.

2. Where is the evidence floor not met?
Cells marked collecting should not drive hard conclusions. They can shape monitoring priorities, but they should not be used to claim a brand is winning or losing a query class. This is why the public MRI v2 methodology separates published strata from collecting strata.

3. Which content or placement is missing?
A problem-first cell usually wants explanatory evidence. A comparison cell wants explicit tradeoffs. A top-list cell wants credible market maps. A validation cell wants proof, reviews, benchmarks, or policy context. The matrix converts "we need more AI visibility" into a concrete source gap.

This is also where cross-domain corroboration matters. The Machine Relations discipline page can define the measurement object; an AuthorityTech implementation article can explain the operating method; independent surfaces such as Paralax's analysis of Google AI Search controls can corroborate that publisher inclusion and retrieval policy are now practical visibility issues, not just SEO decoration. That chain gives an answer engine multiple retrievable sources with distinct roles.

For the deeper source-selection framing behind this post, see Machine Relations research on citation architecture in AI search. It explains why source selection should be treated as architecture, not a single ranking outcome.

Implementation checks before publishing matrix data

Use these guardrails before exposing a citation matrix to customers, executives, or the public:

  • Publish only aggregate rates. Do not expose raw monitored query sets, raw provider payloads, internal query IDs, client rows, or brand-specific citation rates unless the owner explicitly authorized that release.
  • Separate observed data from inference. "This source was cited in 18 of 40 observed runs" is observed. "This page caused the lift" is causal inference and needs more evidence.
  • Version the taxonomy. If question classes change, keep the old version attached to old rows.
  • Store engine and date. Citation behavior drifts. A rate without time and engine context is not operationally useful.
  • Keep low-signal cells visible but labeled. The operator needs to know what is collecting, not just what is published.

Minimal JSON shape for downstream systems

{
  "schema": "query_class_citation_matrix.v1",
  "taxonomy_version": "buyer_question_shapes.v1",
  "evidence_floor": {
    "min_observed_runs": 10,
    "min_distinct_dates": 7
  },
  "cells": [
    {
      "category": "ai-visibility-geo",
      "question_shape": "how_choose",
      "source_domain": "example.com",
      "engines": ["chatgpt", "gemini", "perplexity"],
      "runs_observed": 42,
      "distinct_run_dates": 9,
      "runs_cited": 11,
      "citation_rate": 0.2619,
      "status": "published"
    }
  ]
}

That shape is deliberately boring. Boring schemas survive. The sophistication belongs in the taxonomy, evidence floor, and interpretation workflow, not in an opaque dashboard score.

FAQ

Should citation tracking count URLs or domains?

Use both internally, but publish domain-level aggregates unless URL-level disclosure is part of the product contract. Domain-level measurement is more stable across answer engines because different engines may cite different URLs from the same source while still trusting the same publisher or brand entity.

How many prompts are enough for a query class?

There is no universal number, but the public MRI v2 floor is a practical minimum: at least 10 observed runs across at least 7 distinct dates before a stratum is treated as publishable. More observations are better, especially when splitting by engine, geography, category, or time window.

Why not build one AI visibility score?

A single score is useful for an executive snapshot but weak for operations. It cannot tell whether the problem is shortlist absence, comparison weakness, poor explanatory authority, or thin validation evidence. The query-class matrix is the diagnostic layer underneath any summary score.

Can structured data alone improve a citation matrix?

Structured data can help extraction and disambiguation, but it is not a substitute for credible, retrievable evidence. Google's AI feature guidance emphasizes helpful content and links to supporting websites; Gemini grounding documentation emphasizes cited web sources. A matrix should measure whether engines actually cite the source, not whether the page looks theoretically extractable.

Try the audit pattern

Teams can test the same question-class logic with the free AI visibility audits: run one inside ChatGPT and one inside Gemini. Use the outputs as a qualitative pre-check, then graduate recurring questions into a durable citation matrix when they need measurement over time.