Мы мигрировали сотню страниц документации через MCP-сервер, а не скриптами

в 10:43, , рубрики: ai-агенты, Diplodoc, gitbook, markdown, MCP, YFM, документация, миграция, техническая документация

Сначала мы делали вид, что ничего не происходит.

Портал документации то открывался, то нет. Кто-то из коллег замечал, обновлял страницу, всё грузилось — ну ок, и мы шли дальше. Так продолжалось пару месяцев, пока «то работает, то нет» не превратилось в «чаще не работает». Портал жил на GitBook, большая часть пользователей у нас из России, и в какой-то момент эти два факта перестали быть совместимы — но признавать это очень не хотелось.

Причина простая: у нас идёт глобальная миграция пользователей с MS SQL на PostgreSQL. Когда команда переводит на другую СУБД всю клиентскую базу, любая дополнительная проблема воспринимается как вызов на дуэль. Мы искренне надеялись, что рассосётся само.

Не рассосалось. О недоступности справки начали прилетать звоночки от пользователей — в чаты и на почту, напрямую. Мы не банк на четыре уровня согласований: нам достаточно двух-трёх обращений, чтобы наброситься и пойти чинить. Документация для CRM-платформы — часть контура поддержки: пользователь не нашёл ответ на вопрос, как настроить, как добавить, и идёт уже не в справку, а к нам в чат. Сколько нагрузки help-портал держал на себе, мы поняли, когда плотина перестала её держать.

Когда ломается что-то своё — это лайт-ситуация: за день находим, за день чиним, пользователь обычно даже глазом не успеет моргнуть. А когда перестаёт работать чужое приложение, на котором ты крепко завязан, первая реакция — понятненько, приехали. А чё чинить-то? Кода нет, доступа нет, повлиять не на что. Остаётся выбор: ждать или уходить.

Мы решили уходить. Через четыре дня вся документация работала на Diplodoc. Самое интересное — как именно она переехала. Мы не писали конвертеров и не парсили выгрузку регулярками: у GitBook уже есть MCP-сервер, и мы просто дали агенту в него ходить. Про это — основная часть статьи: что агент сделал сам, где проходит граница его возможностей и почему она оказалась не там, где её обычно ищут. А в конце — десять вещей, которые пришлось корректировать ручками уже после переезда.

Дилемма: что мы вообще рассматривали

Первая реакция на голос в зале — «а давайте напишем своё». Но эта шальная мысль, пока додумывалась до конца, практически сразу и отбросилась. У нас есть продукт, который требует к себе внимания, и тратить время на что-то новенькое — это выстрел в ногу.

Свой движок документации: оценка работ

Свой движок документации: оценка работ

Второй вариант — собрать портал на Tilda. Мы её любим, у нас сайт на Tilda, есть опыт, и в углу стоял дизайнер, на которого мы все посмотрели, и мысль даже мелькнула — а что, он молодец, справится, и получилось бы красиво. Но проблема в мелочах, вернее, в объёме: около сотни страниц документации нужно было бы перенести руками через визуальный редактор. Это недели монотонной работы, унылой, как осень в Питере, — копировать из одного окна, вставлять в другое. И на выходе мы получили бы сайт, в который больше нельзя закоммитить из гита: каждая правка снова идёт через мышку и человека.

Третий вариант — другой SaaS для документации. Но мы-то знаем, чем заканчивается зависимость от зарубежного облачного сервиса, и решили отложить этот вариант.

И это всё? Но послышались шаги, и они принесли нам весть о четвёртом варианте, о котором мы на тот момент ещё не знали.

Как дизайнер принёс Diplodoc в клюве

Тут придётся признаться, что не мы нашли решение в результате вдумчивого сравнения технологий, а случайно оно нашло нас и по касательной.

Нашему дизайнеру нравился визуальный стиль Yandex AI Studio — он периодически ходил к ним на сайт за вдохновением, смотреть иллюстрации. Он забрёл в их документацию и залип уже не на картинках, а на структуре: аккуратная навигация, продуманная подача, приятная типографика.

Страница, на которой залип дизайнер. Полез в код смотреть, на чём сделано, — и нашёл Diplodoc

