Документация в эпоху ИИ: документация — это новый исходный код

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

Но написать документацию — это только половина дела: сразу за этим всплывают две проблемы, и именно им посвящён остаток статьи.

  • Хорошую документацию не читают, когда до неё трудно добраться. Ответ на вопрос «как работает фича X?» обычно уже лежит где-то в docs/ или в коде, но чтобы его найти, нужно знать репозиторий наизусть. Поэтому проще спросить коллегу — а коллега бросает свою работу и заново объясняет то, что в репозитории давно описано.
  • Документация устаревает. Стоит коду измениться, как документация тихо перестаёт быть правдой. Этот сбой никогда не вылезает стектрейсом — он проявляется как «агент (или новый сотрудник) сделал не то», а такую причину куда труднее отследить и куда дороже обнаружить.

Две системы ниже бьют ровно по этим проблемам: мультиагентный Chat с документацией, который делает документацию и код мгновенно доступными для запросов, и автоматический конвейер Jira → Docs, который держит их актуальными. Обе предполагают, что документация, которую стоит поддерживать, у вас уже есть, — они усиливают эту вложенную работу, а не заменяют её. И обе описаны достаточно конкретно, чтобы их можно было повторить.

Chat с документацией: мультиагентные вопросы и ответы по документации и коду

Chat с документацией напрямую решает первую проблему: он превращает уже существующую документацию в то, у чего можно спрашивать, — прямо там, где команда и так общается. Стоит подчеркнуть: это окупается именно потому, что документация есть. Он усиливает вложения в документацию, а не позволяет их пропустить: направьте его на пустую docs/ — и получите разве что красноречивый способ сказать «я не знаю».

Это один «мозг» за несколькими интерфейсами: веб-приложением на рабочем месте и чат-ботом. И там, и там любой член команды может задать вопрос по кодовой базе и получить потоковый ответ со ссылками на источники. Бот начинался в Slack, но в нём нет ничего, завязанного именно на Slack: тот же бэкенд точно так же поднимает Telegram-бота, а в принципе подключается любая платформа с API для ботов (Discord, Microsoft Teams, …). Приходите к людям туда, где они уже общаются, а не заставляйте открывать ещё один инструмент.

Самое интересное здесь — то, чем Chat с документацией сознательно не является: это не RAG-конвейер на эмбеддингах. Это мультиагентная система, которая ищет по документации и коду параллельно, используя файловые инструменты, уже встроенные в Claude Agent SDK.

1
2
3
4
5
Клиент (Lit + Vite)          Сервер (Express + Agent SDK)
UI чата, рендеринг ──► Агент-оркестратор
markdown, SSE ├── Агент документации (дерево docs)
├── Агент кода (ripgrep по репозиторию)
└── Агент-ответчик (синтез ответа)
  • Оркестратор — разбирает вопрос, раздаёт подзадачи, собирает результаты воедино.
  • Агент документации — ищет по дереву docs инструментами SDK (Read, Glob, Grep).
  • Агент кода — гоняет ripgrep по репозиторию.
  • Агент-ответчик — собирает финальный ответ для пользователя.

На стороне клиента связка Lit + TypeScript + Vite держит вес фреймворка меньше 5 КБ и обходится без виртуального DOM; ответы приходят потоком через Server-Sent Events; markdown рендерится через marked + DOMPurify + highlight.js. Сервер — это Express плюс @anthropic-ai/claude-agent-sdk, разворачивается через Docker Compose.

Почему без векторной БД? На корпусе такого размера агент, который делает grep по живой файловой системе, всегда видит актуальное состояние репозитория. Индекс эмбеддингов, наоборот, хранит снимок — и стоит коду измениться, как этот снимок устаревает, пока кто-нибудь заново не пересчитает эмбеддинги и не синхронизирует индекс. Этот цикл «посчитать — синхронизировать — снова устарело» и есть та самая нагрузка на сопровождение, которая тихо убивает большинство RAG-систем. А выигрыша от него нет: Glob и Grep и так отвечают на вопрос. Поэтому индекс мы не строим — пусть агент ищет сам. Запуск в виде чат-бота дополнительно снижает порог входа: не нужно уходить из Slack или Telegram, чтобы спросить «а как работает X?».

Конвейер автообновления: поддерживаем мозг в форме

