PPПётр ПашкуровCursor · наставничество · заказы

Руководство · Cursor

Как ставить задачи Cursor Agent: декомпозиция

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

Как ставить задачи Cursor Agent: декомпозиция

Почему «сделай интеграцию» ломает cursor agent

Фраза «сделай интеграцию» для cursor agent - это не задача, а эпик на неделю. В документации Agent собирается из Instructions, Tools и Model (overview). Instructions - rules, AGENTS.md, ваш промпт. Tools - search, edit, terminal. Model - выбранная LLM. Когда цель размыта, инструменты работают, но направление выбирается вслепую: агент находит похожие файлы, тянет соседние модули, добавляет библиотеку «как в туториале».

Cursor agent mode без границ превращает автономный режим в лотерею. Help перечисляет режимы Agent, Ask, Plan, Debug (help). Ask отвечает без правок. Plan сначала строит план и ждёт approve. Debug копает баги. Agent сразу идёт в код. Если вы жмёте Build на «подключи CRM», модель не знает: это webhook, OAuth, маппинг полей или миграция базы. Итог - diff в пяти папках и сломанный обработчик заявок.

На новостных разборах всплывает отдельный риск: идея «запустить рой агентов на одном репо». Лабораторные отчёты про саботаж между агентами - сигнал не плодить параллельные «сделай всё» на одном модуле. В Cursor субагенты изолированы по контексту, но общий git без зон даёт конфликт правок. Я учу иначе: один чат, одна логическая единица, явный scope (best practices).

Типичный кейс с разбора - вымышленный CRM-бот на Telegraf. Владелец пишет: «подключи AmoCRM, чтобы заявки падали в воронку». Агент находит bot/handlers/lead.ts, web/src/api/crm.ts, shared/types/lead.ts, лезет в deploy/ и меняет env-шаблон. Заявка в тестовую воронку не уходит, зато прод-конфиг уже в diff. Причина не в «глупой модели», а в отсутствии одного результата и критерия «готово».

Когда scope неочевиден, я не жму Agent сразу. Shift+Tab переключает в Plan (plan-mode): вопросы, поиск по репо, план, approve, build. Если план промахнулся - revert и уточнить план, а не долбить follow-up в том же направлении. Смена задачи - новый чат (help): старый контекст сжимается, агент «плывёт» между целями.

Три признака, что задачу пора резать, а не усиливать промпт:

  1. 01

    В одном сообщении и webhook, и UI, и миграция БД.

  2. 02

    Вы не можете назвать один файл-entrypoint без «ну где-то в src».

  3. 03

    Критерий готовности звучит как «чтобы работало» без тестового сценария.

Если узнали себя - следующий раздел про один результат. Контекст репо до задачи - в контексте проекта для Cursor.

Один результат: как сузить задачу до одного исхода

Схема: один результат вместо эпика «сделай интеграцию»

Декомпозиция задачи для агента начинается с вопроса: что изменится в мире после merge, если всё прошло успешно? Не «интеграция готова», а конкретика: «POST /api/leads принимает тело из формы и отдаёт 201 с leadId». Или: «бот после /start показывает кнопку записи без ошибки в логе». Один исход на один чат - рекомендация из best practices Cursor: finished one logical unit of work, затем новый чат.

Как ставить задачи cursor agent на практике: беру эпик «интеграция Amo» и режу на цепочку. Шаг 1 - только маппинг полей в shared/mappers/amoLead.ts. Шаг 2 - только HTTP-клиент с retry. Шаг 3 - только webhook handler. Шаг 4 - smoke: тестовая заявка. Каждый шаг - отдельный промпт, отдельная ветка или commit после verify. Агент не обязан помнить вчерашний план, если вы не положили его в rules.

Задача для cursor agent формулируется в формате «сделай X, чтобы Y». Плохо: «улучши CRM». Хорошо: «добавь валидацию телефона в LeadForm.tsx, чтобы при +7 без 10 цифр показывалась ошибка под полем». Второе предложение - наблюдаемый исход. Третье - где смотреть: UI, лог, тест.

Чеклист декомпозиции из пяти пунктов, который я даю на созвоне:

1. Один исход: что увидит пользователь или что вернёт API?
2. Один слой: только backend ИЛИ только frontend ИЛИ только handler бота.
3. Max 3-5 файлов в scope (остальное - следующий чат).
4. Запреты: не трогать deploy/, .env*, package.json без OK.
5. Verify: команда из package.json + ручной шаг (клик, curl, тестовая заявка).

Пример нарезки для того же CRM-бота. Эпик: «заявки из Telegram в Amo». Итерация A: «в bot/handlers/lead.ts собери payload заявки по типу LeadPayload, не вызывай Amo API». Итерация B: «в shared/clients/amo.ts POST lead с mock-токеном из .env.example». Итерация C: «подключи handler к клиенту, критерий - лог amo_lead_created без 5xx». Три чата, три diff, три verify. Не один чат «сделай всё».

