Осенью 2016 года нам с коллегой поручили улучшить документацию и контент в моей бывшей компании. Мы потратили год на все виды документации: справочник по API, руководства, учебные пособия, сообщения в блогах. До этого я 5 лет писала доки, но официально не обучалась этому. Но и неопытной меня нельзя назвать: кроме документирования API для проектов и стартапа, я ещё преподавала Python Flask на семинарах во время учёбы на последних курсах в университете. Но сейчас выпала возможность сосредоточиться только на любимом деле: помогать специалистам всех уровней через техническую документацию.

В этом году я многому научилась в сообществе Write The Docs, у других провайдеров API, а также методом проб и ошибок. В прошлом году я поделилась опытом в докладе «Что мне хотелось бы знать о написании документации» на конференции API Strategy and Practice в Портленде. Эта статья — обзор полученных знаний.

Как люди на самом деле читают документацию?



«Нация содрогается от большого фрагмента слитного текста», фото The Onion

Знаете это чувство, как на картинке? Так бывает. Может и не физически, но, скорее всего, люди содрогаются умственно. Меня постоянно мучала мысль, что люди не будут читать мои тексты, если я не оформлю их легко усваиваемым способом. Чёрт возьми, такое может произойти даже с этой статьёй.

В исследовании направления взгляда Neilson Norman Group в 2006 году 232 пользователя просмотрели тысячи веб-страниц. Оказалось, что пользователи обычно смотрят на страницы по F-шаблону:

  1. «Сначала читают в горизонтальном направлении, как правило, в верхней части области с контентом. Это верхний элемент фигуры F».
  2. «Затем немного перемещаются вниз по странице — и совершают второе горизонтальное движение, которое обычно охватывает более короткую область, чем предыдущее. Этот дополнительный элемент образует средний элемент фигуры F».
  3. «Наконец, пользователи сканируют левую сторону контента по вертикали. Иногда это медленное и систематическое сканирование, которое отображается в виде сплошной полосы на теплокарте. Иногда движение более быстрое, образующее пятна на теплокарте. Это последний вертикальный элемент в фигуре F».



Теплокарты Nielsen Norman Group

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

Важно отметить, что F-шаблон мешает пользователям, но хорошее позиционирование контента помогает предотвратить F-сканирование.

Каковы конкретные последствия для документации?


  • В первых двух абзацах следует указать самую важную информацию
  • Критически важны первые 3?5 слов
  • Заголовки, абзацы и маркированные списки с информативными словами
  • Изменения шрифта (размер, ссылки, выделения жирным и т. д.) могут быть необходимы, чтобы удержать внимание читателя

Так как структурировать контент на странице?


  • Предотвратите сканирование: убедитесь в выделении информации, которая нужна читателю
  • Одна мысль на абзац. Если их несколько, разбейте абзац
  • Пользователи пропускают всё, что похоже на баннеры, поэтому будьте осторожны с иллюстрациями
  • Не расширяйте слишком сильно колонку с текстом: оптимально 65?90 символов

Некоторые из этих советов я узнала из лекции Кевина Берка «Как писать документацию для пользователей, которые её не читают». Кевин поддерживал документацию Twilio с 2011 по 2014 годы.

Кроме того, у абзацев есть своя специфика. Подобно слитному тексту The Onion, когда вы читаете много абзацев, можно пропустить суть. Тогда зачем использовать их так часто? Давайте проведём эксперимент из документации Keen IO:

Быстро прочитайте это:

У наборов событий может быть практически любое название, но есть несколько правил: в названии должно быть не более 64 знаков. Оно должно содержать только символы ASCII. Оно не может быть значением null.

Теперь быстро прочитайте это:

У наборов событий может быть практически любое название, но есть несколько правил:

  • В названии должно быть не более 64 знаков
  • Оно должно содержать только символы ASCII
  • Оно не может быть значением null

В обоих примерах абсолютно одинаковый текст. Это не бином Ньютона: второй помогает лучше и быстрее усвоить информацию. Если абзац содержит список любого типа, превратите его в маркированный список.

Позже мы подробнее обсудим вёрстку документации и навигацию по ней.

Примеры кода


Что такое документация API без кода, верно? Примеры кода есть во многих наших документах, и пользователи действительно их читают. Но проблема в том, что они не всегда обращают внимание на окружающий текст.