Chat с документацией полезен ровно настолько, насколько актуальна документация, которую он читает, — поэтому вторая система занимается тем, что поддерживает эту документацию свежей автоматически. Workflow в GitHub Actions запускается в тот момент, когда тикет в Jira переходит из Tech Review в Ready for Dev — то есть как только зафиксирован объём работ, но ещё до того, как написана хоть строчка кода. Именно момент запуска здесь неочевиден: обычно команды обновляют документацию, когда тикет уже в Done, а значит, пишут её задним числом, спустя недели, когда контекст уже выветрился. Запуск на Ready for Dev кладёт документацию рядом со спецификацией, пока всё свежо в голове, и заодно даёт разработчику задокументированную цель, под которую он будет писать код.

Конвейер состоит из четырёх типизированных стадий, и главная идея — соизмерять стоимость модели со сложностью задачи, а не натравливать одного большого агента на всё подряд:

  1. Сортировка (дешёвая модель + MCP). Модель уровня Haiku забирает тикет через automation MCP, прогоняет его через фильтры по полям и решает, нужна ли вообще документация. Багфиксы, обновления зависимостей и рефакторинги она пропускает — около $0.001 за запуск, так что 90% тикетов отсеиваются за десятую долю цента ещё до того, как проснётся дорогая модель.
  2. Основной агент. Обычная (сильная) модель работает с репозиторием кода как с рабочей директорией, поэтому сама подхватывает CLAUDE.md и .claude/. Она читает индекс документации, сопоставляет изменённые модули с документами, правит файлы и делает коммит — но пока не пушит.
  3. Агент-ревьюер. Второй проход сильной модели смотрит на git diff HEAD~1 и проверяет правила качества: никаких бизнес-метрик, никакого пересказа кода своими словами, достаточное покрытие логики. На выходе — список замечаний в JSON.
  4. Исправление и PR. Если замечания есть, агент-исправитель вносит правки, после чего workflow пушит ветку docs/jira-<ticket> и открывает (или обновляет) PR.

Фильтры, которые управляют первой стадией, — это просто данные, поэтому всю систему можно настраивать, не трогая код агентов:

1
2
3
4
5
6
7
// config.ts — какой тикет считаем требующим документации
export const filters = {
issueTypes: ["Task"], // [] = разрешить все
projects: ["AND"],
requiredLabels: [],
excludedLabels: ["no-docs", "found_by_automation"],
};

Это тот самый паттерн, который Anthropic рекомендует в Building Effective Agents: сортируем дёшево, работаем сильной моделью, проверяем сильной моделью, исправляем только когда нужно. Затраты предсказуемы, сбои локальны, а каждую стадию можно тестировать отдельно — полная противоположность одному агенту, который бесконечно крутится вокруг огромного набора инструментов.

Что делает репозиторий понятным для агента

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# CLAUDE.md

## Сборка и тесты
- Сборка: ./gradlew assembleDebug
- Тесты: ./gradlew testDebugUnitTest
- Линт: ./gradlew ktlintCheck

## Соглашения
- Одна фича — один модуль в :features/<name>
- ViewModel отдаёт единый UiState; никакого LiveData в новом коде
- Результаты сетевых запросов оборачиваем в AppResult<T>, без «голых» исключений

## Подводные камни
- Экраны с WebView обязаны использовать SafeWebViewClient (см. .claude/rules/webview.md)
- После правки strings.xml запускайте ./scripts/gen-translations.sh

