【SEO×AI検索の両取り戦略】Astroで『llms.txt・ai-corpus.jsonl・citation構造化データ』を自動生成してAIに引用されるサイトを作る実装ガイド
作成日:
更新日:

【SEO×AI検索の両取り戦略】Astroで『llms.txt・ai-corpus.jsonl・citation構造化データ』を自動生成してAIに引用されるサイトを作る実装ガイド


🔧 論旨

個人ブログや技術サイトを運営するうえで、「これからは Google 検索(SEO)の時代が終わって、ChatGPT や Gemini・Perplexity などの AI 検索(GEO / RAG)の時代になるから、どっちに力を入れればいいの?」と迷う方が増えています。結論から言えば、Google 検索と AI 検索は対立するものではなく「二階建ての両輪」であり、Astro なら人間の読者向けデザインを 1 ミリも崩さずに 100% 両取りできます。

本記事では、ビルド時に全公開記事から AI 専用インデックス『/llms.txt』・純粋 Markdown 全文コーパス『/llms-full.txt』・RAG 直結データセット『/ai-corpus.jsonl』を自動生成する実装と、公的出典 URL を Schema.org の『citation』構造化データへ変換し、さらにタグページ 1,200 件のノイズをサイトマップから除外して検索評価を濃縮させた実践手順をすべて公開します。
🔧 合わせて読みたい深まる関連情報
🔧 対象となる方
  • せっかく一次情報や実測データを書いた記事を、Google 検索だけでなく ChatGPT・Gemini・Perplexity などの回答根拠としても正確に引用されたい方

  • 話題の /llms.txt や /llms-full.txt、RAG 用 JSONL データセットを Astro で毎回手作業なしに自動生成したい方

  • MDX 内の独自コンポーネントや定数変数がそのままクローラーに読まれてノイズになるのを防ぎたい方

  • サイトマップの肥大化や初期テンプレートの SITE_DESCRIPTION 放置など、意外と見落としがちな SEO の穴 を塞ぎたい方

吹出しアイコン

最近は調べ物をするにも、検索サイトだけじゃなく AI に直接聞く人が増えとるじゃろ?一生懸命ブログを書いても、画面の飾り付けやメニューバーの HTML タグばっかり多くて、AI たちに中身をちゃんと読んでもらえとらんのじゃないかと心配なんじゃよ……!

吹出しアイコン

おじさん、すごく本質的な視点です!実は人間の目には綺麗に見える Web ページも、AI クローラーから見るとヘッダーやサイドバー、装飾用の HTML タグが全体の半分以上を占める「ノイズだらけの殻付きデータ」に見えているんです。でも Astro の静的エンド機能を使えば、人間には美しい Web ページを、AI には殻をむいた純度 100% のテキストと JSON を同時に自動配膳 できるんですよ!


Google検索とAI検索は対立せず二階建てで繋がる

リアルタイム検索RAGと事前学習の3つの経路

まず押さえておきたい全体像は、「Google の検索ボット対策(SEO)と AI ボット対策(GEO)は、どちらか片方を選ぶものではなく完全に連動している」 という事実です。現代の AI が Web サイトの知識を取り込むルートは大きく 3 つあります。

AIが知識を得る経路主なクローラー・仕組み評価・引用されるためのカギ
① リアルタイム検索引用(RAG / Grounding)Perplexity、ChatGPT Search、Google AI による概要など実は裏側で Google や Bing の検索インデックスを使っている! 検索上位に入ること+ <head> の構造化データ(JSON-LD の citation 等)が直結する。
② AIエージェントの直接読解URL 指定参照、llms.txt 対応エージェント・開発ツール装飾 HTML を省いた /llms.txt(全体案内図)と /llms-full.txt(純粋 Markdown 全文) があると、少ないトークンで正確に丸呑みできる。
③ 次世代モデルの学習・RAG構築GPTBot, Google-Extended, ClaudeBot, 研究・開発者1 行 1 記事でメタデータ・出典・本文が綺麗に整った /ai-corpus.jsonl(JSON Lines) と全文配信 RSS があると最高純度のデータになる。

つまり、1 階部分(見つけてもらう基礎体力)を担うのが Googlebot 向けのサイトマップと JSON-LD であり、2 階部分(誤読ゼロで深く理解・引用してもらう仕組み)を担うのが llms.txt や ai-corpus.jsonl という「二階建て構造」になっているのです。

装飾HTMLではAIの理解効率が落ちる理由

