Теория курса
Это 414 минут чтения — 30% курса. Каждый блок рассчитан на 45 минут. Читать по одному блоку перед практикой соответствующего модуля. Не забегать вперёд.
Модуль 1. Как вайбкодинг работает на самом деле
1.1 Модель не понимает ваш код
LLM предсказывает следующий токен. Когда она пишет функцию, она продолжает наиболее вероятный текст, похожий на код. Из этого следуют три практических факта:
- Шаблонный код она пишет лучше вас. CRUD, парсинг, обвязка HTTP-клиента, регулярки, конфиги — здесь вероятность «правильного продолжения» высокая, потому что в обучающих данных таких примеров миллионы.
- Редкий и новый код она пишет плохо. Нестандартная архитектура, ваш внутренний фреймворк, API трёхлетней давности, нишевая библиотека — она будет уверенно сочинять, потому что уверенный тон статистически вероятнее осторожного.
- Она не «помнит» ваш проект. Она видит только то, что попало в контекст: открытые файлы, ваши сообщения, файл инструкций, результаты поиска по репозиторию.
Отсюда главный вывод курса: вы управляете не кодом, а контекстом и критериями. Чем точнее вы описываете, что должно получиться, тем меньше модель угадывает.
1.2 Почему длинный контекст портит результат
У модели есть окно контекста, и оно не резиновое. Когда в нём накапливаются 40 сообщений, три неудачные попытки фикса и логи на 2000 строк, качество ответов падает: модель начинает цепляться за старые ошибочные гипотезы и повторять неудачные решения.
Практические следствия: - Новая задача — новый чат. Всегда, если задача не продолжение текущей. - Не вставляйте файлы целиком, если можно указать путь и попросить прочитать. - Не держите в чате длинные логи: сначала сами найдите в них 5 ключевых строк. - Если две попытки провалились — перезапуск сессии с чистым описанием проблемы работает лучше, чем пятая попытка «починить».
1.3 Три режима работы с ИИ
| Режим | Что делает | Где полезен | Ограничение |
|---|---|---|---|
| Чат | Отвечает текстом | Объяснения, планы, ревью, обучение | Не видит проект, код копируется руками |
| Автодополнение | Дописывает строку/блок | Ручное набивание знакомого кода | Вы всё равно пишете сами |
| Агент | Читает файлы, правит, запускает команды | Весь курс | Может сломать много файлов за один шаг |
Курс построен на агенте (Claude Code, Cursor, Codex CLI, Windsurf). Отличие принципиальное: агент сам открывает файлы, сам применяет патчи, сам запускает тесты. Значит, ваша работа смещается — вы не печатаете, а ставите задачу, проверяете дифф и решаете, принимать или откатывать.
1.4 Где агент врёт особенно уверенно
Запомните этот список — он экономит дни:
- Названия методов и параметров API. Придумывает
client.fetchData()там, где реальноclient.get_data(). Лечится: документация или curl до кода. - Версии библиотек. Предлагает синтаксис из старой или несуществующей версии.
Лечится:
package.json/pyproject.tomlв контексте + «используй только API, доступные в этой версии». - Причины ошибок. Уверенно называет причину, не посмотрев лог. Лечится: «сначала прочитай стектрейс, потом гипотеза».
- «Готово, всё работает». Не запускал. Лечится: всегда просить вывод команды, а не утверждение о результате.
- Молчаливое изменение чужих файлов. Попутно «улучшил» три файла, которые вы не просили. Лечится: читать дифф, а не только сообщение.
1.5 Ваша роль в процессе
Вайбкодинг не отменяет инженерию, он переносит её на другой уровень:
- Было: придумать архитектуру → написать код → отладить → протестировать.
- Стало: описать, что должно получиться → разбить на шаги → принять или отклонить диффы → проверить результат.
Навыки, которые реально определяют качество: формулировка задачи, чтение диффа, проверка гипотез, дисциплина отката. Программирование в смысле «помнить синтаксис» почти не нужно. Понимание, что должно произойти — нужно абсолютно.
1.6 Итог модуля
- Модель предсказывает текст; точность зависит от вашего описания.
- Контекст — дефицитный ресурс; его надо чистить.
- Агент — основной инструмент; он делает много и может сломать много.
- Ваша работа: спека, дифф, проверка, коммит. Всё остальное — детали.
Модуль 2. Спека и постановка задачи
2.1 Почему спека решает больше, чем модель
Одна и та же модель на одной задаче даёт результат, отличающийся в разы, в зависимости от формулировки. Причина простая: без критериев приёмки модель оптимизирует «похоже на правильный ответ», а с критериями — конкретное проверяемое поведение.
Плохо: «напиши скрипт для обработки CSV».
Хорошо: «скрипт читает data.csv с колонками id,date,amount; отбрасывает строки
с amount ≤ 0; выводит в out.csv сумму по месяцам, отсортированную по убыванию;
при отсутствии колонки amount завершается с кодом 2 и сообщением в stderr».
Второй вариант агент может проверить сам. Первый — только вы, глазами.
2.2 Шесть блоков спеки
1. ЦЕЛЬ: что должно стать возможным после выполнения задачи (1-2 строки)
2. ПОЛЬЗОВАТЕЛЬ: кто и в какой ситуации это использует
3. ВХОДЫ/ВЫХОДЫ: форматы, примеры данных, edge-кейсы
4. ОГРАНИЧЕНИЯ: стек, версии, никаких новых зависимостей, не трогать файлы X
5. КРИТЕРИИ ПРИЁМКИ: список проверяемых утверждений, каждое — да/нет
6. ЧТО НЕ ДЕЛАЕМ: явные границы, чтобы агент не расширял объём
Блок 6 недооценивают, а он экономит больше всего: без него агент «за компанию» добавит авторизацию, кэш и Docker, потому что «так принято».
2.3 Критерии приёмки: главный рычаг
Критерий приёмки — утверждение, которое можно проверить командой или наблюдением.
- Не критерий: «код должен быть чистым», «UI должен быть удобным».
- Критерий: «при пустом списке показывается текст "Пока пусто"»,
«
npm testпроходит», «запрос с невалидным email возвращает 400».
Правило: если критерий нельзя проверить за 30 секунд, он сформулирован плохо. Хорошие критерии автоматически превращаются в тесты — это мост к модулю 6.
2.4 Формулировки, которые ломают результат
| Формулировка | Что происходит | Как переформулировать |
|---|---|---|
| «сделай красиво» | случайный дизайн, потом 10 итераций | «минималистичный, белый фон, один акцентный цвет, шрифт system-ui» |
| «как в Notion» | копия чужого продукта без ваших требований | перечислить 3 конкретных элемента, которые нужны |
| «оптимизируй» | микроправки без измерений | «сократи время ответа /api/search с 800 мс до <200 мс, замер через X» |
| «добавь обработку ошибок» | тихий except: pass |
«на 4xx показывать текст ошибки сервера, на 5xx — "попробуйте позже", оба случая покрыть тестом» |
| «отрефактори» | переписан весь проект | «вынеси валидацию из route в отдельный модуль, поведение не меняется, тесты проходят» |
2.5 Декомпозиция: размер шага
Ориентир по размеру задачи для агента:
- 15 минут — одна функция, один компонент, один эндпоинт. Дифф 30–80 строк. Такой шаг почти всегда проходит с первого раза.
- 1 час — фича целиком: модель данных + эндпоинт + минимальный UI. Требует разбиения на 3–4 шага, иначе дифф 400+ строк, который вы не проверите.
- 3+ часа — «сделай приложение». Почти гарантированно мусор: агент угадывает архитектуру, вы не можете проверить дифф, откат невозможен.
Правило: шаг должен быть таким, чтобы дифф читался за 5 минут. Если не читается — режьте.
2.6 Шаблон спеки (копировать)
## Цель
После задачи пользователь может <действие>, чтобы <ценность>.
## Пользователь и сценарий
Кто: <роль>. Когда: <ситуация>. Делает: <шаги>.
## Входы/выходы
Вход: <формат, пример>. Выход: <формат, пример>.
Edge-кейсы: <пусто>, <очень много>, <неверный тип>, <сеть недоступна>.
## Ограничения
Стек: <...>. Не добавлять зависимостей: <...>. Не менять файлы: <...>.
## Критерии приёмки
- [ ] <проверяемое утверждение 1>
- [ ] <проверяемое утверждение 2>
- [ ] <проверяемое утверждение 3>
## Что не делаем
- <явное исключение 1>
- <явное исключение 2>
2.7 /goal: цель как условие завершения
Обычный запрос заканчивается, когда модель решила, что закончила. /goal меняет
это: вы объявляете проверяемое условие, и агент продолжает работу ходами, пока
условие не выполнено. Проверяет не тот, кто работал, а отдельная быстрая модель —
она смотрит на то, что агент уже показал в сессии: вывод тестов, логи сборки,
список изменённых файлов.
/goal pytest tests/auth выходит с кодом 0, ruff check src/auth чист,
git diff --name-only показывает только src/auth/, или стоп после 15 ходов
Три части, без которых условие не работает:
- Измеримый конечный признак. Код возврата, пустая очередь, зелёный линт. Не «сделай чище» и не «чтобы было удобно» — это проверить нечем.
- Доказательство в сессии. Условие должно проверяться по тому, что агент
может показать прямо в чате. Если для проверки нужен ваш доступ к проду —
/goalне подходит. - Границы. Что нельзя менять (
только src/auth/) и лимит ходов (или стоп после 15 ходов). Без лимита автономный ход жжёт токены.
| Обычный запрос | /goal |
|
|---|---|---|
| Кто решает «готово» | та же модель, один ход | отдельный оценщик после каждого хода |
| Ходов | один, пока не перепишете | сколько нужно до выполнения условия |
| Где полезен | правка, разведка, вопросы | миграции, «пока тесты не зелёные», догон бэклога |
| Где вредит | — | субъективное качество, разведка, задачи без границ |
Практические следствия:
/goalне заменяет спеку, а опирается на неё. Критерий приёмки из блока 5 — это почти готовое условие. Если критерий нельзя проверить командой,/goalего не спасёт, а превратит в бесконечный цикл.- Один активный гол на сессию. Новый заменяет старый и сразу стартует ход. Клик по статусу показывает условие, время, число ходов, токены и причину последней оценки.
- Остановить и снять:
clear(синонимыstop,off,reset,cancel)./clearтоже снимает активный гол. - Требует доверенного рабочего пространства. Если хуки отключены
(
disableAllHooks), команда не работает. - Дорого не по токенам, а по числу ходов. Оценка идёт на дешёвой модели, а вот сами ходы — на полной. Лимит в условии обязателен.
- Автономность нужна не всегда. Ценность
/goal— в отсутствии «продолжай?» после каждого шага, а не в отказе от ревью. Дифф всё равно смотрите вы, а на неудачный автономный заход есть откат.
/goal есть в Claude Code и OpenAI Codex CLI. В Cursor и Windsurf его нет:
там роль цели играет план плюс явные критерии в запросе.
2.8 Итог модуля
- Спека — 10 строк, шесть блоков, критерии приёмки обязательны.
- Критерий приёмки = проверяемое да/нет, иначе это пожелание.
- Блок «что не делаем» ограничивает самовольное расширение объёма.
- Шаг, который не читается в диффе за 5 минут, слишком большой.
/goal— это тот же критерий приёмки, но в виде условия остановки агента.
Модуль 3. Цикл: промпт → диф → проверка → коммит
3.1 Анатомия рабочего запроса
Пять элементов, в этом порядке:
- Контекст: где мы, что уже есть, какие файлы важны. Ссылки на пути, не пересказ.
- Задача: одно действие в повелительном наклонении. Не два, не три.
- Ограничения: что нельзя менять, какие API использовать, какой стиль.
- Формат результата: «правь файлы напрямую», «сначала покажи план», «покажи только дифф», «добавь тест».
- Запрет на самодеятельность: «не рефактори ничего вне этой функции».
Пример:
> В src/api/orders.ts эндпоинт GET /orders возвращает все заказы без
> фильтра. Добавь query-параметр status (значения new, paid, cancelled),
> по умолчанию возвращать все. Невалидное значение → 400 с текстом
> unknown status. Только этот файл. Добавь тест на 400. Ничего не рефактори.
3.2 Чтение диффа: шесть красных флагов
Проверяйте каждый дифф по этому списку — 80% проблем ловится здесь:
- Удалённые или ослабленные проверки. Убрал
if (!user) return 401, заменил валидацию на «попробуем и посмотрим». Самая опасная категория. try/exceptвокруг всего. Тихая обработка, которая скрывает ошибку и превращает баг в «странное поведение».- Магические константы и хардкод.
if (id === 42), локальные путиC:\Users\..., зашитый ключ. - Правки файлов вне задачи. Агент «попутно улучшил» конфиг, зависимости, стили. Каждая такая правка — незапланированный риск.
- Новые зависимости. Новая библиотека ради одной функции — почти всегда плохой размен: вес, уязвимости, поддержка.
- Изменённые тесты. Тест подогнан под код, а не наоборот. Это то же самое, что удалить проверку.
Дополнительно: переписанный целиком файл там, где нужна была одна строка. Дифф на 500 строк вместо 5 — сигнал, что шаг был слишком большим.
3.3 Как проверять: три уровня
- Уровень 1 — запуск. Код стартует, команда отрабатывает без ошибок. Минимум, обязательно.
- Уровень 2 — поведение. Проверяете руками ровно те критерии приёмки, что записали в спеке. Не «вроде работает», а по пунктам.
- Уровень 3 — тест. Критерий превращён в автотест. Это цель модуля 6.
Если агент говорит «готово», а вы не прошли уровень 1 — ответ не принят. Требуйте вывод команды, а не утверждение.
3.4 Когда просить объяснить, а когда переделывать
- Просить объяснить: дифф выглядит разумно, но непонятно, почему выбрано такое решение. Полезно, дешево, часто вскрывает неверную гипотезу.
- Просить план: задача сложнее одного шага. «Покажи план из 4 шагов, правок не делай» — экономит откат.
- Переделывать сразу: красный флаг из списка 3.2, дифф вне задачи, «готово» без запуска, вторая попытка чинить то же место. Объяснения тут не помогут.
Правило двух попыток: если вторая попытка исправить то же место тоже провалилась — откат и переформулировка задачи. С третьей попытки агент закрепляет неверную модель проблемы.
3.5 Коммит как инструмент, а не формальность
- Коммит после каждого принятого шага. Точка отката стоит 5 секунд, отладка сломанного микса — час.
- Сообщение коммита пишет вы, не агент:
feat(orders): фильтр по статусу, тест на 400— через месяц вы поймёте, что произошло и зачем. - Не коммитить: секреты,
node_modules,.env, локальные конфиги — это в.gitignoreдо первогоgit add. - Один коммит = одна причина изменения. «Фича + переформатирование всего проекта» в одном коммите — гарантированный конфликт и нечитаемый дифф.
3.6 Итог модуля
- Рабочий запрос: контекст, задача, ограничения, формат, запрет на лишнее.
- Дифф читается по шести красным флагам; тесты и проверки — неприкосновенны.
- Проверка: запуск → поведение по критериям → автотест.
- Два провала подряд = откат, не третья попытка.
- Коммит после каждого принятого шага, сообщение пишете вы.
Модуль 4. Контекст: как агент видит ваш проект
4.1 Что попадает в контекст
Агент работает с тем, что ему доступно в сессии:
- ваши сообщения и его предыдущие ответы;
- файлы, которые он прочитал или которые открыты;
- файл инструкций проекта (читается автоматически);
- результаты его собственных команд: вывод тестов, логи, ошибки;
- авто-поиск по репозиторию, если вы дали путь, а не текст.
Чего в контексте нет: вашей головы. Стек, конвенции, «мы так не делаем»,
причина, по которой нельзя трогать legacy/ — всё это надо явно записать.
4.2 Файл инструкций проекта
Один файл в корне репозитория. Имена зависят от инструмента: CLAUDE.md,
AGENTS.md, .cursorrules, .github/copilot-instructions.md. Содержание:
# Проект: <название>
Назначение: <одна строка>
## Стек
Node 20, TypeScript strict, Fastify, PostgreSQL 16, vitest.
Python 3.12 для скриптов в /tools.
## Команды
- запуск: npm run dev
- тесты: npm test
- линт: npm run lint (обязателен перед коммитом)
## Правила
- TypeScript strict: никаких any без комментария-обоснования
- Ошибки API: 4xx с текстом, 5xx без внутренних деталей
- Новые зависимости только с согласия: сначала предложи, потом ставь
## Запреты
- не менять /legacy/** без явного указания
- не править тесты, чтобы они проходили
- не трогать .env, миграции и CI-конфиги
Этот файл — самая высокая отдача на вложенную минуту во всём курсе. Один раз написали — каждый следующий запрос короче на треть.
4.3 Почему агент «забывает» и «глупеет»
Качество падает не из-за «усталости модели», а из-за контекста:
- 40+ сообщений: старые ошибочные гипотезы конкурируют с новыми фактами.
- Большие файлы и логи целиком: полезное тонет, модель цепляется за случайное.
- Смешение задач: правки по фиче A и фиче B в одном чате дают диффы, которые невозможно разделить и откатить.
- Пересказ вместо ссылки: вы описываете код словами — модель домысливает.
Лечение: новый чат на новую задачу; путь к файлу вместо содержимого; 5 ключевых строк лога вместо 2000; явное «мы закончили с A, начинаем B» с чистого листа.
4.4 Приёмы управления контекстом
- План до правок. «Покажи план из 5 шагов, ничего не меняй» — ловите неверное понимание до того, как появился дифф.
- Один файл за шаг. «Сейчас только
parser.py, остальное потом». - Явная передача состояния. «Итог: сделан X, Y, осталось Z» — когда продолжаете в новом чате.
- Точечная цитата. Приводите 5–10 строк кода вместо файла целиком.
- Сброс. Две неудачи — новый чат + минимальное описание проблемы + стектрейс.
4.5 Итог модуля
- В контекст попадает только явно сказанное; остальное модель домысливает.
- Файл инструкций — обязательный элемент проекта, а не роскошь.
- Деградация качества = замусоренный контекст, а не «плохая модель».
- Новый чат на новую задачу; план до правок; один файл за шаг.
Модуль 5. Отладка, когда агент ходит по кругу
5.1 Три круга ада
- Угадывание причины. Агент видит симптом и сразу называет причину, не посмотрев лог. Правка мимо, симптом остаётся.
- Лечение симптома. «Ошибка не появляется» — потому что добавлен
catch, который её глотает. Причина жива. - Порча соседнего. Правка работает, но ломает другой сценарий; следующая правка ломает первый. Классический пинг-понг.
Все три лечатся одним правилом.
5.2 Правило одного факта
Сначала воспроизводимый минимальный кейс, потом правка.
Порядок обязательный:
1. Команда, которая стабильно воспроизводит проблему (или точные шаги в UI).
2. Полный текст ошибки / стектрейс — в контекст.
3. Гипотеза, сформулированная как проверяемое утверждение: «если проблема в
пустом массиве, то [] в запросе даст тот же стектрейс».
4. Проверка гипотезы до правки: лог, точка останова, console.log, curl.
5. Только после подтверждения — правка.
Без шага 3 агент правит всё, что похоже на причину. Обычно это 3–4 файла, из которых 2 были в порядке.
5.3 Как заставить агента смотреть, а не фантазировать
Формулировки, которые работают:
- «Сначала прочитай
npm testвывод целиком и процитируй 3 строки, где падает. Гипотезу не предлагай, пока не процитируешь.» - «Предложи 3 гипотезы. Для каждой — команда, которая её подтвердит или опровергнет. Правок не делай.»
- «Объясни, что именно ты проверил и что осталось непроверенным.»
- «Вот стектрейс. Какая строка нашего кода в нём участвует?»
Формулировки, которые не работают: «починить», «исправь ошибку», «не работает, разберись» — они дают карт-бланш на угадывание.
5.4 Когда откатывать
Откат дешевле починки, если:
- две попытки подряд не сдвинули симптом;
- дифф расползся на файлы, которых не было в задаче;
- агент начал «попутно рефакторить» место бага;
- вы не понимаете, что происходит в диффе.
Процедура: git stash или git reset --hard HEAD, затем переформулированная
задача с новым фактом (стектрейс, минимальный кейс, версия библиотеки). Не та же
самая формулировка — иначе результат повторится.
5.5 Специфика ИИ-отладки
- Ложные «исправления»: код меняется, ошибка уходит из этого сценария и всплывает в соседнем. Проверяйте не только кейс, но и соседний сценарий.
- Исправление версии: агент часто предлагает синтаксис не той версии
библиотеки. Проверяйте
package.json/pyproject.toml. - Тихие ошибки:
except Exception: passпревращает падение в неверные данные. Это хуже падения — ищите такие места в диффе всегда. - Фикс без теста: без теста баг вернётся. Каждый фикс — плюс один тест (мост к модулю 6).
5.6 Итог модуля
- Сначала воспроизведение и факт, потом гипотеза, потом правка. Не наоборот.
- «Починить» — плохой промпт; «процитируй стектрейс и предложи 3 проверяемые гипотезы» — хороший.
- Две неудачи подряд = откат и новая формулировка.
- Фикс без теста не считается закрытым.
Модуль 6. Тесты и защита от регрессий
6.1 Тест = критерий приёмки в исполняемом виде
Критерий «при пустом списке показывается "Пока пусто"» можно обмануть словами.
Тест expect(render([])).toContain('Пока пусто') обмануть нельзя: он либо
проходит, либо нет.
Для вайбкодинга это критично, потому что агент оптимизирует под текст задачи. Если критерий только в тексте, он может «выполнить» его формально. Тест — это спецификация, которую нельзя переформулировать в свою пользу.
6.2 Какие тесты писать (и сколько)
Пирамида, адаптированная под ИИ-разработку:
- 70% юнит — чистые функции: парсинг, валидация, расчёты, форматирование. Быстрые, стабильные, ловят основную массу регрессий от правок агента.
- 20% интеграционные — один эндпоинт или один компонент с моками. Проверяют склейку: правильный ли код ответа, что пришло в базу.
- 10% e2e — один-два сквозных сценария: «пользователь открыл, ввёл, увидел». Дорогие и хрупкие; больше двух-трёх на проект в этом курсе не нужно.
Не писать: снимки UI (snapshot) в начале проекта — агент меняет вёрстку, вы получаете 50 падающих снимков и начинаете их «обновлять», то есть отключать проверку. Не писать тесты на геттеры и на фреймворк.
6.3 Почему тест до кода
Агент, которому дали тест, работает принципиально иначе, чем агент с текстовым описанием: у него есть обратная связь. Цикл становится механическим:
- Пишем тест на поведение, которого нет.
- Запускаем — тест падает (обязательно проверяем, что падает по правильной причине: не «модуль не найден», а «ожидалось X, получено Y»).
- Просим реализацию.
- Запускаем — проходит.
- Просим сломать реализацию — тест должен упасть. Если не упал, тест бесполезен.
Шаг 5 — самый недооценённый. Он отделяет настоящую проверку от декоративной.
6.4 Запрет на правку тестов
Самая частая деградация в вайбкодинге: агент не может пройти тест и меняет тест. Формулировка для файла инструкций и для запроса:
> Тесты — спецификация. Если тест падает, чини реализацию. Менять тест можно > только если я явно попросил, и тогда сначала объясни, почему старое ожидание > было неверным.
Проверка в диффе: любое изменение в *.test.* / test_*.py без вашего запроса —
красный флаг №1.
6.5 Покрытие как метрика-обманка
100% покрытия строк достижимо без единой осмысленной проверки: тест вызывает функцию и не проверяет результат. Полезнее смотреть не на процент, а на вопросы:
- Покрыт ли главный сценарий? (обязательно)
- Покрыты ли границы: пусто, очень много, неверный тип, нет сети? (обязательно)
- Есть ли тест на каждый баг, который вы уже поймали? (обязательно)
- Есть ли тест на каждую строку? (не важно)
6.6 Итог модуля
- Тест — единственный критерий приёмки, который нельзя обойти формулировкой.
- 70/20/10: юнит — интеграционные — e2e; снимков UI избегать.
- Тест до кода, проверка «падает по правильной причине», мутационная проверка.
- Тесты не правит агент. Точка.
- Покрытие — не цель; цель — покрытые границы и пойманные баги.
Модуль 7. Данные, API, окружение, безопасность
7.1 Секреты
- Ключи только в
.env,.env— в.gitignoreдо первого коммита. - В репозитории лежит
.env.exampleс именами переменных и пустыми значениями. - Код читает конфиг из окружения; хардкод ключа в коде — красный флаг.
- Ключ, попавший в историю git, считается скомпрометированным:
git rmфайла не удаляет его из истории. Нужен отзыв ключа (rotate), а не «удалили файл». - На хостинге переменные задаются в панели, а не в коде; локальный
.envи прод-переменные — разные наборы.
7.2 Агент и внешние API: где он врёт
Три типовые галлюцинации:
- Несуществующий метод/эндпоинт. Уверенно пишет
api.getUserByEmail(). - Устаревший параметр. Использует
?limit=там, где теперь?page_size=. - Выдуманные поля ответа. Читает
data.items, хотя реальноdata.results.
Процедура, которая закрывает 90% проблем:
- Открыть документацию (или
openapi.json/swagger). - Сделать
curlруками и посмотреть реальный ответ. - Вставить реальный ответ (сокращённый) в контекст: «вот форма ответа, используй только эти поля».
- Только потом просить клиент и обработку ошибок.
7.3 Валидация на границе
Любые данные извне — пользовательский ввод, ответ API, файл, переменная окружения — недоверенные. Валидировать на входе, один раз, в одном месте:
- схема (zod/pydantic) вместо ручных
if; - проверка обязательных полей и типов;
- явное поведение на невалидных данных: 400 с понятным текстом, не падение;
- тесты на «пусто», «не тот тип», «слишком длинно».
Типы в TypeScript/Python — дешёвая защита внутри кода, но не замена валидации
на границе: данные из сети приходят как any / dict.
7.4 Что нельзя отдавать агенту
- Прод-базу и прод-дампы. Локальная копия или фикстуры.
- Приватные данные пользователей, чужие токены, внутренние URL.
- Пароли, приватные ключи, сертификаты.
- Репозитории под NDA без проверки политики компании.
Проверка перед отправкой: «если это сообщение попадёт в публичный лог, будет проблема?» Если да — не отправлять.
7.5 Итог модуля
.env+.gitignore+.env.example; ключ в истории = отзыв ключа.- Сначала curl и реальный ответ API, потом код.
- Валидация на границе и тесты на плохие данные.
- Секреты, прод и персональные данные в контекст не попадают.
Модуль 8. Деплой, git-гигиена, командная работа
8.1 Ветки и маленькие PR
- Основная ветка защищена: прямых пушей нет даже у вас.
- Каждая задача — ветка, каждое изменение — PR. Даже если вы работаете один: PR — это место, где виден дифф и где можно откатить одним нажатием.
- PR на 100–300 строк ревьюится; на 1500 — «одобряю не глядя», то есть не ревьюится вообще. Дробите.
- Агент работает на ветке: испорченная ветка не трогает рабочий main.
8.2 Сборка и прод-окружение
«У меня работает» ≠ «задеплоилось». Различия, которые ловят на деплое:
- переменные окружения: локально есть, на хостинге не заданы;
- версия рантайма: локально Node 22, на хостинге 18;
- регистр в путях: Windows прощает
Components/Button, Linux — нет; - зависимости:
devDependenciesне ставятся в прод-сборке; - файловая система: локально можно писать в
./data, на serverless — нет.
Практика: первый деплой делается до того, как проект готов, — на пустом или почти пустом приложении. Так вы отделяете проблемы окружения от проблем кода.
8.3 Логи, мониторинг, откат
- Логи — единственный источник правды о проде; без них отладка невозможна.
- Ошибка в проде: сначала логи и статус-код, потом гипотезы (то же правило одного факта, что в модуле 5).
- Откат:
revertкоммита или редеплой предыдущей версии. Умение откатиться за 2 минуты важнее умения не ошибаться. - Никогда не «чинить в проде руками»: правка идёт через ветку и деплой, иначе состояние прода не соответствует репозиторию.
8.4 Ревью ИИ-кода: что смотрит человек
Чек-лист, 12 пунктов, по приоритету:
- Удалённые или ослабленные проверки и валидация.
- Изменённые тесты без запроса.
- Тихая обработка ошибок (
catch/exceptбез действий). - Секреты, ключи, токены, локальные пути.
- SQL-запросы: конкатенация вместо параметров.
- Проверка прав доступа там, где она была.
- Новые зависимости: нужны ли, что тянут.
- Граничные случаи: пусто, очень много, неверный тип.
- Логика денег, дат, часовых поясов, округлений.
- Правки файлов вне задачи.
- Читаемость: поймёте ли вы это через месяц.
- Соответствие спеке: все критерии приёмки закрыты.
Пункты 1–4 проверяются за минуту и ловят большинство реальных проблем.
8.5 Сообщения коммитов и описания PR
- Коммит:
тип(область): что сделано— напримерfix(orders): 400 на неизвестный статус. - PR: что меняется, зачем, как проверить (шаги), что не входит в объём.
- Отдельно: «какие компромиссы приняты» — через месяц это спасёт от неверных выводов.
8.6 Итог модуля
- Ветка + PR на каждую задачу; main защищён.
- Первый деплой — рано, чтобы отделить окружение от кода.
- Откат — навык; отлаживать только по логам.
- Ревью ИИ-кода: сначала проверки, тесты, ошибки, секреты — потом всё остальное.
Модуль 9. Капстоун: разбор перед сборкой
9.1 Как выбрать проект
Критерий: высокая ценность для вас / низкая неизвестность для агента. Плохой выбор — «клон Airbnb»: огромная неизвестность, нулевая личная ценность. Хороший — «утилита, которая парсит мой экспорт из банка и считает категории»: мало неизвестности, высокая ценность, есть реальные данные для проверки.
9.2 Четыре шага сборки
Каждый шаг заканчивается чем-то запускаемым:
- Скелет. Репозиторий,
.gitignore,.env.example, файл инструкций, «Hello world» на нужном стеке. Проверка: запускается локально. - Ядро. Главный сценарий end-to-end на минимальных данных. Проверка: сценарий проходит целиком.
- Обвязка. Обработка ошибок, один-два теста на главный сценарий, README. Проверка: тесты проходят, README позволяет запустить с нуля.
- Деплой. Публичная ссылка, переменные окружения на хостинге, проверка с телефона. Проверка: ссылка открывается и работает.
9.3 Что вырезать из MVP
Резать без жалости: авторизацию (если не в ней суть), админку, тёмную тему, настройки, экспорт, мультиязычность, «красиво». Первая версия доказывает, что главный сценарий работает. Всё остальное — после ссылки.
9.4 Чек-лист сдачи
git clone+ инструкция из README → приложение запускается с нуля- Главный сценарий проходит на реальных данных
- Есть минимум один тест на главный сценарий,
npm testзелёный - Публичная ссылка живая, проверена не только на своём браузере
- Секретов в репозитории нет,
.env.exampleактуален - Файл инструкций проекта на месте
- История коммитов читается: по ней понятно, что и зачем делалось
- Известные ограничения записаны в README
9.5 Итог курса
Навык, который вы получили, — не «умение писать код с ИИ». Это умение доводить неопределённую задачу до проверяемого результата: спека, маленькие шаги, чтение диффа, тесты, откат, деплой. Модели будут меняться, этот цикл — нет.