Структура: как расположить материал, чтобы его прочли
Три часа ночи, алерт payments_5xx_rate. Дежурный открывает раннбук и видит: «Введение»,
«Архитектура сервиса», «Используемые технологии», «Мониторинг», «Типовые проблемы». Нужная
команда есть — она в подразделе «Провайдер отвечает 502», четвёртый экран прокрутки.
Дежурный до неё не доходит: через девяносто секунд он пишет в чат «кто живой, помогите».
Документ содержал ответ. Автор ничего не забыл. Проиграла раскладка.
Структура — это не порядок изложения, а порядок доступа. Материал раскладывают под маршрут читателя к решению, а не под путь автора к пониманию.
В предыдущей главе мы определили, кто читатель и какое решение он принимает. Структура — первый инструмент, который переводит ответ на эти два вопроса в форму документа. Ясность, жанры и схемы работают уже внутри выбранного каркаса и не спасают, если каркас неправильный.
Порядок автора против порядка читателя
Разбираясь в задаче, вы шли так: контекст → данные → варианты → сравнение → вывод. Рука сама пишет документ в этом же порядке — он ничего не стоит, он уже в голове. Читателю нужен обратный маршрут: вывод → цена → обоснование → детали. Он открыл документ не чтобы повторить ваше исследование, а чтобы принять решение и закрыть вкладку.
документа"] B1 -.->|"этого уже хватает"| Y["Решение принято
по документу"]
Приём называется инвертированная пирамида — он пришёл из газет, где статью резали снизу под размер полосы и потому главное ставили в первый абзац. В армейской практике то же правило зовут BLUF (bottom line up front), в бизнес-письме — «принципом пирамиды» Барбары Минто.
Почему хронологический порядок так живуч: он бесплатный; он кажется честным («сначала контекст, иначе вывод повиснет» — хотя нужен не весь контекст, а два предложения, без которых вывод непонятен); он защищает автора, показывая объём работы; и так учили в вузе, где IMRaD устроен под воспроизводимость исследования, а не под скорость решения. Потребность в признании работы законна, но решать её лучше прямо, а не длиной преамбулы — см. «Работу вверх».
Где хронология обязательна: таймлайн инцидента в постмортеме, шаги в туториале, changelog. Различайте: хронология как раздел — нормально, хронология как каркас всего документа — почти всегда ошибка. В постмортеме таймлайн стоит в середине, а сверху — что сломалось и что мы меняем.
Первый экран: три вопроса за пять секунд
Первый экран — единственная часть документа, которую увидят все. Он отвечает на три вопроса: что это, моё ли это, что от меня хотят.
Материал слева и справа один и тот же, разница только в порядке доступа: справа всё нужное
для решения лежит выше сгиба, обоснование и приложения ниже — для тех, кто спорит. На первый
экран кладут: заголовок-утверждение («Кэш каталога переносим в Redis», а не
«Кэширование»); шапку-контракт из первой главы
(reader, decision, deadline, owner, review_by); TL;DR в три строки — что
предлагаем, чем платим, что будет, если не решать; «Вам сюда, если…» для документов, куда
попадают случайно (README, справочники, раннбуки); оглавление
при длине больше трёх экранов.
Проверка, которая ловит почти все проблемы раскладки: если удалить всё, кроме первого экрана, документ должен остаться полезным. Не полным — полезным. Как сервис деградирует частично, а не падает целиком, так и текст обязан работать при частичном прочтении (в вебе это зовут progressive disclosure; та же логика, что в информационной архитектуре). А «Термины и определения» на первой странице — инерция ГОСТ-шаблонов: термин нужен в момент встречи с ним, а не за три экрана до.
Слои: документ читают на четырёх глубинах
Один документ читают четырьмя разными способами, и каждый должен быть самодостаточным.
- Слой не должен требовать нижнего, чтобы быть верным. «Подробности в приложении Б» вместо ответа — разрыв слоя: читатель на L1 остался без вывода.
- Слой заканчивается точкой выхода. После L1 должно быть не стыдно закрыть документ; если для решения обязателен L3, вы неверно определили решение или плохо свернули данные.
- Вниз растёт специфичность, а не громкость, и один слой держит один уровень абстракции: смесь «архитектура системы» и «имя переменной в конфиге» заставляет читателя менять масштаб на каждой фразе.
Типичная поломка: вывод оказался в L3 (в «Заключении»), а деталь реализации — в L1, потому что автор ей гордится. Документ формально содержит всё и работает на нуле.
Заголовки — это оглавление мыслей
Заголовки одновременно навигация, поиск и конспект: читатель сканирует их, а не текст — исследования Nielsen Norman Group показывают F-образное движение взгляда по левым краям заголовков и первых строк. Заголовок-утверждение вместо заголовка-темы: тема сообщает, о чём раздел, утверждение — что в нём выяснено, и только второе позволяет прочесть одни заголовки и получить смысл.
| Заголовок-тема (плохо) | Заголовок-утверждение (хорошо) |
|---|---|
| Кэширование | In-process кэш не масштабируется дальше 12 подов |
| Производительность | Redis добавляет 3 мс к p99, но убирает холодный старт |
| Риски | Redis становится новой точкой отказа: нужен режим деградации |
| Заключение | Рекомендуем перенести, откат — один флаг |
Заголовок словами читателя, а не вашими. Это поисковый запрос, который читатель задаст себе или поиску вики: «Процедура предоставления доступа к тестовому контуру» не найдётся никогда, «Как получить доступ к стенду» — найдётся. В раннбуке не «Обработка нештатных ситуаций провайдера», а «Провайдер отвечает 502».
Стабильные якоря. Заголовок превращается в якорь URL, на который ссылаются из тикетов,
чатов и кода; переименовали — молча сломали чужие ссылки. Для таких разделов задают явный
идентификатор или неизменяемый номер (ADR-014, RFC-021). Семантика заголовков — ещё
и доступность: скринридер строит по ним оглавление, см.
«Семантическую основу».
Иерархии h2/h3 хватает почти всегда; появился h4 — внутри живёт второй документ.
Абзац: одно утверждение, вывод в первом предложении
Внутри раздела действует то же правило, что и в документе целиком: абзац несёт ровно одно утверждение, и оно стоит в первом предложении (topic sentence). Остальное — доказательство, пример, оговорка. Абзац в три-пять строк читают, в десять — пролистывают; абзац длиннее экрана почти всегда содержит два утверждения, которые надо разделить. Отсюда самый дешёвый инструмент самопроверки — обратный план (reverse outline): выписать заголовки и первые предложения абзацев и прочесть вслух. Должен получиться связный конспект; получился набор фраз — сломана структура, и правка формулировок этого не исправит.
# Скелет из заголовков и первые предложения абзацев (RS="" режет по пустой строке).
# Абзацы без утверждения видно сразу: «Кроме того, стоит отметить, что…».
grep -nE '^#{2,4} ' docs/rfc-014.md
awk 'BEGIN{RS=""} !/^(#|```|\||-)/ {sub(/([.!?]).*/, "&"); print "- " $0}' docs/rfc-014.md
Форма материала: проза, список, таблица, схема, код
Одни и те же факты можно подать пятью способами, и выбор не вкусовой.
| Форма | Когда работает | Когда вредит |
|---|---|---|
| Проза | есть причинность: «потому что», «зато», «но только если» | перечисление однородных фактов |
| Маркированный список | набор равноправных вариантов, порядок не важен | там, где важна связь между пунктами — она исчезнет |
| Нумерованный список | шаги, которые выполняют по порядку | нумерация ради красоты у неупорядоченных вещей |
| Таблица | у объектов общие измерения и их сравнивают | ячейки по три предложения — это уже не таблица |
| Схема | связи и топология важнее деталей (глава о схемах) | картинка дублирует абзац |
| Код и вывод команды | точная последовательность символов, которую копируют | иллюстрация идеи, которую проще описать словом |
Главная ловушка — буллетизация: превращение рассуждения в список коротких фраз. Список выглядит структурно, но выбрасывает то, ради чего документ писался, — связи. «Плюсы: масштабируется, дешевле, проще» не даёт решить ничего: непонятно, дешевле чего, при каком объёме и какой ценой. Именно поэтому в Amazon на совещаниях запрещены слайды и принят нарратив на шесть страниц: связный текст заставляет автора удерживать логику, которую буллеты позволяют не иметь. Обратная ошибка — прозой пересказывать таблицу: «для создания платежа таймаут 2 секунды и три ретрая, для возврата — 5 секунд и ни одного…». Читатель всё равно строит таблицу в уме — постройте её за него и добавьте колонку «почему так»:
| Операция | Таймаут | Повторы | Почему так |
|---|---|---|---|
POST /payments |
2 с | 3, экспоненциальная задержка | идемпотентна по Idempotency-Key |
POST /refunds |
5 с | нет | без ключа повтор создаст второй возврат |
GET /payments/{id} |
1 с | 5 | чтение, побочных эффектов нет |
Последняя колонка превращает таблицу настроек в запись решений: её можно оспорить осознанно.
Маршруты чтения: один документ, разные траектории
Проектировать надо не страницу, а маршруты по ней. У документа их обычно три-четыре, и каждый должен упираться в ответ, а не в тупик.
Состояние Chat — измеримый признак сломанной структуры. Вопросы в канале, ответ на которые
есть в документе, — не «люди не читают», а данные о навигации, и у каждого перехода своя
причина. Не понял, о чём документ, — проблема первого экрана. Не нашёл раздел — проблема
заголовков. Нашёл, но не смог применить — раздел не самодостаточен: требует контекста
из соседнего, который читатель не открывал. Последнее критично там, куда приходят по прямой
ссылке из алерта: раздел «Провайдер отвечает 502» обязан работать так, будто читатель
не видел ничего выше. Практический приём — выписать пять самых частых вопросов команды
и проверить, что ответ на каждый достижим за один переход с первого экрана; для общих
у нескольких команд документов это стоит делать
на фасилитируемой встрече.
Длина — тоже решение, а не следствие. Её выбирают под читателя: у дежурного секунды, у ревьюера RFC минуты. Документ пора резать, когда в нём два разных решения, два разных читателя (внешний интегратор и внутренний разработчик), два разных темпа изменения или больше трёх экранов без оглавления. Режут не по темам («вынесем всё про Redis на отдельную страницу»), а по решениям и маршрутам — чтобы документ отвечал на один вопрос целиком, а не на треть каждого из трёх; после разреза обязательна навигация в обе стороны. И выносите сырьё, а не пересказывайте: бенчмарки и дампы уходят в приложение или ссылку, в теле остаётся вывод и одна цифра, которая его подтверждает.
Разбор: одна и та же страница до и после
Пара 1. Оглавление документа целиком
Плохо:
1. Введение 4. Текущая архитектура кэширования 7. Предложение
2. Цели и задачи 5. Обзор существующих решений 8. Риски
3. Термины 6. Сравнительный анализ 9. Заключение
Девять разделов, и ни один заголовок не сообщает, что выяснено. Читатель, которому надо сказать «делаем» или «не делаем», не может выбрать точку входа: ему с равной вероятностью нужен раздел 4, 6 или 7, а разделы 1, 2 и 9 пересказывают друг друга.
Переписано:
Решение: переносим кэш каталога в Redis, ответ нужен до 12.03
Что это меняет: холодный старт уходит, p99 растёт с 8 до 11 мс
Если не решать: снимаем масштабирование каталога с плана на квартал
—— дальше только для тех, кто спорит или будет делать ——
Почему in-process кэш упёрся: 1.2 ГБ на под, потолок в 12 подов
Что рассматривали кроме Redis и почему отклонили
Redis становится точкой отказа: режим деградации и план отката
План работ: три шага, два дня, владельцы · Приложение: методика замеров
Заголовки стали утверждениями, порядок — маршрутом решения. «Введение», «Цели» и «Заключение» исчезли не ради краткости, а потому что не поддерживали ни одного решения. Явная граница «дальше только для тех, кто спорит» разрешает читателю остановиться — и тем увеличивает шанс, что он до неё дочитает.
Пара 2. Абзац с закопанным выводом
Плохо:
При анализе логов за последние две недели мы обратили внимание на то, что количество ошибок при обращении к сервису каталога заметно возрастает в определённые моменты времени. Было проведено сопоставление с событиями деплоя и рассмотрены метрики памяти. В результате анализа удалось установить, что всплески ошибок коррелируют с перезапуском подов, что, по всей видимости, связано с прогревом локального кэша.
Утверждение абзаца — «всплески ошибок вызваны холодным кэшем после рестарта» — стоит в последнем предложении и завёрнуто в «по всей видимости», а первые предложения описывают процесс расследования: интересно автору, бесполезно читателю, который решает, чинить или нет. Про пассив и «было проведено» — в главе о ясности.
Переписано:
После каждого деплоя мы отдаём 30% ошибок в течение 3–5 минут: под стартует с пустым кэшем каталога и ходит в базу на каждый запрос. За две недели это 14 всплесков, совпадающих с рестартами один в один; на графике памяти видно, как 1.2 ГБ кэша набираются те же 3–5 минут (дашборд).
Вывод в первом предложении, дальше доказательство и ссылка на сырьё. Абзац стал короче не из любви к краткости: исчезло описание процесса, осталось утверждение с подтверждением.
Пара 3. Раздел, в котором смешаны жанры
Плохо:
## Troubleshooting
The payment service depends on the provider gateway. When the gateway is unavailable,
requests fail with 502. The gateway has its own SLA of 99.9%. In case of problems,
check the dashboards and consider enabling the fallback mode if the issue persists.
Раздел смешивает три жанра: объяснение архитектуры, справочные сведения об SLA и инструкцию. Дежурный в три ночи должен выполнять шаги, а получает эссе с модальностями: «check the dashboards», «consider enabling», «if the issue persists» — ни одного проверяемого условия и ни одной команды. Разделение жанров — центральная идея Diátaxis.
Переписано:
## Провайдер отвечает 502
**Признак:** алерт `payments_5xx_rate`, в логах `gateway: status 502`.
1. Проверьте, что дело в провайдере, а не в нас:
`kubectl logs -l app=payments --since=5m | grep 'gateway: status'`
Ожидаемо: строки только с `502`, других кодов нет.
2. Посмотрите статус провайдера: https://status.provider.example
3. Если 502 держатся дольше 5 минут — включите фолбэк:
`payctl feature enable payments.fallback_provider`
Проверка: `payments_fallback_active` в Grafana становится 1 за 30 секунд.
4. Не помогло за 10 минут — эскалация: `#platform-oncall`, тег `@gateway-duty`.
**Почему так:** [ADR-021](../adr/0021-fallback-provider.md). **Владелец:** `@a.petrov`.
Инструкция стала последовательностью проверяемых шагов: у каждого команда и ожидаемый результат, у условий — числа вместо «долго». Объяснение не выброшено, а вынесено в ADR и подключено ссылкой; побочный эффект тут важнее основного: инструкция и объяснение стареют по разным причинам и теперь правятся независимо.
Структура определяет, устареет документ или нет
Это не отдельная тема «про поддержку», а прямое следствие раскладки: документ устаревает там, где факт продублирован, где непонятно, чей раздел, и где изменчивое перемешано со стабильным. Призыв «обновляйте документацию» этого не лечит — лечит структура.
Один факт — одно место. Если лимит запросов записан в README, в справочнике API и в раннбуке, при изменении обновят одно место из трёх, а два начнут врать. Канонический раздел один, остальные ссылаются на него.
Разделение по скорости изменения. Разложите материал по трём корзинам и держите в разных разделах или файлах:
| Корзина | Что там | Как поддерживается |
|---|---|---|
stable |
зачем система существует, границы ответственности, принятые решения | почти не меняется; записи решений датированы и не переписываются |
volatile |
лимиты, версии, флаги, эндпойнты, имена очередей | правится в том же PR, что и код |
generated |
справочник API, схема БД, список метрик, вывод --help |
не пишется руками вообще |
Перемешать корзины — гарантировать расхождение: раздел с версиями библиотек внутри концептуального объяснения не обновит никто — при смене версии туда просто не смотрят.
Генерируемые блоки внутри рукописного документа. Структура оставляет генератору место — область между маркерами, которую скрипт перезаписывает, не трогая текст вокруг.
## Эндпойнты
<!-- BEGIN GENERATED: endpoints — правит scripts/openapi-to-md.py, руками не трогать -->
| Метод | Путь | Назначение |
|-------|---------------|---------------------|
| POST | /v1/refunds | возврат средств |
<!-- END GENERATED: endpoints -->
Маркеры — структурное решение, а не трюк: они делят документ на «то, за что отвечает человек»
и «то, за что отвечает пайплайн». В CI это замыкает make docs && git diff --exit-code:
изменил openapi.yaml, не обновил документ — сборка красная, как на несобранном коде.
Про исполняемые примеры и docs as code — в главе о поддержке
и в треке git.
Структура каталогов как карта ответственности. Раскладка файлов задаёт владение:
docs/
adr/ неизменяемые записи решений, владелец — архитектор
runbooks/ один файл на алерт, владелец — дежурная команда
api/ генерируется из openapi.yaml, руками не правится
guides/ обучающие тексты, владелец — тот, кто ведёт онбординг
CODEOWNERS /docs/runbooks/ @payments-oncall /docs/adr/ @architects
Раздел, для которого нельзя назвать владельца, — первый кандидат на устаревание, а затем
на удаление. Поле review_by ставят и на разделы: у стабильного срок — год, у лимитов — квартал.
Жанровая чистота как средство от устаревания. Смешанный раздел (объяснение + инструкция + справочник) поддерживать невозможно: он стареет по трём причинам и требует трёх разных людей. Разделив жанры, вы получаете три коротких текста с понятным триггером обновления: изменилось решение, изменилась процедура, изменился контракт (подробнее — в главе о руководствах, а о требованиях и критериях приёмки как жанрах — в системном анализе). И арифметика, объясняющая, почему длинные документы гниют быстрее: вероятность, что документ актуален целиком, — произведение вероятностей по всем фактам; двадцать фактов с надёжностью 0.95 каждый дают на весь документ меньше 0.36.
Когда структуру навязывает шаблон
Честная часть. В любой организации есть документы, чья структура продиктована не читателем, а шаблоном: порядок разделов повторяет порядок согласования. Признаки: «Введение», «Цели и задачи» и «Термины» занимают первые два экрана; есть раздел, одинаковый во всех документах компании (копипаст — верный признак, что информации в нём нет); поля заполняются формально («Влияние на смежные системы: нет» там, где влияние очевидно есть); оглавление длиннее содержания. Проверка: возьмите три последних документа по шаблону и посмотрите, какой раздел реально различается. Различается один из восьми — остальные семь пишутся ради процесса. Это не повод саботировать шаблон, особенно на новом месте (см. «Первые 90 дней»). Что делать:
- Добавить слой сверху. Шаблоны почти никогда не запрещают TL;DR перед первым обязательным разделом. Три строки стоят дёшево и меняют полезность радикально.
- Развести рабочий документ и артефакт. Рабочий текст живёт рядом с кодом и написан под решение; артефакт ссылается на него, а не копирует: копия разойдётся за месяц.
- Переставить внутри разделов. Порядок разделов вы, возможно, изменить не можете, а порядок предложений внутри — всегда: вывод в первую строку каждого.
- Сократить шаблон с цифрами в руках: «раздел 4 за год заполнили осмысленно два раза из семнадцати — предлагаю убрать и посмотреть, спросит ли кто-нибудь».
- Принять двухслойность там, где форма обязательна по регламенту. Если её диктует регулятор, это требование, а не глупость: у формы есть свой читатель (аудитор) и своё решение («принять поставку»). Задача — не дать ей вытеснить рабочий документ.
Типичные ошибки
- Вывод в конце — самая частая и дорогая ошибка: до «Заключения» доходят единицы. Рядом — хронология исследования как каркас: читателю нужен результат, а не ваш путь.
- Заголовки-темы: по оглавлению «Кэширование / Архитектура / Прочее» нельзя выбрать
точку входа.
h4и глубже — признак спрятанного внутри второго документа. - Раздел, который не работает без соседнего — ломает всех, кто пришёл по прямой ссылке.
- Буллетизация рассуждения теряет связи, ради которых документ писался; таблица с абзацами в ячейках перестаёт быть таблицей.
- Дублирование факта в трёх документах гарантирует расхождение, а переименование заголовка тихо ломает чужие ссылки в тикетах.
- Оглавление, написанное последним: каркас после текста повторяет порядок автора.
Практика
- Обратный план. Прогоните свой последний документ командами выше и прочтите результат вслух: всё, что не звучит как утверждение, — кандидат на переписывание или удаление.
- Тест первого экрана. Дайте коллеге документ на пять секунд и закройте. Спросите: о чём это, твоё ли, что от тебя хотят. Меньше трёх ответов — переделывайте первый экран.
- Инверсия и три корзины. Переставьте блоки хронологического документа под пирамиду,
ничего не переписывая (два-три раздела станут очевидно лишними), и разметьте оставшиеся
как
stable,volatile,generated: третье — на скрипт, смешанное — на разделение.
Источники
- Google Technical Writing Courses, абзацы и таблицы (https://developers.google.com/tech-writing/one/lists-tables), style guide про заголовки (https://developers.google.com/style/headings)
- Daniele Procida, Diátaxis — четыре жанра документации: https://diataxis.fr/
- Nielsen Norman Group, «How Users Read on the Web» — F-образное сканирование: https://www.nngroup.com/articles/how-users-read-on-the-web/
- Write the Docs: https://www.writethedocs.org/guide/writing/beginners-guide-to-docs/
- Barbara Minto, «The Pyramid Principle»; Larry McEnerney, «The Craft of Writing Effectively» (https://www.youtube.com/watch?v=vtIzMaLkCaM); Bryar & Carr, «Working Backwards».
Мини-итог
- Структура — порядок доступа, а не порядок изложения: порядок автора (контекст → анализ → вывод) враждебен читателю, работает инвертированная пирамида.
- Первый экран отвечает за пять секунд: что это, моё ли, что от меня хотят; документ должен оставаться полезным, если от него оставить только первый экран.
- Документ читают на четырёх глубинах; каждый слой самодостаточен и заканчивается точкой выхода, а не отсылкой «подробности в приложении». Заголовки — оглавление мыслей: утверждения вместо тем, слова читателя вместо ваших, стабильные якоря.
- Форму выбирают под материал; буллетизация рассуждения убивает связи. Длина — тоже решение: режут по решениям и маршрутам, а не по темам.
- Устаревание — свойство раскладки: один факт в одном месте, разделение stable / volatile / generated, генерируемые блоки между маркерами, владелец на раздел, жанровая чистота.
- Часть структур навязана шаблоном: лечится TL;DR сверху и разведением рабочего документа и артефакта.
Что дальше
Каркас стоит, материал разложен по слоям, заголовки ведут читателя куда надо. Остаётся уровень предложений: почему одна и та же мысль в одной формулировке понятна с первого раза, а в другой требует перечитывания; как работать с терминами; где прячется двусмысленность, которую автор физически не способен заметить в своём тексте.