Страница, на которой залип дизайнер. Полез в код смотреть, на чём сделано, — и нашёл Diplodoc

Захотелось понять, на чём это сделано. Открыл просмотр кода страницы — и вышел на Diplodoc.

И, как вишенка на торте, принёс это нам ровно в тот момент, когда на портале запахло жареным. Мы посмотрели и подумали: ну вот, собственно — нате, берите.

Забавно, что мы даже не поняли, что Diplodoc — это проект Яндекса. Просто увидели инструмент, который делает ровно то, что нужно, и взяли в работу.

Почему Diplodoc подошёл

Когда мы всё-таки сели и посмотрели на инструмент осознанно, сошлось несколько вещей.

Документация как код. Markdown в гите вместо закрытого облачного редактора. Ревью через PR, история изменений, ветки, откат, возможность править доку тем же способом, каким мы правим код. Для команды, которая и так живёт в гите, это снимает целый класс проблем.

Открытый исходный код. Исходники лежат на GitHub — больше 50 репозиториев. Если что-то не так работает, можно пойти и посмотреть почему, а не писать в поддержку и ждать.

YFM. Yandex Flavored Markdown — расширенный markdown с блоками кода, вкладками, нотами, схемами. То, чего обычно не хватает в чистом markdown, когда пишешь техническую документацию.

Предсказуемость. Мы только что на себе прочувствовали, что бывает, когда доступность твоей документации зависит от чужих решений. Инфраструктура, которая не отвалится по причинам вне твоего контроля, — это не идеология, а операционная необходимость.

Вы всегда такие легкомысленные, или Почему мы не сравнивали с другими?

Предвосхищая главный вопрос: а где же Docusaurus, mkdocs, Antora?

Честный ответ — мы их просто не смотрели. Вообще. Не потому, что посчитали хуже, а потому что не дошли до стадии сравнения: дизайнер принёс инструмент, инструмент на глаз решает нашу задачу, и мы пошли пробовать. Go-Go, времени нет.

Мы не тратим много времени на то, что можно решить быстро. Маленькая команда не может позволить себе долгий выбор — он обходится дороже, чем ошибка. Две недели сравнительного анализа генераторов документации стоили бы нам заметно больше, чем неудачная попытка, которую можно откатить за день.

Ровно наоборот мы ведём себя в том, что касается собственной платформы. Там решения принимаются долго, с несколькими подходами к одному и тому же и с готовностью переделать. Асимметрия сознательная: цена ошибки в своём продукте и в инструменте для документации отличается на порядки. Мы стараемся не путать эти два режима — и, кажется, чаще всего команды выгорают именно на том, что выбирают инструменты так же тщательно, как проектируют продукт.

Второе, что сработало, — доверие к чужой компетенции. Мы увидели инструмент не в подборке «10 лучших генераторов документации», а в деле: на нём была сделана документация, которая понравилась нам настолько, что мы полезли смотреть код страницы. Кто-то уже решил задачу выбора и ежедневно проверяет своё решение на себе. Для нас этого было достаточно. Done, в работу.

И о том, что Diplodoc сделан в Яндексе, мы узнали, когда перенос уже начался. Выдохнули: ну вот, норм, с этими точно ничего не случится. Постучали по столу и продолжили. Так что решение было принято не потому, что «Яндекс плохого не сделает», а потому что инструмент понравился раньше, чем мы посмотрели на его происхождение.

И последнее, менее рациональное. Опыт даёт способность понимать, что инструмент хороший, ещё до того, как ты сформулировал критерии: аккуратная документация и продуманная навигация — следы того, что делали люди, которые думали о читателе. Мы пошли за этим ощущением. В этот раз оно не подвело; когда-нибудь подведёт — но проверить за четыре дня всё равно дешевле, чем выбирать две недели.

Как переносили: миграция через MCP

Здесь начинается та часть, которая стала приятной неожиданностью, самой интересной. Мы подключили Claude к MCP-серверу GitBook и дали ему доступ к нашей документации напрямую.

