ふくふくHukuhuku Inc.
EP.09GEO / LLMO 13分公開: 2026-09-01

構造化データを腐らせない ── 手書きをやめて、生成と検証にする

構造化データは、書いた直後から本文とずれ始めます。手で書き続ける限り必ず腐る。生成して自動で検証する構成に切り替える方法を扱います。

#LLMO#構造化データ#運用#自動化
執筆 / 監修
松尾 亮合同会社ふくふく 代表社員

データ基盤・データパイプライン構築 / BI / 生成 AI 活用支援を専門とするエンジニア (28 年)。 本記事は AI 利用ポリシーに基づき、生成 AI の補助で執筆 → 人間が監修・編集して公開しています。

プロフィール詳細
シェア

EP.03 を扱いました。この回はその運用編です。書いたあと、どう維持するか。

結論から言うと、手書きで維持し続けるのは不可能です。ページ数が増え、内容が更新されるようになった時点で、必ずずれます。

1. なぜ必ず腐るのか

構造化データは、本文と同じ情報を、別の場所に別の形式で書いたものです。同じ情報が2箇所にある以上、片方だけ更新されるのは時間の問題です。

片方だけ更新されると何が起きるか
更新される場所更新されない場所結果
本文の価格構造化データの価格古い価格が機械に読まれる
本文の営業時間構造化データの営業時間誤った時間が案内される
記事の更新日構造化データの日付鮮度の判断がずれる
著者の肩書構造化データの著者情報信頼性の評価がずれる

1行目が最も実害が大きい。人が見る画面には新しい価格が出ているのに、機械が読む部分には古い価格が残っている。生成AIが古い価格で回答すれば、問い合わせの現場で齟齬が起きます。

ずれた構造化データは、無いより悪い

構造化データが無ければ、機械は本文を読みます。ずれたものがあると、機械はそちらを優先する可能性があります。「念のため付けておく」つもりが、誤情報を配信する経路になりうるわけです。

2. 本文から生成する

対策は単純で、同じ情報を2箇所に書かないことです。本文のデータから構造化データを生成すれば、ずれようがありません。

