アクセシビリティ属性を JSON-LD で構造化する三層配線

「車椅子で入れる?」「ペット可?」「子連れ大丈夫?」に AI が答えられるようにするための schema.org 配線。amenityFeature の三値表現・業種別 dedicated property・GBP wheelchair_accessible_* の三層を分解し、AI 4 エンジンの引用挙動と失敗モードを整理する。

「車椅子で入れる店を教えて」「ペット可のカフェは?」「離乳食対応の店ある?」。これらは AI アシスタントに対する local business クエリの中でも急速に増えているカテゴリですが、JSON-LD 側の配線となると schema.org の vocabulary は驚くほど散らばっています。amenityFeature は Place と LodgingBusiness にあり、accessibilityFeature は本来 CreativeWork 用、petsAllowed は宿泊業直属、smokingAllowed は Restaurant 直属、isFamilyFriendly は Product と Place。単一の統一 vocab は存在せず、実装する側は毎回どこに書くか判断を迫られます。

本稿はそのエンジニア視点の整理です。私が実装と AI 出力の外形観察を通じて確認した範囲で、accessibility 属性を JSON-LD として構造化する三層 (amenityFeature の三値表現 / 業種別 dedicated property / GBP wheelchair_accessible_* の boolean 4 種) と、それぞれの AI 4 エンジンの解釈差、そして最も遭遇しやすい 5 つの失敗モードを、コードと共に順に書きます。

前提: accessibility は state ではなく stable attribute である

営業時間や在庫状況は「今この瞬間の状態」を表す state field ですが、車椅子対応やペット可は「その店舗が構造的に持っている性質」であり stable attribute です。この違いは AI 引用時の frontier に影響します。state は最新性を疑われますが、attribute は一度書けば「変わっていないはず」の前提で長く引かれます。逆に、undefined (未記載) のまま放置すると、attribute は「その店舗がそれを持たない」と読まれる、あるいはクエリ対象から silent に外される確率が高い。attribute には「未確認」の余地が state ほど残されていないのです。

state field と freshness confidence の関係 で扱った時系列の弱さとは対照的に、accessibility 属性の弱さは「静的な事実の欠落」という別種の問題として現れます。同じ「AI に引かれない」でも原因が違うので、対策も別で組む必要があります。

LLMO Framework の Structure 軸では、accessibility 属性は現在標準化が進む三層モデル (schema.org amenityFeatureLocationFeatureSpecification 三値 + 業種別 dedicated property + GBP wheelchair_accessible_* boolean 4 種) を分解する基本設計として整理されつつあります。GEO は state / attribute の区別を持たず、AEO は QA 場面の disambiguation は扱うものの物理店舗の attribute schema 論は持たない中で、Structure 軸だけがこの三層を明示的に整理しています (LLMO Framework)。

Layer A: amenityFeature + LocationFeatureSpecification (三値)

schema.org で accessibility 属性を書くときに最も汎用的なのが amenityFeature です。値は LocationFeatureSpecification という object で、name (feature の名称) と value (true / false / undefined の三値) を持ちます。ここで重要なのは、value を書かずに name だけを書いてしまうと、AI parser は「feature が存在する」以上の意味を取れず、boolean 化に失敗する点です。

{
  "@context": "https://schema.org",
  "@type": "CafeOrCoffeeShop",
  "@id": "https://example-cafe.jp/#store",
  "name": "Example Cafe 神楽坂店",
  "amenityFeature": [
    {
      "@type": "LocationFeatureSpecification",
      "name": "Wheelchair Accessible Entrance",
      "value": true
    },
    {
      "@type": "LocationFeatureSpecification",
      "name": "Wheelchair Accessible Restroom",
      "value": false
    },
    {
      "@type": "LocationFeatureSpecification",
      "name": "Pets Allowed",
      "value": true
    },
    {
      "@type": "LocationFeatureSpecification",
      "name": "High Chair Available",
      "value": true
    },
    {
      "@type": "LocationFeatureSpecification",
      "name": "Diaper Changing Station",
      "value": false
    }
  ]
}

