discourse-to-markdown は、クライアントが Accept: text/markdown を送信するか、コンテンツ URL の末尾に .md を追加した場合に、フォーラムのコンテンツを Markdown 形式で返す新しいプラグインです。
当社のフォーラム https://discourse.roots.io でもこのプラグインを実行しています:
curl -H "Accept: text/markdown" https://discourse.roots.io/latest
curl https://discourse.roots.io/t/serve-your-wordpress-posts-as-markdown/30321.md
HTML を LLM に渡すのはコストが高く、コンテンツのみを含む Markdown を提供することで、トークン使用量を 3〜5 倍削減できることが多いです。これにより、API 呼び出しのコストが下がり、応答が高速化され、モデルが推論を行うためのコンテキストウィンドウの余裕が生まれます。詳細な提案と任意のサイトの準備状況チェックについては、https://acceptmarkdown.com をご覧ください。
クライアントが Markdown をリクエストする方法
3 つのエントリーポイント:
Accept: text/markdownヘッダー(LLM に最適).mdURL サフィックス- 発見(すべての HTML 応答は
Link: <...>; rel="alternate"; type="text/markdown"および<head>内の<link rel="alternate">タグを介して、その Markdown 版を広告します。RSS フィードには、Markdown 版を指す<atom:link>が含まれます)
サポートされているルート
| ルート | HTML | Markdown |
|---|---|---|
| トピック | /t/:slug/:id |
/t/:slug/:id.md |
| 単一の投稿 | /t/:slug/:id/:post_number |
/t/:slug/:id/:post_number.md |
| カテゴリ | /c/:slug/:id |
/c/:slug/:id.md |
| タグ | /tag/:tag |
/tag/:tag.md |
| 最新 | /latest |
/latest.md |
| 上位 | /top |
/top.md |
| 人気 | /hot |
/hot.md |
| ユーザーアクティビティ | /u/:username/activity |
/u/:username/activity.md |
インストール
app.yml にプラグインを追加します:
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/roots/discourse-to-markdown.git
コンテナを再構築します:
cd /var/discourse
./launcher rebuild app
その後、管理 → 設定 → プラグイン → Markdown 出力 で有効にします。
変換に関する注記
このプラグインは、Discourse の cooked HTML(読み込み者が表示するレンダリングされた表現で、1 ボックスが展開され、メンションがリンクされ、引用が帰属付けられたもの)を変換します。raw ではありません。これにより、読み込み者が実際に表示するものが保持され、出力が任意の GFM 互換レンダラー間で移植可能になります。Discourse 固有の構造(引用、1 ボックス、詳細、メンション、ハッシュタグ、絵文字、ライトボックス、投票)は、変換前に適切に書き換えられます。
変換された Markdown は、post.id と post.updated_at をキーとして Redis に投稿ごとにキャッシュされ、編集は自動的に無効化されます。
設定
| 設定 | デフォルト | 目的 |
|---|---|---|
discourse_to_markdown_enabled |
false |
プラグインのマスタースイッチ |
discourse_to_markdown_md_urls_enabled |
true |
HTML ルートの兄弟として .md URL サフィックスを受け入れる |
discourse_to_markdown_strict_accept |
false |
クライアントの Accept ヘッダーに text/html と text/markdown の両方が含まれていない場合に 406 Not Acceptable を返す |
discourse_to_markdown_emit_vary |
true |
Markdown および 406 応答で Vary: Accept を発行し、キャッシュが表現を横断して提供されないようにする |
discourse_to_markdown_include_post_metadata |
true |
Markdown 表現に URL、カテゴリ、タグ、著者、タイムスタンプを含める |
リソース
- ソース/問題: GitHub - roots/discourse-to-markdown: Serve Discourse content as Markdown via Accept: text/markdown or .md URLs — content negotiation for LLMs and agents. · GitHub
- acceptmarkdown.com — コンテンツネゴシエーションを介してエージェントに Markdown を提供し、サイトの準備状況をチェック
- RFC 9110 §12.5.1 — プロアクティブネゴシエーション — このプラグインが実装する仕様
- RFC 7763 —
text/markdownメディアタイプの登録 - MDN — コンテンツネゴシエーション — コンセプトへのわかりやすい入門
- 完全な仕様と開発者ドキュメントリストについては、acceptmarkdown.com/reference をご覧ください