I built a system that auto-generates a JSON-LD Knowledge Graph on every post of this blog. Five connected entities: WebSite, Organization, Person, WebPage, and BlogPosting. Automatic topic detection, relationships between posts, translations in three languages. All in one PHP function that runs on every page load.

I wanted to know how well it works from the perspective of the AI models that read it. So I copied the JSON-LD block from a published post and sent it to three models with the same prompt, word for word. I asked for a score from 1 to 10 for AI citation visibility, what is implemented correctly, what is missing, and what should change.

Gemini gave 9 out of 10. ChatGPT gave 8.2 out of 10. Perplexity gave 7.5 out of 10.

The same schema. The same prompt. Three different evaluations.

Where all three agreed

All three confirmed that the @graph architecture with entities connected by @id is correct. It is not the approach most JSON-LD tutorials teach (nested objects without identifiers), but it is the one knowledge graph systems prefer. Each entity has a persistent @id that is reused across every page on the site. When a machine reads the homepage and then a blog post, it recognizes the same author, the same organization, the same knowledge system.

All three also validated the separation between about and mentions. about declares the main topics of the article. mentions declares tools and references that appear in the content. This distinction helps AI models categorize correctly. An article about Knowledge Graphs that mentions Claude should not be categorized under Claude.

The workTranslation property connecting the Spanish, English, and Japanese versions also received unanimous approval. Most multilingual sites treat each language as a separate island. Connected translations consolidate authority instead of fragmenting it.

What all three flagged as problems

Four issues appeared in all three audits.

First, headline pollution. The title included "| Shinobis" at the end. Gemini and ChatGPT flagged it explicitly: the site name belongs in the HTML title tag for browsers, not in the headline property of the schema. AI models use the headline for semantic matching. A brand name at the end adds noise without information.

Second, Person versus Organization confusion. The sameAs on the Person entity pointed to the company LinkedIn page instead of a personal profile. All three audits caught it. If the Person and the Organization share the same LinkedIn profile, knowledge graph systems cannot distinguish the two entities. The fix is to use the personal LinkedIn profile for the Person and the company profile for the Organization.

Third, the Person entity name. ChatGPT and Perplexity suggested inverting the names: use "Diego Sanchez" as name and "Shinobis" as alternateName. The reason: the Organization is already called "Shinobis". If the Person is also called "Shinobis", knowledge graphs cannot resolve the ambiguity. The human is the real name. The alias is the alternative.

Fourth, the interaction statistic. The schema included interactionStatistic with a count of 2 likes. ChatGPT and Perplexity flagged it as potentially harmful: a low number can signal low authority instead of engagement. The recommendation was to remove the property until the numbers are significant.

Where they diverged

This is where it gets interesting. Each model prioritized different aspects.

Gemini focused on the audience property and hasPart for article sections. Its perspective: RAG (Retrieval-Augmented Generation) systems need to know who the content is for when users ask role-specific questions. "What should a UX designer do about GEO?" is a different query from "What should an SEO do about GEO?" The audience property helps the model decide which to serve.

ChatGPT focused on entity typing. The strongest feedback was about anonymous Thing objects. Every about and mentions entity was a generic Thing with just a name. ChatGPT suggested switching to DefinedTerm with sameAs pointing to Wikipedia. "Knowledge Graph" as a Thing is a text string. "Knowledge Graph" as a DefinedTerm with sameAs to Wikipedia is an identifiable concept that models can resolve against their own knowledge base. It also proposed creating persistent @id values for each concept (like /entity/geo) and reusing them across all posts and all languages.

Perplexity was the most granular. It requested explicit affiliation connecting Person to Organization, structured hasOccupation instead of just jobTitle, timeRequired so models can assess content depth, and noted that author and publisher inside BlogPosting should use @id references instead of inline objects. The point about @id versus inline is technically correct: @id references are cleaner for graph resolution. But Google Rich Results Test sometimes does not resolve @id references, so the current approach (both: @id plus inline properties as fallback) is intentional.

What I implemented

From the three audits combined, I implemented six changes.

I cleaned the headline by removing "| Shinobis" from the property. The site name stays in the HTML browser_title but does not pollute the schema.

I separated sameAs profiles. The Person now points to personal profiles. The Organization points to company profiles.

I inverted the names. name is "Diego Sanchez", alternateName is "Shinobis".

I removed interactionStatistic until the numbers are significant.

I added the citation property with links to the sources each post references. All three models requested it. It is the strongest missing trust signal.

I added audience with the specific roles each post is relevant for.

What I discarded

Three suggestions I did not implement.

The Blog entity connecting all 52 posts. ChatGPT and Perplexity requested it. It is technically correct but adds significant complexity to the PHP generator. Every post would need to include the @id of all 52 articles. On a blog that grows every week, that means regenerating the schema of all existing posts every time a new one is published. The benefit does not justify the complexity for now.

BreadcrumbList. All three mentioned it. It is useful for navigation but my blog has a flat structure (no hierarchical categories). A breadcrumb of Home > Blog > Article does not add information that the existing schema does not already have.

DefinedTerm with persistent @id for each concept. ChatGPT's idea is brilliant in theory: create /entity/geo as an @id that is reused across all posts and all languages. In practice, it requires an entity management system I do not have. It is an improvement for the future, not for now.

What the score difference reveals

Gemini gave the highest score (9/10) and was the least detailed in its improvements. ChatGPT gave 8.2/10 with the most architectural feedback. Perplexity gave 7.5/10 with the most granular and technical feedback.

The difference does not mean one is a better auditor than the others. It means they evaluate with different criteria. Gemini prioritizes overall structure and high-level relationships. ChatGPT prioritizes entity resolution and semantic typing. Perplexity prioritizes individual properties and schema completeness.

If I had asked only Gemini, I would have thought I was nearly perfect. If only Perplexity, I would have thought I had serious problems. The reality is that the schema was solid in architecture but weak in granularity. The three perspectives together gave a more complete picture than any one of them alone.

This is Cogitare Debes applied to technical structure. You do not ask one AI. You ask three. You implement what overlaps. You evaluate what diverges. You discard what does not justify the complexity.

The updated schema is running in production. Every post on this blog auto-generates the JSON-LD with the six changes implemented. If you want to audit your own schema, copy the JSON-LD block from any page and paste it into ChatGPT, Gemini, and Perplexity with the same prompt. All three will find different things. That is exactly the point.