У меня небольшой бюджет на AI-ассистент — $20 в месяц. Хватает, но только если понимаешь как работает тарификация. Я потратил время чтобы разобраться что именно ест токены, и написал framework который пытается решить эти проблемы. Расскажу про оба.

Как формируется контекст

Каждый запрос к модели стоит денег пропорционально размеру контекста — всего что модель читает перед ответом. В Cursor контекст состоит из нескольких слоёв:

  1. Файлы которые вы явно указали через @

  2. Файлы которые Cursor подтянул автоматически как связанные

  3. Содержимое .cursor/context/ — если есть

  4. Правила из .cursor/rules/ — если есть

  5. Проиндексированное содержимое проекта

Последний пункт — главная проблема. По умолчанию Cursor индексирует всё в директории проекта. В Go проекте это vendor/ с зависимостями, .git/ с историей, dist/, логи. Реальный код занимает процент от этого.

.cursorignore работает как .gitignore — говорит Cursor что не трогать. После его настройки индексируется только то что нужно.

Почему Agent Mode дорогой

В Agent Mode Cursor может создавать и редактировать файлы. Но есть особенность: при каждом File Edit контекст перечитывается заново. Не один раз за задачу — а для каждого изменения отдельно.

Когда AI исправляет баг, он обычно создаёт два файла: исправленный код и тест. Это два перечитывания контекста. Нормально.

Проблема в том что AI по своей инициативе часто создаёт дополнительные файлы: описание что было сделано, чеклист, саммари изменений. Я видел как одна задача порождала 11 File Edits вместо двух. При контексте в 100K токенов это 1.1M токенов входа вместо 200K.

Есть механизм Prompt Caching — повторное чтение одного и того же контекста стоит дешевле. Но кэш работает только если контекст не меняется между запросами. Каждый новый файл меняет контекст — кэш инвалидируется, платишь полную цену снова.

Запрет на создание лишних файлов через .cursor/rules/ решает это напрямую: AI создаёт только код и тест, всё остальное запрещено правилами которые Cursor применяет автоматически.

Кеш на стороне платформы и почему он не всегда помогает

Anthropic поддерживает Prompt Caching на уровне API. Если вы отправляете одинаковый контекст в нескольких запросах подряд — повторное чтение кешированной части стоит значительно дешевле.

Но у этого кеша есть TTL — он живёт около 30 минут без обращения. Если вы ушли на кофе, отвлеклись на встречу, вернулись через час — кеш протух. Следующий запрос снова читает весь контекст по полной цене.

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

Потеря контекста при смене модели

Cursor Composer — stateless. У каждого разговора нет памяти о предыдущих. Когда меняешь модель — начинаешь с чистого листа.

Это важно если используешь разные модели для разных задач. Дорогая модель для анализа архитектуры, дешёвая для рутинных задач — логичная стратегия. Но если дешёвая модель не видит что делала дорогая, приходится объяснять контекст заново.

Решение через файловую структуру: дорогая модель пишет результаты анализа в файл, дешёвая читает этот файл через @. Контекст не теряется при смене модели — он хранится на диске, а не в памяти сессии.

.cursor/
├── analysis/
│   └── project-map.md    # Opus написал один раз
└── plans/
    └── tasks/
        └── task-003.md   # Haiku читает и выполняет

Проблема большого плана

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

При выполнении задачи №7 модель читает задачи 1-6 которые уже сделаны, и задачи 8-20 которые ещё не актуальны. Это лишние токены при каждом запросе.

Вторая проблема — план устаревает. Анализ написан в начале: "функция ProcessOrder, строка 47". После первых задач строки сдвинулись, что-то переименовано. Модель работает по устаревшим координатам и ошибается.

Разделение на маленькие файлы решает первое: при выполнении задачи в контексте только её файл — 15-20 строк, не весь план на 300.

Для второго — снапшоты. Но сначала стоит понять саму проблему подробнее, потому что это ключевой момент.

Opus анализирует проект и создаёт карту:

## service.go — 150 строк

### Функции:
- `ProcessOrder` (~строка 47) — обрабатывает заказ
- `withdrawAndDeposit` (~строка 124) — списание и пополнение

На основе этого Sonnet создаёт план. Задача task-003 выглядит так:

## Функция
`withdrawAndDeposit` (~строка 124)

Выполняем задачи 001 и 002. В ходе task-001 рефакторим service.go — разбиваем большую функцию, добавляем обработку ошибок. Файл вырастает со 150 до 220 строк.