通常の HTML ページだけを置いていると、AI がページを取得した際に <header>、<nav>、SVG アイコンの長いパス文字列、インライン CSS などが大量に混ざり込みます。するとトークン枠を無駄遣いするだけでなく、肝心の数値や結論が薄まってしまいます。

さらに MDX で記事を書いている場合、原稿ファイルの中には GadgetSection や SpeechBalloon、KaTeXFormula などの独自コンポーネントや、{ISF_FUND_SCALE} のような JSX 変数が入っています。これらをビルド時に「純粋な Markdown と展開済みの実数値」へクレンジングした専用エンドポイントを用意してあげれば、AI にとってこれ以上ないご馳走になります。


Astroビルド時にAI専用3大ファイルを自動生成する

llms.txtと全文コーパス自動生成の役割

Astro には、.astro ページだけでなく .txt や .json などの任意の静的ファイルをビルド時に自動生成できる APIRoute(静的ファイルエンドポイント) という仕組みがあります。src/pages/ 直下に以下の 3 つの TypeScript ファイルを置くだけで、astro build のたびに全公開記事から最新ファイルが自動出力されます。

  1. src/pages/llms.txt.ts → /llms.txt を生成 : サイト全体のコンセプト、主要定数の定義、そして全公開記事の「カテゴリ別タイトル・要約・正規 URL・出典件数リスト」を 1 枚の軽量な Markdown 目次として出力します。AI エージェントが最初に読む「総合案内板」です。
  2. src/pages/llms-full.txt.ts → /llms-full.txt を生成 : 非公開記事(hidden: true / private: true)を除外した全公開記事の本文から MDX コンポーネントタグを除去し、数式コンポーネントを標準 LaTeX($$ ... $$)へ戻し、全記事を 1 つの純粋な Markdown ファイル(数百記事で約 5MB 前後)に統合します。
  3. src/pages/ai-corpus.jsonl.ts → /ai-corpus.jsonl を生成 : ベクトルデータベース(RAG)や機械学習パイプラインへそのまま 1 行ずつ流し込める NDJSON(application/x-ndjson) 形式のデータセットです。

RAG直結のai-corpus.jsonlと定数展開の罠

実際に /ai-corpus.jsonl を出力しているエンドポイントの基本構造は非常にシンプルです。

// src/pages/ai-corpus.jsonl.ts(構成例)
import type { APIRoute } from "astro";
import { getSortedPublicPosts, getCanonicalPostUrl, parseReferences, cleanMdxForAi } from "../utils/ai-corpus-helper";

export const GET: APIRoute = async ({ site }) => {
  const siteBase = site ? site.toString().replace(/\/$/, "") : "https://example.com";
  const { publicPosts, allPostsMap } = await getSortedPublicPosts();
  const jsonLines: string[] = [];

  for (const post of publicPosts) {
    const { parsed: references } = parseReferences(post.data.references);
    const record = {
      id: post.id,
      url: getCanonicalPostUrl(post.id, siteBase),
      title: post.data.title,
      description: post.data.description || "",
      pubDate: post.data.pubDate ? new Date(post.data.pubDate).toISOString() : null,
      references: references.map((r) => ({ name: r.name, url: r.url ?? null })),
      content: cleanMdxForAi(post, allPostsMap), // MDX装飾を除去した純粋本文
    };
    jsonLines.push(JSON.stringify(record));
  }

  return new Response(jsonLines.join("\n") + "\n", {
    headers: { "Content-Type": "application/x-ndjson; charset=utf-8" },
  });
};
🔧 ⚠️ 実装後の出力検査で見つかった『定数名の部分一致バグ』と対策

