目次
AI検索の時代が来ています。ChatGPTのウェブ検索、Perplexity、Google AI Overviews——ユーザーがAIを通じて情報を得る機会が急増する中、「AIにあなたのサイトを正しく理解してもらう」ことの重要性が高まっています。
そこで登場したのがllms.txtです。robots.txtがGooglebotなどの検索エンジンクローラーに「このページはクロールしていい/ダメ」を伝えるファイルだとすれば、llms.txtはGPTBotやClaudeBotなどのAIクローラーに「うちのサイトはこういうサイトです」と自己紹介するファイルです。
この記事では、llms.txtのフォーマット仕様、記載すべき情報、静的ファイルと動的生成の判断基準、主要フレームワークでの実装コードまで、徹底的に解説します。
1. llms.txtとは何か
llms.txtは、Webサイトのルートディレクトリに配置するプレーンテキストファイル(Markdown形式)で、LLM(大規模言語モデル)にサイトの概要・構造・コンテンツ一覧を伝えることを目的としています。
基本情報
| 項目 | 内容 |
|---|---|
| ファイル名 | llms.txt |
| 配置場所 | ドメインのルート(https://example.com/llms.txt) |
| フォーマット | Markdown(プレーンテキスト) |
| 文字コード | UTF-8 |
| 提唱者 | llmstxt.org(Jeremy Howard他) |
| 標準化状況 | デファクト標準(RFC等の正式規格ではない) |
| 読み取るBot | GPTBot、ClaudeBot、PerplexityBot、Google-Extended等 |
一言で言うと
robots.txt = 「入るな」 / llms.txt = 「うちはこういうサイトです」
robots.txtがアクセス制御(許可/拒否)のファイルなのに対し、llms.txtはサイトの内容説明(自己紹介)のファイルです。両者は競合しません——むしろ併用するものです。
2. なぜ必要なのか——robots.txtとの違い
「sitemapとmetaタグがあればAIもサイトを理解できるのでは?」と思うかもしれません。確かにその通りですが、llms.txtには固有のメリットがあります。
robots.txt / sitemap.xml / llms.txt の役割比較
| ファイル | 目的 | 対象 | 内容 |
|---|---|---|---|
| robots.txt | クロールの許可/拒否 | 全クローラー | Allow/Disallow ルール |
| sitemap.xml | ページ一覧の提供 | 検索エンジン | URL・更新日・優先度 |
| llms.txt | サイトの内容説明 | LLMクローラー | 概要・構造・コンテンツ要約 |
llms.txtが必要な3つの理由
理由1:LLMはサイト全体を効率的にクロールできない
Googlebotは何十億ページもクロールして大規模なインデックスを構築しますが、LLMのクローラーはそこまで網羅的にクロールしません。llms.txtを置くことで、「このサイトで最も重要なコンテンツはこれです」とAIに効率的に伝えられます。
理由2:AIの回答で引用される可能性が上がる
ChatGPTやPerplexityがWeb検索で回答を生成する際、llms.txtでサイトの専門性と内容を明示しておくと、そのサイトが信頼できる情報源として認識されやすくなると考えられています。これはLLMO(大規模言語モデル最適化)の一環です。
LLMOの詳しい解説は「LLMOとは?」をご覧ください。
理由3:sitemap.xmlにはないメタ情報を伝えられる
sitemap.xmlはURL一覧に過ぎません。llms.txtでは以下の情報も伝えられます。
- サイトのテーマ・専門分野
- 各コンテンツの要約・カテゴリ
- サイトの更新頻度・規模
- 多言語対応の有無
- 連絡先情報
3. フォーマット仕様——何をどう書くか
llms.txtはMarkdown形式で記述します。llmstxt.orgの仕様に基づくフォーマットは以下の通りです。
基本構造
# サイト名
> サイトの概要説明。1〜3文程度で、サイトのテーマ・対象・提供する価値を簡潔に伝える。
## セクション名1
- [ページタイトル](URL): ページの要約説明
## セクション名2
- [ページタイトル](URL): ページの要約説明
- [ページタイトル](URL): ページの要約説明
フォーマットのルール
| 要素 | Markdown記法 | 役割 |
|---|---|---|
| H1見出し | # サイト名 | サイトの正式名称。ファイル内に1つだけ |
| 引用ブロック | > 概要テキスト | サイトの概要説明。H1直後に配置 |
| H2見出し | ## セクション名 | コンテンツのグループ分け |
| リストリンク | - [タイトル](URL): 説明 | 個別コンテンツの情報 |
実際の記述例
# My Tech Blog
> My Tech Blog is a software engineering blog covering web development, cloud infrastructure, and AI tools. Updated weekly with practical tutorials and comparisons.
## Main Sections
- [Articles](https://example.com/articles): 50+ in-depth technical articles
- [Tutorials](https://example.com/tutorials): Step-by-step coding tutorials
## Popular Articles
- [React vs Vue in 2026](https://example.com/articles/react-vs-vue): A detailed comparison of React and Vue.js for modern web development, covering performance, ecosystem, and learning curve.
- [Docker for Beginners](https://example.com/articles/docker-beginners): Complete guide to Docker containers for developers who have never used containerization.
## Site Information
- URL: https://example.com
- Sitemap: https://example.com/sitemap.xml
- Languages: en, ja
- Contact: admin@example.com
注意点
- 基本は英語で書く。llms.txtの読み手はAI(LLM)であり、仕様や実例が英語で統一されているため、英語で記述するのがベストプラクティスとされる。多言語サイトの場合は英語で記述し、
Languages: ja, en, es, ...のように対応言語を明記するのが推奨される。一方、単一言語のサイト(たとえばサイトのコンテンツがすべてフランス語、すべてロシア語等)であれば、サイトの言語で記述しても実用上問題ない。主要LLM(GPT、Claude、Gemini等)はほとんどの言語を高精度で処理でき、そのサイトを利用するユーザーも同じ言語で質問するため、一貫性のある応答が期待できる - 文字コードは必ずUTF-8にすること。Shift-JIS等では文字化けする
- emダッシュ(—)等の特殊文字は避ける。プレーンテキストとして表示されるため、ブラウザによっては文字化けする可能性がある。ハイフン(-)やダブルハイフン(--)を使う
- URLは絶対パス(https://から始まる完全なURL)を使うこと
- 1ファイル内のH1は1つだけ。セクション分けにはH2を使う
4. 記載すべき情報——必須・推奨・任意
何を書くかで迷う人が多いので、優先度別に整理します。
必須情報(これがないとllms.txtの意味がない)
| 情報 | 記述場所 | 例 |
|---|---|---|
| サイト名 | H1見出し | # AI Arte |
| サイト概要 | 引用ブロック | > AI learning platform... |
| 主要セクション | H2 + リンクリスト | - [Articles](URL): 説明 |
推奨情報(あった方がAIの理解度が上がる)
| 情報 | なぜ必要か |
|---|---|
| 全コンテンツ一覧 | AIがサイト全体のカバー範囲を把握できる |
| 各コンテンツの1行要約 | AIがページ内容を事前に理解できる |
| カテゴリ/タグ体系 | サイトの情報構造を示す |
| サイトURL | 正規URLの明示 |
| Sitemap URL | 詳細なURL一覧への誘導 |
| 対応言語 | 多言語サイトの場合に重要 |
| 連絡先 | サイト運営者の身元を示す |
任意情報(あれば望ましいが必須ではない)
- 技術スタック:何で構築されているか(フレームワーク等)
- 更新頻度:どのくらいの頻度でコンテンツが追加されるか
- コンテンツ総数:記事数等
- ライセンス/引用ポリシー:AIが引用していいかどうか
- API情報:プログラマティックアクセスが可能な場合
書くべきでない情報
- 機密情報:管理画面のURL、内部APIのエンドポイント等
- 個人情報:必要以上の個人情報(住所、電話番号等)
- 認証情報:APIキー、パスワード等
5. llms.txt と llms-full.txt の違い
llmstxt.orgの仕様では、llms.txtに加えてllms-full.txtというファイルも定義されています。
| ファイル | 内容 | サイズ目安 | 用途 |
|---|---|---|---|
| llms.txt | サイトの概要・構造・リンク一覧 | 1〜50KB | サイト全体の「目次」 |
| llms-full.txt | 全コンテンツのテキスト全文 | 100KB〜数MB | コンテンツの全文をAIに提供 |
llms-full.txtが必要なケース
- 技術ドキュメント:APIリファレンスやライブラリのドキュメントなど、AIに全文を理解してもらうことで回答精度が上がるケース
- ナレッジベース:FAQ集や用語集など、断片的に引用されることが多いコンテンツ
llms-full.txtが不要なケース
- ブログ・メディアサイト:記事数が多く、全文を1ファイルにまとめると巨大になりすぎる。llms.txtの要約で十分
- ECサイト:商品情報は構造化データ(JSON-LD等)で提供する方が適切
- コーポレートサイト:ページ数が少なく、llms.txtだけでカバーできる
一般的なブログやメディアサイトでは、llms.txtだけで十分です。llms-full.txtは技術ドキュメント向けと考えてください。
6. 静的ファイル vs 動的生成——どちらを選ぶべきか
llms.txtの運用方法は大きく2つあります。
方法1:静的ファイル
public/llms.txt(または同等のパス)に直接テキストファイルを配置する方法です。
メリット:
- 実装が最も簡単(ファイルを置くだけ)
- サーバー負荷がゼロ
- フレームワークなしでも動作する
デメリット:
- コンテンツを追加・修正するたびに手動でファイルを更新する必要がある
- 更新を忘れると古い情報がAIに伝わる
- コンテンツ数やカテゴリ数がファイルの記載と実際のサイトでズレる
方法2:動的生成
/llms.txtへのリクエストをアプリケーションが受け取り、データベースから最新の情報を取得してテキストを動的に生成する方法です。
メリット:
- 常に最新の情報が反映される
- 記事を追加すれば自動的にllms.txtにも反映
- コンテンツ数やカテゴリ名も常に正確
デメリット:
- 実装の手間がかかる(ルート定義+コントローラー)
- リクエストのたびにDBアクセスが発生する(キャッシュで軽減可能)
- フレームワークが必要
判断基準
| 条件 | おすすめ |
|---|---|
| コンテンツが10件以下で滅多に増えない | 静的ファイルでOK |
| コンテンツが10件以上 or 月1回以上更新 | 動的生成を推奨 |
| WordPress / Laravel / Django等を使っている | 動的生成が容易 |
| 静的サイト(Hugo, Jekyll, Astro等) | ビルド時に自動生成が理想 |
| 1人運用でメンテナンスを最小化したい | 動的生成(一度作れば放置できる) |
結論:迷ったら動的生成。最初の実装コストはかかりますが、「設置して終わり」にできるので長期的には運用コストが低くなります。静的ファイルで始めて「更新を忘れて古い情報がAIに伝わっていた」というのが最悪のパターンです。
7. 実装方法——主要フレームワーク別コード例
ここからは、主要フレームワークでのllms.txt動的生成の実装方法を紹介します。
Laravel(PHP)
ルート定義(routes/web.php):
use App\Http\Controllers\LlmsTxtController;
Route::get('/llms.txt', [LlmsTxtController::class, 'index']);
コントローラー(app/Http/Controllers/LlmsTxtController.php):
class LlmsTxtController extends Controller
{
public function index()
{
$articles = Article::published()
->with(['translations' => fn($q) => $q->where('locale', 'en')])
->orderBy('published_at')
->get();
$lines = [];
$lines[] = '# My Site Name';
$lines[] = '';
$lines[] = '> Site description here.';
$lines[] = '';
$lines[] = '## All Articles (' . $articles->count() . ')';
$lines[] = '';
foreach ($articles as $article) {
$t = $article->translations->first();
if (!$t) continue;
$url = 'https://example.com/en/articles/' . $article->slug;
$lines[] = '- [' . $t->title . '](' . $url . '): ' . $t->meta_description;
}
$content = implode("\n", $lines);
return response($content, 200)
->header('Content-Type', 'text/plain; charset=utf-8');
}
}
ポイントはContent-Type: text/plain; charset=utf-8を明示すること。これを忘れるとHTMLとして解釈される可能性があります。
Django(Python)
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('llms.txt', views.llms_txt, name='llms_txt'),
]
# views.py
from django.http import HttpResponse
from .models import Article
def llms_txt(request):
articles = Article.objects.filter(
status='published'
).order_by('published_at')
lines = ['# My Site', '', '> Description.', '', '## Articles', '']
for a in articles:
lines.append(f'- [{a.title}](https://example.com/articles/{a.slug}): {a.meta_description}')
content = '\n'.join(lines)
return HttpResponse(content, content_type='text/plain; charset=utf-8')
Next.js(TypeScript)
// app/llms.txt/route.ts (App Router)
import { NextResponse } from 'next/server'
export async function GET() {
// DBやCMSからデータ取得
const posts = await getAllPosts()
const lines = [
'# My Site',
'',
'> Description.',
'',
'## Articles',
'',
...posts.map(p =>
`- [${p.title}](https://example.com/posts/${p.slug}): ${p.description}`
),
]
return new NextResponse(lines.join('\n'), {
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
})
}
WordPress(PHP)
functions.phpまたはプラグインに追加:
// functions.php
add_action('init', function() {
add_rewrite_rule('^llms\.txt$', 'index.php?llms_txt=1', 'top');
});
add_filter('query_vars', function($vars) {
$vars[] = 'llms_txt';
return $vars;
});
add_action('template_redirect', function() {
if (!get_query_var('llms_txt')) return;
header('Content-Type: text/plain; charset=utf-8');
$posts = get_posts(['numberposts' => -1, 'post_status' => 'publish']);
echo "# " . get_bloginfo('name') . "\n\n";
echo "> " . get_bloginfo('description') . "\n\n";
echo "## Articles (" . count($posts) . ")\n\n";
foreach ($posts as $post) {
$url = get_permalink($post);
$desc = get_the_excerpt($post);
echo "- [{$post->post_title}]({$url}): {$desc}\n";
}
exit;
});
WordPressの場合は、パーマリンク設定を保存し直す(リライトルールのフラッシュ)ことを忘れないでください。
静的サイトジェネレーター(Hugo / Astro等)
ビルド時に自動生成するスクリプトを書きます。
# build-llms-txt.sh (Hugo向けの例)
#!/bin/bash
echo "# My Site" > public/llms.txt
echo "" >> public/llms.txt
echo "> Site description." >> public/llms.txt
echo "" >> public/llms.txt
echo "## Articles" >> public/llms.txt
echo "" >> public/llms.txt
for file in content/posts/*.md; do
title=$(grep '^title:' "$file" | sed 's/title: //')
slug=$(basename "$file" .md)
desc=$(grep '^description:' "$file" | sed 's/description: //')
echo "- [${title}](https://example.com/posts/${slug}): ${desc}" >> public/llms.txt
done
CIパイプライン(GitHub Actions等)でビルド前に実行すれば、デプロイのたびに自動更新されます。
8. 設置後の確認と検証
llms.txtを設置したら、以下の点を確認しましょう。
基本チェックリスト
| チェック項目 | 確認方法 |
|---|---|
| URLでアクセスできるか | curl https://yoursite.com/llms.txt |
| Content-Typeが正しいか | curl -I で text/plain; charset=utf-8 を確認 |
| 文字化けしていないか | ブラウザで直接開いて日本語が正しく表示されるか |
| リンクが正しいか | 記載したURLに実際にアクセスできるか |
| HTTPステータスが200か | curl -o /dev/null -w "%{http_code}" |
| robots.txtでブロックしていないか | robots.txtにDisallow: /llms.txtがないこと |
動的生成の場合の追加チェック
- 記事を1つ追加した後にllms.txtを確認:新しい記事が反映されているか
- コンテンツ数の表示が正しいか:「All Articles (27)」の数字が実際の公開記事数と一致するか
- 非公開記事が含まれていないか:下書きや予約投稿が表示されていないことを確認
検証ツール
2026年4月時点で、llms.txtの公式バリデーターは存在しません。ただし、以下の方法で検証できます。
- ChatGPTやClaudeに読ませる:「https://yoursite.com/llms.txt を読んで、このサイトについて教えて」と聞く
- Markdownプレビューア:llms.txtの内容をMarkdownプレビューアに貼り付けて、構造が正しくレンダリングされるか確認
- SEO監査ツール:一部のSEO監査ツールがllms.txtの存在チェックに対応し始めている
9. 実際のサイトのllms.txt事例
llms.txtを導入しているサイトの傾向を見てみましょう。
導入が進んでいるサイトの特徴
| サイト種類 | 導入率 | 理由 |
|---|---|---|
| AI関連サービス・ツール | 高い | AI業界自体がLLMO意識が高い |
| 技術ドキュメント | 高い | AIに正しく情報を伝えたいニーズ |
| テックブログ | 中程度 | 技術的なトレンドへの感度が高い |
| コーポレートサイト | 低い | まだ認知度が低い |
| ECサイト | 低い | 構造化データ(JSON-LD)が優先 |
良いllms.txtの特徴
- 簡潔でわかりやすい概要説明——サイトの専門分野が一読でわかる
- 全コンテンツが要約付きで列挙——AIが全体像を把握できる
- カテゴリ体系が明示——情報の構造がわかる
- 動的生成——常に最新の状態
悪いllms.txtの特徴
- サイト名と連絡先だけ——情報量が少なすぎてAIの理解の助けにならない
- 全コンテンツの本文をコピペ——llms.txtは「目次」であって「全文」ではない。全文はllms-full.txtの役割
- 古い情報のまま放置——「10 articles」と書いてあるのに実際は50記事あるなど、信頼性を損なう
- 機密情報が含まれている——管理画面のURLやAPIキーが書かれているケース
FAQ
Q. llms.txtを設置しないとAIの検索結果に表示されませんか?
いいえ、llms.txtがなくてもAIはサイトをクロールし、検索結果に表示できます。llms.txtはあくまで「AIの理解を助ける補助ファイル」です。ただし、設置することでAIがサイトの構造や内容をより正確に把握できるようになるため、AI検索での引用可能性が高まると考えられています。SEOにおけるsitemap.xmlと同じような位置づけです——なくても動くが、あった方が有利。
Q. robots.txtでAIクローラーをブロックしている場合、llms.txtは意味がありますか?
robots.txtでUser-agent: GPTBot等をDisallowしている場合、そのBotはサイトをクロールしません。しかしllms.txt自体はrobots.txtのルールとは独立しています。AIが別の経路(ユーザーがURLを直接貼り付けるなど)でllms.txtにアクセスする可能性はあります。意図的にAIクローラーをブロックしている場合は、llms.txtも設置しないのが一貫性のある対応です。
Q. llms.txtはどの言語で書くべきですか?
多言語サイトなら英語、単一言語サイトならサイトの言語でもOKです。仕様や実例は英語が主流で、多言語サイトでは中立的な言語として英語が最も合理的です。ただし、コンテンツが1つの言語で完結しているサイトであれば、その言語で書いても問題ありません。主要LLMはほとんどの言語を高精度で処理でき、ユーザーもサイトと同じ言語で質問するため、一貫性のある応答が得られます。
Q. llms.txtのファイルサイズに制限はありますか?
仕様上の明確な制限はありません。ただし、実用上は50KB以下に収めるのが推奨されます。数百記事のサイトでも、各記事のタイトル+1行要約であれば十分50KB以内に収まります。全文テキストを含めたい場合はllms-full.txtを別途用意してください。
Q. 更新頻度はどのくらいが適切ですか?
動的生成の場合はリクエストのたびに最新情報が返されるので気にする必要はありません。静的ファイルの場合は、コンテンツを追加・修正するたびに更新するのが理想です。最低でも月1回は確認・更新しましょう。古い情報が放置されるくらいなら、動的生成に切り替えることを推奨します。
Q. SEOに影響はありますか?
llms.txtは従来のSEO(Google検索のランキング)には直接影響しません。GoogleはGooglebotを使ってHTMLをクロールしており、llms.txtを検索ランキングの要因としていません。ただし、AI Overviews(Googleの検索結果上に表示されるAI回答)やChatGPT、PerplexityなどのAI検索での引用可能性には影響する可能性があります。従来のSEOとは別のレイヤー(LLMO)の施策として捉えてください。
Q. WordPressのプラグインはありますか?
2026年4月時点で、llms.txtを自動生成するWordPressプラグインはいくつか登場しています。ただし、機能や品質にばらつきがあるため、プラグインに頼る場合は生成された内容を必ず確認してください。自分でfunctions.phpに数十行のコードを追加するだけでも実現できるので、プラグインなしでも十分対応可能です。