Теперь ситуация такая:

В плане написано:          В реальном коде:
withdrawAndDeposit         withdrawAndDeposit
~строка 124                ~строка 187  ← сдвинулась на 63 строки

Когда приходит время task-003, модель идёт к строке 124, видит там что-то другое и либо ошибается, либо тратит токены на повторный поиск. Чем больше задач выполнено — тем сильнее план расходится с реальностью.

Снапшоты решают это так. После каждого git commit запускается скрипт:

# snapshot-state.sh
DATE=$(date '+%Y-%m-%d %H:%M')
CHANGED=$(git diff --name-only HEAD)

echo "## $DATE" >> .cursor/snapshots/changes.md

echo "$CHANGED" | while read f; do
    lines=$(wc -l < "$f")
    echo "- $f ($lines строк)" >> .cursor/snapshots/changes.md
done

После task-001 в changes.md появляется запись:

## 2026-02-23 14:30
- src/mascot/service.go (220 строк)
- src/mascot/service_test.go (45 строк)

Это просто лог. Сам по себе он ничего не делает.

Важное происходит в run-next-task.txt — перед выполнением следующей задачи промпт читает этот лог и обновляет файл только следующей задачи:

Прочитай .cursor/snapshots/changes.md.
service.go изменился.
Задача task-003 ссылается на этот файл.
Найди актуальное расположение функции withdrawAndDeposit
и обнови строку в task-003.md.
Остальные задачи не трогай.

Модель открывает service.go, находит withdrawAndDeposit на строке 187, обновляет task-003.md. Задача выполняется по актуальным координатам.

Ключевое здесь — обновляется только следующая задача, не весь план. Переписывать весь план при каждом изменении было бы дорого и медленно.

Как это запускается: анализ и план

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

Анализ проекта. Промпт 01-analyze-project.txt запускается один раз с Opus. Он сначала выполняет bash-скрипты локально — собирает структуру проекта, количество строк, список TODO — и использует этот вывод как контекст. Потом читает сам код и создаёт файл .cursor/analysis/project-map.md:

## service.go — 150 строк | оценка 4/10

### Функции:
- `withdrawAndDeposit` (~строка 124) — списание и пополнение
- `ProcessOrder` (~строка 47) — обрабатывает заказ

### Проблемы:
- [КРИТИЧНО] нет DB-транзакции между GetBalance и UpdateBalance
- [ВАЖНО] функция ProcessOrder больше 50 строк, сложно тестировать

Это карта проекта. Она не меняется — создаётся один раз и служит исходником для следующего шага.

Создание плана. Промпт 02-create-plan.txt запускается с Sonnet. Он читает карту и создаёт два вида файлов.

Первый — индекс optimization-plan.md, просто список ссылок:

## Очередь
- [ ] task-001 — утечка горутин в retry (03-fix-simple-bug, Haiku, ~$0.03)
- [ ] task-002 — валидация параметров (05-refactor, Haiku, ~$0.12)
- [ ] task-003 — race condition в withdrawAndDeposit (03-fix-simple-bug, Sonnet, ~$0.15)

Второй — отдельный файл для каждой задачи в .cursor/plans/tasks/. Эти файлы и есть суть хранения контекста: каждый содержит всё что нужно для выполнения одной задачи — конкретный файл, конкретную функцию, конкретное решение. Индекс — это только ссылки на них, сами задачи живут отдельно.

Такое разделение нужно именно для контроля контекста: при выполнении задачи модель читает только её маленький файл, не весь план целиком.

Как работает run-next-task под капотом

Основной промпт framework'а run-next-task.txt — это последовательность bash команд которые Cursor выполняет сам в Agent Mode:

Шаг 1: найти задачу

grep -m 1 '^\- \[ \]' .cursor/plans/optimization-plan.md

Возвращает первую строку без ✅, из неё берётся номер задачи.

Шаг 2: прочитать файл задачи

cat .cursor/plans/tasks/task-003.md

Файл содержит проблему, путь к файлу, имя функции, конкретное решение, какой промпт использовать.

Шаг 3: прочитать сам промпт

cat .cursor/scripts/prompts/05-refactor.txt

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

Шаг 4: прочитать целевой код

cat src/mascot/types.go

Шаг 5: выполнить Модель следует инструкциям из промпта, используя детали из файла задачи.

Шаг 6: зафиксировать

bash .cursor/scripts/bash/snapshot-state.sh
git commit -m "feat: add input validation"

Шаг 7: закрыть задачу