.claude/rules/*.md хранят узкие тематические правила, которые ездят вместе с кодом (по файлу на тему: webview.md, app-result.md, …). Субагент читает нужное правило как готовый чек-лист, а не выводит соглашения заново при каждом запуске.

Индекс документации (docs/INDEX.md или формат llms.txt) связывает модули с их документами, чтобы первым шагом агента всегда было «посмотреть, где это лежит», а не слепой поиск. Именно этот единственный переход и позволяет каждому скилу ниже стартовать с нужного документа.

Документация питает каждый скил

Когда фундамент есть, скилы — переиспользуемые именованные процедуры, которые вызывает агент (/implement-feature, /task-worker, /check-coverage), — все работают по одной схеме: сначала прочитать нужный документ, потом действовать.

  • task-worker забирает тикет из Jira, по индексу документации находит папку фичи, открывает её спецификацию и пишет план, опираясь на задокументированное поведение.
  • implement-feature сначала ищет уже существующие паттерны в документации, чтобы новый код ложился в принятые соглашения, а не изобретал свои.
  • review-pr-advanced запускает узкоспециализированных субагентов (архитектура, Compose, структура пакетов, тесты, производительность), и каждый берёт за основу свой .claude/rules/*.md.
  • check-coverage гоняет JaCoCo и по документации модулей понимает, что вообще должно быть покрыто тестами, — и пишет осмысленные тесты, а не ради процента покрытия.

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

Идея под капотом: Software 3.0

Ничто из этого не завязано на конкретный стек — всё это следствие сдвига, который чётко описали два человека.

Андрей Карпаты называет это Software 3.0: после 1.0 (код, написанный руками) и 2.0 (обученные веса) программы теперь отчасти задаются промптами на естественном языке к LLM. В такой картине код, документация, конфиги и промпты — это всё входные токены, а сама LLM — среда выполнения: контекстное окно как оперативная память, документация как диск. Практический вывод — делать репозиторий удобным для LLM: простой текст, явные соглашения, примеры вместо длинных описаний, один источник истины на каждую фичу, и хранить его в репозитории, а не закапывать в Confluence. Даже «vibe coding», термин самого Карпаты, — это не про отказ от структуры: чем чётче спецификация, тем быстрее сходятся «вайбы».

Рекомендации Anthropic для Claude Code и Agent SDK приходят к тому же с инженерной стороны: понятный структурированный контекст прямо в репозитории работает лучше изощрённых промптов, а попадания в кэш промптов резко падают, когда документация меняется по косметическим поводам, — так что аккуратный текст с низкой текучестью оказывается ещё и способом сэкономить. Оба взгляда сводятся к одному правилу: дайте агенту тот же контекст, что дали бы сильному инженеру в его первый день, и держите этот контекст в актуальном состоянии.

Это не привязано к одной модели

В примерах выше используется Claude Agent SDK — просто потому, что эти системы работают на нём. Но в самом подходе нет ничего, что было бы завязано на Claude. Переносимое здесь — это архитектура:

  • Chat с документацией требует LLM, которая умеет в цикле вызывать инструменты (прочитать файл, сделать grep, решить, что читать дальше) и отдавать ответ потоком. Любая модель с function calling за любым агентным фреймворком — SDK от OpenAI, LangChain/LangGraph, локальная модель через Ollama с обёрткой под tool use — без изменений встаёт на роли оркестратора, агента документации, агента кода и ответчика. А решение «никакой векторной БД, просто grep по живому репозиторию» от модели не зависит вовсе.
  • Конвейер для Jira — это workflow, разнесённый по стоимости: дешёвая модель сортирует, сильная пишет, сильная проверяет. Подставьте любую пару «дешёвая/сильная» от вашего провайдера — границы стадий, передача данных через JSON и момент запуска останутся теми же.
  • Соглашения в репозитории переносятся легче всего. CLAUDE.md — это просто имя файла, который автоматически читает Claude Code; сама идея — корневой файл с контекстом, тематические файлы правил, индекс документации — работает с любым агентом. Другие инструменты читают свои аналоги (AGENTS.md, .cursorrules, llms.txt), и их можно сделать симлинками или генерировать из одного источника, чтобы все модели читали одну и ту же правду.

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

Итог

В мире Software 3.0 документация — уже не вежливая формальность, какой она была в 2010-х. Это часть программы, и устаревает она ровно в тот момент, когда код уезжает у неё из-под ног. Две описанные системы — рабочий ответ на это: Chat с документацией позволяет запрашивать этот «мозг», не таская за собой векторную БД, а конвейер Jira держит «мозг» честным, записывая документацию, пока контекст ещё свежий. Обе стоят на одном и том же дешёвом и непримечательном фундаменте — CLAUDE.md, несколько файлов с правилами и индекс документации — и обе окупаются на каждом следующем запуске агента.

Что почитать дальше

  • Андрей Карпаты — Software 2.0 (2017) и его доклады «Software 3.0 / LLM OS» (2024–2025)
  • Anthropic — Building Effective Agents (декабрь 2024)
  • Anthropic — Claude Code best practices
  • Model Context Protocol — открытый протокол для подключения инструментов к LLM-агентам
  • llms.txt — соглашение о машиночитаемой точке входа в репозиторий