Есть старая шутка: «Документация – это то, что устаревает быстрее, чем билд в CI». Смешно ровно до первого случая, когда интеграция падает в проде, а выясняется, что «актуальный формат события» лежит в переписке двухмесячной давности.
В этой статье – про Documentation as Code: что это такое по-взрослому, почему ИИ внезапно сделал тему более актуальной, и почему OpenAPI – лучший пример того, как документация может стать программным артефактом. В конце материала – разбор инструментов и аккуратный мостик к AxenAPI, так как особенно сложно эта тема проявляется в асинхронных интеграциях.
0. Что мы имеем ввиду, когда говорим «документация»
Начнем с типовой сцены.
«Где актуальная схема/API/событие?»
«В Confluence есть страница.»
«Она про прошлый релиз.»
«Окей, тогда в коде.»
«В коде - иначе.»
«В чате есть JSON, который вроде работал.»
«Ага… а что из этого правда?»
Вот здесь и важный момент: в инженерных системах документация – это не текст «для чтения», а знание «для действий». То, что помогает быстро и однозначно сделать правильно. Что мы считаем документацией в этой статье:
Контракты: OpenAPI, схемы сообщений/событий, структура payload, правила версионирования;
Примеры: запросы/ответы, sample events, edge-cases, типовые ошибки;
Эксплуатация: runbook, troubleshooting, «что делать, если…»;
Решения: ADR, ограничения, договоренности;
Изменения: changelog поведения/контрактов.
Документацию «потребляют» не только люди глазами. Да, ее читают разработчики, интеграторы, DevOps и support. Но все чаще ее читают и инструменты: генераторы, валидаторы, порталы, поисковики – а теперь еще и ИИ-агенты. Им нужен проверяемый контекст, а не «кто-то когда-то писал в чате».
Отсюда появляется главное ожидание от документации: актуальность, полнота и проверяемость, чтобы ей действительно можно было доверять. Если документация этого не делает, команда все равно пойдет сверяться с кодом и переписками, а «дока» останется просто формальностью.
Проще говоря, документация бывает рабочей и бывает архивной.
Рабочая – это та, которой можно доверять в моменте: она привязана к версии, обновляется вместе с кодом и проходит проверки. Все остальное со временем превращается в «литературу»: может быть красиво написано, но опираться рискованно. Если документация – критически важная информация, вопрос не «в каком редакторе писать», а как встроить ее в процесс поставки. Отсюда и Doc as Code.
1. Проблематика: почему Word/вики/Confluence не спасают
Confluence хорошо закрывает потребность команды обмениваться знаниями. Но когда появляется несколько релизов, веток и «подверсий», внезапно становится сложно ответить на простой вопрос: какая страница соответствует конкретной версии продукта прямо сейчас. В инженерной реальности это обычно вылезает тремя проблемами:
Документация живет вне жизненного цикла продукта
Код меняется через PR/MR (pull/merge request), review, CI, релизы. Дока – часто «когда будет время». В итоге она не просто устаревает, она расходится с реальностью.Слабая связь с изменениями и релизами
Да, вики хранит историю. Но обычно нет ощущения:
«Вот PR → вот изменения контракта → вот обновление примеров → вот релиз».
А без этой связки документация не успевает за продуктом.Нет нормальных автоматических проверок
Сломанные ссылки, невалидные схемы, устаревшие примеры – все это легко ловится автоматически, но в типичной вики это не встроено в процесс.
И появляется то, что знакомо многим: знание в чате + «страницы-зомби»
Мини-формула боли, которую полезно держать в голове:
Если документация не проходит тот же путь, что и код (review → CI → release), ее сложно считать источником правды: поддерживать актуальность становится дороже и сложнее, чем при Doc as Code, потому что все держится на ручном контроле – и «правда» неизбежно расползается по чатам, коду и страницам разных версий.
2. Почему ИИ делает Doc as Code не модой, а необходимостью
ИИ в разработке – уже не «вау-игрушка», а рабочий инструмент: подсказать, объяснить, сгенерировать пример, найти ошибку, собрать черновик runbook. Но есть нюанс, который быстро превращается в проблему:
ИИ хорошо работает там, где есть структура + версия + источник истины.
Без этого он будет очень убедительно отвечать «не в тему».
Почему так происходит:
RAG/поиск: если знания лежат в plain-text и структурированы, их легко индексировать и доставить кусками «как есть». Если знания размазаны по вики/чатам/вложениям – качество выдачи падает.
Версии и контекст: ИИ не знает, что у вас «вчера поменяли поле status». Если у документации есть Git-история и привязка к релизам – контекст появляется.
Автоматизация: когда документация живет как код, ИИ может работать не «в вакууме», а как помощник:
o подсказать, что пример не соответствует схеме,
o предложить PR с обновлением FAQ,
o заменить breaking change в контракте и попросить changelog.
Локальные агенты: когда документация живет в Git и версионируется вместе с продуктом, агент видит ее в одном контуре с кодом. Это банально удобнее, чем прыгать по вкладкам и копипастить.
Фраза, которую я бы держал как «лакмус»:
Doc as Code превращает документацию в датасет, которому можно доверять. А ИИ без доверенного датасета – просто убедительный собеседник.
3. Documentation as Code: что это и почему это «архитектурный принцип»
Doc as Code – это подход, где документация:
Хранится в plain-text;
Живет в Git рядом с кодом;
Собирается и проверяется в CI;
Публикуется как артефакт: сайт, PDF, референсы, спеки.
Почему это не «про формат»? Потому что вы получаете архитектурный эффект.
Документация становится модулем системы:
Входы: .md, диаграммы, openapi.yaml, adr/*.md;
Сборка: линтеры, генераторы, валидаторы;
Выходы: портал/сайт, API-референсы, SDK, спецификации.
И вот тут меняется отношение: дока перестает быть «какой-то страницей» и превращается в управляемый артефакт поставки. По сути, это тот же подход, который у вас уже работает для кода: review, проверки, релизы, история.
4. Минимальный инструментарий Doc as Code
Если не хочется городить сложную систему и тяжелые процессы, можно стартовать с минимального набора – он уже даст много пользы.
Хранилище и процесс:
Git + PR + review
CODEOWNERS для /docs (файл в репозитории, который назначает ответственных за папки/файлы, чтобы PR автоматически запрашивал ревью у нужных людей)
Опционально: шаблон PR (чек-лист), чтобы не забывать мелочи: «что поменялось?», «есть ли breaking change?», «обновлены ли примеры/схемы?».
Сборка и публикация:
Статический сайт: MkDocs или Docusaurus
API-референсы из OpenAPI: Swagger UI или Redoc
Проверки в CI:
Проверка ссылок (dead links)
Линт Markdown
Орфография/термины
Валидация OpenAPI/схем
Если хочется представить это как «инженерный продукт», то выглядит оно примерно так:
docs/ index.md guides/ runbook/ spec/ openapi.yaml events/ adr/ 0001-why-we-chose-kafka.md
Это всего лишь один из рабочих вариантов. В жизни встречаются как минимум три схемы:
Monorepo – документация лежит рядом с кодом в /docs;
Отдельный docs-репозиторий – когда над документацией работает больше людей, чем над кодом;
Отдельный repo со спецификациями/контрактами – удобно, когда контракты общие для нескольких сервисов или команд. Суть подхода не в названии папок, а в том, что документация проходит тот же цикл, что и код.
И ключевое: CI должен ругаться, если «дока сломалась». Иначе она снова окажется вне процесса – вроде бы есть, но на релиз не влияет.
Примеры того, что CI может проверять «из коробки»:
Битые ссылки в гайдах;
Валидация OpenAPI/схем;
Линт Markdown;
Breaking changes в контракте.
Как это выглядит на практике:
В PR кто-то меняет контракт: например, в событии order.created поле status стало строкой вместо enum.
В репозитории это видно обычным diff’ом в spec/events/order.created.yaml
CI прогоняет валидацию и сравнение контрактов: если изменение breaking – PR получает красный статус и требует либо миграционный гайд, либо новую версию контракта.
Результат: изменения не «просачиваются» в прод молча, и документация перестает быть догоняющей.
5. Как перейти на Doc as Code без революции
Самая частая ошибка – пытаться «перетащить всю Confluence в Markdown за выходные». Обычно это заканчивается еще одной мертвой документацией, только в другом месте. Рабочая миграция выглядит поэтапно.
Мини-кейс из жизни: продукт с несколькими версиями под разных заказчиков
Представьте систему, которая живет сразу в нескольких вариантах: у разных заказчиков разные интеграции, настройки, иногда даже разные ветки/форки. Код вы естественно ведете по веткам и тегам. А документацию часто продолжают вести «одну на всех» в вики.
Итог предсказуем: техподдержка и интеграторы читают не ту версию, релиз закрыли – а инструкция осталась прежней.
В Doc as Code этот класс проблем лечится банально: дока живет в тех же ветках/тегах, что и продукт. Открыл release/1.8 – получил и код, и OpenAPI/схемы, и примеры именно для этой версии.
Практика: публикацию документации запускаем по релизному тегу/ветке. Тогда «дока для версии X» получается автоматически, а не руками.
Этап 1 – зафиксировать «зону правды»
Выберите, что будет источником истины в первую очередь:
OpenAPI/схемы событий;
Короткие гайды «как начать»;
ADR по ключевым решениям.
Остальное может пожить как legacy.
Этап 2 – завести структуру
/docs, /spec, /adr, /runbook + минимальные шаблоны страниц.
Этап 3 – включить CI
Правило простое: если в main не проходит линт/валидация – документация не должна «публиковаться как будто все ок».
Этап 4 – распределить ответственность за разделы документации
Например: команда сервиса подтверждает изменения в /spec, DevOps – в /runbook, технический писатель – в /docs/guides. Технически это фиксируется через CODEOWNERS, чтобы нужные люди автоматически попадали в ревью.
Правило простое: изменил контракт/поведение → обнови соответствующую страницу/пример в том же PR.
Этап 5 – расширять
Добавлять примеры, типовые ошибки, FAQ из чатов.
Это самый дешевый способ ускорить онбординг: новички и интеграторы обычно задают одни и те же вопросы. Если ответы оформлены как страницы и примеры – команда меньше отвлекается на «подскажи, где это».
Именно этот шаг обычно дает самый заметный эффект на онбординге.
6. OpenAPI как «ранний Doc as Code»: почему это уже работало до ИИ
OpenAPI – декларативная спецификация в YAML/JSON. Она:
Живет рядом с кодом;
Версионируется;
Валидируется;
Из нее генерятся UI/SDK/заглушки;
И часто выступает контрактом между командами.
Но так бывает не всегда. Иногда OpenAPI – это просто слепок реализации: его генерят из кода/аннотаций «как получилось», чтобы получить Swagger UI и клиентов. Полезно – да. Контрактом спецификация становится тогда, когда изменения в ней обсуждаются и п��оверяются до релиза: через PR, валидаторы и правила breaking change.
По сути, это уже документация, ставшая исполняемым знанием: ее можно проверить, из нее можно что-то построить.
Из этого вытекает простая мысль:
Многие команды уже применяют Doc as Code – просто обычно только в части REST API.
7. Где все ломается: асинхронные интеграции и «документация по событиям»
А вот дальше начинается самое интересное.
REST API чаще оказываются лучше задокументированы – просто потому, что вокруг них давно есть привычный инструментарий (Swagger UI/Redoc, генерация клиентов, контракты).
С событиями в брокере ситуация разная: в зрелых командах их тоже описывают аналитики и архитекторы. Но на практике именно события чаще «расползаются» по продюсерам/консюмерам и версиям – и без единого контрактного артефакта быстро превращаются в набор неявных договоренностей.
В экосистеме Kafka это часто пытаются решить через Avro/Protobuf + Schema Registry – и это реально помогает со схемами. Но даже со схемами остаются вопросы: где примеры, где changelog, как связать версию схемы с конкретными продюсерами/консюмерами и релизами продукта.
В итоге они часто оказываются:
«В голове у пары людей / в коде нескольких consumer’ов»;
«В схеме где-то в отдельном месте»;
«В примере, который кто-то скинул в чат».
Отсюда классика:
Несовместимые payload’ы;
Неожиданные изменения «без предупреждения»;
Интеграционный ад, где баги похожи на мистику.
Идея напрашивается: перенести дисциплину «контракт-как-код» на события/топики/интеграции. То есть сделать так, чтобы изменения формата сообщений были такими же видимыми, проверяемыми и ревьюимыми, как изменения API.
Вот здесь и появляется AxenAPI – как инструмент, который пытается сделать для событий и интеграций то, что OpenAPI давно сделал для REST: превратить описание контрактов в управляемый артефакт.
Есть два важных отличия от «обычной вики»: спецификацию можно собирать графически (элементами и связями), а затем связывать ее с документацией и сущностями системы (сервис ↔ топик ↔ событие).
Дальше самое интересное: когда есть структура и связи, ИИ можно подключать не «для красивого текста», а для полезной рутины – например, чтобы он находил, что не задокументировано, и автоматически создавал задачи в трекере. Плюс есть экспорт: результаты можно превращать в артефакты, которые дальше живут в вашем CI/CD и релизах.
8. Недостатки Doc as Code
Минусы есть. Их лучше перечислить в явном виде – так будет меньше разочарований:
Порог входа: Git/Markdown не всем комфортен.
Решается шаблонами, гайдом «как править», минимальным набором правил – и, при желании, визуальным редактором/preview поверх Markdown (но с сохранение в Git через PR)Нет совместного редактирования «как в Google Docs».
Да, зато появляется review, история и дисциплина. В инженерии это часто ценнее.Markdown «простоват».
Где-то хочется интерактивных блоков, сложных таблиц, встроенных форм.
Решается расширениями/генерацией/порталами поверх.Вопрос владения («кто отвечает?»).
Решается CODEOWNERS и привычкой: изменения идут через PR.
9. Инструменты для Documentation as Code: где заканчивается «вики», и начинается «контракт»
Пока мы говорим про подход, легко скатиться в спор «Confluence vs Markdown». Но на практике команды выбирают не философию – они выбирают инструменты под конкретную боль.
Я бы разделил «документацию» на три слоя:
Текст и знания (гайды, runbook, FAQ, ADR) – это то, что читает человек.
Контракты (OpenAPI, схемы событий, правила версий) – это то, что должна уметь проверять машина.
Связи между сущностями (сервис ↔ метод ↔ событие ↔ топик ↔ страница документации) – то, что превращает доку в «контекст», который можно автоматически вытягивать и анализировать.
Дальше – про инструменты, которые закрывают разные части этой пирамиды.
Obsidian: личная база знаний, которая неожиданно хорошо дружит с Doc as Code
Obsidian хорош, когда нужно: быстро писать Markdown, держать заметки локально, связывать их ссылками и искать по графу. Это отличный инструмент для:
Личных/командных заметок,
Черновиков документации,
Runbook’ов и небольших «операторских» инструкций.
Но у Obsidian есть естественное ограничение: он не про контракты как артефакты.
Да, туда можно положить openapi.yaml или схемы событий – но:
Он их не валидирует как контракт,
Не подсвечивает breaking change,
Не связывает сервис/топик/событие как типизированные сущности (это все будет «текст и ссылки».
Итого: Obsidian – супер, если ваша цель «писать и структурировать текст». Но если цель – «контракт, который проверяется в CI», понадобится следующий слой.
Confluence/Notion: командная вики и совместное редактирование:
Командные вики выигрывают там, где важнее всего:
Совместное редактирование «здесь и сейчас»,
Комментарии, обсуждения, быстрые страницы.
Но как только вы хотите, чтобы документация жила вместе с релизами и проходила проверки, она начинает требовать ручной дисциплины. Вики справляются с «написать», но плохо заставляют «держать в версии и проверять».
Инструменты вокруг OpenAPI: когда контракт – главный артефакт:
Если ваш основной интерфейс – REST API, вокруг OpenAPI уже давно есть зрелый инструментарий:
Визуализация (Swagger UI / Redoc),
Линтеры и правила качества,
Генерация клиентов/SDK,
Процессы review и governance.
Это почти идеальный пример «Doc as Code»: спецификация превращается в то, что можно проверять и собирать, а не просто читать.
Но у событий и асинхронных интеграций часто нет такого «первоклассного артефакта», и именно там чаще всего начинается хаос.
AxenAPI: «вики + граф связей + ИИ, который сам находит дыры и ставит задачи»
AxenAPI - не «еще одна вики», а инструмент, который добавляет недостающий слой – структуру и связи.
Что принципиально отличает AxenAPI от обычных doc-инструментов:
Спецификацию можно собрать графически, а не писать вручную
Элементы «тыкаются», связываются, поля редактируются, можно хранить примеры заполнения и метки/теги.Сущности связаны как система, а не как текст
Например: сервис ↔ брокер ↔ топик ↔ событие (и дальше – потребители/производители). Это не «картинка в Miro», а структура, поверх которой можно делать проверки и анализ.Связь «спецификация ↔ документация»
Страницы документации можно связать со спецификацией (и наоборот). Смысл простой: чтобы дальше можно было «поднимать контекст» не поиском по словам, а по связям.ИИ + трекер задач: находить незадокументированное и раскладывать в backlog
ИИ сканирует сервис и связи, видит пробелы (что не описано), формирует задачи и складывает их в трекер. И это важно: ИИ не «пишет доку магией», он работает по структуре и связям – поэтому качество задач получается адекватным даже без супер-промпта.Экспорт
Есть встроенные функции экспорта – то есть результаты можно превращать в артефакты, которые дальше живут в вашем процессе поставки.
Если коротко: Obsidian помогает писать текст, OpenAPI – инструменты помогают жить контрактам API, а AxenAPI пытается сделать то же самое для событий/интеграций – но с графом связей и AI-автоматизацией. Если интересно потрогать это вживую: AxenAPI
Быстрый выбор «что брать»
Нужна личная/командная база знаний, много текста, быстрые заметки → Obsidian
Нужна командная вики и «совместно отредачить прямо сейчас» → Confluence/Notion.
Нужен контракт REST API как артефакт → OpenAPI-first + привычный стек вокруг.
Боль – события/асинхронные интеграции и хочется, чтобы «контракт + дока + связи» стали системой, а ИИ мог находить пробелы и ставить задачи → AxenAPI.
10. Финальный месседж
OpenAPI показал ценность «документации как кода» задолго до нынешнего AI-хайпа.
ИИ просто сделал цену бардака выше: без структурированной и версионируемой доки вы теряете качество ответов, скорость онбординга и предсказуемость изменений.
Doc as Code – это не «Markdown вместо Confluence». Это способ управлять знаниями как продуктом: review, проверки, релизы, история.
AxenAPI – практичный мост для зоны, где обычно хуже всего: контракты асинхронных интеграций (события/потоки/сообщения), чтобы они стали такими же управляемыми артефактами, как код.
