# Your schema validates. Google AI Mode still can&#39;t find you. Here&#39;s the missing piece.

A site I work on dropped out of Google AI Mode citations for the operator&#39;s own name after a routine schema cleanup. The fix was not more schema. It was binding the entity to Google&#39;s Knowledge Graph with kgmid, Maps cid, and dual-typed JSON-LD.

Author: J.A. Watte
Published: May 13, 2026
Source: https://jwatte.com/blog/blog-ai-mode-entity-anchors-knowledge-graph/

---

A site I work on stopped showing up in Google AI Mode for the operator's own first and last name. 48 hours earlier, typing the name in AI Mode surfaced the site as a cited source. The day after a schema cleanup, the citation was gone. Typing the brand name still pulled the site. Typing the person's name only worked when paired with the brand.

I want to walk through what actually broke, because the answer surprised me, and it has nothing to do with "is my schema valid." It was valid before, and it is valid now. The lesson is about a separate layer of signals that most schema audits never look at.

## What changed in the schema cleanup

The night before the citations dropped, I made three changes:

1. Swapped the primary contact email from an employer-domain address to a brand-domain address. Both addresses still appear on the site. The brand-domain one is canonical now.
2. Changed `worksFor` on a vertical-business node to `parentOrganization`, because a schema validator flagged `worksFor` as a Person property when the node was typed as `RealEstateAgent` (a LocalBusiness subtype).
3. Trimmed a couple of CSS selectors out of the `Speakable` block that did not exist in the DOM.

Each change individually made the schema cleaner. None of them broke parseability. Nine JSON-LD blocks, zero errors, on every locale. Google's Rich Results Test would have given the page a green light.

But two of those changes severed a quieter set of signals: the ones AI search uses to bind a person's name to a specific URL.

## The thing schema validators do not check

Validators answer one question: does this JSON-LD parse, and do the required fields exist for the rich-result type. That is a useful check. It is not the same question AI search is asking.

AI search, when it sees the query "Jane Smith real estate agent Portland," is not running a rich-results test on candidate pages. It is doing entity reconciliation: which entity in my knowledge graph does "Jane Smith real estate agent Portland" refer to, and which URLs has that entity been bound to.

The binding happens through cross-references. Every signal that says "this URL is associated with this entity" feeds the binding. Strong signals: a Wikipedia article, a Wikidata Q-number, a Google Knowledge Panel the entity has claimed. Medium signals: LinkedIn, Google Business Profile, industry directory profiles (Realtor.com, Avvo, ZocDoc, Amazon Author Central). Weak signals: incoming links from any other site to a profile page.

Where does schema fit in? Schema is how the page tells Google which entity it claims to be about. The `sameAs` array is the page declaring its own cross-references. The `@id` field is the page declaring its canonical entity identifier. When schema is missing, weak, or self-referential, the reconciliation gets noisy.

What I did in the cleanup made the reconciliation noisier in two specific ways:

