つれづれなる Agent OPS
つれづれなる Agent OPS
AgentOps

個人ブログをAI Agentに読ませる llms.txtとMCP ServerでAIOを整える

PerplexityやChatGPTが検索の代わりになる中、個人ブログをAI Agentからも発見可能にするAIO(AI最適化)の実装。llms.txt、JSON API、MCP Serverの3層設計と、46本規模での採用判断基準。

Xでシェア
Markdown を表示

最近、情報を探すときの入り口が変わってきたことに気づきました。技術的な疑問を調べるとき、まずGoogleを開く機会が減り、PerplexityやClaude Code、ChatGPTに問いかけることが増えています。もちろん、これは私個人の行動変化にすぎません。ただし、検索エンジンだけでなくAI Agentも情報探索の入り口になりつつあることは、ブログの届け方を見直すきっかけになります。

そこで、ふと疑問が浮かびました。

自分のブログは、AI Agentからどう見えているのだろう。

人間向けSEOは整いましたが、AI向けの入口がありません

このブログは2024年からAstroで構築し、日本語と英語の両言語で46本の記事を公開しています。人間向けのSEO基盤は、一通り整えたつもりでした。

全文検索にはPagefindを導入し、日本語と英語の92ページをインデックスしています。多言語対応ではhreflangとcanonical、JSON-LDのBreadcrumbList、OGPを設定し、検索エンジンがページの関係を解釈できるようにしています。記事内には、目次、前後の記事ナビゲーション、コードブロックのコピーボタンも用意しました。

しかし、これらは「人間がブラウザで読むこと」を前提とした最適化です。AI Agentがサイトへアクセスした場合、個々の記事はHTMLとして取得できても、サイト全体の構成や記事同士の関係を効率よく把握できるとは限りません。Pagefindの検索UIも人間向けであり、AI Agentが利用するにはプログラムから扱えるインターフェースが必要です。

そこで、AI Agentがサイトの構造を把握し、「どの記事に何が書かれているか」を機械的に確認できる入口を用意することにしました。そのためには、構造化されたサイト概要と、プログラムで取得できる記事メタデータが必要です。

AIOを3層に分けて設計する

この課題に対し、AIO(AI Optimization)を次の3層に分けて設計しました。

  • Layer 1 llms.txtによって、AI向けのサイト概要を提供する
  • Layer 2 JSON APIによって、記事メタデータを機械可読な形式で提供する
  • Layer 3 MCP Serverによって、AI Agentからツールとして呼び出せるようにする

この3層は、それぞれ「概要を伝える」「データを提供する」「ツールとして動作する」という異なる役割を担います。すべてのブログに3層が必要なわけではありません。今回の規模では、比較的小さな実装で導入できるLayer 1とLayer 2を先に実装し、Layer 3は設計までにとどめました。

Layer 1としてllms.txtを導入する

llms.txtは、AIがWebサイトの内容を把握しやすいよう、サイト名、概要、主要セクションなどをプレーンテキストで提供するための仕様です。今回はllmstxt.orgで示されている形式を参考にしました。

実装にあたり、最初に迷ったのは「どこまで機械的な形式に寄せるか」という点です。厳密なデータ形式を独自に設ける案も考えましたが、llms.txtは人間も読めるプレーンテキストであることに価値があります。AIからの読みやすさと、人間による保守のしやすさを両立させるため、今回はMarkdown風のテキスト形式を採用しました。

実装は、Astroのエンドポイントである src/pages/llms.txt.ts に配置しました。独立したスクリプトではなくAstroビルドの一部にした理由は、ビルド時に最新の記事リストとカテゴリ数を自動取得できるためです。記事を公開するたびにllms.txtを手動更新する運用では、遅かれ早かれ本文との不整合が生じます。

llms.txtには、次の情報を含めています。

  • サイト名と概要(日本語・英語両方)
  • 主要カテゴリと記事数(13カテゴリ)
  • 人気記事上位15本のタイトルとURL
  • シリーズ一覧(Langfuse朝ブリーフィング、Vercel Eve入門、Flue実践入門)
  • Markdownエクスポートの案内
  • ライセンスと連絡先

正直、ここまで含める必要があるのか、最初は迷いました。

最終的には、AIがサイトの対象範囲と主要コンテンツを把握できることを優先しました。ただし、情報量を増やせばよいわけではありません。今後の記事増加に合わせて、掲載件数や選定基準は見直す必要があります。

Layer 2としてJSON APIを用意する

Layer 2では、全46本の記事メタデータをJSON形式で公開する /api/articles.json を作成しました。

設計時の主な論点は、GraphQLのような柔軟な問い合わせ機構が必要かどうかでした。結論として、46本規模では全件を返すシンプルなJSON APIで十分です。現時点では機能を増やさず、記事数や応答サイズが大きくなった段階で、?limit=?category= といったクエリパラメータの追加を検討する方が保守しやすいと判断しました。