Что это такое: MCP (Model Context Protocol) — открытый стандарт, по которому модель получает доступ к внешней системе не через выгрузку файлов, а через описанный интерфейс: что там есть, что можно прочитать, что можно сделать. GitBook поднимает MCP-сервер для каждого опубликованного сайта автоматически — достаточно добавить /~gitbook/mcp к адресу портала. То есть источник данных для миграции уже был готов, мы просто об этом не знали.

Дальше выглядело так: модель сама обошла структуру документации, вычитала содержимое страниц, разложила их в дерево под Diplodoc и сконвертировала разметку в YFM.

В лимиты мы не упёрлись. Сотня страниц вычиталась через MCP без ограничений, без урезанных ответов и без страниц, до которых нельзя было бы дотянуться. Никаких «а теперь давайте порежем документацию на части и будем скармливать кусками».

Где проходит граница доверия

Раз уж речь про агента, который что-то делает сам, сразу про рамки — этот вопрос всегда задают вторым.

Прав на отправку в репозиторий у агента нет. Знаем-знаем, читали: хитреца надо держать крепко. Он коммитит, отправляем мы. Между работой модели и тем, что уезжает в сборку, всегда стоит человек, который смотрит в оба.

Такое разделение снимает целый класс страхов. Агент работает свободно, ошибки при этом остаются локальными и обратимыми — их видно в дифе до того, как они станут частью истории репозитория. Дилеммы «доверять или не доверять ИИ» не возникает: доверие тут вообще ни при чём, требуется ревью.

Чего агент не видит: вёрстка в репозитории и вёрстка на странице — не одно и то же

Вот здесь и обнаружилась настоящая граница между «модель сделала» и «мы сделали».

Разметка в гите может быть абсолютно корректной. Markdown валидный, диф чистый, сборка зелёная. А потом открываешь собранную страницу — и видишь, что блок разъехался, список склеился с абзацем, а таблица поехала. Исходник при этом безупречен: просто YFM отрисовал его не так, как ты предполагал, глядя на текст.

Поймать такое чтением дифа невозможно в принципе. Нужен человек, который открывает готовую страницу и смотрит на неё глазами.

Дальше мы работали в паре, и это оказалось самым эффективным режимом за весь переезд: человек смотрит на страницу и говорит, что не так, — агент правит. Не «поставь задачу и жди результат», а короткий цикл «увидел — сказал — исправлено — посмотрел снова».

Что именно приходилось ловить — вещи предельно банальные:

  • Отступы. Блоки прижимаются друг к другу или, наоборот, расползаются. В исходнике всё выглядит логично, на странице — нет.

  • Видеоплеер. Вставка, которая в разметке описана правильно, на странице отрисовывается не тем, чем ожидалось, или не отрисовывается вовсе.

  • Поведение на разных устройствах. Страница, которая на широком мониторе выглядит нормально, на телефоне складывается неудачно.

Было: статья «Столбцы и колонки» на GitBook

Было: статья «Столбцы и колонки» на GitBook
Стало: та же статья на Diplodoc сразу после переезда

Стало: та же статья на Diplodoc сразу после переезда

Дьявол кроется в мелочах. Ошибки были не в смысле, не в структуре и не в разметке: с этим агент справился. Всё, что осталось человеку, — визуальные мелочи, которые не видны ни в дифе, ни в логе сборки, ни в валидаторе. Их видно, только когда открываешь страницу и смотришь.

10 вещей, которые придётся сделать руками

Что Diplodoc не делает за вас при переезде с GitBook.

Сразу оговорка: это не претензии к инструменту. Движок документации честно занимается тем, чем должен, — превращает markdown в сайт. Проблема в ожиданиях: когда съезжаешь с готового SaaS, привыкаешь, что куча вещей происходит сама собой, и обнаруживаешь их отсутствие уже на проде.

Мы переезжали не только на другой движок, но и на другой домен. Часть пунктов ниже — про это.

1. Страница приезжает к поисковому роботу пустой.

По умолчанию текст рисуется в браузере, а в HTML лежит только контейнер. Человек видит документацию, робот — пустоту. Пока не включён статический рендер, вашего сайта для поиска просто не существует. Обнаруживается это не сразу и очень неприятно.

