---
title: "Claude Code — Best Practices"
url: "https://romankryvolapov.com/ru/claude-code-best-practices/"
description: "Как организовать работу с Claude Code: инструкции проекта, правила и скилы, трекер задач и багов в репозитории, план перед кодом, подагенты, контекст, разрешения и расход бюджета."
language: ru
updated: 2026-08-06
---
**Привет!**

Здесь раньше лежала статья про практики работы с Cursor. Я её переписал.

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

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

## Всё упирается в контекст

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

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

Отсюда вывод, из которого растёт всё остальное. Контекстом надо управлять сознательно: решать, что туда попадёт, а что нет. Не «пусть накапливается, потом сожмётся».

## Дайте агенту способ проверить себя

Это первое, что стоит настроить, и это же чаще всего пропускают.

Агент останавливается, когда работа выглядит сделанной. Если проверить её нечем, «выглядит» — единственный доступный сигнал, и проверяющим становитесь вы. Каждая ошибка ждёт, пока вы её заметите.

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

Разница видна прямо в формулировке задачи:

```text
✗ сделай функцию валидации email

✓ сделай функцию валидации email. Примеры: user@example.com — верно,
  invalid — неверно, user@.com — неверно. После реализации запусти тесты
  и покажи вывод

✗ сборка падает

✓ сборка падает вот с этим: [текст ошибки]. Исправь причину, а не симптом,
  и убедись, что сборка проходит
```

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

И просите показывать доказательство: вывод тестов, саму команду, скриншот. Прочитать доказательство быстрее, чем перепроверять руками. А для сессии, за которой вы не следили, это вообще единственный способ понять, что произошло.

## Сначала разведка, потом план, потом код

Если сразу просить код, получите аккуратное решение не той задачи.

В Claude Code есть отдельный режим планирования: агент читает файлы, отвечает на вопросы, но ничего не меняет. Рабочий цикл выходит такой: разобраться в нужной части кода → составить план → выйти из режима планирования → реализовать → коммит.

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

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

```text
Хочу сделать [одно предложение про фичу]. Проинтервьюируй меня подробно,
через инструмент вопросов.

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

Когда закончим — запиши полную спецификацию в SPEC.md.
```

Только не превращайте это в ритуал. Если правку можно описать одним предложением, план не нужен: лишний круг стоит дороже, чем польза от него.

## Три уровня настройки

Знание агенту передаётся тремя способами, и они не взаимозаменяемы.

**Инструкции проекта** читаются в начале каждой сессии. Сюда идут факты, нужные всегда: как собрать, как запустить тесты, чем этот проект отличается от типового. Рекомендация Anthropic — держаться в пределах двухсот строк, и это не формальность. Чем длиннее файл, тем хуже соблюдаются его же указания.

Хороший тест для каждой строчки: если это убрать, агент начнёт ошибаться? Нет — убирайте.

**Правила** лежат отдельными файлами в каталоге правил, по файлу на тему, и грузятся так же. Их можно ограничить масками путей, и тогда правило подтянется только когда агент трогает подходящие файлы:

```markdown title=".claude/rules/api-endpoints.md"
---
paths:
  - "src/api/**/*.ts"
  - "apps/backend/**/*.ts"
---

# Правила для API

- Каждый эндпоинт валидирует вход, без исключений.
- Ошибки отдаются в общем формате из `ErrorResponse`.
- Новый эндпоинт сначала описывается в api.md, потом пишется код.
```

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

Раскладка, которой пользуюсь я:

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

Последний пункт стоит особняком. Всё, что выше, — текст, который модель читает и обычно выполняет. Хук — код, который выполнится независимо от её решения. Критичное поведение должно быть хуком, а не абзацем в инструкциях. Разбор хуков со всеми событиями и рабочими примерами у меня в [отдельной статье](/ru/claude-code-hooks/).

### И всё это — промпты

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

Инструкции проекта, правила, скилы, описания подагентов — это не конфигурация. Это системные промпты, которые кто-то (вы) пишет один раз, а модель читает в каждой сессии. Разница между «агент постоянно делает не то» и «агент работает предсказуемо» очень часто оказывается разницей между небрежно и аккуратно написанным промптом.

Что из техник промпт-инжиниринга реально окупается в этих файлах:

