- BrainTools - https://www.braintools.ru -

Качество работы LLM — функция от качества контекста на входе. Это утверждение звучит банально, однако зачастую разработчики оптимизируют модель, выбирая между GPT, Claude, Gemini и прочими, и промпт, но не контекст в целом. Между тем, разница между “агент с правильным контекстом” и “агент без контекста” — не 20% и не 50%. Эта разница находится в дистанции вариантов между “решил задачу за 5 минут” и “потратил час, сломал два сервиса, и результат пришлось откатить из-за массы новых проблем”.
Я solo-разработчик. В моей экосистеме десятки актуальных проектов: платформа из десятков микросервисов, AI-инференс кластер на неспецифическом железе типа mac studio и dgx spark, масса shared-библиотек, инфраструктура на нескольких физических и десятках виртуальных хостов.
Последний год “пишу” код почти исключительно через LLM и Cursor. Начинал с deepseek на уровне “подскажи как написать функцию для …” и дошел до полноценной оркестрации на Claude 4.6: я формулирую задачу, агент анализирует условия и кодовую базу, обсуждаем архитектурный план, агент пишет код и тесты, запускает тесты, исправляет ошибки [1], получает от меня обратную связь по результатам ручной проверки.
Это работает хорошо, когда агент глубоко понимает контекст. И катастрофически плохо, когда контекста недостаточно. Эта статья — про то, как я решаю проблему контекста системно.
Описанная методология разрабатывалась и обкатывалась на одной из наиболее сильных моделей для работы с кодом — Claude 4.6 Opus с контекстным окном в миллион токенов. Это важно зафиксировать: большое окно контекста означает, что агент физически способен “увидеть” knowledge base, а сильные аналитические способности модели позволяют извлечь из неё пользу, а не утонуть в шуме.
Даже на такой модели разница между “с workbench” и “без workbench” оказалась существенной — и именно это стало основанием для формализации подхода. Если структурированный контекст заметно улучшает и без того сильную модель, можно предположить, что для менее мощных моделей — с меньшим окном или слабее — он может быть ещё важнее: у них меньше способности компенсировать отсутствие контекста “сообразительностью”.
Однако практической проверки на open source моделях или моделях с меньшим окном контекста я не проводил. Вероятно, потребуется адаптация: более компактные документы, приоритизация контекста, возможно — автоматическая выборка релевантных фрагментов вместо подключения всей knowledge base. Это остаётся открытым вопросом, и если у кого-то из читателей есть опыт [2] подобных экспериментов — это интересно обсудить.
У LLM-агентов нет долговременной памяти [3]. Это фундаментальное свойство архитектуры на текущем уровне развития технологий: каждый чат — изолированный контекст, который исчезает после завершения сессии. Cursor Rules и system prompts дают агенту характер (конвенции, стиль, ограничения), но не дают знаний о системе — историю решений, архитектуру, состояние проектов.
Для одного проекта это терпимо: ключевая часть кодовой базы помещается в контекст, README описывает основные моменты, агент ориентируется используя небольшой объем контекстного окна и времени на вызов инструментов. Но когда проектов десятки и они связаны — каждая сессия начинается с фазы ориентации, на которую уходят лишние токены и время. Агент не знает без дополнительных усилий:
Что проект использует шину данных для коммуникации, а не REST
Что два месяца назад был отвергнут Redis в пользу NATS KV Store и почему
Что один из проектов намеренно остановлен из-за ограничений используемой БД
Что другой проект — это legacy, который находится в процессе замены
Какие shared-библиотеки существуют и какая кодовая база их использует
Отсутствие системного контекста порождает четыре класса ошибок:
1. Повторение [4] отвергнутых решений. Без ист��рии решений агент зачастую предлагает то, что уже было рассмотрено и отвергнуто. Из сессии в сессию. “Давайте используем Redis для кэширования” — мы уже это обсуждали два месяца назад, вот почему не Redis.
2. Нарушение неявных контрактов. В распределённой системе изменение в одном сервисе может сломать несколько других. Агент без информации о топологии зависимостей может изменить формат сообщения, не зная, что его читают потребители вне контекста текущей сессии.
3. Потеря времени на ориентацию. Без навигационных документов существенная часть сессии уходит на рекогносцировку: “какие файлы отвечают за X”, “где конфигурация Y”, “как деплоится Z”.
4. Generic-код вместо идиоматического. Без знания конвенций проекта агент пишет в стиле “среднего по больнице”: camelCase вместо snake_case, axios вместо project-specific api_request(), console.log вместо structured logger.
Cursor Rules (.cursor/rules/) частично решают проблему — проектные конвенции, anti-patterns, стек. Но rules — это про один проект. Всё иначе, когда нужно, чтобы агент понимал систему целиком: как проекты связаны, какие решения приняты, что в каком состоянии.
Контекст должен быть постоянным (persistent), структурированным (structured) и находиться рядом с кодовой базой (co-located).
Если контекст теряется между сессиями — ему нужно обеспечить долговременное хранение. Если контекст хранится хаотично — его нужно структурировать. Если контекст лежит в отдельном инструменте (wiki, Notion, Google Docs) — LLM-агент его не видит. Значит, контекст должен лежать рядом с кодом, в фор��ате, который агент может прочитать.
Из этих принципов вытекает следующий вариант решения: один git-репозиторий с документацией по всей системе, подключаемый вторым (или дополнительным) корнем в IDE.
Я назвал его workbench. Он подключается еще одним корнем в каждый workspace через .code-workspace файл:
{
"folders": [
{
"name": "front-app",
"path": "/path/to/generic/front-app"
},
{
"name": "workbench",
"path": "/path/to/meta/workbench"
}
]
}
Агент видит и код текущего проекта, и весь контекст — в одном окне. Не нужно переключаться, не нужно copy-paste, не нужно “прочитай этот документ из Notion”.
Документация различается по двум независимым параметрам, и оба влияют на то, как её организовать.
Scope — масштаб применимости. Одни документы касаются конкретного проекта: его бэклог, план миграции, заметки по расследованию бага. Другие — пересекают границы проектов: карта серверов, справочник shared-библиотек, архитектурные решения, затрагивающие несколько сервисов. Если кросс-проектное знание лежит внутри одного проекта, остальные его не видят.
Lifecycle — скорость устаревания. Бэклог проекта устаревает за недели по мере реализации. Описание протокола взаимодействия — возможно, за месяцы. Архитектурное решение сохраняет актуальность годами. Если свалить документы с разным жизненным циклом в одну папку, быстро станет невозможно понять, чему доверять: актуален ли этот план, или это артефакт прошлого периода.
На практике эти два измерения коррелируют: проектная документация чаще бывает быстроживущей, а кросс-проектная — долгоживущей. Но совпадение не полное: стратегический план по конкретному проекту может жить месяцами, а кросс-проектный бэклог обновлений зависимостей — устаревать за недели. Тем не менее, для верхнеуровневой структуры scope оказывается более надёжным критерием: он определяет, где искать документ, в то время как lifecycle определяет, насколько ему доверять.
Отсюда основное разделение — по scope:
workbench/
├── projects/<name>/ Документация конкретного проекта
│ ├── service-alpha/ Архитектура, бэклоги, планы
│ ├── frontend/ UI планы, improvements
│ └── compute-engine/ Migration plan, протокол
│
├── domains/ Кросс-проектные знания
│ ├── platform/ Реестр, топология, CI, решения
│ ├── infrastructure/ Железо, модели, инциденты
│ └── engineering/ Практики разработки
│
├── tools/ Скрипты валидации и автоматизации
├── workspaces/ .code-workspace файлы
└── .cursor/rules/ Глобальные cursor rules
projects/<name>/ — документация, привязанная к конкретному репозиторию: планы, бэклоги, логи рабочих сессий, заметки по расследованию проблем. При работе с конкретным сервисом агент заглядывает в его проектную папку за контекстом.
domains/<topic>/ — знания, пересекающие границы проектов: карта серверов, справочник библиотек, стратегические планы, архитектурные решения. Нужно агенту независимо от того, в каком проекте идёт работа.
Scope определяет навигацию: “как деплоить сервис X” — ищется в projects/X/, а “какие серверы вообще существуют” — в domains/platform/topology.md [5]. А lifecycle определяет доверие: документ с пометкой “обновлён 3 месяца назад” в projects/ — повод для подозрения, в domains/ — скорее всего, нормально.
В системе из десятков сервисов знание о состоянии разработки каждого из них неизбежно рассыпается: версия — в package.json, сервер деплоя — в CI-конфигурации, статус — в голове разработчика. Агент не может собрать это из разрозненных источников за разумное время. Нужен один документ, агрегирующий ключевые факты по всем проектам.
В моём workbench эту роль выполняет Project Registry — таблица, где по каждому проекту собрано:
|
Поле |
Что даёт агенту |
|---|---|
|
Версия в репо vs версия в production |
Видит рассинхронизацию |
|
Сервер и способ деплоя |
Знает куда и как деплоить |
|
Наличие CI/CD |
Знает, есть ли pipeline |
|
Зависимости от shared-библиотек |
Видит граф зависимостей |
|
Статус: active / legacy / stopped |
Не тратит время на неактуальный код |
На практике это означает: задача “добавь streaming результатов в подсистему бэктестинга” не начинается с рекогносцировки. Агент смотрит в реестр и сразу видит, какие сервисы задействованы, на чём они написаны, где развёрнуты и как взаимодействуют. Без реестра та же ориентация занимала бы минуты вызовов инструментов и намного большее окно контекста.
Визуализация архитектуры — стандартная практика. Но выбор формата определяет, кто её потребитель. draw.io создаёт бинарный файл — LLM его не прочитает. Mermaid — текстовый, но описывает структуру декларативно, а не визуально: чтобы понять диаграмму, её нужно отрендерить. Для knowledge base, ориентированной на LLM, нужен формат, который читается как текст и при этом передаёт топологию.
ASCII-диаграммы — компромисс, который работает:
frontend UI ──→ backend API ──→ orchestrator
│
┌───────────────────┼──────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ worker-1 │ │ worker-2 │ │ worker-3 │
│ 24 cores │ │ 512 cores│ │ 512 cores│
└──────────┘ └──────────┘ └──────────┘
У этого формата есть и другие достоинства помимо LLM-совместимости: diff-friendly в git, рендерится в любом контексте (терминал, чат, email), не зависит от внешних инструментов. В моём workbench несколько таких диаграмм — по основным подсистемам. Агент видит, как данные текут через систему, не задавая вопросов.
У каждого проекта — и тем более у системы из десятков проектов — есть история архитектурных развилок: что рассматривали, что выбрали, что отвергли и почему. У человека эта память [6] живёт в голове, в истории переписок, в wiki. LLM не имеет доступа ни к чему из этого — и потому будет раз за разом предлагать варианты, которые уже были рассмотрены и отвергнуты. Причём каждый раз — убедительно аргументируя, потому что вариан�� может выглядеть сильным в изоляции, если не учитывать контекст конкретной системы: её ограничения, зависимости между компонентами, историю эксплуатации и причины, по которым альтернатива не подошла.
Architecture Decision Records (ADR) — способ сделать эту память явной и доступной. Суть формата — не в тяжёлой бюрократии, а в четырёх полях:
– Контекст — что происходило, какая проблема решалась
– Рассмотренные варианты — что оценивали, с плюсами и минусами
– Решение — что выбрали и почему
– Условия пересмотра — когда решение стоит переоценить
Последнее поле — ключевое. Без него ADR фиксирует прошлое, с ним — задаёт условия для будущего пересмотра. Пример:
# ADR-001: СУБД для аналитического pipeline
## Контекст
Текущая СУБД не поддерживает оконные функции для near-realtime агрегации.
## Варианты
A. Оптимизация текущей СУБД — ограничение фундаментальное, не решается настройкой
B. ClickHouse + потоковый ETL — полноценный SQL, materialized views
C. TimescaleDB — на порядок медленнее на аналитике тиковых данных
## Решение
Выбран вариант B.
## Условия пересмотра
Текущая СУБД добавит оконные функции и continuous aggregation.
Без ADR агент предложит “а давайте попробуем вариант C”. С ADR — увидит, что C уже рассматривался, и при необходимости задаст правильный вопрос: “условия пересмотра не изменились?”. Без ухода сессии в нежелательное пространство вариантов.
Несколько ретроспективных ADR по ключевым развилкам системы — и цикл “обсудить → забыть → обсудить заново” разорван.
Есть знания, общие для всех проектов: стиль кода, подход к обработке ошибок, формат коммитов. И есть специфика конкретного проекта: какие API-обёртки использовать, какие паттерны запрещены в этой кодовой базе. Если смешать оба уровня в одном месте, при каждом новом проекте придётся заново описывать общие правила. Если разделить — общее наследуется автоматически.
В Cursor этот принцип реализуется через иерархию правил:
workbench/.cursor/rules/ → Общие для всех проектов
workbench.mdc → Структура системы, навигация
robust-implementation.mdc → Defensive coding, анализ blast radius
project/.cursor/rules/ → Специфичные для проекта
project-overview.mdc → Стек, модули, команды запуска
anti-patterns.mdc → Что запрещено в этом проекте
git-commits.mdc → Формат коммитов
Общие правила из workbench действуют в каждом workspace. Проектные могут ужесточить, но не ослабить. Пример общего правила:
> Не использовать console.log для ошибок. На фронтенде — console.error с префиксом модуля, на бэкенде — structured logger сервиса.
Пример проектного ограничения:
> Не вызывать fetch() напрямую из компонентов. Использовать обёртку api_request(), которая добавляет retry, нормализацию ошибок и заголовки авторизации.
Агент получает оба уровня и генерирует код, соответствующий конвенциям — без напоминаний.
При работе с LLM естественный ритм — несколько проектов параллельно: один в активном фокусе, в остальных агент работает автономно и ждёт ревью. Узкое место в этом процессе — не LLM, а человек. Нужно мгновенно отличать окна друг от друга, чтобы не отправить промп�� не в тот проект и не сбиться с “потока”.
Простое решение — визуальная кодировка workspace. В каждом .code-workspace задаётся уникальный цвет заголовка окна и статус-бара:
"workbench.colorCustomizations": {
"titleBar.activeBackground": "#2d1f3d",
"statusBar.background": "#2d1f3d"
}
Цвета назначаются по ассоциации [7] с проектом: фронтенд — фиолетовый (цвет UI), Rust-сервис — оранжевый, сервис автоматизации — зелёный. Приглушённые тёмные тона, различимые периферийным зрением [8]. Взгляд на полоску внизу экрана — и контекст переключился. Эта мелочь экономит когнитивный ресурс, который лучше потратить на содержательное ревью.
По отдельности каждый из описанных элементов — реестр, топология, ADR, уровни правил — решает свою узкую задачу. Вместе они работают как система: агент начинает продуктивную работу не через несколько минут ориентации, а сразу.
Без knowledge base: “Расскажи про архитектуру подсистемы бэктестинга” → минуты на поиск по файлам, чтение разрозненных README, уточняющие вопросы.
С knowledge base: Агент открывает реестр, видит задействованные сервисы и их связи, читает топологию для понимания потоков данных, заглядывает в план проекта для деталей. Через короткое время он ориентируется и может работать.
Без ADR: “Может, перейдём на другую СУБД?” → повторение дискуссии, которая уже была три месяца назад, с теми же выводами. Или забег по старым “граблям”.
С ADR: Агент видит, что альтернатива рассматривалась и отвергнута. Задаёт единственный нужный вопрос: «условия пересмотра не изменились?» — ответ занимает секунды.
При нескольких рабочих сессиях в день разница накапливается в часы. Это не абстрактная «продуктивность» — это конкретное время, которое уходит на решение задач вместо повторения пройденных шагов.
Для следующих частей есть наработки – как не дать knowledge base устареть: автоматическая валидация, агрегация бэклогов, жизненный цикл документов. Мета-ловушки рекурсивной оптимизации и как с ними бороться.
Автор: VsBirdEye
Источник [9]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/27157
URLs in this post:
[1] ошибки: http://www.braintools.ru/article/4192
[2] опыт: http://www.braintools.ru/article/6952
[3] долговременной памяти: http://www.braintools.ru/article/9500
[4] Повторение: http://www.braintools.ru/article/4012
[5] topology.md: http://topology.md
[6] память: http://www.braintools.ru/article/4140
[7] ассоциации: http://www.braintools.ru/article/621
[8] зрением: http://www.braintools.ru/article/6238
[9] Источник: https://habr.com/ru/articles/1010478/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1010478
Нажмите здесь для печати.