JSONは日本語記事を主軸とし、対応する英語版を同じオブジェクトにまとめる構造にしました。日英の紐付けには translationKey を使い、値がない場合は permalink を利用します。これにより、同一記事の異言語版を機械的に対応付けられます。

{
  "title": "APIで最小ループを組むと...",
  "titleEn": "When You Build a Minimal API Loop...",
  "slug": "llm-loop-engineering-minimal-api",
  "url": "https://llm-lab.dev/posts/llm-loop-engineering-minimal-api/",
  "urlEn": "https://llm-lab.dev/en/posts/llm-loop-engineering-minimal-api/",
  "date": "2026-06-28",
  "category": "設計",
  "categoryEn": "Design",
  "tags": ["agentops", "eval", "loop-engineering", "aidd"],
  "description": "...",
  "series": null,
  "seriesOrder": null
}

CORSヘッダーには Access-Control-Allow-Origin: * を設定しました。このAPIが返すのは公開済みの記事メタデータだけであり、認証情報や非公開データを含まないためです。将来、非公開情報や利用制限が必要な機能を追加する場合は、この設定を分離して見直す必要があります。

Layer 3としてMCP Serverを設計する

Layer 3のMCP Serverは、今回は実装せず、設計までとしました。Model Context Protocol(MCP)は、AI Agentと外部のデータや機能を接続するためのプロトコルです。

MCP Serverを設計するうえでは、接続方式の選択が必要です。ブログの記事情報を公開サービスとして提供する目的を踏まえると、ローカル環境で利用するstdioではなく、リモートから接続できるHTTPベースのトランスポートが適しています。

実行基盤の候補にはCloudflare Workersを選びました。既存サイトと同じCloudflareの環境で運用でき、小規模な検索APIをエッジで実行できるためです。ただし、今回はMCP Serverを実装していないため、実際のレイテンシや利用量は未検証です。料金や制限も変更される可能性があるため、実装時点の公式情報を基に再評価します。

設計したツールは次の5つです。

  • search_articles: キーワード・カテゴリ・タグ・シリーズ・言語での検索
  • get_article: slug指定での個別記事メタデータ取得
  • list_categories: カテゴリ一覧(日本語/英語ラベル付き)
  • list_tags: タグ一覧(記事数付き)
  • list_series: シリーズ一覧(順序付き記事リスト付き)

これらの詳細は docs/mcp-design.md に整理しました。実装時には、まず検索と個別取得の2ツールに絞り、実際の利用ログを見て機能を増やす方針です。

個人ブログのAIOで優先すべきこと

今回の実装と設計を通じて、個人ブログにも転用できる判断基準が3つ見えてきました。

第一に、llms.txtは比較的小さく始められます。今回の実装では、約100行のエンドポイントで、サイト概要と主要コンテンツをまとめた入口を用意できました。ただし、llms.txtを公開するだけでAIサービスからの参照が保証されるわけではありません。まずは機械可読な入口を低コストで整える施策として位置付けるのが妥当です。

第二に、JSON APIは将来の自動化に向けた共通のデータソースになります。現時点ではメタデータの一覧にすぎませんが、ニュースレターの生成、SNS投稿支援、MCP Serverなど、複数の用途から再利用できます。記事数が少ない段階でも、公開情報の構造を一度決めておくことには意味があります。

第三に、MCP Serverの設計は、記事を「読む対象」から「ツールで検索・取得できる知識源」へ拡張する発想につながります。一方で、MCP Serverを用意すること自体が目的になると、運用対象だけが増えかねません。JSON APIでは不足する利用シナリオが見えてから実装する、という順序が重要です。

次の段階

AIOの基盤を整えた次の段階では、記事数の増加に応じて検索方式を見直します。ただし、「500本を超えたらベクトル検索へ移行する」と先に決めるのではなく、応答サイズ、検索精度、レイテンシを計測して判断すべきです。キーワード検索で不足が生じた場合には、Cloudflare Vectorizeなどを使ったセマンティック検索も選択肢になります。

また、インタラクティブなデモも検討しています。たとえば、ブログのメタデータを基にMCPクライアント向けの設定例を生成するツールがあれば、記事を読むだけでなく、実際に接続して挙動を確認できます。これは現時点では構想であり、実装と検証は今後の課題です。

AI Agentが情報探索の入口として使われる場面が増える中、個人ブログにも、人間向けの画面とは別に機械が扱いやすい入口が必要です。今回の判断は、llms.txtとJSON APIを先に実装し、MCP Serverは利用目的が明確になるまで設計にとどめる、というものでした。

重要なのは、流行している仕組みをすべて導入することではありません。誰に、どの情報を、どの粒度で渡したいのかを分けて考えることです。その結果として、サイト概要、構造化データ、ツール呼び出しという3層が必要になったときに、AIOは単なる言葉ではなく、運用可能な設計になります。

DUOps

Author

DUOps(デュオプス)

LLMOps、Agent、MCP、Langfuse、Cloudflare 周辺の実装と運用を、個人で試しながら記録しています。

Xを見る

コメント

Related