記事データから構造化データを組み立てる
TypeScript
type Article = {  slug: string;  title: string;  excerpt: string;  date: string;  dateModified?: string;  author: { name: string; url: string };};
/** 記事データから JSON-LD を生成する。手で書かない。 */export function articleJsonLd(a: Article, siteUrl: string) {  const url = `${siteUrl}/blog/${a.slug}`;  return {    "@context": "https://schema.org",    "@type": "Article",    headline: a.title,          // 本文と同じ値を使う    description: a.excerpt,     // ここも同じ    datePublished: a.date,    dateModified: a.dateModified ?? a.date,    author: {      "@type": "Person",      name: a.author.name,      url: a.author.url,    },    mainEntityOfPage: { "@type": "WebPage", "@id": url },  };}

要点は、`headline` に `a.title` を渡していることです。タイトルを変更すれば構造化データも自動的に変わります。ここに文字列を直接書くと、その瞬間から腐り始めます。

元データが1つであれば、更新漏れという概念自体がなくなります。これは 壊れないデータ基盤の作り方 で扱う「同じ情報を2箇所に持たない」という原則と、まったく同じ話です。データ基盤の設計原則が、そのまま の運用にも当てはまるわけです。同じ問題は、領域を変えて何度も現れます

3. 生成できない場合

現実には、生成できない場面もあります。本文が手書きの HTML だったり、元データが構造化されていない場合です。

状況ごとの対処
状況対処
記事データが構造化されている生成する(上の形)
本文がマークダウン先頭のメタ情報から生成する
手書きHTML、ページ数が少ない手書きでよいが、検証を入れる
手書きHTML、ページ数が多いまず元データの構造化から

最下行は、構造化データの話を超えた課題です。ページごとに内容が手書きで散らばっている状態では、構造化データ以前に更新自体が大変なはずです。そちらを先に解決するほうが、結果的に早い。逆に言えば、構造化データを入れようとして初めて、元データが構造化されていないことに気づくというのはよくある流れです。それ自体が有益な発見だと考えてください。

4. 形式ではなく、値を検証する

検証というと、形式が正しいか(構文エラーがないか、必須項目が揃っているか)の確認を思い浮かべます。それも必要ですが、本当に効くのは値の検証です。

2種類の検証
検証の種類見つかるもの見つからないもの
形式の検証構文エラー、項目の欠落値が本文とずれている
値の検証本文との不一致

形式が正しくても、中身が本文と違っていれば意味がありません。むしろ形式が正しいぶん、機械は素直に読み込みます。

本文と構造化データが一致しているかを検証する
TypeScript
import { describe, it, expect } from "vitest";
describe("構造化データが本文と一致していること", () => {  it("タイトルが一致する", () => {    const article = getArticle("llmo-09-structured-data-ops");    const jsonLd = articleJsonLd(article, "https://example.com");    expect(jsonLd.headline).toBe(article.title);  });
  it("更新日が本文の更新日以降である", () => {    const article = getArticle("llmo-09-structured-data-ops");    const jsonLd = articleJsonLd(article, "https://example.com");    expect(new Date(jsonLd.dateModified).getTime())      .toBeGreaterThanOrEqual(new Date(article.date).getTime());  });
  it("全記事で必須項目が欠けていない", () => {    for (const article of getAllArticles()) {      const jsonLd = articleJsonLd(article, "https://example.com");      expect(jsonLd.headline, `${article.slug}: headline が空`).toBeTruthy();      expect(jsonLd.author.name, `${article.slug}: author が空`).toBeTruthy();      expect(jsonLd.datePublished, `${article.slug}: 日付が空`).toBeTruthy();    }  });});

3番目のように全記事に対して回すのが重要です。1ページだけ確認しても、他のページがずれていれば同じことです。LLM時代のテスト戦略 で扱った考え方が、そのまま使えます。失敗したときにどのページか分かるメッセージを添えておくのも要点で、これがないと数百件の中から探すことになります。

5. 公開前に止める

検証は、公開前に自動で走るようにします。公開後に気づく仕組みでは、その間ずれた情報が配信され続けます。

  1. 1変更のたびに検証を回す — 手動確認にしない
  2. 2失敗したら公開を止める — 警告だけでは無視される
  3. 3新しいページも自動的に対象になる — 一覧に追加し忘れない形にする
  4. 4外部の検証ツールも定期的にかける — 仕様の変更に気づける

3番目が地味に効きます。検証対象を手で列挙する方式にすると、新しいページを追加したときに登録し忘れます。全記事を自動的に走査する形にしておいてください。

4番目は、こちらのコードが正しくても仕様のほうが変わることへの備えです。推奨される項目が増えたり、扱いが変わったりします。定期的に外部のツールで確認すると気づけます。自前の検証は自分が想定した範囲しか見ないので、外部の目を入れる意味がここにあります。

6. どこまでやるかの線引き

構造化データは、種類を増やそうと思えばいくらでも増やせます。ただし増やすほど維持の対象も増えます。

何から入れるか
対象優先度理由
記事・ページの基本情報高い全ページに関わる
組織・著者の情報高い信頼性の判断に効く(EP.04)
よくある質問回答として引用されやすい
価格・在庫慎重にずれたときの実害が大きい
細かい属性の網羅低い維持の負担に見合わない

4行目は入れるべきだが、生成と検証が確実にできる場合に限るという位置づけです。手書きで価格を書くくらいなら、書かないほうが安全です。誤った価格が機械可読な形で流れるより、本文だけを読ませたほうがよい。

ここまでのまとめ

構造化データは同じ情報を2箇所に持つため、必ず腐る。対策は本文のデータから生成すること。検証は形式ではなく値を見る(本文と一致しているか)。全記事に対して自動で回し、失敗したら公開を止める。そして維持できない項目は、書かないほうが安全です。

シェア

この記事の感想を教えてください

あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。

シリーズの外も探す:

まずは、現状を聞かせてください。

要件が固まっていなくて大丈夫です。現状診断と方針提案までを無料でお手伝いします。

無料相談フォームへ hello [at] hukuhuku [dot] co [dot] jp