Контекст в примере кода важен для успеха разработчика. Разработчики любят быстро копировать и вставлять. Вот пример с Keen IO API:

var client = new Keen({
  projectId: "your_project_id",
  writeKey: "your_write_key"
});

var ticketPurchase = {
  price: 50.00,
  user: {
    id: "020939382",
    age: 28
  },
  artist: {
    id: "19039",
    name: "Tycho"
  }
}

client.addEvent("ticket_purchases", ticketPurchase);

Разработчик быстро копирует и вставляет этот код. И…



Во-первых, как они вообще запускают файл? Вероятно, как node file_name.js, но этого нет в коде. Можно было бы указать в комментарии вверху.

Хорошо, они запустили его и… ReferenceError: Keen is not defined. :-( Клиент Keen не инициировался, в верхней части нет оператора import или require, и он работает только после установки библиотеки npm.

Пользователь всё починил и запустил ещё раз… Угадайте?! Ещё одна ошибка! your_project_id и your_write_key отсутствуют.

Всё это можно было бы сделать более очевидным.

Вот пример из документации Twilio, которая предоставляет хороший контекст для конечного пользователя:


Скриншот из документации библиотеки Twilio Node Helper

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

Копипаст багов


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

# Скопируйте и вставьте следующую команду
$ gem install rails

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

bash: command not found: $

Распространённая ошибка. Либо вы хотите, чтобы команда выглядела как в командной строке, либо вы случайно её скопируете. Я бы рекомендовала отказаться от $. Ещё можно найти способ запретить копипаст этого символа, чтобы ошибка не раздражала пользователей.

Более свежий пример: вы проверяли, насколько легко выделить код, который пользователь хочет скопировать?

Келси Хайтауэр изо всех сил пытался скопировать образец кода из StackOverflow на презентации Google Cloud Next.


«Хорошие программисты копируют, великие программисты вставляют»

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

«Вот и всё!»



«Вот и всё!» Фраза кажется довольно безобидной вне контекста, но представьте, как воспринимаются определённые слова вроде «легко», «просто», «тривиально» и «несложно», когда у вас проблемы — не здорово! Когда человек застрял, пытаясь заставить API работать, такая фраза подвергает сомнению его интеллект и заставляет задать вопрос: «Значит, я глупый?» Это деморализует.

Чрезмерное упрощение


Упрощение встречается повсеместно. Оно наиболее распространено среди новичков в написании документации. Зачастую авторы документации — одновременно и разработчики системы, поэтому некоторые вещи им кажутся «лёгкими». Но ведь они разработали эту функцию, написали для неё код, проверили много, много раз, а потом написали документацию. Когда вы делаете что-то десятки раз, то ясное дело, что это будет «легко» для вас. Но как насчёт того, кто никогда раньше не видел UI или функцию?

Сопереживание


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

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

  • Попросите менее опытных участников проекта честно прокомментировать документацию
  • Поощряйте менее опытных участников проекта вносить свой вклад или указывать на пункты документации, которые они не понимают
  • Создайте окружение, где поощряются вопросы, в том числе такие, какие могут показаться «очевидными» для опытных участников проекта — это поможет заметить «слепые зоны»
  • В процессах код-ревью и CI используйте линтеры, чтобы гарантировать эмпатию и дружественность языка для всех пользователей
  • Наконец, попросите прокомментировать документацию реальных пользователей, покажите им текст и спросите, всё ли понятно

Сообщения об ошибках как вид документации


Обычно пользователи чаще видят сообщения об ошибках, чем документацию. Как говорит Кейт Восс, «сообщения об ошибках на самом деле представляют собой возможность». Я считаю, что многие разработчики документации упускают эту возможность. Здесь есть место для обучения, установления доверительных отношений и ожиданий пользователей. Прежде всего, вы поможете людям помочь самим себе.

Кейт на сайте Write The Docs рассказывает много полезного о написании сообщений об ошибках. Многое я узнала во время прошлой работы над сообщениями об ошибках API, а также будучи на другой стороне баррикад, получая сообщения об ошибках других API в качестве разработчика.

Кейт говорит, что хорошие сообщения об ошибках построены на трёх принципах:

  • Скромность
  • Гуманность
  • Полезность

Скромность


Сразу нужно извиниться, даже если это не ваша вина. Это я практикую также в службе поддержки.

Пример:

Извините, не удалось подключиться к ___. Пожалуйста, проверьте сетевые настройки, подключитесь к доступной сети и повторите попытку.

Гуманность


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

Пример (ошибка кода состояния 401 у Twilio):

{ 
    “code”: 20003,
    “detail”: “Your AccountSid or AuthToken was incorrect.”,
    “message”: “Authenticate”,
    “more_info”: “https://www.twilio.com/docs/errors/20003",
    “status”: 401
}

Полезность


Если вы запомните что-то из этих советов, запомните о полезности. Поделитесь с пользователем информацией, как устранить проблему.

Пример:

Извините, изображение, которое вы пытались загрузить, слишком большое. Попробуйте снова с изображения меньше, чем 4000px по высоте и 4000px по ширине.

Как писать сообщения об ошибках


Как и в любой другой документации, сначала укажите важную информацию. Это можно сделать, указав сначала объект, затем действие. Пользователь ищет результат, а не как туда добраться. Это полезно, когда пользователи быстро сканируют сообщения об ошибках.

Плохой пример:

Нажмите кнопку «назад», чтобы вернуться на предыдущую страницу.

Хороший пример:

Чтобы вернуться на предыдущую страницу, используйте кнопку «назад».

Сообщения об ошибках в документации


Я считаю очень полезным, когда общие сообщения об ошибках API упоминаются в документации. Так автор документации может разъяснить сообщение об ошибке, не увеличивая документацию, в то же время помогая пользователю понять, почему возникает ошибка.

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

В случае ошибки 20003 (ошибка кода состояния 401, упомянутая ранее), есть много возможных причин, которые чётко изложены в каталоге.


Источник: https://www.twilio.com/docs/api/errors

Stripe делает нечто подобное с детальным описанием различных кодов ошибок.




Источник: https://www.twilio.com/docs/api/errors

Вы даже можете найти свои сообщения об ошибках в вопросах StackOverflow. Ответьте на них скромно, по-человечески и с пользой. Из-за SEO пользователи часто попадают с вашими сообщениями об ошибках на StackOverflow, а не в реальную документацию.

Подсказка: если кто-то не ответил скромно, по-человечески и с пользой, то с достаточной «репутацией» можно редактировать ответы StackOverflow.

Выбор слов


У многих слов есть устоявшиеся ментальные модели. Например, такие слова, как «библиотеки», SDK, «обёртки» и «клиенты» уже перегружены и проходят мимо внимания читателя.

В своей лекции «Даже для этой лекции трудно подобрать название» на Write The Docs Рути Бендор говорит, почему выбор правильных слов может быть таким трудным.

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

В такой ситуации как никогда справедлива известная поговорка: «Есть только две трудные задачи в области информатики: инвалидация кеша и придумывание названий». Цитату часто приписывают Филу Карлтону, но сегодня ходит много вариантов этой поговорки. Иногда в конце добавляют «… и ошибка на единицу». Рути считает это демонстрацией, что программное обеспечение в наши дни во многом основано на чужом коде или работе.

Почему же сохраняются плохие названия объектов (или документация)?


Как и с чрезмерным упрощением, мы часто не понимаем, что название плохое. Это то, что Рути называет сбоем эмпатии. Это как сказать, что проблема неудачных слов меня не касается, поэтому её не существует.

Подсказка для США: во избежание случайного расизма используйте слова «запрещённый список» и «разрешённый список» вместо «чёрный» и «белый».
(Источники: Андре Штальц и rails/rails/issues/33677)

Мне это ещё напоминает то, что Рути называет ошибкой мышления новичка. Это как сказать «Мне это совершенно ясно. Не понимаю, как кто-то не может этого понять».

Наконец, Рути упоминает ошибку локализации. Например, слово Bing по-китайски означает «больной».

Согласно исследованию GitHub Open Source Survey за 2017 год:

Почти 25% разработчиков читают и пишут по-английски не «очень хорошо». При общении в проекте используйте понятный и доступный язык для людей из неанглоязычных стран.

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

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

Есть ещё случаи, когда мы признаём ошибку, но не можем или не хотим её исправлять, потому что мы…

  • Привязаны к ней
  • Не находим времени
  • Не видим важности
  • У нас нет агентства, чтобы её исправить

Вы можете сказать или услышать: «Но это моё детище!», «Кто убрал мою конфетку?» «Если мы переименуем, всё сломается», «Не верю, что изменение этого названия повлияет на что-то важное».

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

Как правильно подобрать слова?


Для начала рекомендую задать вопрос: какие слова используют ваши пользователи? В разных программистских кругах в ходу разные термины, не пытайтесь использовать другие. Это полезно не только для читателей, но также для поиска и SEO.

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

  • смутить
  • огорчить
  • ввести в заблуждение
  • запутать
  • оскорбить

С другой стороны, хорошие названия:

  • способствуют внезапному прояснению («вот оно что!»)
  • вводят в контекст
  • объясняют
  • освещают
  • оказывают поддержку

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

Подбирать верные слова трудно. Волшебной формулы не существует. Все пользователи отличаются, как и варианты использования продукта; что работает для одних, может не работать для других. Если бы это было легко, у всех была бы намного лучшая документация. Как говорит Рути разработчикам: «Написание программ — это упражнение в придумывании названий. Смиритесь с этим». И если вы пишете документацию для чужой программы, «сообщите разработчику, если его названия не попадают в цель».

Комментарии (5)


  1. namikiri
    29.08.2018 14:06

    Про сообщения об ошибках хочется всё же добавить. Если для веб-сервиса ещё хоть как-то допустима формулировка «у нас что-то сломалось, приходите завтра», то для приложений, работающих на устройствах пользователя, это, на мой взгляд, недопустимо. Яркий пример — приложение ВК для Android. Если оно не может загрузить или выгрузить фотографию, оно пишет «Ошибка, проверьте подключение к сети». Какая ошибка? Что за ней стоит? Нет доступа? Сервер не отвечает? Может, у меня в телефоне закончилась память для кэша? В чём причина ошибки? Возможно, это малозначительно и «напугает» большинство, но я умоляю, давайте пользователю знать, что именно пошло не так. Пусть даже для этого нужно будет сделать дополнительный клик по «Подробнее», только не кидайте меня на сайт с базой знаний. Мне было бы удобнее знать, что доступ к фотографии ограничен, или телефон не смог отрезолвить имя сервера, чем видеть тупое «Ошибка» без комментариев.


    1. CryptoPirate
      29.08.2018 14:21

      На всякий случай, есть небольшое исключение из правила «сообщение об ошибке должно объяснить что конкретно пошло не так». Это исключение для всяких правил безопасности и тесно связанных с безопасностью вещей. Небольшая разница в сообщениях об ошибке может послужить средством для проникновения в систему (или чтобы выудить из системы секретную информацию).
      Пример: Если сообщение зашифровано и при этом используется аутентификация (скажем, MAC), то нужно и в слечае неправильной расшифровки (invalid padding), и в случае неправильного MAC вернуть одинаковое сообщение об ошибке. В противном слечае может получится что-то типа «Bleichenbacher’s attack».


      1. UnclShura
        30.08.2018 20:45

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


        Нет (я даже повторю: нет!) причин не показывать абсолютно всю информацию об ошибке. Да хоть регистры показываете. Это никак не должно влиять на безопасность приложения. Если влияет — приложение или middleware — говно.


        1. CryptoPirate
          31.08.2018 11:14

          «А вот да!» Попробую ещё раз обяснить. Если вы напишете библиотеку для шифрования, а потом ей будуте пользоваться и пользователям присылать разные сообщения в случае если дополнение (padding) не правильное и в случае если контрольная сумма не правильная (та, которая MAC)… то тогда я с радостью вытащу из вашего сервера всю необходимую мне информацию с помощью одной очень простой разновидности «Bleichenbacher’s attack». Если быть более точным: я смогу «заставить» ваш сервер расшифровать сообщения которыми он с другими пользователями обменивается.
          При этом, сам протокол и все алгоритмы в полном порядке, атака использует разницу в ошибках (кодах), которые сервер возвращает на «неправиьное» сообщение.


  1. telobezumnoe
    29.08.2018 15:47

    это им наших ГОСТов не хватает, и нормоконтроля)) сразу бы не возникало вопросов как и что написать