コーパス生成スクリプトを作って実際に出力テキストを検査した際、思わぬエッジケースバグを発見しました。記事内の定数プレースホルダを展開する処理で、もし定数リストに BURDEN_RATE(短い名前)と POTENTIAL_NATIONAL_BURDEN_RATE(長い名前)の両方があるとき、単純な順番で文字列置換をかけると 長い定数名の一部が先に短い定数の値で置換されて文字が壊れる 場合があったのです!

  • 対策 : 定数オブジェクトのキーを置換する際は、必ず 「キー名の文字数が長い順(b.length - a.length)」にソートしてから完全一致(または境界括弧 {...} 付き)で展開する ことで、部分置換ミスを 100% 根絶しました。生成した .txt や .jsonl は必ず一度中身を grep して { の消し残りがないか確認するのがおすすめです。

あわせて、全ページ共通の <head> コンポーネント(BaseHead.astro)に <link rel="alternate" type="text/plain" href="/llms.txt" title="LLMs Index" /> などを埋め込み、robots.txt でも GPTBot・Google-Extended・ClaudeBot・PerplexityBot を明示的に Allow: / として案内しています。


一次資料の信頼を証明するJSON-LDと巡回最適化

出典URLをSchema.orgのcitationへ変換

Google 検索(E-E-A-T や Information Gain=独自情報利得の評価)と AI 検索(Grounding)の両方に強烈に効くのが、「この記事は思い込みのポエムではなく、公式ドキュメントや公的統計・査読論文に基づいている」と機械語で直接証明すること です。

当サイトでは各記事のフロントマターに references:(出典名 <https://...>)を記載するルールにしています。これをページ下部に人間向けの参考資料リンクとして表示するだけでなく、レイアウト側で自動的に JSON-LD の citation プロパティ に変換して <head> へ出力しています。

{
  "@context": "https://schema.org",
  "@type": "TechArticle",
  "headline": "記事タイトル",
  "datePublished": "2026-10-19",
  "citation": [
    {
      "@type": "CreativeWork",
      "name": "Schema.org 公式リファレンス|citation プロパティ仕様",
      "url": "https://schema.org/citation"
    }
  ]
}

こうしておくと、検索 AI が回答を作る際に「どの一次資料に裏付けられた記事か」を一瞬で構造的に把握でき、引用ソースとしての信頼スコアが一段引き上がります。

タグ一覧除外でクロールエネルギーを本編へ集中

さらに Googlebot 目線で自分のサイトを総点検してみたところ、個人開発あるあるの「2 つのもったいない穴」 が見つかり、即座に修正しました。

吹出しアイコン

ええっ、どんな穴が見つかったの!?私たちが作った Astro サイトでも同じことになってるかもしれないわ!

吹出しアイコン

1 つ目は 「サイトマップのタグページ水増し」、そして 2 つ目はまさかの 「初期テンプレート英語の放置」 でした!どちらも 5 分で直せて効果絶大なので要チェックですよ!

🔧 🔍 AstroサイトのSEO点検で必ず確認したい2大盲点
  1. 細切れタグページによるサイトマップ肥大化の排除 : @astrojs/sitemap をデフォルト設定で入れていると、記事が 1〜2 本しか入っていないタグ別一覧ページ(/tags/〇〇/)まで何百・何千ページもサイトマップに出力されていました(当サイトでも約 1,200 ページ・150KB に膨張)。astro.config.mjs の sitemap({ filter: (page) => !page.includes('/tags/') }) でタグ一覧を除外し、タグページ自体には <meta name="robots" content="noindex, follow" /> を設定した結果、本当に読んでほしい本編記事とカテゴリハブの約 355 ページ(約 40KB)だけに純度 100% 濃縮 できました。

  2. src/consts.ts の SITE_DESCRIPTION = "Welcome to my website!" 放置チェック : 記事の中身ばかり作り込んでいた結果、Astro 初期テンプレートの英語説明文がトップページや RSS フィードの <description> にそのまま残っているのに気づき、冷や汗をかきました!トップページの <meta name="description"> と RSS の説明文がちゃんとした日本語要約になっているか、今すぐ確認してみてください。


まとめ:人間には読みやすさを、AIには高純度データを

これからの Web サイト運営で一番強いのは、小手先のテクニックではなく 「実体験や一次資料に基づく独自の中身(Information Gain)を書いたうえで、人間にも AI クローラーにも一番食べやすいお皿で出してあげること」 です。

  • Googlebot 向け(1 階) : タグ水増しを除いた高純度な sitemap-index.xml、適切な日本語 SITE_DESCRIPTION、そして出典 URL を citation 化した JSON-LD を整える
  • AI ボット向け(2 階) : Astro の APIRoute でビルド時に /llms.txt・/llms-full.txt・/ai-corpus.jsonl を自動生成し、装飾ノイズゼロで知識を届ける

一度エンドポイントを作ってしまえば、あとは普段どおり記事を書いてビルドするだけで毎回全自動で最新コーパスが更新されます。Astro でブログやドキュメントサイトを運営されている方は、ぜひ導入してみてください!

日当たりの良い部屋で安心しきって眠るノルウェージャンフォレストキャット

▲ 裏側の案内板と自動生成の仕組みさえ作っておけば、あとは安心して毎日の記事執筆に集中できます