mv .cursor/plans/tasks/task-003.md .cursor/plans/done/task-003.md

В индексе ставится ✅, проверяется следующая задача по changes.md.

Вся эта цепочка запускается одним промптом. Контекст при этом минимальный: файл задачи (15-20 строк) + целевой файл кода + base.md который Cursor читает автоматически.

Установка в проект

Framework распространяется как репозитарий на гитхабе. После клониования:

cd your-go-project
bash /path/to/framework/setup.sh
bash test-framework.sh

setup.sh копирует всю структуру .cursor/ в ваш проект, создаёт .cursorignore, копирует промпты, bash-скрипты и test-framework.sh.

test-framework.sh проверяет что всё на месте — структура папок, все промпты, скрипты, содержимое .cursorignore. Выдаёт список ✅ и ❌ по каждому пункту. Если что-то не так — сразу видно что именно.

После установки в корне проекта появляется:

your-project/
├── .cursorignore
├── test-framework.sh
├── GUIDE.md
└── .cursor/
    ├── rules/optimization.mdc   # правила — запрет лишних файлов
    ├── context/base.md          # описание проекта — заполнить под себя
    ├── analysis/                # сюда Opus запишет карту проекта
    ├── plans/
    │   ├── optimization-plan.md # индекс задач
    │   ├── tasks/               # файлы задач
    │   └── done/                # выполненные
    ├── snapshots/changes.md     # лог изменений кода
    └── scripts/
        ├── bash/                # скрипты анализа
        └── prompts/             # все промпты

Единственное что нужно сделать руками — заполнить .cursor/context/base.md. В архиве есть готовый пример для Go + Clean Architecture, обычно достаточно поменять название проекта и цель.

Эту проблему решают и другие

Пока я разбирался с токенами, наткнулся на Get Shit Done — framework для Claude Code который решает ту же проблему деградации контекста, но с другой стороны.

Их подход: оркестратор + subagents. Главная сессия остаётся лёгкой и только координирует. Тяжёлую работу делают subagents — каждый стартует с чистым контекстом, выполняет одну задачу, записывает результат в файл (SUMMARY.md, STATE.md) и умирает. Следующий subagent читает эти файлы и продолжает. Основная сессия никогда не деградирует.

Это та же центральная идея — контекст живёт в файлах, а не в памяти сессии. Только у GSD это автоматизировано на уровне multi-agent оркестрации, а у меня реализовано вручную через промпты в Cursor.

Где расходимся: GSD не контролирует что загружается в контекст subagent при старте. Если в проекте нет аналога .cursorignore — subagent получает раздутый контекст из vendor/ и .git/ с первого же запроса. Мой framework решает именно этот пласт: что попадает в контекст, сколько это стоит, как не платить за мусор. GSD про это не говорит вообще.

Они скорее дополняют друг друга чем конкурируют. GSD — система управления проектом. Мой framework — оптимизация затрат внутри Cursor.

Результаты на тестовом проекте

Я прогнал framework на Go сервисе около 1500 строк — несколько багов, валидация параметров, тесты, godoc.

Фаза

Без framework

С framework

Анализ

~$5

~$2

4 бага

~$4

~$0.12

Рефакторинг

~$3

~$0.15

3 теста

~$2

~$0.54

Документация

~$2

~$0.40

Итого

~$16

~$3.21

Цифры получились ожидаемыми — каждый компонент экономит на своём. Но это один тестовый проект в контролируемых условиях. Насколько это воспроизводится на других проектах с другим кодом — непонятно.

Вопросы которые возникнут

— У Cursor есть RAG, он сам индексирует проект и находит нужные файлы. Зачем тогда вся эта структура?

RAG в Cursor действительно работает — он умеет находить релевантные файлы по семантическому сходству. Но это не то же самое что явный контроль контекста.

Во-первых, RAG решает поиск, но не решает проблему объёма. Если проект не огорожен .cursorignore, поиск идёт по всему включая vendor/ и .git/. Найденные файлы всё равно попадают в контекст и стоят токенов.

Во-вторых, RAG — это вероятностный поиск. Он находит то что семантически похоже на запрос. Файловая структура .cursor/ — это детерминированный контекст: конкретный файл задачи, конкретный промпт, конкретный целевой файл. Никакой случайности в том что попадёт в контекст.

В-третьих, RAG не решает проблему потери контекста между моделями и между сессиями. Результат анализа который Opus записал в файл — он там и лежит. RAG-индекс при смене модели начинается заново.

