# Правила для кодящего ИИ-агента: не повторять чужие ошибки

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

Формат каждого правила: **что делать** - почему - чем проверяется.

---

## 1. Работа с ИИ-моделями

### 1.1. У модели три параметра, а не один

**Перед тем как качать модель, проверь три числа и отсекай по первому же несовпадению.**

| Параметр | Как узнать | Что значит |
|---|---|---|
| Вес файла | каталог моделей | сколько занимает на диске |
| Память в работе | `docker stats`, а не `ollama ps` | всегда больше веса файла |
| Окно контекста | карточка модели | сколько текста влезает за раз |

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

**Проверка:** посчитай длину своего текста в токенах и сравни с окном **до** первого запуска.

### 1.2. Длинный текст режется молча и с начала

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

**Проверка:** сверяй число обработанных токенов в ответе модели с тем, что отправлял.
Расходятся - текст резали.

### 1.3. Измерь, сколько нужно, прежде чем поднимать отсечку по времени

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

**Почему:** иначе замер показывает твою отсечку, а не скорость модели. В исходном
проекте это стоило двух прогонов по 68 и 368 минут, оба с пустым результатом.

### 1.4. Нехватка памяти выглядит как работа, а не как ошибка

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

**Проверка:** `ps -o stat` показывает `D` (ждёт диск) вместо `R` (работает), и `free -m`
показывает занятый своп. Оба признака держатся минутами - считаешь на диске.

### 1.5. Не выбирай модель по числу заполненных полей

Метрика полноты хвалит того, кто больше выдумывает. Метрика достоверности хвалит того,
кто больше молчит. Считай обе и смотри на них вместе.

### 1.6. Качество разбора оценивает код, а не модель

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

### 1.7. Критерий качества пишется ДО первого замера

Записанный после, он не измеряет, а оправдывает уже выбранную модель. Дата в файле
важнее формулы.

### 1.8. Не переноси цифры с выдуманного текста на живые данные

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

### 1.9. Более мощная модель не чинит неверную раскладку

Если модель берёт верные слова и кладёт их не в тот раздел, это задано твоим описанием
разделов, а не мощностью модели. Модель втрое дороже разложит так же неверно.

---

## 2. Работа на боевом сервере

### 2.1. Никогда не запускай починку данных от root

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

**Проверка:** после любой правки данных - `ls -l` на затронутые файлы и проверка, что
владелец не изменился.

### 2.2. Право записи в папку не равно праву записи в её файлы

Проверяй то, что ломается, а не то, что рядом.

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

Если пользователь сохраняет - проверь сохранение, а не открытие страницы.

### 2.4. Правку конфигурации проверяй глазами самой программы

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

### 2.5. Конвейер обязан звать владельца, когда задание зависло

Задача, застрявшая между этапами, не считается потерянной, но и не считается сделанной.
Молчащий конвейер неотличим от работающего.

---

## 3. Проверки и наблюдение

### 3.1. Пустой результат обязан отличаться от отказа

`0 найдено` и `не смог посмотреть` - разные события. Смешал их - сломанная проверка
годами выглядит успешной.

### 3.2. Проверка, которая смотрит не туда, порождает ложные факты

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

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

### 3.3. Сторож обязан сообщать, что сам ослеп

Молчащий сторож и здоровый сервис выглядят одинаково. Отказ проверки - это событие
уровня тревоги, а не тишина.

### 3.4. Тревога приходит с разбором, а не с заданием разобраться

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

### 3.5. Дорогой совет только по прямому признаку

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

### 3.6. Приёмка по артефакту, а не по статусу

`systemctl is-active` говорит, что процесс запущен, и ничего не говорит о том, что он
работает. Бэкап проверяется распаковкой, файрвол - проверкой снаружи, отправка -
полученным сообщением.

---

## 4. Данные людей

### 4.1. Обезличивай до отправки, а не после

Замена имён и дат на условные обозначения происходит перед выходом из контура. Ключ
соответствия наружу не уходит никогда.

**Проверка:** прогон по готовым запросам с поиском исходных имён. Ожидаемый результат - ноль.

### 4.2. Голос обезличить нельзя

Аудио с человеческой речью не отправляется во внешние сервисы: маскировать там нечего.
Распознавание речи считается внутри контура.

### 4.3. Спроси провайдера три вещи до интеграции

1. Сохраняете ли вы текст запроса и на какой срок
2. Где физически считается модель
3. Можно ли выключить сохранение и подтверждается ли это документом

Ответы сохрани письменно. Отсутствие ответа тоже фиксируй: два запроса без ответа - это
документ, а не предположение.

### 4.4. Инструмент, показывающий, где лежат данные, показывает и сами данные

Проверка утечек не должна печатать то, что ищет. Маскирование вывода - часть инструмента.

---

## 5. Как агент отчитывается

### 5.1. Не выдумывай то, что можно проверить

Названия моделей, версии пакетов, возможности чужого сервиса, цены, содержимое файла -
проверяются запросом или чтением, а не вспоминаются. Не проверил - так и скажи.

### 5.2. Раздели в отчёте проверенное и предполагаемое

«Прогнал команду, вот вывод» и «скорее всего работает так» - разные утверждения, и
человек должен видеть, какое перед ним.

### 5.3. Сдавай работающее, а не отчёт о попытках

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

### 5.4. Внешние действия и опасные права - гейт человека

Деньги, доступы, удаление данных, публикация, письма клиентам, работа на боевом сервере.
Агент готовит, человек нажимает.

---

Составлено по материалам разбора: Евгений Ганимар, @ganimarketing
