discourse-to-markdown — это новый плагин, который возвращает содержимое форума в формате Markdown, если клиент отправляет заголовок Accept: text/markdown или добавляет .md к любому URL-адресу контента.
Мы используем его на нашем собственном форуме по адресу 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
Три точки входа:
- Заголовок
Accept: text/markdown(идеально для LLM) - Суффикс URL
.md - Обнаружение (каждый HTML-ответ объявляет о наличии своего Markdown-аналога через
Link: <...>; rel="alternate"; type="text/markdown"и тег<link rel="alternate">в<head>, RSS-ленты содержат<atom:link>, указывающий на эквивалент в Markdown)
Поддерживаемые маршруты
| Маршрут | 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.
Примечания по конвертации
Плагин конвертирует HTML-код cooked из Discourse — это отрисованное представление, которое видят читатели, с раскрытыми onebox, ссылками на упоминания и атрибутированными цитатами, а не raw. Это сохраняет то, что видят читатели, и делает вывод переносимым для любого рендерера, совместимого с GFM. Специфичные для Discourse конструкции (цитаты, onebox, блоки details, упоминания, хештеги, эмодзи, лайтбоксы, опросы) перед конвертацией переписываются осмысленно.
Конвертированный Markdown кэшируется в Redis для каждого поста с ключом post.id + post.updated_at, а редактирование автоматически инвалидирует кэш.
Настройки
| Настройка | Значение по умолчанию | Назначение |
|---|---|---|
discourse_to_markdown_enabled |
false |
Главный переключатель плагина |
discourse_to_markdown_md_urls_enabled |
true |
Принимать суффиксы URL .md как аналог HTML-маршрута |
discourse_to_markdown_strict_accept |
false |
Возвращать 406 Not Acceptable, если заголовок Accept клиента исключает и text/html, и text/markdown |
discourse_to_markdown_emit_vary |
true |
Добавлять заголовок Vary: Accept к ответам в формате Markdown и 406, чтобы кэши не смешивали представления |
discourse_to_markdown_include_post_metadata |
true |
Включать URL, категорию, теги, автора и временные метки в представление Markdown |
Ресурсы
- Исходный код/проблемы: 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