— В Cursor есть встроенный режим планирования. Почему не использовать его?

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

Он работает в рамках одного разговора. Как только сессия закончилась или модель сменилась — план исчез. Нет персистентности между сессиями.

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

Файлы задач в .cursor/plans/tasks/ живут на диске независимо от сессий, моделей и перезапусков Cursor.

— Кеш же должен спасать, зачем тогда минимизировать контекст?

Кеш на стороне платформы живёт около 30 минут. Если не успел продолжить работу до истечения TTL — кеш протух, следующий запрос снова платный в полную цену. Маленький контекст стоит меньше и при попадании в кеш, и при промахе.

— Это работает только для Go?

Структура .cursor/ и принципы — универсальны. Bash-скрипты для анализа и промпты — написаны под Go. Для другого языка нужно адаптировать промпты и скрипты, структура остаётся той же.

— В промптах и файлах задач указаны конкретные модели — Haiku, Sonnet, Opus. Это обязательно?

Нет, это рекомендации фреймворка основанные на балансе цена/качество для типичных задач. Haiku для простых багов, Sonnet для рефакторинга, Opus для первоначального анализа — это не правила, а отправная точка.

Перед каждой задачей вы сами выбираете модель в Cursor. Если хотите перестраховаться и взять Sonnet там где стоит Haiku — никто не запрещает. Если у вас другой бюджет или другие предпочтения — слушайте себя. Модели в файлах задач просто подсказывают что авторы framework'а использовали бы в этой ситуации.

— А если у меня не Clean Architecture?

base.md — это просто описание вашего проекта. Можно описать любую структуру. Clean Architecture там как пример, не как требование.

Если у вас есть Go проект и желание проверить — буду рад обратной связи в комментариях. Особенно интересно где не работает как ожидается и насколько цифры отличаются от моих.

GitHub