The email swap replaced a multi-year-old employer-domain address (which appeared in industry directories, MLS records, public licensee lookups, and the operator's LinkedIn profile) with a brand-new brand-domain address that exists nowhere else on the public web. From the model's perspective, the old email was a strong cross-reference. The new email is a self-reference. Self-references do not strengthen a binding. They restate what the model already knows.

The `worksFor` → `parentOrganization` swap was technically correct but semantically different. `worksFor` says "the person works for the parent company." `parentOrganization` says "this business entity is a subsidiary of the parent company." Both are valid. Only the first one tells Google that there is a Person entity here who is employed somewhere else.

## What I actually changed to recover the citation

The fix was not "put it back." Some of the cleanup was correct. The fix was binding the entity properly. Five additions to the JSON-LD across all three locale templates:

**1. Dual-typed Person and vertical business**

Schema.org allows multiple types on one node. Instead of typing the agent as a standalone `RealEstateAgent`, type it as both:

```json
"@type": ["Person", "RealEstateAgent"],
"@id": "https://yoursite.com/#you"
```

This matters because it makes `worksFor` valid on the same node that declares the vertical type. Google merges properties. The dual-typed node is one entity that knows both "this is a person" and "this person is also a real estate agent." Most individual practitioner sites (real estate agents, attorneys, dentists, physicians, photographers, financial advisors, independent consultants) should be using this pattern.

**2. Shared `@id` across schema blocks**

The site had two JSON-LD blocks describing the same person: one typed `RealEstateAgent`, one typed `Person`. They had different fields. To a naive reader, they look like two separate entities.

Adding the same `@id` to both tells Google "merge these. They are the same entity." The merged entity carries the union of properties from both blocks. This is a quiet but very strong consolidation signal.

**3. Google Knowledge Graph kgmid**

If your entity already has a Knowledge Panel, it has a kgmid. The kgmid is the machine identifier Google uses internally. Looks like `/g/11z2t3900w`. You can find yours by inspecting the share link on your Knowledge Panel or by querying the [Knowledge Graph Search API](https://developers.google.com/knowledge-graph).

Once you have it, expose it two ways in your schema:

```json
"identifier": [{
  "@type": "PropertyValue",
  "propertyID": "googleKgmid",
  "value": "/g/<your-kgmid>"
}],
"sameAs": [
  "https://www.google.com/search?kgmid=/g/<your-kgmid>",
  ...
]
```

This is the single strongest binding you can publish, because you are handing Google a direct pointer to its own internal entity. It cannot be misinterpreted.

**4. Google Maps cid URL**

For local entities, the Maps canonical URL is the second-strongest binding. Format: `https://www.google.com/maps?cid=<your-numeric-cid>`. You can find it by clicking Share on your Business Profile and inspecting the embed URL, or via the long-form Maps URL when you search your business.

Add it to `sameAs`. Together with the kgmid, you now have two direct Knowledge Graph references on the same node.

**5. Remove circular self-references from `sameAs`**

The page had the site's own canonical URL listed in the `sameAs` of an entity whose `url` field was already the same. `sameAs` is for pointing to OTHER profile URLs of the same entity. A circular self-reference is noise that dilutes the array. I removed three of them across the schema blocks.

The new `sameAs` ended up looking like this, with the placeholders showing the shape:

```
https://www.linkedin.com/in/<your-handle>
https://www.google.com/search?kgmid=/g/<your-kgmid>
https://www.google.com/maps?cid=<your-cid>
https://share.google/<your-gbp-share>
https://www.realtor.com/realestateagents/<your-id>     (or industry equivalent)
https://directories.apps.realtor/memberDetail/?personId=<your-id>...
```

Six off-site profile URLs, all of which point back to the same person, none of which are self-references.

## Three identity anchors from one Google Maps share URL

For local businesses, this technique unlocks the three highest-impact KG anchors at once: the kgmid, the Maps canonical CID, and the Google Place ID. All you need is the share URL Google emits when you tap "Share" on your Business Profile (`https://maps.app.goo.gl/<token>`).

Step 1 — follow the redirect to get the canonical Maps URL:

```bash
curl -sIL "https://maps.app.goo.gl/<your-share-token>" \
  -A "Mozilla/5.0" | grep -i ^location
```

The Location header looks like:

```
https://www.google.com/maps/place/<NAME>/@<lat>,<lng>,<zoom>m/data=!3m2!1e3!4b1!4m6!3m5!1s0x<PLACEID_HEX>:0x<CID_HEX>!8m2!3d<lat>!4d<lng>!16s%2Fg%2F<KGMID>
```

Three identifiers fall out of that one string:

- **kgmid** is the segment after the URL-encoded `%2Fg%2F`. Decode to `/g/<base32>`. This is the Google Knowledge Graph machine ID for your business.
- **Place ID** is the hex value before the colon in `!1s0x<HEX>:0x<HEX>`.
- **CID** is the hex value AFTER the colon in the same segment. Convert to decimal with `BigInt('0x<HEX>').toString()` to build the canonical Maps URL.

Step 2 — wire all three into your LocalBusiness schema:

```json
{
  "@type": ["LocalBusiness", "<your vertical>"],
  "@id": "https://yourbusiness.com/#business",
  "hasMap": "https://www.google.com/maps?cid=<decimal-CID>",
  "geo": { "@type": "GeoCoordinates", "latitude": "<from Maps URL>", "longitude": "<from Maps URL>" },
  "identifier": [
    { "@type": "PropertyValue", "propertyID": "googleKgmid", "value": "/g/<base32>" },
    { "@type": "PropertyValue", "propertyID": "googlePlaceId", "value": "0x<PLACEID_HEX>" }
  ],
  "sameAs": [
    "https://www.google.com/maps?cid=<decimal-CID>",
    "https://maps.app.goo.gl/<your-share-token>",
    "https://www.google.com/search?kgmid=/g/<base32>"
  ]
}
```

Use the lat/lng from the resolved Maps URL as your `geo.GeoCoordinates`. Google's own value is the ground truth — your old coords are probably off by 10–50 meters, which is enough to weaken local-entity binding when AI Search compares them against Google's place graph.

This is the playbook I used on a self-storage operator I work with the same day Google Business Profile was claimed. Two minutes of `curl` and `BigInt` work, three new sameAs entries, two new `identifier` PropertyValues, refined lat/lng across the schema and the meta tags. The kgmid is the single strongest KG reconciliation signal you can publish, and it's only available once a Business Profile is verified — so the share URL is the moment where you can finally claim that strongest anchor.

## ProfilePage — the one rich result type that surfaces Person/Org entities

Person and Organization schema feed the Knowledge Graph but do not render rich results in Google's tester. If your "About" page or your operator-bio page has Person/Org but nothing else rich-result-eligible (no FAQ, no HowTo, no Article, no Recipe), Google's Rich Results Test will show "no rich results detected" — even though your structured data is excellent for AI Search.

The fix is `ProfilePage`. Google added it in 2023 specifically for pages that ARE a profile of a person or organization (author bios, team-member pages, individual-practitioner pages, operator-bio pages, AboutPage variants).

Required:
- `@type: "ProfilePage"`
- `mainEntity` referencing the Person or Organization by `@id`
- Either `dateCreated` or `datePublished`

Recommended:
- `dateModified`
- `primaryImageOfPage`
- `breadcrumb` (referencing your existing BreadcrumbList by `@id`)

Inline example:

```json
{ "@context": "https://schema.org",
  "@type": "ProfilePage",
  "name": "Your Name — Author profile",
  "url": "https://yoursite.com/about/",
  "mainEntity": { "@id": "https://yoursite.com/#yourname" },
  "about": { "@id": "https://yoursite.com/#yourname" },
  "dateCreated": "2024-01-01",
  "datePublished": "2024-01-01",
  "dateModified": "2026-05-14",
  "primaryImageOfPage": { "@type": "ImageObject", "url": "https://yoursite.com/headshot.jpg" }
}
```

ProfilePage is the only Google-supported rich result type that surfaces a Person-centric or Organization-centric page in search. Without it, all the canonical Person work you did still feeds the KG, but Google's Rich Results Test will tell you "only FAQ + Breadcrumb" — which is technically correct because FAQ and Breadcrumb are the only rich-result-eligible types on a generic page without ProfilePage. Adding it unlocks the dedicated profile presentation immediately.

## The checklist, if you operate your own site

You do not need to be a real estate agent for any of this to apply. The same pattern works for anyone whose name is the search query that should resolve to their site: indie authors, photographers, attorneys in solo practice, financial advisors, consultants, dentists, anyone running a personal brand.

Run this against your own about page:

1. Is there one `@id` on your Person or Organization node, and is it reused across every JSON-LD block on the page that mentions you?
2. If you are a vertical business type (`RealEstateAgent`, `Attorney`, `Dentist`, `Physician`, etc.), is your `@type` an array that also includes `Person`?
3. Does your `sameAs` include at least three off-site profile URLs that are NOT your own domain?
4. If you have a Google Knowledge Panel or claimed Business Profile, is your kgmid in `sameAs` as the `https://www.google.com/search?kgmid=...` form, AND in `identifier` as a `PropertyValue` with `propertyID: "googleKgmid"`?
5. If you have a Google Business Profile, did you follow the Maps share URL redirect to extract the canonical `?cid=<decimal>` URL, the Place ID, and refined Google coordinates — and wire all of them in?
6. Are you listing your own page URL in your own `sameAs`? If yes, remove it.
7. Is `mainEntityOfPage` set on your entity node pointing to the URL you want treated as the entity's canonical home?
8. If you are an employed practitioner, do you declare `worksFor` (the Person side) AND `parentOrganization` (the LocalBusiness side) on a dual-typed node? Both is fine. The redundancy reinforces the same fact for the model.
9. If the page is an "about" or operator-bio page, does it use `@type: "ProfilePage"` (with `mainEntity` referencing the Person/Org `@id`) so it qualifies for the Google ProfilePage rich result?
10. Is each inline entity declared once with full data and referenced everywhere else via `{ "@id": "..." }` — not duplicated as five inline copies with subtly different `alternateName` values? (See the [entity duplication post](/blog/blog-entity-duplication-ai-search/) for why this matters.)

## What I added to the Mega Analyzer

I shipped a new "Entity anchors" section to the [Mega Analyzer](/tools/mega-analyzer/) on the same day I wrote this, then expanded it with ProfilePage detection, Google Place ID identifier detection, `hasMap` field detection, and duplicate-inline-block conflict detection in follow-up passes. It runs every check above against any URL you point it at and tells you which signals are present, missing, or actively hurting (circular self-references show up red, multiple inline blocks at the same `@id` show up red, conflicting `alternateName` types show up red). It also adds an eighth cell to the AI Eligibility composite labeled "Entity anchors (KG)" that summarizes the binding strength in one glance and flips to red the moment the duplicate-inline antipattern is detected.

If you are working through your own about page or your operator-bio page, that is the fastest way to see all eight signals in one read. No signup, no capture, free.

## Why this matters more in 2026

Google AI Mode rolled out broadly in early 2026. Perplexity, ChatGPT search, and Claude search all do similar entity-aware retrieval. None of them index every page the same way Googlebot does. Most of them rely heavily on the Knowledge Graph as a routing layer: which entity is the user asking about, and which URLs has that entity claimed.

The pages that get cited are not always the pages with the most words or the highest authority score. They are the pages the model can confidently bind to a specific named entity in its graph. If the binding is strong, you get cited. If the binding is ambiguous, the model defaults to a directory listing, a Wikipedia article, or a competitor whose binding happens to be stronger.

This is the layer below "is my schema valid." Most of the audit tools you can buy or run for free will tell you about the schema layer. Very few will tell you about the entity-binding layer. That gap is what I am trying to close in the Mega Analyzer additions, and it is what cost me a citation for 48 hours on a site that was already shipping good schema.

If you want the longer playbook on running these audits as your own one-person SEO operation, that is most of what I cover in [*The $20 Dollar Agency*](https://the20dollaragency.com/). The thesis is that the same audits a $5,000-a-month agency runs are now cheaper than a sandwich if you know where to look and how to read the output. The kgmid and Maps cid binding I described above costs nothing to add. Just time.

## Fact-check notes and sources

- Schema.org `@type` allows arrays for multi-typing per the [JSON-LD 1.1 specification, section on type values](https://www.w3.org/TR/json-ld11/#typed-values) and the underlying [schema.org Person documentation](https://schema.org/Person). Google has supported multi-typed entities on `RealEstateAgent`, `Attorney`, `Dentist`, `Physician`, and other vertical types since the 2019 rich-results expansion.
- The Google Knowledge Graph kgmid format `/g/<base32>` is documented in the [Knowledge Graph Search API reference](https://developers.google.com/knowledge-graph). The `https://www.google.com/search?kgmid=...` URL form is the canonical user-facing entity URL Google itself emits in Knowledge Panel share links.
- Google Business Profile cid URLs (`https://www.google.com/maps?cid=<numeric>`) are the canonical machine-readable form of a verified Business Profile and predate the share.google rebrand. They are still emitted by Maps APIs in place-id lookups.
- `sameAs` semantics (linking entities to canonical off-site profile URLs, not self-references) are codified in the [schema.org `sameAs` documentation](https://schema.org/sameAs) and reinforced in Google's [Article structured data documentation](https://developers.google.com/search/docs/appearance/structured-data/article) on author and publisher entities.
- `worksFor` is a Person property; `parentOrganization` is an Organization property. Both are valid on a dual-typed `["Person", "RealEstateAgent"]` node per schema.org's type-inheritance rules.

## Related reading

- [Building Your E-E-A-T Profile Network: Google, Wikidata, LinkedIn & More](/blog/blog-eeat-google-wikidata-profiles/) covers which off-site profiles actually feed the Knowledge Graph and which are decorative.
- [E-E-A-T schema and structured data](/blog/blog-eeat-schema-structured-data/) is the foundation post on why schema matters for the expertise side of E-E-A-T.
- [Crunchbase and the Knowledge Graph](/blog/blog-crunchbase-knowledge-graph/) looks at one specific profile vector that punches above its weight for business entities.
- [Why writing for AI citations rewards entity density](/blog/blog-ai-citation-writing-frameworks-bluf-entity-density/) is the on-page version of this argument: entity-dense prose binds the same way schema entity anchors bind.
- [Cross-domain entity consistency](/blog/blog-tool-cross-domain-entity-consistency/) is the audit pattern for catching the case where your name, role, or credentials drift across profiles.

*This post is informational, not legal or SEO-consulting advice. Mentions of Google, LinkedIn, Realtor.com, NAR, and other third parties are nominative fair use. No affiliation is implied.*


---

Canonical HTML: https://jwatte.com/blog/blog-ai-mode-entity-anchors-knowledge-graph/
RSS: https://jwatte.com/feed.xml
JSON Feed: https://jwatte.com/feed.json
Hero image: https://jwatte.com/images/blog-ai-mode-entity-anchors-knowledge-graph.webp
