Инструменты и рабочие процессы: Cursor, CLAUDE.md, харнессы и автоматизация
Почему два разработчика с одинаковыми навыками получают от AI-модели принципиально разный результат? Один тратит часы на переписывание сгенерированного кода, другой — получает работающий модуль за два запроса. Разница не в модели и не в «удачном промпте». Разница в инструментальной среде, которую каждый из них выстроил вокруг агента. Именно об этом — рабочие процессы агентной инженерии.
CLAUDE.md: онбординг-документ для AI-агента
Промпт-инженерия работает на уровне отдельного запроса. Но каждый раз заново прописывать стек, архитектуру и правила проекта — нереально. Всё, что ты пишешь руками в промпте, можно зафиксировать один раз в конфигурационном файле, и агент будет загружать его автоматически.
CLAUDE.md — это не документация и не README. Это онбординг для AI-агента. Точно так же, как ты вводишь нового разработчика в проект — объясняешь архитектуру, показываешь паттерны, предупреждаешь о граблях — ты делаешь это для модели. Один раз. Дальше агент читает этот файл перед каждой задачей и работает в рамках твоих правил.
Аналогичные механизмы есть в других средах: Cursor использует .cursorrules, Windsurf — .windsurfrules, Copilot — .github/copilot-instructions.md. Принцип одинаковый, формат файла отличается.
Структура из пяти секций
Рабочий CLAUDE.md строится по шаблону, который покрывает 90% ситуаций:
Проект — краткое описание, стек, архитектура. Одним абзацем: «SaaS-платформа. Next.js 15, Prisma, PostgreSQL, мультисхемная архитектура».
Структура директорий — где что лежит. src/app/api/ — роуты, src/models/ — схемы, src/components/ — компоненты. Агент должен знать, куда класть новый файл.
Паттерны кода — один-два примера типичного эндпоинта или компонента. Не описание, а реальный фрагмент. Модель копирует стиль из примера.
Правила — что делать всегда: async/await вместо промисов, валидация через Zod, формат ошибок, согласование новых зависимостей.
Запрещено — что не делать никогда: any в TypeScript, console.log в продакшене, прямые SQL-запросы, изменение ядра без явного указания.
Аналогия из жизни: CLAUDE.md — это как памятка новому сотруднику на первом рабочем дне. Не энциклопедия на 500 страниц, а лист А4 с ключевыми правилами, контактами и «вот тут — грабли, не наступи».
Три ошибки, которые убивают эффективность
Слишком длинный. Больше 1000 строк сложно поддерживать в актуальном состоянии. Чем больше правил — тем чаще они противоречат друг другу, и модель начинает выбирать между конфликтующими инструкциями. Держи документ компактным.
Слишком абстрактный. «Пиши чистый код» — бесполезно. «Каждый API-эндпоинт возвращает { data, error, meta } — вот пример» — работает. Без реальных фрагментов кода CLAUDE.md превращается в корпоративную миссию на стене.
Устаревший. Переименовали директорию, сменили ORM, обновили фреймворк — а CLAUDE.md описывает прошлую архитектуру. Агент будет генерировать код для проекта, которого больше нет.
> Начните с 50 строк. Запустите агента, посмотрите, где он ошибается. Добавьте правило. Снова ошибся — добавьте пример. Через неделю у вас будет рабочий документ, выросший из реальных проблем. CLAUDE.md — живой артефакт, не высеченный в камне манифест.
>
> codenrock.com
Model Context Protocol: мост между агентом и реальным миром
CLAUDE.md даёт агенту знания о проекте. Но чтобы агент мог действовать — создавать задачи, отправлять письма, запрашивать данные из базы — ему нужен протокол взаимодействия с внешним миром. Это Model Context Protocol (MCP).
Архитектура: три роли
MCP разделяет агента на три компонента:
Host — приложение, в котором живёт агент: IDE, терминальный клиент или кастомное приложение. Host управляет жизненным циклом и принимает решение, какой инструмент вызвать.
Client — компонент внутри Host, который держит соединение с конкретным сервером. Один Host содержит несколько Client.
Server — отдельный процесс, предоставляющий возможности: доступ к файлам, базам данных, API-сервисам. Сервер описывает свои инструменты, и Client получает эти описания при подключении.
При запуске нового агента по протоколу MCP происходит следующее: Client отправляет на известные ему сервера дискавери-запрос — получает список доступных инструментов с описаниями и схемами параметров. Эти описания записываются в системный промпт агента. Когда пользователь задаёт вопрос, модель читает список инструментов и решает, какой вызвать. Client отправляет запрос нужному Server, получает результат и возвращает его в Host.
Три примитива MCP
Tools — функции, которые агент вызывает: создать задачу, выполнить SQL-запрос, отправить письмо. Это основной примитив; подавляющее большинство серверов используют только tools.
Resources — данные для чтения без побочных эффектов: файлы, конфиги, состояние системы. Resources нужны, когда агенту важно увидеть текущее состояние перед принятием решения.
Prompts — шаблоны для типовых сценариев. Используются реже, но полезны для стандартизации повторяющихся задач.
Транспорт
Два варианта. stdio — для локальных серверов: хост запускает процесс и общается через stdin/stdout. Просто, быстро, без сети. Streamable HTTP — для удалённых серверов: HTTP-запросы с стримингом через Server-Sent Events. Подходит для облачных деплоев.
Под капотом — JSON-RPC 2.0. Каждый вызов инструмента — пара запрос/ответ. Всё типизировано через JSON Schema — модель точно знает, какие аргументы передать.
Как агент выбирает инструмент
Ключевой момент: описание инструмента — это промпт для модели, а не комментарий для человека. Описание «работает с данными» бесполезно. Описание «Возвращает список открытых задач проекта. Принимает статус фильтрации. Если задач нет — пустой массив» — работает. Плохое описание = tool не будет вызван, даже если он делает именно то, что нужно.
Три грабли при создании MCP-серверов
Абстрактные описания. «Работает с задачами» — агент не поймёт. «Добавляет задачу в TODO-список. Принимает название и приоритет. Возвращает ID» — поймёт сразу.
Нет error handling. Когда tool падает с необработанным исключением, агент получает stack trace и пытается его «починить» — обычно делая хуже. Оборачивай в try/catch и возвращай понятное сообщение.
Переусложнённые параметры. Tool с 10 обязательными полями — лабиринт. Агент запутается и начнёт галлюцинировать значения. Лучше пять простых tools, чем один универсальный.
Харнессы: упряжь для AI-агента
Харнес (harness) — это программная оболочка, которая управляет жизненным циклом AI-агента: запускает, контролирует, ограничивает и верифицирует его работу. Если агент — лошадь, то харнес — упряжь, которая направляет её силу в нужное русло.
Харнес решает три задачи:
Контроль выполнения. Ограничение по времени, количеству итераций, потреблённым токенам. Если агент «залип» на задаче — харнес прерывает его.
Санбоксинг. Запуск сгенерированного кода в изолированной среде: контейнере, песочнице, временном worktree. Агент может экспериментировать свободно, но не навредит основному проекту.
Верификация результата. Автоматический прогон тестов, линтеров, проверки типов после каждого шага агента. Если результат не проходит проверку — харнес возвращает агенту ошибку с контекстом.
На практике харнес — это набор скриптов и конфигураций, которые оборачивают вызовы агента. Например, перед запуском агента харнес создаёт временную ветку git, после завершения — прогоняет тесты, и только при успехе предлагает создать pull request.
Git Worktrees: параллельная работа без конфликтов
Одна из неочевидных проблем AI-разработки: агент занят долгой задачей в одной ветке, а тебе нужно параллельно делать что-то в другой. Переключать ветки нельзя — агент работает с файлами. Клонировать репозиторий заново — долго и неудобно.
Git worktree — это дополнительная рабочая копия того же репозитория, привязанная к другой ветке. Один .git, несколько директорий с кодом. Каждая может быть открыта в своей сессии AI-агента одновременно.
Создать worktree: git worktree add ../my-project-feature feature/new-api. Теперь в ../my-project-feature — полная копия проекта на ветке feature/new-api. Открываешь там отдельную сессию — и работаешь параллельно.
Для мультиагентных воркфлоу это критически важно: каждый агент работает в своём worktree, никто не мешает друг другу. Если результат не понравился — удаляешь директорию. Основная ветка не тронута.
Автоматизация: от ручных промптов к CI/CD для агентов
На старте ты работаешь с агентом interactively: пишешь промпт, получаешь код, проверяешь, исправляешь. Но настоящая эффективность приходит, когда этот процесс автоматизируется.
Автоматизированный пайплайн выглядит так: триггер (push в ветку, создание issue) → запуск агента в sandbox → генерация кода → прогон тестов → создание PR. Человек проверяет только финальный PR, а не каждую строчку.
Ключевые элементы автоматизации:
Триггеры: webhook от git, расписание, ручной запуск
Sandbox: контейнер или worktree для изолированного выполнения
Верификация: тесты, линтеры, проверка типов — всё, что можно запустить автоматически
Уведомления: агент сообщает о результате — успех, ошибка, требуется ревьюТакой пайплайн превращает агента из «умного автодополнения» в полноценного участника команды, который работает по тем же процессам, что и разработчики-люди.
MCP-сервер за пять шагов
Чтобы закрепить теорию практикой, построим простой MCP-сервер:
Шаг 1. Инициализация. npx @modelcontextprotocol/create-server todo-server — готовая структура проекта: index.ts, tsconfig, зависимости.
Шаг 2. Tools. У каждого tool четыре составляющих: имя (add_todo), описание на естественном языке, схема параметров через Zod и обработчик — async-функция. Критически важно: у каждого параметра .describe(). Агент читает именно эти описания.
Шаг 3. Resources. Текущее состояние данных в JSON — чтение без побочных эффектов.
Шаг 4. Подключение. В .mcp.json добавляешь сервер: имя и команду запуска. Перезапуск IDE — агент видит tools.
Шаг 5. Отладка. npx @modelcontextprotocol/inspector — визуальный клиент, показывающий то, что видит агент: список tools, параметры, описания. Можно вызвать любой tool вручную.
MCP отвязывает инструмент от модели. Написал сервер один раз — он работает с любой моделью, поддерживающей протокол. Это и есть экосистема, в которой агентная инженерия выходит за рамки одного проекта.