- **Структура и разделители.** Заголовки, списки, явные блоки: модель разбирает структурированный текст надёжнее сплошной прозы, а вы получаете возможность сослаться на конкретный кусок из другого правила. Подробнее про [разделители и структуру промпта](/ru/prompt-engineering/#Delimiters-and-structure).
- **Иерархия правил.** Когда правил больше пяти, они начинают конфликтовать, и надо прямо написать, какое из них главнее. У меня, например, правило «не коммить без просьбы» стоит выше правила про проверку перед коммитом, и в тексте это сказано словами, а не подразумевается. Про то, как задавать [иерархию правил](/ru/prompt-engineering/#Rule-hierarchy), есть отдельный раздел.
- **Позитивные формулировки вместо запретов.** «Оставь изменения в рабочем дереве и расскажи, что сделал» работает лучше, чем «не коммить». Одни запреты оставляют модель без образца поведения.
- **Примеры вместо описаний.** Пара «так плохо / так хорошо» в правиле стоит трёх абзацев объяснения. Это обычный [few-shot](/ru/prompt-engineering/#Few-shot-examples), просто применённый к конфигурации проекта.
- **Явный формат ответа.** Если вы хотите определённую форму отчёта, её надо описать, а лучше показать. Про [контроль формата ответа](/ru/prompt-engineering/#Output-format-control) — там же.
- **Экономия контекста.** Каждая строка инструкций и правил оплачивается в каждой сессии, поэтому лишнее слово здесь дороже, чем в обычном промпте. Это ровно то, что в статье про промпты называется [контекст-инжинирингом](/ru/prompt-engineering/#Context-engineering).

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

Полный разбор техник — в статье [про промпт-инжиниринг](/ru/prompt-engineering/); дальше по тексту я буду ссылаться на конкретные разделы оттуда.

## Как это выглядит на живом проекте

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

### Правила

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

Вот как выглядит правило целиком, самое короткое из моих:

```markdown title=".claude/rules/never-commit-unless-asked.md"
# Никаких коммитов, пока не попросили

**Не запускать `git commit` (а также push, PR, merge), пока пользователь
не попросил об этом прямо, своими словами.**
Законченная работа, зелёная сборка и ощущение «вроде готово» разрешением
не являются.

Сделал правки — оставь их в рабочем дереве, коротко расскажи, что изменилось,
и остановись. Сомневаешься, просили или нет, — не коммить, спроси.

## Чек-лист

- [ ] Ни одного коммита, push или PR без явной просьбы своими словами.
- [ ] Работа оставлена в рабочем дереве, изменения описаны.
- [ ] При сомнении задан вопрос, а не сделан коммит.
```

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

Дальше пройдусь по остальным восьми. Оригиналы у меня написаны по-английски (так исторически сложилось, правила переезжали между проектами), поэтому цитаты привожу в переводе.

#### Проверка перед коммитом

Самое длинное правило, вступает в силу когда коммит всё-таки попросили. Четыре стадии: прочитать весь diff по кускам; разобрать всё, чего изменения касаются за пределами diff, то есть вызывающий код, контракты и документацию, которая от этих правок только что устарела; поохотиться за дефектами; вынести вердикт.

Вердиктов ровно три, и написаны они так, чтобы агенту некуда было увильнуть:

```text
PASS — не найдено ничего, либо всё найденное уже исправлено и перепроверено.

FIX, ЗАТЕМ PASS — есть настоящие, но чинибельные находки. Чини их сам,
  немедленно, прогони проверку заново по исправленному состоянию и честно
  расскажи разработчику, что нашёл и что починил. Чинить — поведение
  по умолчанию: проблемы никогда не «оставляют на потом» и никогда
  не ограничиваются упоминанием в отчёте.

STOP — серьёзная проблема (потеря данных, дыра в безопасности, сломанный
  контракт, изменение противоречит собственному требованию) либо настоящая
  развилка, где обе конструкции защитимы и выбор принадлежит разработчику.
  Коммита нет. Объясни просто и конкретно, в чём проблема.
```

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

Ещё оговорено, что `--no-verify` запрещён: упавший хук чинят, а не глушат.

Отдельно скажу про приём, который здесь работает. Стадии пронумерованы, у каждой свой список того, что проверять, а в конце — обязательный вердикт одним словом. Это тот же [контроль формата ответа](/ru/prompt-engineering/#Output-format-control), что и в обычных промптах: модели гораздо труднее «примерно проверить» и сказать «вроде нормально», когда от неё требуется выбрать один из трёх помеченных исходов.

#### Стиль ответа

Правило про то, как со мной разговаривать. Начинается оно так:

```text
Пользователь — человек, читающий чат, а не Claude Code.
У него НЕ открыт исходник параллельно, и он НЕ хочет расшифровывать
идентификаторы кода, имена полей и пути к файлам внутри ответа.
Говори с ним как коллега, а не как инструмент код-ревью.

Считай, что читатель — компетентный разработчик, который НЕ погружён
в этот проект. Он умеет писать код, но, скорее всего, ведёт несколько
проектов сразу и не держит специфику этого в голове.
```

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

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

```text
✗ «Осталось: своё дерево миграций с проверкой расхождения, образ и манифест,
   проводка в скрипте запуска.»

✓ «Осталось:
   - Описать изменения базы отдельными шагами обновления: сейчас таблица
     создаётся на лету, и на настоящем сервере её просто не будет.
   - Собрать образ и добавить в описание кластера, иначе некуда разворачивать.
   - Прописать сервис в скрипте запуска, чтобы поднимался вместе с остальными.»
```

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

Пара «плохо / хорошо» тут работает лучше любого описания, и это ровно [few-shot](/ru/prompt-engineering/#Few-shot-examples): один показанный пример заменяет абзац объяснений про самодостаточность формулировок.

#### Бюджет сессии

```text
Трать токены пропорционально реальной сложности задачи — самым дешёвым
путём, который надёжно её решает, а не самым тщательным, какой позволил бы
бюджет. Лимиты — это ограждение: они показывают, где ты упрёшься в стену
или в ограничение частоты, чтобы остановиться заранее, а не бюджет,
который надо освоить.
ЗЕЛЁНАЯ зона НЕ означает «жги свободно».
```

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

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

#### Сомневаешься — ищи в интернете

Короткое правило, семнадцать строк, и почти всё в нём — описание одного сценария:

```text
Известный сценарий провала, которого надо избежать: что-то не работает →
ты применяешь исправление, основанное на том, что «знаешь» → всё равно
не работает → каждое следующее исправление закапывает решение, построенное
на неверном предположении.

Поэтому во ВСЕХ сомнительных случаях — когда что-то неясно, неочевидно,
ведёт себя не так, как ты ожидал, или расходится с твоими знаниями —
ВСЕГДА ищи в интернете, прежде чем чинить дальше, и смотри в первую
очередь на свежую официальную документацию.

Если и поиск не дал решения — ОСТАНОВИСЬ и спроси пользователя.
```

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

#### Подтянуть ветку перед работой

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

Дальше три шага: получить изменения и посмотреть, насколько ветка отстала; перемотать; прочитать пришедшее, если оно касается вашей области. И отдельный раздел на случай грязного рабочего дерева.

#### Останавливаться на архитектурных развилках

Пожалуй, самое ценное правило из всех. Начинается с формулировки, которая мне нравится:

```text
Часть решений — это правка. Часть — переписывание. Это правило про второй тип.

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

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

Дальше — признаки, по которым решение считается развилкой: трудно отменить; расходится больше чем на один компонент или команду; определяет, кто чем владеет и где проходит граница доверия; меняет то, что видно снаружи (развёрнутый компонент, схему данных, контракт API); затрагивает деньги, безопасность или приватность. Два признака и больше — стоп.

А вот вторая половина правила, без которой первая вредна:

```text
Поднять развилку стоит разработчику настоящего внимания. Прежде чем поднимать:

— Обратимо в течение дня? → решай сам.
— Проект уже принимал равнозначное решение? → следуй ему;
  прецедент важнее предпочтения.
— Тебя устроил бы любой из вариантов? → это не развилка, это вкус. Выбирай.
— Неясно только потому, что ты не посмотрел? → сначала посмотри.
  Большинство «развилок» растворяется при чтении.

Ожидай в проекте несколько настоящих развилок, а не по одной на задачу.
Если ты поднимаешь их еженедельно — фильтр настроен неправильно.
```

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

#### Символьная навигация

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

```text
| Задача                          | Инструмент             | Вместо чего        |
| Понять API файла                | обзор символов         | чтения всего файла |
| Найти класс или функцию         | поиск символа          | grep по имени      |
| Прочитать тело одного символа   | символ с телом         | чтения с отступом  |
| Узнать, кто это вызывает        | поиск ссылок           | grep по имени      |
| Переименовать по всему проекту  | переименование символа | десятков правок    |
```

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

#### Учёт работ

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

### Скилы — это документация

Главная мысль раздела: скилы у меня не «плагины для агента», а документация проекта. Та самая, которую раньше писали в вики и никто не открывал.

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

**Префикс в имени — это адресат.** Скилы разложены не по темам, а по тому, чьей команде адресованы:

```text
.claude/skills/
├── req-uc-auth/SKILL.md              требования: сценарии авторизации
├── req-personas/SKILL.md             требования: персонажи
├── req-business-rules-core/SKILL.md  требования: бизнес-правила
├── ba-acceptance-criteria/SKILL.md   бизнес-анализ: как писать критерии
├── qa-bug-report/SKILL.md            тестирование: как оформлять находки
├── dev-backend-new-endpoint/SKILL.md разработка: процедура нового эндпоинта
├── dev-tests-backend-unit/SKILL.md   разработка: юнит-тесты
└── dev-workflow-git/SKILL.md         разработка: конфликты слияния
```

Приходит новая роль в команде — появляется новый префикс, а не новая вики.

**Как выглядит скил.** Заголовок с именем и описанием, дальше обычный markdown:

```markdown title=".claude/skills/dev-backend-new-endpoint/SKILL.md"
---
name: dev-backend-new-endpoint
description: Процедура добавления HTTP-эндпоинта: контракт, валидация, слои,
  тесты, регенерация клиента. Применять при создании нового эндпоинта или
  модуля на бэкенде.
---

# Новый эндпоинт

1. Описать контракт в `api.md` — до кода, иначе файл и код разойдутся.
2. Контроллер только принимает и отдаёт; логика в сервисе, доступ к данным
   в репозитории.
3. Валидация входа обязательна, ошибки — общим форматом.
4. Тесты: успешный путь, отказ валидации, отсутствие прав.
5. Перегенерировать клиент фронтенда и проверить, что он собирается.

## Чек-лист
- [ ] api.md обновлён до кода
- [ ] логика вне контроллера
- [ ] три теста на месте
- [ ] клиент перегенерирован, сборка зелёная
```

Описание — самое важное поле: по нему агент решает, подходит ли скил задаче. «Справочник по FastAPI» работает плохо. «Архитектура и продакшн-практики FastAPI; применять при создании и ревью сервисов на FastAPI» — хорошо.

По сути это маленький промпт маршрутизации: он должен содержать и предмет, и условие срабатывания. Тело скила при этом держат коротким, потому что после загрузки оно остаётся в контексте до конца хода и оплачивается каждым следующим сообщением. Здесь работают те же соображения, что и в [контекст-инжиниринге](/ru/prompt-engineering/#Context-engineering): длинный справочник лучше разбить, вынеся детали в соседние файлы, на которые скил ссылается.

**Требования как скилы.** Скил с требованиями выглядит как нормальный документ аналитика. Сценарии со своими номерами, персонажи, границы, критерии приёмки. Ничего «под агента» в нём нет:

```markdown title=".claude/skills/req-uc-auth/SKILL.md (фрагмент)"
## UC-AUTH-002 Войти по почте и паролю

**Персоны:** PER-001 Агент, PER-002 Менеджер
**Приоритет:** P0

### Критерии приёмки
- AC-UC-AUTH-002-001 — при верных данных сессия открыта и действует
  в обоих приложениях без повторного входа.
- AC-UC-AUTH-002-002 — при неверном пароле ответ одинаков независимо
  от того, существует ли аккаунт (не подсказываем перебором).
- AC-UC-AUTH-002-003 — после пяти неудач подряд вход по этой почте
  блокируется на 15 минут.
```

А дальше главное: на эти номера ссылаются задачи и баги. В записи трекера стоит не пересказ, а ссылка. Текст требования не копируется никуда и живёт в одном месте. Если запись и требование разошлись — прав документ с требованием.

Лечит знакомую болезнь: критерий, переписанный в задачу, в вики и в тест-кейс, и три его версии через полгода.

### Но это лишь один из вариантов

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

**Обычная папка с документацией в репозитории.** Самый простой вариант: markdown в `docs/`, а в инструкциях проекта строчка «документация лежит там-то». Ничего настраивать не надо, читается людьми в GitHub как есть. Минус ровно один, но существенный: агент о ней не вспомнит, пока вы не назовёте файл. Он не знает, что там внутри, и в лучшем случае найдёт нужное поиском по словам.

**AGENTS.md.** Кросс-инструментальный файл контекста, который читают Codex, Cursor и ещё десяток агентов. Claude Code читает свой файл инструкций, но умеет импортировать AGENTS.md, так что оба варианта уживаются. Хороший выбор для команды, где разные люди работают разными агентами. Ограничение то же, что у инструкций проекта: это один файл, и раздувать его до справочника нельзя.

**Внешняя вики через MCP.** Confluence, Notion, Linear и что угодно ещё: документация остаётся там, где её и так ведут люди, а агент ходит туда по MCP-серверу. Аналитик правит страницу в привычном интерфейсе, с комментариями и историей, а агент читает то же самое. Платой идут сеть, аккаунты и то, что версия документации живёт отдельно от версии кода: страница поменялась вчера, а ветка, которую вы чините, отвечает состоянию месячной давности.

**Obsidian и его родня.** Локальное хранилище markdown-файлов, к которому агента подключают либо MCP-сервером, либо просто открывая ему каталог. Формат тот же plain-text, поэтому хранилище можно держать в гите, а поверх него работает и человек со своим графом ссылок и поиском, и агент. Люди используют это как общую память между инструментами и сессиями: заметки, решения, наработки в одном месте, доступном и Claude Code, и другому агенту. Для личной базы знаний вариант отличный. Для проектной документации команды слабее: связь с кодом опять теряется, а хранилище живёт своей жизнью.

**Платформы документации с MCP и llms.txt.** Современные сервисы вроде GitBook или Mintlify отдают документацию сразу в двух видах: человеческий сайт и машиночитаемый слой, вплоть до автоматически поднятого MCP-сервера. Разумно, когда документация публичная и её всё равно надо где-то издавать.

**Поиск по большому корпусу.** Если документации тысячи страниц, ни один из вариантов выше в контекст не влезет, и вопрос переходит в область поиска: векторная база, гибридный поиск, отдельный сервер, который отдаёт агенту нужные куски. Это уже отдельная инженерия, а не «положил файлы в папку».

#### Чем скилы выигрывают

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

Дальше по мелочи, но приятно. Документация версионируется вместе с кодом, и в старой ветке лежит та документация, которая соответствует старому коду. Правки проходят обычное ревью в pull request'е. Ничего не надо настраивать, всё работает офлайн, без токенов и внешних сервисов. И формат стандартизуется: тот же скил можно отдать не только Claude Code.

#### Чем расплачиваешься

Минусы честнее перечислить сразу.

**Список скилов сам занимает контекст.** Не тела, а именно перечень имён и описаний, зато в каждой сессии. На сотне скилов это уже сотни строк, которые вы оплачиваете всегда. У описания даже есть предел длины, после которого его обрежут: разработчики явно защищаются от того, чтобы этот список рос бесконтрольно.

**Людям читать неудобно.** Внутри репозитория нет ни поиска по документации, ни оглавления, ни комментариев на полях, ни удобной работы с картинками. Аналитик, привыкший к Confluence, в GitHub за требованиями не пойдёт. У меня это решается тем, что требования правит тот же человек, который работает с агентом, но в большой команде это станет проблемой.

**Нет совместного редактирования и обсуждения.** Комментарий к абзацу, обсуждение прямо в документе, уведомление «вас упомянули» — всего этого нет. Есть pull request, что в разы формальнее.

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

**Соблазн свалить туда всё.** Скилы дёшевы, поэтому в них легко накидать сто файлов и получить ту же самую мёртвую вику, только в гите. Одно спасение: описание, по которому агент выбирает скил. Если оно написано небрежно, документ не подтянется никогда, и вы даже не узнаете.

**Ролевой фильтрации нет.** Скилы аналитика видит разработчик, и наоборот, а платят контекстом все. Про это подробнее ниже, в разделе про роли.

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

### Сколько это стоит

Инструкции проекта и правила грузятся в каждую сессию целиком. У меня это 571 строка инструкций плюс 1245 строк правил. Почти две тысячи строк до того, как вы напечатали первое слово.

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

Кстати, если агент упорно нарушает какое-то правило — дело почти всегда не в формулировке, а в объёме. Правило потерялось. Лечится сокращением, а не добавлением заглавных букв.

## Документация: как и где

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

Что из этого следует:

**Правила и скилы — источник истины.** Агенту прямо запрещено придумывать поведение, им противоречащее. Считает документ неправым — говорит человеку, а не действует по-своему.

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

**Новое — новый документ, изменение существующего — правка существующего.** Иначе через полгода в проекте два скила про одно и то же с разными версиями истины.

**Единый шаблон.** Есть отдельный скил про то, как писать правила и скилы: структура, формулировки, разделители, обязательный чек-лист в конце. Чек-лист превращает описание в проверяемое требование, а заодно даёт агенту способ самому проверить, выполнил ли он документ.

Этот скил, по сути, свод техник промпт-инжиниринга, приложенный к конфигурации проекта, и правило требует применять его при создании или правке любого правила и любого скила. Звучит бюрократично, но окупается: документы, написанные по одному шаблону, реже противоречат друг другу и лучше соблюдаются. Разбор самих техник — в статье [про промпт-инжиниринг](/ru/prompt-engineering/).

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

**Технические справочники отдельно.** Развёртывание, миграции, результаты нагрузочных тестов лежат в обычной папке документации в корне. Агенту в работе над кодом они не нужны, а человеку нужны эпизодически.

## Трекер задач и багов прямо в репозитории

Самая своеобразная часть моей конфигурации.

Задачи и баги лежат в репозитории обычными markdown-файлами, по файлу на запись. Никакой базы, никакого веб-интерфейса, никаких проверок в CI. Скрипт умеет две вещи: завести запись и пересобрать индекс. На этом автоматизация заканчивается.

```text
management/
├── tasks/
│   ├── auth/TASK-001-one-password-for-both-apps.md
│   ├── billing/TASK-037-invoice-pdf-export.md
│   ├── done/TASK-012-import-legacy-contacts.md
│   ├── INDEX-AUGUST-2026.md
│   └── TEMPLATE.md
├── bugs/
│   ├── auth/BUG-003-sign-in-loops-on-expired-token.md
│   ├── done/BUG-001-avatar-upload-fails-over-2mb.md
│   └── INDEX-AUGUST-2026.md
├── decisions/ADR-0001-where-user-sessions-are-stored.md
├── logs/roman/2026-08-06/a1b2c3d4.log
└── new.py
```

Что это даёт. Агент видит задачу целиком, не выходя из проекта, вместе с требованием, на которое она ссылается, и кодом, который она правит; запись живёт в той же истории, что и код, поэтому всегда видно, каким коммитом она закрыта и что по ней менялось по дороге. Два человека (или два агента) над разными записями физически не редактируют один файл, так что конфликтов слияния не бывает по построению — это, пожалуй, главный аргумент против одного большого файла со списком задач, к которому все привыкли. Плюс всё работает офлайн, без аккаунтов и токенов.

### Как выглядит запись

Вот реальный шаблон бага, только с выдуманным содержимым:

```markdown title="management/bugs/auth/BUG-003-sign-in-loops-on-expired-token.md"
---
id: BUG-003
title: 'Sign-in loops on an expired token'
severity: P1
status: CONFIRMED
module: auth
area: 'sign-in / refresh token'
found: 2026-08-04
closed:
assignee: ''
req: 'AC-UC-AUTH-002-001'
source: 'QA wave 12'
---

# BUG-003 — Sign-in loops on an expired token

- **Steps:** open the app with a token older than 24h → sign-in screen →
  enter valid credentials → back to the sign-in screen.
- **Expected:** AC-UC-AUTH-002-001 — a valid sign-in opens a session.
- **Actual:** the refresh call returns 401 and the client retries forever.
- **Log:**
  - 2026-08-04 — filed from the QA wave.
  - 2026-08-05 — reproduced on staging, confirmed. Refresh interceptor
    does not clear the stale token before retrying.

## Screenshots

- 2026-08-04 — `BUG-003_04-AUGUST-2026_11-20_loop.png` — the loop, three
  redirects in the network tab.
```

Заводится командой, а не копированием файла руками:

```bash
python management/new.py bug  --module=auth --severity=P1 \
  --title="Sign-in loops on an expired token"

python management/new.py task --module=auth --priority=P1 \
  --title="One password for both apps"

python management/new.py attach BUG-003 shot.png --note="the loop after the fix"
```

Скрипт выдаёт следующий свободный номер, кладёт файл в папку модуля и пересобирает индекс месяца. Индекс выглядит так:

```markdown title="management/tasks/INDEX-AUGUST-2026.md"
# Task index — AUGUST 2026

**Entries:** 31 · **Open:** 30 · **Closed:** 1

| ID | Prio | Status | Batch | Module | Title |
| --- | --- | --- | --- | --- | --- |
| TASK-029 | P1 | IN_PROGRESS | 2026-08-04-export | billing  | Export invoices as PDF from the admin panel |
| TASK-030 | P1 | TODO | PROJ-42 | platform | Choose a feature-flag library |
| TASK-031 | P1 | TODO | PROJ-42 | platform | Set up CI/CD for the staging environment |
```

Детали, которые важны на практике:

**Номера вечные.** Не переиспользуются и не перенумеровываются никогда: на них ссылаются коммиты, переписка и другие записи.

**Папки названы по требованиям.** Область записи называется так же, как файл требований, который ею владеет: `req-uc-auth` → папка `auth`. Задачи и баги делят одни и те же папки. Мелочь, но убирает вечный спор «куда это положить» и соединяет трекер с документацией.

**Закрытие только через `git mv`.** Меняется статус, ставится дата, дописывается строка в журнал, файл переезжает в папку закрытых. Обычное перемещение выглядит в истории как удаление плюс новый файл, и вся история записи теряется. Я это узнал не из документации.

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

**Язык — английский латиницей.** Имя файла строится из заголовка, а трекер читают люди без общего родного языка. Описание можно оставить на языке жалобы, если попросили, но заголовок и служебные поля всегда латиницей.

### Что в трекер не попадает никогда

Самое важное правило учёта, и оно противоречит привычке: в трекере только продукт.

Тест ровно один. Работает ли это у заказчика? Приложения, библиотеки, из которых они собраны, данные, инфраструктура — да, это продукт.

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

Формулировка в правиле звучит жёстко, и это намеренно:

```text
Ни записи вообще — как бы сломанным оно ни выглядело и сколько бы работы
ни стоило: устаревший документ, мёртвая ссылка, неверный путь в правиле,
дефект в этом самом трекере или в служебном скрипте, хук, неправильно
читающий свой ввод, кривая настройка CI, переименованная папка, правило,
о котором кто-то попросил. До заказчика ничего из этого не доезжает,
значит это не баг. А превратить его в задачу — та же ошибка под другой
вывеской. Не заводите. Сделайте работу, коммит скажет за неё.
```

Соблазн велик: работы много, хочется, чтобы она была видна. Но трекер, набитый хозяйственными делами, никто не читает, а он заводился ровно ради чтения.

Второе разделение — задачи против багов. Всё, что нашло тестирование, это баг, и только баг. Исправление бага не порождает задачу. Задача — новая функциональность или переделка существующей, о которой попросили.

### Решения

Рядом с задачами лежат архитектурные решения, по файлу на решение. Формат обычный, знакомый по ADR:

```markdown title="management/decisions/ADR-0001-session-storage.md (структура)"
---
id: ADR-0001
title: Where user sessions are stored: database or cache
status: Proposed
date: 2026-07-31
deciders: Engineering lead / Architect
related:
  - management/tasks/auth/TASK-001, TASK-002
  - Requirements BR-SEC-004 (one session shared by both apps)
supersedes: none
---

## Context      что заставило принимать решение и какой вопрос заблокирован
## Decision     пронумерованные пункты: что именно решено
## Verified facts (checked in code, not assumed)   таблица «факт → где в коде»
## Consequences что это упрощает и чем за это платим
## Alternatives что рассматривали и почему отвергли
```

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

Толк простой: спор, который решается один раз, потом не всплывает заново каждые два месяца.

### Журнал сессий, который пишется сам

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

Выглядит так:

```text title="management/logs/roman/2026-08-06/a1b2c3d4.log"
session start: source=startup · model=claude-opus-5

════════════════════════════════════════════════════════════

prompt:
почини бесконечный редирект на протухшем токене, BUG-003

turn: model=claude-opus-5 · effort=high · 4m 12s · tools=23
  (Read 9, Grep 5, Edit 3, Bash 6) · subagents=1

files:
  ~ apps/web/src/api/interceptors.ts  +14/-6  +[41-48,52-57] -[41-46]
  ~ apps/web/tests/auth.spec.ts       +31/-0  +[88-118]

answer:
Причина была в том, что перехватчик повторял запрос со старым токеном...

subagent done: general-purpose
session end: reason=prompt_input_exit · duration=51m
```

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

Сорок семь таких файлов накопилось за время работы над проектом. Открывал я их чаще, чем ожидал: обычно чтобы понять, когда и почему появилось странное место в коде. Заодно это ответ на вопрос «а где учитывается работа над самим репозиторием, которую запрещено заводить задачей». Вот здесь. Автоматически, без единой строчки ручного учёта.

### Чего у схемы нет

Честно про ограничения. Здесь нет доски, уведомлений, отчётов по спринту, учёта времени. Если менеджмент живёт в Jira, эта схема её не заменяет: у меня, например, метка группировки хранит как раз ключ из Jira.

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

## Чего не хватает: роли

Раз уж я разложил скилы по префиксам под разные команды, скажу и про то, чего для этой схемы не хватает в самом инструменте.

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

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

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

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

```text
.claude/
├── CLAUDE.md              общая часть для всех
├── settings.json
├── skills/
└── roles/
    ├── dev/{CLAUDE.md, settings.json, skills/, agents/}
    ├── qa/{CLAUDE.md, settings.json}     запрет на миграции и деплой
    └── ba/{CLAUDE.md, settings.json}     запись только в docs/ и specs/
```

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

Я оформил это [запросом на добавление ролей](https://github.com/anthropics/claude-code/issues/81615) в Claude Code: с описанием проблемы, схемой слияния настроек (роль может только сужать проектные права, но не расширять), способами выбрать роль и минимальной полезной версией. Если боль знакома, сходите поддержать — чем больше подтверждений, тем выше шанс, что до этого дойдут руки.

## Подагенты

Подагент — отдельная сессия со своим контекстом, своими инструментами и своим системным промптом. Делает часть работы, возвращает результат.

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

Своего подагента описывают одним файлом:

```markdown title=".claude/agents/security-reviewer.md"
---
name: security-reviewer
description: Ревью изменений на предмет уязвимостей. Запускать перед
  релизом и при правках в авторизации, загрузке файлов, работе с БД.
tools: Read, Grep, Glob, Bash
model: opus
---

Ты старший инженер по безопасности. Смотри изменения на предмет:
- инъекций (SQL, XSS, команды оболочки);
- дыр в аутентификации и авторизации;
- секретов в коде;
- небезопасной работы с пользовательскими данными.

Указывай конкретные строки и предлагай исправление. Стилистику не трогай.
```

Тело такого файла — системный промпт отдельной модели, а не заметка для себя. Работает всё то же самое: заданная роль, явные границы («стилистику не трогай»), формат ответа и условие вызова в описании. Про то, как писать промпты для агентов и вызова инструментов, есть [отдельный раздел](/ru/prompt-engineering/#Agentic-and-tools) в статье о промптах.

Второе применение — независимая проверка. Тот, кто писал код, плохой проверяющий: он видит не diff, а свои намерения. Просить подагента стоит конкретно:

```text
Подагентом проверь изменения против PLAN.md. Убедись, что каждое требование
реализовано, что на перечисленные пограничные случаи есть тесты и что
ничего вне задачи не изменилось. Пиши про пробелы, а не про вкусовщину.
```

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

И про деньги. Подагенты дешевле не бывают: каждый несёт свой контекст и свою обвязку. Веер из десяти стоит примерно как десять сессий. Правка в одном-двух файлах всегда быстрее в основной сессии; делегировать имеет смысл чтение многих файлов.

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

## Контекст на практике

Приёмы, которыми пользуюсь постоянно:

**Новая задача — чистый контекст.** Очистка между несвязанными задачами дешевле любой оптимизации. Хвост чужой задачи — это и лишние токены, и лишние поводы отвлечься.

**Две неудачные попытки — стоп.** Поправили дважды и всё ещё не то? Дело уже не в формулировке: контекст забит неудачными подходами. Чистая сессия с более точной постановкой почти всегда обгоняет длинную с накопленными исправлениями.

**Сжатие настраивается.** Когда окно кончается, история сжимается автоматически. Можно попросить сжать с акцентом на нужном, а в инструкциях проекта указать, что сохранять обязательно:

```markdown title="CLAUDE.md"
При сжатии контекста обязательно сохраняй: список изменённых файлов,
команды запуска тестов и принятые архитектурные решения с их причинами.
```

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

**Короткий вопрос в сторону.** Для мелочи вроде «что делает этот флаг» есть режим, где ответ не попадает в историю.

**Строка состояния.** Заполненность окна лучше держать перед глазами. Иначе вы замечаете проблему в тот момент, когда сжатие уже произошло.

## Разрешения

По умолчанию агент спрашивает разрешение на всё, что меняет систему. Безопасно и невыносимо: после десятого подтверждения вы уже не читаете, а кликаете.

Способов сократить три, разной радикальности. Список заранее разрешённых команд:

```json title=".claude/settings.json"
{
  "permissions": {
    "allow": [
      "Bash(npm run test:*)",
      "Bash(npm run lint)",
      "Bash(git status)",
      "Bash(git diff:*)",
      "Read(src/**)"
    ],
    "deny": [
      "Read(.env)",
      "Read(.secrets/**)",
      "Bash(git push:*)"
    ]
  }
}
```

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

Что бы вы ни выбрали, одно правило остаётся. Перед коммитом смотреть полный diff. Оно было важным и до агентов, а сейчас важнее: модель охотно правит то, о чём не просили, и заодно приводит в порядок соседний файл.

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

## Модели, усилия и деньги

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

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

```markdown title=".claude/skills/dev-changelog/SKILL.md"
---
name: dev-changelog
description: Собрать changelog из истории коммитов между двумя тегами.
model: haiku
effort: low
disable-model-invocation: true
---
```

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

## MCP и консольные утилиты

Два способа дать агенту доступ к внешнему миру.

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

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

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

## Что осталось верным из практик Cursor

Часть советов из старой статьи никуда не делась. Они про работу с моделью вообще.

**Декомпозируйте и контролируйте шаги.** Просьба «сделай всё» даёт код, который работает не так, как вы ожидали, и разбираться в нём дороже, чем было бы написать. Шаги должны быть самодостаточными: после каждого проект собирается.

**Логируйте щедро.** Человеку перегруженная логами консоль мешает, агенту помогает: сопоставляя вывод с кодом, он точнее понимает, что сломалось.

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

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

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

## Как всё испортить

Собрал те способы, которые вижу чаще всего. У себя в том числе.

**Сессия-помойка.** Начали с одной задачи, спросили про другую, вернулись к первой. Контекст забит всем сразу.

**Бесконечные исправления.** Агент сделал не то, вы поправили, снова не то. После двух кругов дешевле начать заново.

**Раздутые инструкции.** Файл вырос, половина указаний перестала работать: важное потерялось. Лечится безжалостным сокращением.

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

**Бесконечная разведка.** «Разберись, как тут всё устроено» без границ, и агент прочитал двести файлов, а окно кончилось. Ограничивайте область или отдавайте разведку подагенту.

## Коротко

Если забирать из статьи одно: сначала настройте среду, потом просите код.

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

Работа разовая, окупается в каждой сессии. И разница между «агент постоянно делает не то» и «агент делает что нужно» обычно именно здесь, а не в модели и не в формулировке очередного запроса.

И ещё раз про то, с чего начинал: всё это — промпты. Инструкции, правила, скилы, описания подагентов. Написанные небрежно, они дают ровно тот результат, который дают небрежные промпты, только вы платите за него в каждой сессии, а не один раз. Техники, которые тут работают, разобраны в статье [про промпт-инжиниринг](/ru/prompt-engineering/).

Про хуки — механизм, который делает поведение агента детерминированным, — [отдельная статья](/ru/claude-code-hooks/) со всеми событиями и тремя рабочими примерами.