Plan Mode уместен, когда исход ясен, а путь - нет. «Нужна валидация email в форме» - Agent с @LeadForm.tsx. «Нужна синхронизация статусов Amo ↔ бот, не знаю где живёт логика» - Plan, approve, build. Промах по плану - откат checkpoint и новый план, не «ну доделай».

Таблица «эпик → одна итерация»:

Эпик в чатеОдна итерация AgentКритерий готовности
Сделай интеграцию AmoМаппинг полей в один файлunit-тест на mapper, exit 0
Почини форму заявкиВалидация одного поляручной ввод невалидного телефона
Добавь оплатуWebhook stub без prod keyscurl 200 на /webhooks/payment/test
Рефактор ботаПереименовать handler + тестgrep не находит старое имя, test green

Какие файлы трогать: scope и запретные зоны

Scope cursor agent - это не пожелание, а список путей в промпте и в brief. Документация советует прикреплять @ на файлы, когда entrypoint известен (prompting). Без списка агент ищет сам: находит lead.ts, Lead.ts, leads.service.ts и правит все три.

Я пишу scope в двух местах. Долгая память - AGENTS.md или project rule: «разрешено bot/handlers/*, запрещено deploy/». Тактика на задачу - промпт: «меняй только bot/handlers/lead.ts и shared/validators/phone.ts». Плюс @ на entrypoint. Не весь src/ и не dump дерева файлов.

Список файлов для вымышленного CRM-бота (учебный пример):

Scope (эта итерация)
Разрешено:
  bot/handlers/lead.ts      - сбор payload заявки
  shared/validators/phone.ts - валидация телефона
  shared/types/lead.ts      - только если нужен новый field

Запрещено:
  deploy/*
  prisma/migrations/*
  web/src/*
  package.json
  .env*

Запретные зоны закрываю не только словами. .cursorignore убирает файлы из read и @ для Agent (security):

.env
.env.*
secrets/
deploy/production.*
node_modules/
dist/
*.pem
*.key

Оговорка из доки: ignore не граница безопасности. Terminal и MCP могут прочитать то, что закрыто от индекса (enterprise LLM safety). Команды в терминале по умолчанию требуют approve. Я не прошу cat .env в задаче и не вставляю токены в промпт - они уходят в LLM и историю чата.

Сколько файлов в scope? Ориентир 3-5 на одну итерацию. Больше - выше шанс «улучшил заодно» соседний модуль. Меньше одного - часто достаточно Ask или Inline Edit, Agent избыточен. Monorepo: указываю пакет явно (apps/crm, не корень). Соседние app закрыты в rule: «не трогать apps/web без отдельной задачи».

@Branch (Diff with Main) в промпте показывает агенту, что уже изменено (prompting). Это снижает дубли, если вы правили руками между итерациями. Checkpoints внутри сессии откатывают файлы (overview), но не заменяют git-ветку и commit до агента.

Пять шагов перед Build:

  1. 01

    Ветка feat/короткое-имя, commit чистого состояния.

  2. 02

    Scope в промпте списком путей, не «где-нибудь в боте».

  3. 03

    @ на 1-3 entrypoint-файла.

  4. 04

    .cursorignore на секреты и prod-конфиги.

  5. 05

    Запрет новых npm-пакетов одной строкой, если не обсуждали.

Подробнее про карту репо и brief - в контексте проекта.

Критерий готовности и команды verify

Критерий готовности agent - то, по чему вы сами, не модель, решаете принимать diff. «Агент сказал готово» не считается. Best practices Cursor прямо советуют TDD и явную verification (best practices). Для бизнес-бота это часто ручной шаг: тестовая заявка, запись в лог, один зелёный тест на handler.

Я дублирую критерий в двух формулировках - для агента в промпте и для себя в чеклисте:

Кто проверяетЧто смотримЗачем
Агент (до отчёта)npm run lint && npm test exit 0Меньше ложных «всё ок»
Я (перед merge)те же команды в терминале + git diffЧат не заменяет CI
Бизнес-smokeодин сценарий из продуктаКод зелёный, заявка не ушла

Типичный блок в промпте:

Verify
npm run lint && npm test

Готово когда
- lint и test - exit 0
- изменены только файлы из scope
- нет новых зависимостей в package.json
- тестовая заявка из бота даёт log line "lead_accepted"
- .env* не в diff

Проверка diff cursor после Agent - обязательный ритуал. Скрипт, который копирую на разборах:

#!/usr/bin/env bash
set -euo pipefail
npm run lint
npm test
git diff --stat
git diff --name-only | diff - <(echo "bot/handlers/lead.ts
shared/validators/phone.ts") && echo "scope OK" || echo "STOP: files outside scope"
git diff | grep -E '\.env|SECRET|TOKEN|password' && echo "STOP: secrets in diff" && exit 1 || true

Последние строки - грубый smoke, не замена секрет-сканера. Полный чеклист ревью - в как проверять код от ИИ. В интерфейсе Cursor есть Review → Find Issues после Agent (best practices) - дополнение, не замена вашему verify.

Порядок, который держу сам:

  1. 01

    Agent закончил - не Apply All сразу.

  2. 02

    Терминал: lint и test вручную.

  3. 03

    git diff пофайлово: scope, секреты, лишние зависимости.

  4. 04

    Ручной smoke: кнопка в боте, curl на endpoint, одна тестовая заявка.

  5. 05

    Commit только после зелёного набора.

Если verify падает, следующий промпт - с логом ошибки и @ на failing test, не «попробуй ещё раз без деталей». Несколько провалов подряд - новый чат с ужатым scope, а не наращивание истории.

Ask уместен, когда нужен план без правок. Debug - когда баг локализован. Agent - когда исход, scope и критерий уже записаны. Иначе вы платите токенами за поиск того, что должны были сформулировать до Build.

Шаблон промпта: до и после декомпозиции

До и после: промпт для cursor agent с одним результатом и scope

Промпт для cursor agent после декомпозиции читается как мини-ТЗ: исход, scope, запреты, verify, @ на файлы. До декомпозиции - одна строка на весь эпик. Ниже пара на вымышленном CRM-боте (без реальных ключей).

Плохо - так приходит на разбор:

Сделай интеграцию с AmoCRM чтобы заявки из телеграм бота падали в воронку.
Почини если что не работает. Деплой тоже настрой.

Хорошо - одна итерация после нарезки:

Результат
После отправки заявки из бота handler пишет в лог "lead_mapped" и возвращает
объект AmoLeadPayload без HTTP-вызова (следующий чат - клиент API).

Scope
Только:
  @bot/handlers/lead.ts
  @shared/mappers/amoLead.ts
Не трогать: deploy/, web/, package.json, .env*

Запреты
- Не добавлять npm-пакеты
- Не читать и не копировать .env
- Max 2 файла в diff

Verify
npm run lint && npm test
Готово когда: unit-тест TestMapTelegramLeadToAmo - green

Контекст
Стек: Node 20, Telegraf 4, Vitest. Токены только в .env (в ignore).

Разница не в длине ради длины. В плохом варианте пять целей и ноль границ. В хорошем - один слой, два файла, наблюдаемый лог и тест. Агенту не нужно угадывать, что «интеграция» значит для вас сегодня.

Шаблон, который копируют ученики:

Результат
[одно предложение: что изменится]

Scope
Разрешено: [пути]
Запрещено: [пути]
@файл1 @файл2

Запреты
- без новых deps / без deploy / без секретов в коде

Verify
[команды из package.json]
Готово когда: [тест или ручной шаг]

Контекст (если нет в AGENTS.md)
[стек одной строкой]

Готовые формулировки под разные ситуации - в промптах для Cursor. Rules и brief - в контексте проекта. Не дублируйте в чат то, что уже в AGENTS.md: повтор создаёт шум и иногда противоречия.

Ctrl+I / Cmd+I открывает Agent (overview). Очередь сообщений: Enter ставит в queue, Cmd/Ctrl+Enter отправляет сразу. Пока агент работает, не сыпьте новые эпики в тот же чат - дождитесь diff или остановите и начните новый чат с одной итерацией.

Типовые ошибки и как исправить

Таблица: симптом постановки задачи и конкретный фикс

Ошибки ниже - с разборов, не абстрактный список. У каждой строки симптом и действие, которое я реально делаю на созвоне.

СимптомВероятная причинаКак исправить
Diff в 10+ файлахэпик в одном промптенарезать итерации, новый чат на шаг
Новый axios/lodash в package.jsonне было запрета на depsстрока в промпте и AGENTS.md, откат lockfile
Правки в deploy/ или prod yamlнет запретной зоныscope + .cursorignore на deploy
.env или токен в diff/чатесекреты не в ignoreignore + rule, ротация ключа
«Готово», тесты красныенет verify в промптеявные команды + не merge до exit 0
Агент повторяет ту же ошибкудлинный чат, сжатый контекстновый чат, ужатый scope, @ на failing test
Plan уехал не тудаapprove без чтения планаrevert, уточнить план, не долбить follow-up
Два агента правят один файлпараллель без зонодин чат, одна ветка, scope по файлам

Три мини-истории с поля, без выдуманных цифр. Разбор А: CRM-бот, промпт «сделай интеграцию», diff затронул web/ и bot/. Фикс - итерация только на mapper, @shared/mappers/amoLead.ts, критерий unit-тест. Разбор Б: форма заявки, агент положил API-ключ в config.ts. Фикс - ключ в env, example в репо, ключ ротирован, rule «не хардкодить секреты». Разбор В: два follow-up в одном чате - сначала валидация, потом Amo - агент смешал правки. Фикс - commit после валидации, новый чат на Amo с чистым scope.

Отдельно про cursor agent mode без декомпозиции: режим не виноват, размытая задача виновата. Переключение Ask → Agent не заменяет формулировку исхода. Plan без approve тоже не спасёт, если вы не читаете план.

Разбор вашей задачи: наставничество и проекты

На наставничестве я не даю один промпт на все случаи. Разбираем ваш репо: где entrypoint, какой один исход на эту неделю, какие файлы в scope, какой smoke для CRM или бота. Ученик приносит сырой текст «сделай интеграцию» и реальный diff - режем задачу вместе, прогоняем verify, смотрим, что попало в историю чата.

На разработке проектов делаем пилот на одном модуле: webhook, handler заявки, один endpoint. Тот же каркас: один результат, список файлов, критерий, checkpoint до Agent. Не пять субагентов на весь monorepo.

Первый вечер с веткой и diff без эпиков - в первом проекте в Cursor. Режимы и когда жать Build - cursor agent mode. Контекст до задачи - контекст проекта. Проверка после Agent - как проверять код от ИИ.

Процесс разбора на 20 минут:

  1. 01

    Вы присылаете сырую задачу и 1-3 скрина diff или ошибки.

  2. 02

    Формулируем один исход на ближайшую итерацию.

  3. 03

    Пишем scope и запреты под ваш стек.

  4. 04

    Собираем промпт по шаблону из H2-5.

  5. 05

    Вы гоняете Agent у себя, приносите diff на ревью.

  6. 06

    Фиксируем verify-команды в AGENTS.md для следующих задач.

Если задача упирается в инфраструктуру (GitHub, Vercel, env на сервере) - это отдельный созвон, не один промпт в Agent. Декомпозиция работает и там: «сначала зелёный deploy preview», потом «webhook в боте».

По теме в блоге: cursor agent mode - режимы Ask, Agent, Plan, Debug; контекст проекта для Cursor - brief до задачи; промпты для Cursor - готовые формулировки; как проверять код от ИИ - diff после Agent; первый проект в Cursor - вечерний сценарий с веткой.

FAQ

Частые вопросы

Как ставить задачи cursor agent, если задача звучит «сделай интеграцию»?

Режу эпик на итерации с одним исходом: сначала mapper полей, потом HTTP-клиент, потом handler. Каждый шаг - отдельный чат, scope из 3-5 файлов, критерий вроде зелёного unit-теста или log line. Plan Mode - если путь неочевиден, но исход уже сформулирован.

Что делать в cursor agent mode без декомпозиции?

Остановить Build, откатить checkpoint или git, записать один результат, список путей и verify. Переключение Ask или Plan не заменяет формулировку: режим инструмент, задача остаётся размытой. Если в чате уже несколько целей - новый чат с ужатым scope.

Сколько файлов включать в scope cursor agent?

Ориентир 3-5 на одну итерацию. Меньше - часто хватает Ask или Inline Edit. Больше - растёт риск правок в соседних модулях. Пути пишу списком в промпте и дублирую запреты в AGENTS.md; entrypoint прикрепляю через @.

Что писать в критерии готовности agent?

Наблюдаемый исход: exit 0 у lint и test из package.json, плюс бизнес-smoke - тестовая заявка, curl на endpoint, кнопка в боте. Формулировка «агент сказал готово» не считается. Критерий копирую в промпт и проверяю сам в терминале до merge.

Когда не поручать Agent и открыть новый чат?

Сменилась цель, в истории уже другая задача, verify падает третий раз подряд, или scope разросся за 5 файлов. Cursor рекомендует one logical unit per chat. Следующую итерацию начинаю с чистого промпта, @ на файлы и ссылкой на AGENTS.md.

Как проверить diff после Agent?

Вручную: npm run lint, npm test, git diff --stat, сверка путей со scope, grep на .env и TOKEN. Плюс Review → Find Issues в Cursor. Полный чеклист - в статье про проверку кода от ИИ на сайте. Merge только после зелёного набора и ручного smoke.

Дальше

Связанные страницы

Птенец в капюшоне печатает сообщение в телефоне
Telegram

Обсудить вашу задачу

Напишите в Telegram цель, что уже сделано и где стопор.

Отвечаю сам — без бота и «оставьте заявку».