LLMがWebサイトの情報を効率的に取得するための仕様 llms.txt を、このHugoブログに導入した。
環境
- Hugo v0.155.2
- テーマ: Beautifulhugo
- Cloudflare Pages
llms.txtとは
llmstxt.org
で提案されている、Webサイトのルートに配置するMarkdown形式のテキストファイル。robots.txt や sitemap.xml のように、サイトの概要と主要なリンクをLLMが読みやすい形で提供する。
主に2種類のファイルがある:
- llms.txt — サイトの概要と記事リンクの一覧(目次的な役割)
- llms-full.txt — 全記事の本文を含む完全版
技術ブログに導入するメリット
正直なところ、個人の技術ブログにおけるメリットは限定的。APIドキュメントやライブラリのリファレンスほどの需要はない。
ただし以下の点で「やっておいて損はない」と判断した:
- LLM搭載の検索エンジン(Perplexity、ChatGPT Search等) がサイトの文脈を掴みやすくなる可能性がある
- コストがほぼゼロ — Hugoのテンプレートで自動生成すれば、記事が増えても手動メンテ不要
- 先行投資 — 仕様が普及すれば将来的に有利になるかもしれない
導入手順
Hugo の outputFormats を使ってビルド時に自動生成する方式を採用した。static/ に静的ファイルを置く方式だと記事の増減が反映されないため、テンプレート方式がベスト。
1. hugo.toml に outputFormats を追加
[outputs]
home = ["html", "rss", "llms", "llmsfull"]
[outputFormats.llms]
baseName = "llms"
isPlainText = true
mediaType = "text/plain"
rel = "alternate"
root = true
[outputFormats.llmsfull]
baseName = "llms-full"
isPlainText = true
mediaType = "text/plain"
rel = "alternate"
root = trueoutputs.home のデフォルト値は ["html", "rss"] なので、明示的に指定しつつ llms と llmsfull を追加する。
2. layouts/index.llms.txt を作成
記事リンクの一覧を日付降順で自動生成するテンプレート。
{{- $baseURL := .Site.BaseURL | strings.TrimSuffix "/" -}}
# {{ .Site.Title }}
> セルフホスティング、DevOps、Linux管理、開発ツールに関する日本語の技術ブログ。Hugo + Cloudflare Pagesで運用。
- 記事の主な言語は日本語です
- 記事はAIの支援を受けて作成されている場合があります
## Docs
- [About]({{ $baseURL }}/about/): ブログの方針・サイト概要
## Articles
{{ range where (sort .Site.RegularPages "Date" "desc") "Section" "post" }}
- [{{ .Title }}]({{ .Permalink }}): {{ .Date.Format "2006-01-02" }}
{{- end }}3. layouts/index.llmsfull.txt を作成
全記事のMarkdownソースを含む完全版テンプレート。
{{- $baseURL := .Site.BaseURL | strings.TrimSuffix "/" -}}
# {{ .Site.Title }}
> セルフホスティング、DevOps、Linux管理、開発ツールに関する日本語の技術ブログ。Hugo + Cloudflare Pagesで運用。
{{ range where (sort .Site.RegularPages "Date" "desc") "Section" "post" }}
--------------------------------------------------------------------------------
title: "{{ .Title }}"
date: "{{ .Date.Format "2006-01-02" }}"
url: {{ .Permalink }}
--------------------------------------------------------------------------------
{{ .RawContent }}
{{ end -}}区切り文字に --- ではなく長い罫線を使っているのは、記事内に ---(YAML区切り / 水平線)が含まれるケースがあるため。
4. ビルド確認
hugo --gc --minifypublic/ 配下に生成される:
llms.txt— 約61KB(記事リンク一覧)llms-full.txt— 約781KB(全記事本文込み)
Cloudflare Pagesでの配信
特別な設定は不要。Cloudflare Pagesは .txt ファイルに対して text/plain; charset=utf-8 を自動で付与するため、日本語の文字化けは起きない。
nginxの場合は charset UTF-8 の設定が別途必要になるが、Cloudflare Pagesではその心配がない。
生成結果
セキュリティ・盗用リスクについて
llms-full.txt には全記事の本文が含まれるため、コンテンツの盗用や悪用が気になるかもしれない。
結論としては、リスクは実質的に変わらない。
- 全記事は既にHTMLとして公開済みで、
sitemap.xmlに全URLが掲載されている - スクレイピングしたい人は llms.txt がなくてもsitemap.xml + curlで同じことができる
- LLMのトレーニングデータに使われる可能性はllms.txtの有無に関係なくある(CommonCrawl等で既に収集されている)
llms.txt の本来の用途は推論時(ユーザーがLLMにサイト情報を渡す時)であり、トレーニングデータ収集とは別の文脈。
気になる場合の対策
| 対策 | 方法 | トレードオフ |
|---|---|---|
| llms-full.txt をやめる | llms.txt(リンク一覧のみ)だけ残す | LLMが全文を一括取得できなくなるが、個別URLは辿れる |
| 記事数を制限する | テンプレートで直近N件だけ出力する | 古い記事は含まれない |
| Cloudflare WAF/Rate Limit | 大量アクセスをブロック | 正当なLLMアクセスもブロックされうる |
| robots.txt で制御 | Disallow: /llms-full.txt を追加 | 行儀の良いクローラーだけ従う |
個人技術ブログであれば実害は小さいので、そのまま公開で問題ないと判断した。気になる場合は llms-full.txt だけ外して llms.txt(リンク一覧のみ)だけ残す のが一番バランスが良い。