Комментарии (15)


  1. iafilin
    23.02.2026 22:00

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


    1. rkazmin Автор
      23.02.2026 22:00

      Интересная гипотеза. Я поинтересовался ИИ, он подтверждает что

      1. Правда ли, что кириллица дороже?
      Да, абсолютно. Это связано с механизмом токенизации
      (BPE — Byte Pair Encoding):
      Латиница токенизируется почти по принципу «одно слово ≈ один-два токена».
      Кириллица в современных моделях (особенно у OpenAI и Anthropic)
      часто разбивается на части слогов или даже отдельные байты.
      Результат: Одно и то же предложение на русском может занимать в
      2–3 раза больше токенов, чем на английском.
      
      2. Почему «думать на английском» — это двойная выгода?
      Помимо прямой экономии на токенах, есть еще два фактора:
      Качество рассуждений (Reasoning): Большинство моделей 
      (особенно малые, как Haiku) обучались преимущественно на
      англоязычных датасетах. На английском их «логические связи» плотнее.
      Когда модель рассуждает (CoT) на английском, она реже совершает
      логические ошибки в коде.
      
      Экономия на Output-токенах: Если в промпте «Chain-of-Thought» ты
      просишь модель расписать план на 500 слов, то на английском это
      будет ~600 токенов, а на русском — ~1500 токенов. При цене за
      выходящие токены это существенная разница.


      В рамках нового исследования Cursor-Probe я хочу посмотреть, влияет ли формат промпта (XML против обычного текста) на качество кода у слабых моделей. Я хочу проверить, станет ли Haiku реже ошибаться в логике, если загнать её в жесткие рамки структуры, или же это никак не поможет её "интеллекту".
      В рамках Cursor-Probe я проверю разницу между кириллицей и латиницей как побочный фактор..


      1. AlexanderMatveev
        23.02.2026 22:00

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


  1. Pusk1
    23.02.2026 22:00

    Статья отличная. Для уменьшения контекста ещё помогает писать код максимально независимыми модулями сверху вниз. Прямо аля паскаль. И тогда можно открывать как проект папку с отдельным модулем, в котором только тесты и сам модуль + что - то вложенное в него. Так и дешевле и быстрее, более красиво по архитектуре.

    Но есть более качественное и универсальное решение.

    Я тоже долго без него мучился и изголялся. И даже Sonet при отладке выходил дороговато. А потом стал платить 60 вместо 20 и как то веселей стало работать. Особенно при проверке гипотез или дебаге. Через пару месяцев упёрся, что мне не хватает и 60. Теперь у меня корпоративный аккаут и это не совсем мои проблемы в рамках разумного, конечно.


    1. rkazmin Автор
      23.02.2026 22:00

      К сожалению у меня нет корпоративного аккаунта... :((. Поэтому приходитьяс оганичивать себя в опытах, экономя токены


  1. criminalist
    23.02.2026 22:00

    Нужен уже гибридный подход, локальная модель которая будет экономить токены, формировать нужный участок кода скармливать его уже платное, но тут опять скорость, для простых задач например прочитать файл выкусить участок кода и показать ai плат6ой, было бы не плохо


  1. aladkoi
    23.02.2026 22:00

    Какая то жесть написана. Стоит claude code с подпиской за "копейки" на glm модель . Нет никаких лимитов на запросы. Claude code делает все тоже, что и курсор, контекст сессии не теряется даже после ее окончания или перезагрузки компа. Есть их локальная история по проекту , с которой claude умеет работать. Правильно выбранный инструмент и его настройка снимает все проблемы.


    1. inetstar
      23.02.2026 22:00

      Как обходите блокировку? Через переменные среды и прокси? Говорят клод банит даже платные аккаунты.


      1. aladkoi
        23.02.2026 22:00

        Клод Claude code никак не банит, это всего лишь агент. Glm работает в клоде без VPN и прописывается вместо родных моделей. Все инструкции у них на сайте z.ai


        1. inetstar
          23.02.2026 22:00

          По ощущениям, что лучше Opus или GLM?


  1. LionMuzzle
    23.02.2026 22:00

    Я тоже столкнулся. Жрёт токеты как не в себя. Но вы пишете не совсем правду:

    Если не создавать .cursorignore, то по умолчанию будут включены в игнор лист все пути из вашего .gitignore. Вот тут написано это, и показан дополнительный обширный список того, что исключается, даже .git там указан: https://cursor.com/ru/docs/context/ignore-files#-5

    Планы можно сохранять персистентно. Во-первых, они и так не удаляются, они просто лежат в домашней папке. Во-вторых, в плане можно нажать на три точки и выбрать Save to workspace, чтобы перенести его в папку проекта внутрь папки .cursor. Вот тут написано: https://cursor.com/ru/docs/get-started/quickstart#

    И ещё от меня. В последнее время стал пользоваться моделью auto, и заметил на моем очень большом веб-проекте, что она ведёт себя довольно хорошо. Я сравнивал с opus и sonet. Меня этот режим сильно удивил. В бюджете аккаунта режим auto тарифицируется отдельно, и упереться в лимит у меня пока не получилось. https://cursor.com/dashboard?tab=spending

    У меня:

    Auto + Composer: 5%

    Consumed by Auto and Composer models.

    API: 47%

    Consumed by other models. 


    1. dmiche
      23.02.2026 22:00

      Авто стала чудо как хороша. С летом вообще не сравнить. Хотя ровно сегодня попал под какую-то более кондовую. Возможно тестят чего-то новое.

      А вообще doc-first рулит. Начинать с документации. Поддерживать ее, чтобы не разъезжалась стало необременительно, а архитектурный документ нынче ценнее кода.


  1. Lashadkach
    23.02.2026 22:00


    План за 20 мне показался скорее ознакомительным, а вот за 60 хорошо себя показывает на крупном проекте. Свежая composer 1.5 работает гораздо лучше 1.0 от курсора и теперь не особо и нужно использовать codex/opus или сильно экономить токены при условии использования всех модов.

    Так же заметил для себя что сформировать план, затем через ask определить корректировки и внести их снова через plan мод тоже не хило экономит токены. И в целом ask мод который отрезает возможности преждевременно создавать файлы очень полезен в целях экономии.

    Во многом задача ИИ это снизить когнитивную нагрузку и повысить за счёт этого продуктивность, поэтому писать скрипты для инструмента ИИ вообще считаю оверхедом, даже для оптимизации токенов. Уж лучше использовать бесплатные модели в браузере, скармливая им модули проекта.

    Ну и заголовок статьи байтит, а прямого и структурированного ответа на вопрос "что с этим можно сделать?" в статье не нашёл, хотя очень хотелось :D


    1. inetstar
      23.02.2026 22:00

      Разве в нём всего не в 3 раза больше токенов, чем в плане за 20?


  1. serjeant
    23.02.2026 22:00

    Есть ещё вот такая удобная штука:
    https://github.com/vanzan01/cursor-memory-bank
    а к ней в связку платный плагин https://supercode.sh/ru. Правда после обновления курсора он перестал у меня работать и поддержка не отвечает...