要点は三つです。第一に、value: false を書くのを恐れてはいけません。「対応していない」を明示することで「未確認」から明確に区別され、AI は不要な hedge を挟まずに答えられます。「レストランのトイレは車椅子対応ではないが、入口とテーブルは対応」のような部分対応の店舗こそ、false を書く価値が最も高い。第二に、name は英語 vocab で統一します。schema.org は英語 vocabulary が canonical で、日本語表記を混ぜると entity 曖昧化の原因になります。第三に、feature の粒度は細かいほうがよく、「子連れ OK」でまとめず「High Chair Available」「Diaper Changing Station」「Kids Menu」に分けて書けば、AI は「離乳食対応の店」「オムツ替えできる店」といった細粒度クエリに答えられます。

AI 引用時の挙動としては、ChatGPT (browsing) は LocationFeatureSpecification の boolean を正確に反映し、Perplexity は source card の badge として表示要素に使う場合があります。Claude は「reportedly wheelchair accessible」の hedge を挟む頻度が高く、undefined (未記載) を「対応していない可能性」に流す傾向が強い。

Layer B: 業種別 dedicated property

schema.org には accessibility 系の情報を扱う dedicated property が、業種ごとに散らばって存在します。petsAllowed は LodgingBusiness 直属、smokingAllowed は Restaurant / FoodEstablishment 直属、isFamilyFriendly は Product / Place 直属で、それぞれ boolean を取ります。amenityFeature と重複する部分もありますが、業種と一致した dedicated property を優先するのが semantically 正しい配線です。

{
  "@context": "https://schema.org",
  "@type": "Hotel",
  "@id": "https://example-hotel.jp/#hotel",
  "name": "Example Hotel 箱根",
  "petsAllowed": true,
  "smokingAllowed": false,
  "amenityFeature": [
    {
      "@type": "LocationFeatureSpecification",
      "name": "Wheelchair Accessible Entrance",
      "value": true
    },
    {
      "@type": "LocationFeatureSpecification",
      "name": "Wheelchair Accessible Restroom",
      "value": true
    }
  ]
}

Restaurant に petsAllowed を書く、Hotel に isFamilyFriendly を書く、といった業種外の使い方は schema バリデータでは通ってしまいますが、AI parser は silent drop します。ここで書きたい実装者は「他業種で pet 可を表現するには?」と迷うことになりますが、答えは Layer A の amenityFeature に「Pets Allowed: true」を書くことです。dedicated property が使えない業種では amenityFeature が事実上の唯一の窓口になります。

Perplexity は業種 dedicated property を明示的に拾う挙動を見せ、petsAllowed: true の Hotel を「pet-friendly」の source card badge に反映するのが観察されます。ChatGPT は dedicated と amenityFeature の両方から拾いますが、両方書かれていると重み付けは dedicated 側がやや強い印象です。

Layer C: GBP wheelchair_accessible_* boolean 4 種

Google ビジネスプロフィール側には、accessibility 属性のうち車椅子対応に絞った 4 つの boolean が dashboard の UI 選択項目として存在します。wheelchair_accessible_entrance (入口)、wheelchair_accessible_restroom (トイレ)、wheelchair_accessible_parking (駐車場)、wheelchair_accessible_seating (座席) の 4 つで、それぞれが Google Knowledge Graph 経由で AI に露出します。schema.org の amenityFeature とは別 vocabulary で、両者を実装側で意識的に同期させる必要があります。

私が観察した挙動として、Gemini はこの 4 boolean を最優先で読み取り、JSON-LD 側の amenityFeature より GBP 側の値のほうが引用結果に強く反映されます (payment 属性と同型症状で、Google 由来の attribute は Gemini で trust boost がかかる)。ChatGPT (browsing) は逆に JSON-LD 側を素直に読む傾向が強く、Claude は両方を突き合わせて矛盾があると hedge を強めます。

