Klepa AI
Установить
Часть 5 · Большие проекты · Урок 9

Агент в старом проекте: как подготовить legacy и внедрять постепенно

AI-First — это не «подключить чат к IDE». Это сделать проект понятным и проверяемым, чтобы агент мог в нём работать. Разберём паттерны для старых проектов и порядок внедрения.

~50 минут 4 интерактива 2 песочницы с проверками Примеры: JS · PHP · Python · Markdown

После урока вы сможете

  • оценить, насколько ваш проект готов к работе с агентами;
  • назвать семь паттернов, которые делают legacy понятным для агента;
  • составить план внедрения: какие задачи давать агенту первыми, а какие позже;
  • заменить старый модуль по частям, не останавливая систему.
1 Аналогия

Склад переходит на роботов

Представьте

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

Разметка полоккарта проекта, правила
Датчикитесты, линтер, CI
Робот на простом участкебезопасные задачи
Расширениебольше задач и агентов
Порядок важен: каждый шаг опирается на предыдущий.
Разметка и схема склада= AGENTS.md, README модулей, карта сервисов
Датчики на полках= тесты, типы, линтер — агент видит, что сломал
Простой участок= тесты, документация, мелкие баги
Хаотичный склад= legacy без тестов, где всё связано со всем

Агент работает так же хорошо, как хорошо устроена среда вокруг него. В понятном проекте с быстрыми проверками он полезен. В хаосе — опасен.

2 Объяснение

От простого к сложному

Уровень 1 · Суть

Агенту нужны карта и обратная связь

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

Две вещи решают почти всё:

  • Карта. Где модули, какие правила, что нельзя трогать. Это файл правил для агента и короткие README.
  • Обратная связь. Одна команда, которая за минуты говорит: «всё хорошо» или «сломано вот тут». Тесты, линтер, проверка типов.
ПримерЗадача: «почини расчёт скидки». В проекте без тестов агент поправит формулу и скажет «готово». Проверить нечем. В проекте с тестами он запустит их, увидит красный тест про скидку для оптовиков и исправит до того, как вы откроете PR.
Уровень 2 · Детали

Семь паттернов AI-First

  1. Карта проекта и правила. AGENTS.md (или CLAUDE.md) в корне: как запустить, как проверить, правила кода, запреты. Короткие README в ключевых модулях.
  2. Быстрая обратная связь. Одна команда make check или composer check: тесты, линтер, статический анализ. Чем быстрее, тем чаще агент её запускает.
  3. Характеризационные тесты. Перед правкой старого кода фиксируем, как он работает сейчас, даже если странно. Агент правит — тест показывает, что поведение не уехало.
  4. Границы модулей и контракты. Чем меньше модуль связан с остальными, тем меньше контекста нужно агенту и тем меньше он сломает.
  5. Генераторы для шаблонного. CRUD, DTO, клиенты API делает генератор, а не агент (урок 6). Быстрее, дешевле, одинаково.
  6. Спецификации для изменений. Новая функциональность начинается со спеки, а не с «сделай фичу» (урок 5).
  7. Постепенное внедрение. Сначала безопасные задачи, потом средние, потом сложные. На каждом шаге — метрики.
Пример AGENTS.md для legacy-проекта — шаблон

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

# Магазин — правила для агента

## Запуск и проверка
- Поднять: `docker compose up -d`
- Проверить всё: `make check` (тесты + PHPStan + php-cs-fixer, ~3 мин)
- Один тест: `vendor/bin/phpunit --filter ИмяТеста`

## Карта
- `src/Order/` — заказы и расчёт цены. Владелец: команда Checkout.
- `src/Billing/` — платежи. Любая правка — только с тестом.
- `legacy/` — старый код. Не рефакторить без характеризационных тестов.

## Правила
- Деньги — только в копейках (int), никаких float.
- Миграции БД не писать без отдельной задачи.
- Не трогать `config/secrets/` и `.env`.

## Готово, если
- `make check` зелёный;
- на новое поведение есть тест;
- в описании PR — что и зачем изменено.
Одна команда «проверь всё» — PHP, JS, Python
{
  "scripts": {
    "test": "phpunit",
    "stan": "phpstan analyse --no-progress",
    "cs": "php-cs-fixer fix --dry-run --diff",
    "check": ["@cs", "@stan", "@test"]
  }
}
{
  "scripts": {
    "lint": "eslint .",
    "typecheck": "tsc --noEmit",
    "test": "vitest run",
    "check": "npm run lint && npm run typecheck && npm test"
  }
}
.PHONY: check
check:
	ruff check .
	mypy src
	pytest -q

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

Уровень 3 · Усложнение

Как внедрять, не ломая систему и команду

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

Удушающее дерево (strangler fig). Старый модуль не переписывают целиком. Ставят перед ним фасад и по одной функции переносят в новый код. Новый код агент пишет по спеке и с тестами, старый тем временем продолжает работать.

Метрики внедрения. Сколько задач решено с агентом, время от задачи до PR, доля откатов и регрессий, стоимость на задачу. Если откатов стало больше — притормозите и усильте проверки.

Люди и процесс. За код агента отвечает человек, который открыл PR. Ревью остаётся. Команде нужно обучение: как ставить задачи, как читать сессию агента, когда остановить его.

Анти-паттерныАгенту дали доступ к проду. «Большой взрыв»: переписать всё за месяц агентами. Внедрение без тестов: агент быстро производит код, который никто не может проверить.
Характеризационный тест — PHP, Python, JS

Мы не знаем, правильно ли старый код считает доставку. Но знаем, что сейчас клиенты платят именно так. Фиксируем текущие ответы на реальных входах. Потом агент рефакторит — тест следит, чтобы ничего не уехало.