2. Служебных файлов нет вообще.

Ни robots.txt, ни sitemap.xml, ни canonical. Всё это — отдельный шаг сборки, который надо написать самому. В GitBook оно было по умолчанию, и мы даже не думали, что об этом придётся вспоминать.

3. Каждая страница живёт по двум адресам сразу.

С расширением и без. Без canonical вы аккуратно, своими руками создаёте дубли на всём сайте — и поисковик сам решает, какую версию считать главной.

4. Про карту редиректов со старых URL придётся принять решение.

Классический ответ — собрать полную карту старых адресов и увести их 301-редиректами на новые. Иначе в день переключения умирают все внешние ссылки и весь накопленный вес.

Мы пошли другим путём и осознанно решили за старые ссылки не цепляться. Причины две. Первая: старый домен остался за нами, портал на GitBook продолжает открываться, так что пользователь по забытой ссылке попадает не в пустоту, а на старую версию страницы. Вторая: подавляющее большинство ссылок на документацию у нас живёт внутри самого приложения, и их проще перебить на новые прямо в продукте, чем строить и поддерживать карту редиректов.

Оговорка для честности: этот путь закрывает ссылки внутри продукта, но не закрывает внешние — те, что в поисковой выдаче и на чужих сайтах. Пока старый портал жив, разницы не видно. Когда он умрёт — станет видно.

5. Редиректы платформы — это не 301.

Внутри — заглушки с meta refresh. Браузер пользователя послушно переходит, а поисковик считает это обычной страницей. В sitemap.xml такие адреса класть нельзя, а по-хорошему нужны настоящие 301 на уровне сервера.

6. Старые абсолютные ссылки внутри документации превращаются в 404 молча.

Относительные пути проверяются при сборке — тут всё честно. А вот абсолютные адреса на старый домен никто не проверяет: сборка проходит зелёной, ссылка ведёт в никуда. Проверять надо отдельным прогоном.

7. Страница, не прописанная в оглавлении, просто не собирается.

Без ошибки, без предупреждения. Файл лежит в репозитории, в сайте его нет.

8. Нужна настоящая 404, а не редирект на главную.

Редирект на главную отдаёт код 200: для поисковика несуществующий адрес остаётся живой страницей и продолжает висеть в индексе, а человек теряет контекст и не понимает, куда попал и что искать дальше.

9. Локальный поиск врёт из-за стоп-листа.

Самая обидная находка. Русский языковой пакет выбрасывает как «незначимые» слова, которые в документации по CRM являются рабочими терминами: «день», «время», «имя». Пользователь ищет — получает ноль результатов при живом, написанном, лежащем на сайте контенте.

10. Экспорт — это не переезд, а сырьё.

Даже когда всё технически перенеслось, вы получаете не документацию, а её исходники в плохом состоянии: дубли одного и того же разными словами, куски, где текст превратился в буллеты, мёртвые видео, картинки со случайными именами файлов.

Отдельная ловушка уже на выкладке: каталог сборки не очищается автоматически, а образ копирует то, что в нём лежит. Один невнимательный деплой — и на прод уезжает вчерашняя версия сайта.


Если свести всё в одну мысль: SaaS продавал нам не движок документации, а десяток мелких решений, о которых мы не думали. Переезд на docs-as-code эти решения возвращает вам вместе со свободой. Это хороший размен, но платить за него приходится сразу и в полном объёме.

Хронология: четыре дня

Самое неожиданное в этой хронологии — насколько ровно она легла. Каждый этап занял ровно день.

Этап

Сколько заняло

Увидели Diplodoc, изучили, приняли решение

1 день

Подключение MCP и первый прогон

1 день

Конвертация контента

1 день

Сборка и деплой

1 день

Четыре дня — и вся документация переехала на новый движок, открылась по новому адресу и работает. Миграция на этом закончилась, а не перешла в фазу бесконечного допиливания.

Дальше был отдельный слой работы: разобраться с индексацией, редиректами, поиском и остальными десятью пунктами из списка выше. Но это уже не «мы всё ещё переезжаем», а нормальная эксплуатация нового портала.

