# ブログをAIに参照されやすくするために実装したこと

> AI検索やLLMが記事を引用する時代に、自分たちのAstro製ブログがAIから参照されやすい状態か棚卸しし、JSON-LDやrobots.txt、Markdown配信など効く順に5つの仕組みを入れた記録です。

- 公開日: 2026-06-28
- 著者: 村井 謙太
- タグ: Astro, LLM, 生成AI
- URL: https://tech.anycloud.co.jp/articles/ai-friendly-astro-blog

---

最近、ChatGPT や Claude、Perplexity に「○○について教えて」と聞くと、答えのなかに参照元の記事へのリンクが並ぶようになりました。検索エンジンで自分の記事が上位に出るかを気にしていたのと同じ感覚で、今度は「AIが答えを作るときに、自分たちの記事をちゃんと引用してくれるか」が気になり始めます。

このブログ（tech.anycloud.co.jp）は Astro で作っています。では、AIに参照される準備はできているんだっけ？と思って中身を棚卸ししたところ、できている部分と、すっぽり抜けている部分がはっきり分かれていました。この記事は、その棚卸しと、抜けていた部分を埋めた作業の記録です。

こうした「AIに引用されやすくする」取り組みは GEO（Generative Engine Optimization）と呼ばれます。日本語の記事では LLMO（LLM最適化）や AEO（Answer Engine Optimization）という言い方も見かけますが、指しているものはだいたい同じです。この記事では GEO に統一します。

## 棚卸しでわかった、一番大事だったこと

先に結論を書くと、一番の収穫は、AI向けに何か新しいファイルや仕組みを足したことではなく、すでにあった土台が効いていると気づけたことでした。

AIのクローラ（GPTBot や ClaudeBot など）の多くは、ブラウザのように JavaScript を実行してくれません。つまり、本文を JavaScript で後から描画する SPA だと、クローラから見ると中身がほとんど空っぽに見える可能性があります。

その点、Astro は静的サイトとしてビルドするので、本文は最初から HTML に焼き込まれています。これは意識して入れた施策ではなく、ただ Astro を選んでいただけなのですが、結果的にこれが一番効く土台になっていました。canonical や OGP、sitemap、記事のメタデータ（タイトル・公開日・タグ・著者）を構造化して持つ仕組みも、すでに入っていました。

逆に抜けていたのは、その構造化データを「機械が読める形で外に出す」層でした。ここを効く順に5つ埋めていきます。

## 1. JSON-LD（schema.org の BlogPosting）

一番効くと判断したのがこれです。記事のタイトル・説明・公開日・更新日・著者・運営元などを、`schema.org` の語彙にそって JSON で `<head>` に埋め込みます。AIや検索エンジンが「これは誰がいつ書いた、何についての記事か」を推測ではなく構造から読み取れるようになります。