診断としては、GBP dashboard で 4 boolean を明示し、同じ内容を JSON-LD 側の amenityFeatureLocationFeatureSpecification として書き、両者が一致していることを確認するのが最短です。差分があると Gemini と ChatGPT で回答が食い違い、「同じ店を聞いても答えが違う」状態が発生します。

三層の比較

場所表現力業種制約主に読む AI
A: amenityFeatureschema.org (Place / LodgingBusiness / Restaurant 等)任意 feature × true/false/undefinedなし、汎用ChatGPT / Perplexity
B: dedicated propertyschema.org (petsAllowed=LodgingBusiness / smokingAllowed=Restaurant / isFamilyFriendly=Product,Place)boolean のみあり (業種一致必須)Perplexity / ChatGPT
C: GBP wheelchair_accessible_*Google Business Profile dashboard4 boolean 固定 (entrance/restroom/parking/seating)Google 側で type ごとに UI 出し分けGemini (最優先) / ChatGPT

三層は排他ではなく重畳です。同じ「車椅子対応」を Layer A の amenityFeature に書き、Layer C の GBP dashboard でも塗る、が正しい配線です。両者が一致していれば AI 側の解釈は安定し、矛盾があれば hedge か Gemini/ChatGPT で回答分岐が起きます。

AI 4 エンジン別の分岐挙動

外形観察の範囲での挙動サマリです。エンジンの内部は確認できないので推測を含みます。

エンジンamenityFeature の解釈dedicated property の解釈GBP wheelchair_accessible_*
ChatGPT (browsing)value: true/false を正確に反映、undefined は「不明」で hedge業種一致していれば強く拾う、業種外は silent drop補助的に参照、JSON-LD 側と一致すれば信頼度上昇
Perplexitysource card の badge に利用、citation 経路も明示badge 表示で強く反映source card の visual badge に反映
Claudehedge を挟む頻度高、undefined を「対応していない可能性」に流しがち業種一致で拾うが hedge 表現多めJSON-LD と GBP の矛盾を検知して両方 hedge
Gemini参照するが Knowledge Graph 経由の GBP 側を優先認識するが Google 側との一致度が支配的最優先、ローカルパック UI にも反映

一貫している傾向として、Perplexity は accessibility 属性を UI 上の visual element として使うことに積極的で、Gemini は Google 由来の attribute を最も信頼します。Claude は保守的で、undefined を「未対応」に流すバイアスがあるため、false を明示的に書くことが Claude 対策として最も効きます。ChatGPT は中間で、書かれた通りに素直に読む挙動です。

Common failure modes

実装後にレビューでよく指摘される失敗モードを 5 つ挙げます。診断チェックリストとして使えます。

1. amenityFeature の value を省略name: "Wheelchair Accessible" だけ書いて value を落とすと、LocationFeatureSpecification としては不完全で、AI は boolean 化に失敗します。「対応している」とは読まれず、Claude は特に silent exclusion に流します。value: true / false を必ず明示することが accessibility 属性の最低要件です。

2. undefined を false と誤読させる書き方。amenityFeature 配列に一部の feature だけ入れて他を書かないと、書いていない feature が「対応していない」と読まれる可能性があります。Claude は特にこのバイアスが強い。対策は「対応していない属性」も明示的に value: false で書くこと、あるいは undefined を残す場合は description で「未確認」と補足すること。

3. 業種 property の誤用による silent drop。Restaurant に petsAllowed を書く、Cafe に numberOfRooms を書く、といった業種外 property は schema バリデータでは通っても AI parser には silent drop されます。ここで指定したかった意味は amenityFeature に移し替えます。

4. GBP と JSON-LD の矛盾。JSON-LD に「Wheelchair Accessible Entrance: true」と書いても GBP の wheelchair_accessible_entrance: false なら AI は矛盾を検知して両方 hedge、あるいは Gemini なら GBP 側を優先します。両者を必ず同期させ、entrance / restroom / parking / seating の 4 boolean は両方で埋めるのが唯一の解です。

