Markdown для агентов: content negotiation для LLM
Зачем отдавать Markdown-версию страниц для AI, как работает content negotiation, минимальный пример, ошибки и как проверить.
Обновлено:
Что это
«Markdown для агентов» — отдача чистой Markdown-версии страницы, когда клиент
просит её заголовком Accept: text/markdown. Людям отдаём HTML, агентам —
Markdown. Реализуется через content negotiation (один URL, разный формат) либо
через стабильный параллельный .md-адрес для каждой страницы.
Зачем это AI-агентам
HTML для LLM — это шум: навигация, скрипты, разметка, баннеры. Модель тратит токены и контекст на мусор и хуже извлекает суть. Markdown плотный и чистый: меньше токенов, точнее понимание, выше шанс корректной цитаты в ответе AI.
Минимальный рабочий пример
Сервер смотрит заголовок Accept и отдаёт нужный формат:
GET /guides/llms-txt HTTP/1.1
Accept: text/markdown
HTTP/1.1 200 OK
Content-Type: text/markdown; charset=utf-8
Vary: Accept
# Как написать llms.txt
> Кратко: ...
Альтернатива попроще: публиковать статичный /guides/llms-txt.md рядом с HTML и
анонсировать его (<link rel="alternate" type="text/markdown" ...>).
Правильно vs неправильно
| Правильно | Неправильно |
|---|---|
Accept: text/markdown → Content-Type: text/markdown | Всегда HTML, заголовок игнорируется |
Заголовок Vary: Accept (для корректного кеша) | Нет Vary — прокси отдаёт не тот формат |
| Markdown повторяет основной контент | Markdown-версия урезана/устарела |
Типичные ошибки
- Игнор заголовка
Accept— сервер всегда отдаёт HTML. - Нет
Vary: Accept— CDN/прокси кешируют один формат для всех. - Markdown ≠ HTML по содержанию — рассинхрон версий.
- Отдаётся
text/plainвместоtext/markdown.
Как проверить
Скан проверит content negotiation. Вручную — сравните два запроса:
curl -s -H "Accept: text/markdown" https://example.com/ | head
curl -sI -H "Accept: text/markdown" https://example.com/ | grep -i 'content-type\|vary'
Во втором ответе ждём Content-Type: text/markdown и Vary: Accept.