補足しておくと、JSON-LD や [schema.org](https://schema.org/) は、AIのために生まれたものではなく、もともと検索エンジンのための仕組みです。schema.org は Google や Bing といった検索エンジン各社が共同で策定した「ページの意味を機械に伝えるための共通ボキャブラリ」で、JSON-LD はそれを書く形式のひとつ（[Google が推奨する形式](https://developers.google.com/search/docs/appearance/structured-data/article)）です。これを入れておくと、検索エンジンがタイトル・画像・公開日などをより正確に理解し、検索結果での見せ方（リッチリザルト）に活かせる、というのが従来からのSEO上の狙いでした。`BlogPosting` は、その語彙の中で「ブログ記事」を表す型（`Article` の一種）です。

要するに、昔からSEOの定番だった仕組みに、今度はAIが同じように乗ってきた、という構図です。新しく覚えることは、思ったより多くありませんでした。

実際に出力されるのはこんな形です。

```json
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "記事タイトル",
  "datePublished": "2026-06-28T09:00:00.000Z",
  "dateModified": "2026-06-28T09:00:00.000Z",
  "author": { "@type": "Person", "name": "村井 謙太" },
  "publisher": {
    "@type": "Organization",
    "name": "エニテック",
    "logo": { "@type": "ImageObject", "url": "https://tech.anycloud.co.jp/images/site/logo.svg" }
  },
  "inLanguage": "ja",
  "keywords": "astro, llm, generative-ai"
}
```

記事ページはもともと著者やタグを解決済みだったので、その値をそのまま JSON に詰めるだけでした。

## 2. セマンティックなHTML

本文を囲う要素を `<div>` から `<article>` に変え、公開日を `<time datetime="...">` にしました。見た目は1ピクセルも変わりませんが、「ここが記事本体」「これが日付」という意味が要素自体に乗ります。AIは整形後のHTMLから本文を抜き出すので、意味のあるタグで囲っておくと抽出の精度が上がるはずだ、という判断です。

## 3. robots.txt

意外なことに、これまで robots.txt を置いていませんでした。クロールは黙認されている状態だったので、意図を明文化する意味で追加しました。今回はAIに引用してほしいのが目的なので、AI系のクローラを明示的に歓迎しています。

```
User-agent: *
Allow: /

User-agent: GPTBot
Allow: /

User-agent: ClaudeBot
Allow: /

Sitemap: https://tech.anycloud.co.jp/sitemap.xml
```

学習や引用をブロックしたい運営者も当然いるので、ここは方針次第です。私たちは「読んで、引用してもらえるなら歓迎」という立場なので全面的に許可しました。

## 4. article: 系のメタタグ

OGP の補完として、`article:published_time` `article:modified_time` `article:author` `article:tag` を追加しました。公開日と更新日を機械が読める形で持たせると、記事の鮮度が伝わりやすくなります。3 の JSON-LD と内容は重なりますが、読み取り口を複数用意しておくという位置づけです。

## 5. 本文のMarkdown版を配信する

最後に、各記事の本文を Markdown のまま返すエンドポイントを `/articles/<スラッグ>.md` に用意しました。HTMLには装飾やナビゲーション、スクリプトが混ざりますが、Markdown ならAIが本文だけを素直に取り込めます。Astro ではルートを1つ足すだけで実現できました。

```ts
// src/pages/articles/[slug].md.ts
export const GET: APIRoute = async ({ params }) => {
  const article = await getEntry("articles", params.slug);
  const markdown = `# ${article.data.title}\n\n${article.body}\n`;
  return new Response(markdown, {
    headers: { "Content-Type": "text/markdown; charset=utf-8" },
  });
};
```

`<head>` には `<link rel="alternate" type="text/markdown">` を入れて、Markdown版の存在を案内しています。

## 予想と違ったところ

調べる前は「`llms.txt` を置けば終わりでしょ」くらいに思っていました。サイト全体をLLM向けにまとめるファイルとして最近よく話題になっているものです。

ところが調べてみると、2026年6月時点で `llms.txt` を実際に読みにくるクローラはまだ多くありませんでした。置くコスト自体は低いのですが、「これを置けばAIに読まれる」と期待するのは早そうだったので、今回は見送りました。話題の大きさと実際の効果は別物だな、と改めて思った部分です。

もうひとつ地味にハマったのが、共通レイアウトの `<head>` に記事ごとのメタを差し込む口が無かったことです。Astro の名前付きスロット（`<slot name="head" />`）を共通レイアウトに足して、記事ページからJSON-LDを流し込む形にしました。

全体としては大きな作りこみは不要で、`npm run build` が通り、ビルド後のHTMLに JSON-LD やメタタグが、`/articles/<スラッグ>.md` に本文が出力されることまでは確認できました。

## 所感

やってみて一番良かったのは、ここで入れたものの多くが「AIのための特別な対策」ではなく、もともと良いとされてきたWebの作法そのものだった、と気づけたことです。JSON-LD（構造化データ）もセマンティックなHTMLも、robots.txt からの sitemap 参照も、検索エンジン向けのSEOでは定番として勧められてきたものです。AIに引用されやすくするための仕込みが、そのまま検索エンジンへの最適化にもなっている、というのは素直に嬉しいポイントでした。

AI経由の参照はアクセス解析に素直には出てこないので、「AIからの引用が増えたか」の効果測定は今後の宿題です。ただ、仮にAI側の効果が見えにくくても、構造化データやSEOという確実に意味のある側に倒れる作業なので、やって損のない投資だと感じています。

しかもコスト自体は低く、土台（静的HTML＋構造化データ）さえあれば後から足せるものばかりでした。ふだんはクライアントのプロダクト開発を技術支援している立場なので、こういう仕込みを自社のブログで先に試しておくと、お客さんのサイトで提案するときの実感にもなります。AIにも検索エンジンにも読まれる前提でコンテンツを置く。その準備を低コストで整えられたのが、今回の収穫でした。