<?php
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;

final class LegacyShippingCharacterizationTest extends TestCase
{
    // Значения сняты с текущего прода. Странное (бесплатно при 0 кг) — тоже фиксируем.
    public static function cases(): iterable
    {
        yield 'лёгкая посылка' => [0.5, 'MINSK', 350];
        yield 'тяжёлая посылка' => [12.0, 'MINSK', 1890];
        yield 'регион' => [2.0, 'BREST', 790];
        yield 'вес 0 — так сейчас' => [0.0, 'MINSK', 0];
    }

    #[DataProvider('cases')]
    public function testKeepsCurrentBehaviour(float $kg, string $city, int $expectedKopecks): void
    {
        self::assertSame($expectedKopecks, legacy_calc_shipping($kg, $city));
    }
}
import pytest
from legacy.shipping import calc_shipping

# Значения сняты с текущего поведения. Не «как должно быть», а «как есть».
@pytest.mark.parametrize("kg, city, expected", [
    (0.5, "MINSK", 350),
    (12.0, "MINSK", 1890),
    (2.0, "BREST", 790),
    (0.0, "MINSK", 0),   # странно, но так сейчас работает прод
])
def test_keeps_current_behaviour(kg, city, expected):
    assert calc_shipping(kg, city) == expected
import { test } from "node:test";
import assert from "node:assert/strict";
import { calcShipping } from "../legacy/shipping.js";

const cases = [
  [0.5, "MINSK", 350],
  [12.0, "MINSK", 1890],
  [2.0, "BREST", 790],
  [0.0, "MINSK", 0], // фиксируем как есть
];

for (const [kg, city, expected] of cases) {
  test(`доставка ${kg} кг в ${city}`, () => {
    assert.equal(calcShipping(kg, city), expected);
  });
}
3 Интерактив

Оцените свой проект и спланируйте внедрение

Насколько проект готов к агентам

интерактив 1 из 4

Ответы заполнены примером «типичный legacy-проект». Поменяйте их под свой проект и нажмите «Оценить».

Лестница внедрения: какие задачи и когда

интерактив 2 из 4
1. Чтениеобъяснить, найти
→
2. Безопасные правкитесты, доки, мелкие баги
→
3. Фичи по спекесредние задачи
→
4. Сложноеденьги, миграции
Нажмите «Дальше», чтобы подняться на ступень.

Что дают вложения в проект

интерактив 3 из 4

Двигайте ползунки и давайте агенту 50 задач. Модель — иллюстрация: коэффициенты подобраны, чтобы показать направление, а не точные цифры.

решеноне решено, видно сразу«решено», но сломано незаметно
—решено
—не решено
—скрытых регрессий

Strangler fig: заменяем модуль скидок по частям

интерактив 4 из 4
Фасад (роутер)
Старый монолит
скидки внутри OrderService, 2 000 строк
Новый модуль скидок
по спеке, с тестами
старый 100%
Нажмите «Дальше».
4 Практика

Песочницы с автопроверкой

Код выполняется в браузере. Ctrl+Enter — запуск. Ваш код сохраняется.

Песочница 1. Оценка готовности проекта

JS

Ответы — числа 0 (нет), 1 (частично), 2 (да) по областям. Уже объявлены константы WEIGHTS (вес области) и PLAN_STEPS (первый шаг для области). Посчитайте оценку и план.

const WEIGHTS = { docs: 2, tests: 3, feedback: 2, modules: 1, safety: 3, env: 1 };
const PLAN_STEPS = { docs: '…', tests: '…', feedback: '…', modules: '…', safety: '…', env: '…' };

Песочница 2. Разложить бэклог на волны

JS

Решите, какие задачи давать агенту сначала. Риск задачи: деньги +3, миграции +2, размер S/M/L — +0/+1/+2, нет тестов +2. Волна 1 — риск 0–1, волна 2 — риск 2–3, волна 3 — риск 4 и выше (там нужна спека и человек).

Проверьте себя

Команда решила внедрять агентов в старый проект. С чего начать?

Без карты агент блуждает, без проверок — ломает незаметно. Это фундамент, на котором работают все следующие шаги.

Что такое характеризационный тест?

Мы не всегда знаем, как «правильно». Но знаем, как работает сейчас. Тест не даст агенту случайно это поменять.

Как работает паттерн strangler fig?

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

Какая метрика первой покажет, что внедрение агентов вредит?

Объём кода и активность ничего не говорят о качестве. Откаты и регрессии — прямой сигнал, что проверки слабее, чем скорость.

Задание на своём проекте — 1 час
  1. Пройдите самооценку выше честно. Запишите три самые слабые области.
  2. Напишите первую версию AGENTS.md по шаблону из урока. Не больше 40 строк.
  3. Сделайте команду check. Засеките, сколько она идёт.
  4. Возьмите 10 задач из бэклога и разложите на волны функцией из песочницы 2. Первую задачу из волны 1 отдайте агенту.
5 Чек-лист

Отметьте, что усвоили

  • Понимаю: AI-First — это понятный и проверяемый проект, а не чат в IDE.
  • Знаю, что писать в AGENTS.md и почему он должен быть коротким.
  • У меня есть или я знаю, как сделать одну команду «проверь всё».
  • Могу объяснить, зачем характеризационные тесты перед правкой legacy.
  • Знаю порядок внедрения: чтение, безопасные правки, фичи по спеке, сложное.
  • Могу объяснить strangler fig на примере.
  • Знаю анти-паттерны: прод-доступ агенту, «большой взрыв», внедрение без тестов.
Урок пройденПроект готов к агентам. Остался последний шаг — много агентов и много репозиториев сразу.