5. 英語 vocab と日本語 UI ラベルの断絶。schema.org の amenityFeature.name は英語 vocabulary (Wheelchair Accessible / Pets Allowed / High Chair Available) で書くのが canonical ですが、site 側の日本語 UI (「車椅子対応」「ペット可」) と混在させると entity 曖昧化の原因になります。JSON-LD は英語で統一し、日本語表示は別 layer に持ち、sameAs で GBP URL を配線して名寄せを AI 側に任せるのが安全です。

業種別の非対称

すべての業種で同じ accessibility 属性が同じ重みで引かれるわけではありません。ここは 業種オーバーレイの記事 で扱った業種別の signal 非対称と直接つながる論点です。

業種別に「どの層 (A / B / C) を厚く書くか」の優先順位が変わるのが accessibility 属性の特徴で、単一のテンプレートで全業種をカバーしようとすると必ず何かが薄くなります。業種オーバーレイと accessibility の交点は、業種テンプレートを構築するときの主要な設計変数になります。

実装後の最短診断

自社の JSON-LD に対して、まず curl でページの application/ld+json を dump し、jq '.amenityFeature[] | {name, value}' で全 feature の name と value を並べて、value が undefined になっている feature がないかを確認するところから入ります。undefined が残っていれば、それは AI にとって「引けない属性」なので、true / false を意識的に埋めます。

次に GBP dashboard を開き、wheelchair_accessible_entrance / restroom / parking / seating の 4 boolean が dashboard 上で選択済みか、そして JSON-LD 側の amenityFeature と一致しているかを突き合わせます。矛盾があれば Gemini と ChatGPT で回答分岐が起きるので、優先的に解消すべき箇所です。

最後に、業種 dedicated property (petsAllowed / smokingAllowed / isFamilyFriendly) の業種一致を確認します。書き手が「pet 可を書きたい」と思って全業種の LocalBusiness に petsAllowed を挿入している実装は珍しくありませんが、これは LodgingBusiness 以外では silent drop されます。他業種は amenityFeature に「Pets Allowed: true」で移し替えます。

私たちが書いた accessibility 属性は、GBP 側の attribute UI や schema.org 側の vocabulary boundary の変更で、来週にはまた少し違う読まれ方をするかもしれません。それでも三層 (amenityFeature の三値 / 業種別 dedicated / GBP boolean 4 種) を同時に埋め、undefined を残さないことは、accessibility クエリで silent exclusion されないための最低ラインとして機能します。

内部リンク

よくある質問

amenityFeature の value を書かず name だけ書くと AI はどう解釈しますか
value を省略すると LocationFeatureSpecification は「name という feature が存在する」以上の意味を持たなくなり、boolean 化に失敗します。ChatGPT や Perplexity は「対応している」とは読まず、Claude は hedge を強めます。true / false を明示的に書くことが accessibility 属性の最低要件です。
GBP の wheelchair_accessible_entrance と JSON-LD の amenityFeature が矛盾しているとどう扱われますか
私の観察では Gemini は GBP 側を優先し、ChatGPT (browsing) は JSON-LD 側を素直に読み、Claude は矛盾自体を検知して両方を hedge 付きで併記する傾向があります。実装側で GBP dashboard と JSON-LD を必ず同期させ、entrance / restroom / parking / seating の 4 boolean を両方で埋めるのが唯一の解です。
petsAllowed や smokingAllowed は LocalBusiness に直接書けますか
petsAllowed は LodgingBusiness 直属、smokingAllowed は Restaurant 直属の property で、他業種の LocalBusiness に書くと schema バリデータでは通っても AI parser には silent drop されます。他業種で同じ意味を表したい場合は amenityFeature の LocationFeatureSpecification に「Pets Allowed: true」を書くのが安全です。
英語の schema.org vocab と日本語 UI ラベルはどう揃えればよいですか
amenityFeature の name は英語 vocab (Wheelchair Accessible / Pets Allowed) で書き、site 側の日本語 UI (「車椅子対応」「ペット可」) は別に持たせ、sameAs で GBP URL を配線して名寄せを AI 側に任せます。JSON-LD 内で英日混在させると entity 曖昧化の原因になります。