Hugoブログにllms.txtとllms-full.txtを導入した

Adding llms.txt and llms-full.txt to a Hugo blog on Cloudflare Pages

* 本ページはプロモーションが含まれています

LLMがWebサイトの情報を効率的に取得するための仕様 llms.txt を、このHugoブログに導入した。

環境 

llms.txtとは 

llmstxt.org で提案されている、Webサイトのルートに配置するMarkdown形式のテキストファイル。robots.txtsitemap.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 = true

outputs.home のデフォルト値は ["html", "rss"] なので、明示的に指定しつつ llmsllmsfull を追加する。

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 --minify

public/ 配下に生成される:

  • 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(リンク一覧のみ)だけ残す のが一番バランスが良い。

参考