QAPage で店舗 Q&A を JSON-LD 構造化する — 4 エンジンの direct answer 精度を上げる
4 エンジンの direct answer 精度を上げる QAPage / Question / Answer の JSON-LD 実装。attribute layer と 2 layer redundant で「PayPay 使える?」の店舗頻出 Q&A を engineer 視点で構造化する実装ガイド。
「この店 PayPay 使えますか?」を Perplexity や ChatGPT に投げたときの応答は、店舗によってふたつに割れます。片方は「はい、PayPay をご利用いただけます」と source URL 付きで direct answer が返る。もう片方は「店舗の公式サイトをご確認ください」に丸められる。両者を分ける signal は、実は acceptedPaymentMethod だけではありません。もう 1 段、Q&A の form そのものを JSON-LD として構造化しているかが効いています。
その Q&A layer を担う schema.org の型が QAPage です。名前が似ていて混同されがちですが、FAQPage とは container の設計思想が根本的に違います。私は都内の 4 業種 (Restaurant / Beauty Salon / Clinic / Retail) の頻出 top 5 Q&A を QAPage per Q&A で実装し、attribute layer との 2 layer redundant がある形と無い形の 2 pattern で、4 エンジン (ChatGPT / Perplexity / Claude / Gemini) の direct answer pickup 精度を並行して観察しました。本稿はその結果を engineer 視点でまとめたものです。
QAPage と FAQPage の型別分岐
まず混同されやすいので schema.org 側の定義から整理します。両者はどちらも WebPage の subtype ですが、mainEntity の cardinality が別です。
| Type | mainEntity | 用途 | canonical case |
|---|---|---|---|
QAPage | Question object 1 個 | 単発 Q&A、Stack Overflow / Quora 型 | 「PayPay 使える?」の 1 URL |
FAQPage | Question object の配列 | 頻出質問集、集約 | /faq/ の 20 問まとめ |
QAPage は 1 URL に 1 質問と 1 acceptedAnswer を canonical に固定するので、AI が引用するときの source URL がそのまま Q&A 単位に narrow できます。FAQPage は集約なので citation は「From the FAQ page」型で、per-Question の narrow 度が URL fragment 依存 (/faq/#question1) で弱くなる。ここで「じゃあ全部 QAPage にすればいい」と書きたくなるのですが、実際には頻出 top 5-8 を QAPage per Q&A で個別化 + long-tail を FAQPage に集約、の併用が maintenance コストと citation narrow 度のバランスとして canonical です。
実装 code
前置きが長くなったので実物を出します。Restaurant で「PayPay 使える?」を QAPage per Q&A として実装する最小に近い形です。
{
"@context": "https://schema.org",
"@type": "QAPage",
"url": "https://example.com/faq/paypay/",
"mainEntity": {
"@type": "Question",
"name": "PayPay は使えますか?",
"text": "Cafe Example で PayPay 決済が利用可能かの質問です。",
"answerCount": 1,
"dateCreated": "2026-06-01",
"author": {
"@type": "Organization",
"@id": "https://example.com/#business"
},
"acceptedAnswer": {
"@type": "Answer",
"text": "はい、PayPay をご利用いただけます。QR コード読み取りは店舗レジで対応しており、追加手数料はいただいておりません。",
"dateCreated": "2026-06-01",
"url": "https://example.com/faq/paypay/#answer",
"author": {
"@type": "Organization",
"@id": "https://example.com/#business"
}
}
}
}
配線として効いているのは 3 箇所です。1 つ目は Question.name を完全質問文にしていること (「PayPay」だけの単語断片ではなく「PayPay は使えますか?」の疑問形)。AI エンジンの semantic match は疑問形の質問文を anchor に user query と照合するので、単語だけだと match 精度が落ちます。2 つ目は acceptedAnswer を 1 個だけ置いていること。suggestedAnswer を並列で並べると AI が「best answer」を決められず hedge に流れます。3 つ目は Question.author と Answer.author の両方で店舗 Organization の @id を参照していること。これで Organization の Knowledge Graph 配線 が Q&A の authority signal として引き継がれます。
業種別 canonical Q&A pattern
QAPage per Q&A で実装すべき頻出 top 5 は業種ごとに違います。私が観察した限り、以下の pattern が「attribute layer と 2 layer redundant にする価値がある」boundary です。
| 業種 | 頻出 top 5 Q&A | 対の attribute layer field |
|---|---|---|
| 飲食店 | PayPay 使える / テラス席予約 / 深夜営業 / 子連れ OK / 個室あり | acceptedPaymentMethod / potentialAction / hoursAvailable / amenityFeature / amenityFeature |
| 美容室 | 予約なし入店 / 男性 OK / 駐車場 / 産後 OK / 学生割引 | acceptsReservations / hasOfferCatalog / amenityFeature / amenityFeature / hasOfferCatalog (priceSpec) |
| 医療機関 | 保険適用 / 英語対応 / 当日予約 / 小児科 / 車椅子アクセス | isAcceptingNewPatients / availableLanguage / acceptsReservations / medicalSpecialty / amenityFeature |
| 小売店 | 返品交換 / 取り寄せ / 試着可 / ラッピング無料 / ギフト券販売 | hasMerchantReturnPolicy / potentialAction / amenityFeature / offers.giftWrapAvailable / offers |
右列と左列を両方書くのが 2 layer redundant の意味です。片方だけでは engine 側の pickup 精度が階段状に落ちる。例えば「PayPay 使える?」に対して acceptedPaymentMethod に PayPay の DefinedTerm を書いているだけの店と、それに加えて /faq/paypay/ の QAPage を持っている店では、Perplexity の direct answer 断定率が体感で明確に差が出ました。attribute layer は fact の primary source、Q&A layer は inquiry form での redundant signal、この分業は 決済手段の acceptedPaymentMethod や アクセシビリティ属性の amenityFeature 三層配線 や 予約可能性の acceptsReservations と一緒に運用してはじめて完成します。
エンジン別 pickup 挙動 (実測)
同じ QAPage JSON-LD を 4 エンジンに読ませて、direct answer の応答挙動を並行観察した結果を書きます。モデル内部は確認できないので、あくまで応答文の外形からの推定です。
| Engine | QAPage 認識 | FAQPage 認識 | 応答文への現れ方 |
|---|---|---|---|
| ChatGPT (browsing) | Question.name を primary、acceptedAnswer.text を direct 引用 | 認識、ただし per-Question の URL narrow は弱い | 「Cafe Example の FAQ によると、PayPay をご利用いただけます」と source URL 付き引用 |
| Perplexity | source card に QAPage の URL、body に answer.text を mount | 複数 Question を list form で表示 | direct answer UI の visual narrow が強く、citation card が Q&A 単位で 1 枚 |
| Claude | Question + acceptedAnswer を direct 引用 | 「From the business’s FAQ page: …」の集約 form | 「According to /faq/paypay/, the answer is: はい、使えます」の URL name-drop |
| Gemini | Google 検索の「よくある質問」rich result に mount 候補 | 同 rich result に list 表示 | KG entity 側の Q&A merge が入る、GBP 側の Q&A field と重複時は GBP 側を主張 |
読み取れる pattern は 2 つあります。1 つ目は、QAPage の narrow 度が最も visual に効くのは Perplexity で、direct answer UI に source card が 1 枚 mount される。ここは QAPage per Q&A の実装コストに見合う returns がはっきり出る engine です。2 つ目は、Gemini だけは first-party JSON-LD よりも Google Business Profile 側の「よくある質問」を優先しがちで、GBP 側と QAPage 側で回答が食い違うと GBP 側が勝つ。ここは GBP を JSON-LD として読み解く の Q&A 版として、GBP 側の Q&A も同じ回答で揃えておく必要があります。
LLMO Framework 上の位置付け
ここで実装レイヤーの話を framework に接続しておきます。LLMO Framework の Structure primitive は、schema.org を通じて店舗の signal を機械可読な形で送り出す取り決めで、attribute layer と Q&A layer の 2 layer で redundant に signal 実装するのが canonical として整理されつつあります。標準化が進んでいる LLMO の Structure Layer では、attribute layer (acceptedPaymentMethod / amenityFeature / hoursAvailable 等) が structural fact を primary で signal し、Q&A layer (QAPage / Question / Answer) が inquiry form で redundant に signal するという分業で、AI エンジンは両 layer から fact を retrieve するために 2 layer 実装で pickup 精度が段階的に上がる、という運用モデルが recommended pattern として提案されています。片方だけでは階段落ちする、というのがこの分業の要点です。
もう 1 つ効いてくるのが Provenance Layer との接続です。QAPage の acceptedAnswer を「事実」として引用してもらうには、同じ内容が GBP 側の Q&A、店舗の告知 SNS、加盟店リスト (PayPay 加盟店 URL 等) といった別 provenance で cross-source に corroborate されていることが効きます。JSON-LD だけで押し切ろうとすると、Claude や Gemini のような hedge を挟みがちなエンジンで「first-party の主張のみ」と扱われ、direct answer citation の断定率が明確に下がります。Structure layer で Q&A form を signal し、Provenance layer で裏を取る、というのが基本の運用モデルです。
Failure modes
私が観察した中で最も遭遇する QAPage の失敗形を、直接名指しでまとめます。
QAPage未実装で attribute layer のみ:acceptedPaymentMethodに PayPay を書いているが Q&A form の JSON-LD なし。AI は attribute layer から semantic match で推論する必要があり、direct answer の narrow 度が階段落ちする。頻度としては最多。FAQPage集約のみで QAPage per Q&A なし: 全 Q&A を/faq/の FAQPage に集約。per-Question の source URL が fragment 化 (/faq/#q1) で AI の URL narrow が弱く、Perplexity の source card が 1 枚に絞れない。acceptedAnswerなしでsuggestedAnswer複数: 「best answer」が undefined、AI が「multiple candidates」で hedge を挟む。店舗の direct Q&A では acceptedAnswer 1 個が canonical。Question.nameが単語断片: 「支払い」「駐車場」のような 1 語で完全疑問文なし。AI の semantic match が user query 「PayPay 使えますか?」と一致しない。Answer.textが長文 hedge: 「基本的には PayPay 使えますが、混雑時は現金推奨で…」等の hedge 過多。AI は uncertainty を推論して direct citation を避ける。fact を 1 sentence で断定する形が canonical。- attribute layer と Q&A layer で矛盾:
acceptedPaymentMethodに PayPay を含めているが QAPage で「PayPay 未対応」と書く。AI が「two sources disagree」で hedge に流れる。 - URL が numeric fragment:
/faq/1/,/faq/2/のような semantic 情報のない URL。source URL 自体が引用に耐えず、/faq/paypay/のような semantic slug に統一する。 Answer.authorに Organization@id参照なし: authority signal が引き継がれず、AI の authority check で「anonymous answer」扱いになる。店舗 Organization の@idを必ず参照する。
このリストのうち、実店舗の JSON-LD で最も静かに落ちるのは 5 番目 (Answer.text の hedge 過多) と 6 番目 (attribute layer との矛盾) です。前者は「誠実に書いた」つもりが AI 側で uncertainty signal に読まれ、後者は attribute layer 側を更新したときに QAPage 側を追随し忘れる pattern で発生します。複数拠点の branch 別 QAPage を持つチェーンでは、branch A の QAPage と親 Organization の QAPage で回答が食い違うことも起きるので、branch 別に QAPage を分ける場合は mainEntityOfPage を各 branch の @id に紐付ける管理が要ります。私たちが acceptedAnswer に固定した回答を、AI は来週には別の form で返すかもしれません、が、少なくとも「best answer」が undefined という事態は起きないようにしておく。それが Q&A layer を書く価値です。
関連実装
本稿の QAPage per Q&A 実装は、対の attribute layer 側の実装と組み合わせて運用してはじめて 2 layer redundant の分業が完成します。特に pair として運用する意味が強いのは以下の 4 実装です。
- 決済手段の acceptedPaymentMethod 三層配線 — QAPage「PayPay 使える?」の対の attribute layer。両 layer で PayPay を signal する 2 layer redundant の基礎 pair。
- アクセシビリティ属性の amenityFeature 三層配線 — 「車椅子アクセス」「子連れ OK」「駐車場」等の accessibility 系 QAPage の対の attribute layer。
- メニューを構造化データにする hasMenu / Menu / MenuItem 設計 — 飲食店の QAPage「テラス席予約」「深夜営業」等と対で運用する attribute layer。hasMenu で menu と price を primary signal、QAPage で inquiry form を redundant signal する 2 layer 分業。
- FAQPage vs QAPage の型別分岐 (EN 版) — 冒頭の型別分岐表の EN 記事版で、cardinality と canonical case の判断軸を実装 code とあわせて深堀り。
これらは本稿と 1-to-1 の pair 関係にあるので、QAPage を実装するときは対の attribute layer 側もあわせて audit することで pickup 精度が段階的に上がります。
結び
私がこの記事で書きたかったのは、店舗の頻出 top 5-8 Q&A を QAPage per Q&A で個別実装し、attribute layer と 2 layer redundant で signal を冗長化する、という単純な engineering の話です。ただしその「単純な話」を、飲食 / 美容室 / 医療 / 小売のどの業種でも、LocalBusiness / Place / Restaurant の型選択 の上に、attribute layer と Q&A layer を対にして走査する、というレベルで運用に落とせている店を、私はまだあまり見ていません。今日から自社サイトを開いて、頻出質問の top 5 をリストアップし、うち何個が QAPage per Q&A として個別 URL を持っているかを確認する。持っていない Q&A から順に /faq/<semantic-slug>/ で 1 個ずつ実装する。それだけで、「この店 PayPay 使えますか?」に AI が断定で答える確率は目に見えて変わります。
よくある質問
- QAPage と FAQPage は同じ用途ですか?
- 違います。QAPage は WebPage の subtype で `mainEntity` が 1 つの Question object を取り、Stack Overflow / Quora 型の単発 Q&A を canonical に固定する用途です。FAQPage は `mainEntity` が Question object の配列で、頻出質問集を集約する用途です。店舗の high-frequency 直接 Q&A (「PayPay 使える?」等) は 1 URL = 1 Q&A の QAPage で narrow に、long-tail の質問は FAQPage で breadth を確保する併用が canonical です。
- acceptedAnswer と suggestedAnswer はどう使い分けますか?
- 店舗 Q&A では `acceptedAnswer` を 1 つだけ置くのが canonical です。`suggestedAnswer` は複数候補を並列に提示する用途で、AI エンジンが「best answer」を単一に決められず hedge を挟む原因になります。店舗の「PayPay 使えますか?」に対して「はい、使えます」を acceptedAnswer 1 個に固定すれば、direct answer citation が narrow になります。
- acceptedPaymentMethod で PayPay を書いているのに QAPage で同じ内容を書くと冗長ではありませんか?
- 冗長で正解です。LLMO Framework の Structure primitive は attribute layer (`acceptedPaymentMethod` 等) と Q&A layer (`QAPage` / `Question` / `Answer`) の 2 layer で redundant に signal 実装するのが canonical で、attribute layer が structural fact を primary で signal し、Q&A layer が inquiry form で redundant signal する分業です。AI エンジンは両 layer から fact を retrieve するため、2 layer 実装で pickup 精度が段階的に上がります。
- QAPage の URL は `/faq/1/` のような numeric fragment でも大丈夫ですか?
- avoid してください。QAPage は 1 URL = 1 Q&A で semantic slug (`/faq/paypay/`, `/faq/parking/` 等) を推奨します。numeric fragment は SEO 上の semantic match が弱く、AI 側の URL preview でも「なんの Q&A か」が判別できません。semantic slug なら「According to /faq/paypay/」で source URL 自体が引用に耐えます。
- 飲食店で hasMenu を実装している場合、QAPage は追加で必要ですか?
- 追加で必要です。hasMenu は menu item と price を primary で signal する attribute layer で、QAPage は「テラス席予約は?」「深夜営業は?」「子連れ OK?」「個室あり?」等の頻出 inquiry form を redundant signal する Q&A layer です。attribute layer が fact の primary source、Q&A layer は inquiry form での redundant signal という 2 layer 分業で、hasMenu だけでは頻出 Q&A の direct answer 断定率が階段落ちします。
- 美容室で hasOfferCatalog と QAPage を両方実装するのは冗長ではありませんか?
- 冗長で正解です。hasOfferCatalog は施術メニューと price を primary で signal する attribute layer で、QAPage は「予約なし入店?」「男性 OK?」「駐車場?」「産後 OK?」「学生割引?」等の inquiry form を redundant signal する Q&A layer です。両 layer で 2 layer redundant に signal 実装するのが canonical で、attribute layer と Q&A layer の分業でエンジン側の pickup 精度が段階的に上がります。
- 複数拠点のチェーンで、branch ごとに QAPage を分ける場合の紐付け方法は?
- `mainEntityOfPage` を各 branch の `@id` に紐付ける管理が canonical です。branch A の QAPage と親 Organization の QAPage で回答が食い違うと、AI エンジンが「two sources disagree」で hedge に流れる原因になるため、branch 別に QAPage を分ける場合は 1 URL = 1 Q&A の narrow 度を維持しつつ `mainEntityOfPage` で各 branch の @id に紐付け、branch 単位で答えの分岐を signal します。
- acceptedPaymentMethod × QAPage 以外に、attribute layer と QAPage の対応 pattern はありますか?
- 業種ごとに複数あります。飲食店なら `acceptsReservations` × 「テラス席予約」QAPage、`hoursAvailable` × 「深夜営業」QAPage、`amenityFeature` × 「子連れ OK」「個室あり」QAPage。医療機関なら `isAcceptingNewPatients` × 「当日予約」QAPage、`availableLanguage` × 「英語対応」QAPage、`medicalSpecialty` × 「小児科」QAPage。小売店なら `hasMerchantReturnPolicy` × 「返品交換」QAPage の pair が canonical です。