А старый портал, кстати, работает

Самое смешное во всей истории: старый портал на GitBook открывается до сих пор. Мы переехали, а он живёт.

Легко сделать вывод, что мы зря подняли панику и можно было ничего не делать. Мы этот вывод рассмотрели и не согласились — по одной причине.

Проблема была не в том, что портал не открывался, а в том, что мы не могли ни предсказать, откроется ли он завтра, ни повлиять на это. Доступность твоей документации перестаёт быть твоим решением.

А инфраструктура, которая работает через раз по причинам вне твоего контроля, — это не инфраструктура, а ружьё на стене. Оно обязательно выстрелит, вопрос лишь когда. Переезжать спокойно за четыре дня лучше, чем в тот день, когда оно окончательно отвалится.

Что бы сделали иначе

Не тянули бы два месяца. Это главный вывод. Все два месяца, пока мы надеялись, что рассосётся, задача не становилась ни проще, ни дешевле — только ближе к моменту, когда решать её пришлось бы в аварийном режиме.

Включили бы статический рендер до переключения, а не после. Пункт первый из списка выше — самый дорогой по последствиям и при этом самый незаметный. Пока не начнёшь специально проверять, что видит робот, ты об этом не думаешь.

Собрали бы служебные файлы заранее. robots.txt, sitemap.xml, canonical — это работа на несколько часов, если делать её до релиза, и работа в панике, если после.

Сразу смотрели бы на собранную страницу, а не на диф. Мы дошли до этого сами, но не в первый день. Привычка «проверил разметку — значит проверил» из мира кода сюда не переносится.

Переезд закончился, документация — нет

Технический переезд занял четыре дня и закрылся. Портал живёт, собирается, деплоится.

Но параллельно у нас идёт другая работа, которую легко перепутать с миграцией, хотя она к ней не относится. Мы активно выпускаем релизы, интерфейс и функциональность меняются — и документация от этого устаревает сама по себе, без всяких переездов. Мы сейчас переписываем статьи именно поэтому: не потому что что-то не доехало, а потому что продукт ушёл вперёд.

Это, кстати, ровно тот случай, когда docs-as-code начинает окупаться. Обновление документации перестало быть отдельным ритуалом в чужом редакторе и стало частью того же процесса, что и разработка: правка идёт коммитом, проходит ревью, выкатывается вместе с релизом.

Как это выглядит на практике. Обычный коммит из нашей текущей работы — страница про оплату подписки:

Обновление документации выглядит как обычный коммит: старые картинки со случайными именами из экспорта GitBook уходят, на их место встают нормальные файлы

Обновление документации выглядит как обычный коммит: старые картинки со случайными именами из экспорта GitBook уходят, на их место встают нормальные файлы

Оплата подписки: перестроена страница и обновлены скриншоты

— убраны два устаревших видео и упоминания коробочного решения — три вкладки интерфейса (Тарифы, История платежей, Документы) собраны в блок {% list tabs %} с новыми скриншотами — скриншоты переведены в WebP шириной 1800px, четыре старых файла удалены

Восемь изменённых файлов, +42 −45. Всё видно в дифе, всё откатывается одной командой, всё лежит в истории рядом с кодом.

Отдельно доставляет список удалённых файлов: -MczmhIMC-RuWSnLzdXj.png, -Mcznf1MnudGHUk6wtIs.png и ещё пара таких же. Это те самые картинки со случайными именами из экспорта, о которых шла речь в десятом пункте. На их место встали payment.webp и paydoc.webp — файлы, по имени которых понятно, что внутри. Мелочь, которая через год работы экономит много времени.


Если вы стоите перед тем же выбором. Diplodoc — открытый проект, потрогать можно бесплатно, документация у самого проекта хорошая. Готового инструмента миграции с GitBook мы не нашли — и, как выяснилось, он и не нужен: если ваша документация опубликована в GitBook, у неё уже есть MCP-сервер, а дальше вопрос в том, как вы поставите задачу агенту.

Вопросы про детали миграции — задавайте в комментариях, отвечу.

Автор: About_everything

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js