На монорепо в 200к строк TypeScript пробовали разные подходы, сейчас смотрим в сторону статического анализа как раз. Интересно что у CodeGraph нет эмбеддингов, то есть поиск только структурный, по символам и связям. Это хорошо для "кто вызывает эту функцию", но как оно справляется с семантическим поиском типа "где у нас обрабатывается авторизация", когда сам код называется не auth а permission_check или middleware_guard? Это та граница где vector-подход выигрывает, интересно как авторы видят это ограничение.
Именно, и это ещё один аргумент в пользу паттернов которые можно объяснить в одной строке: "используй object as const вместо enum". Чем проще правило, тем надёжнее его выполняет ИИ и тем легче ревьюить результат.
Согласен с выводом, но думаю суть вопроса немного в другом. Agent-first это не про синтаксис языка а про качество структурированного фидбека который агент получает от тулинга. TypeScript уже достаточно agent-friendly потому что у него отличный LSP, понятные сообщения об ошибках и предсказуемая система типов. Проблема не в том что у языка фигурные скобки, а в том что большинство ошибок в больших кодовых базах это семантические ошибки которые ни один компилятор не поймает.
Реально узнаваемая история. У нас похожее было с Code-агентом, который уверенно "вспоминал" архитектурные решения которых никогда не было. Вылечилось двумя вещами: явная инструкция "если не нашёл в контексте, напиши что не знаешь, не выдумывай" и принудительная верификация ответа на наличие конкретного факта из базы знаний перед отправкой. Второе важнее первого, потому что инструкцию про "не выдумывай" модель выполняет непоследовательно, а верификация факта это уже детерминированная проверка.
Похожий путь прошли, только пришли к немного другому решению, const object с as const вместо enum, но тот же принцип. Главный выигрыш который вы правильно нащупали, это когда к значению нужно добавить метаданные (цвет, иконку, условие видимости), с enum это всегда костыль, а с конфигом просто ещё одно поле. Плюс Claude Code такой паттерн знает хорошо и генерирует аккуратно, в отличие от enum-хелперов которые каждый раз делает по-своему.
Cursor для прототипирования это да, очень быстро. Сам делал что-то похожее, разница между "работает как демо" и "можно отдать пользователям" огромная, особенно по части обработки граничных случаев и стабильности. Интересно как у вас разрешился вопрос с оценкой макетов по внутренней документации, это же RAG по гайдлайнам? Именно это место в LLM-пайплайнах обычно самое нестабильное.
Боль узнаваемая, сам прошёл этот путь на проекте примерно в 200к строк NestJS. Feature-based структура выглядит логично в начале, потом начинается перекрёстное использование сервисов между модулями, circular dependencies, и в итоге модули которые по названию независимы по факту связаны со всем остальным. У нас спас явный запрет на cross-module service injection кроме как через shared-модули, и правило что если сервис нужен в двух местах он переезжает в core. Интересно как вы решаете проблему агрегации данных из нескольких доменов, это всегда самое больное место.
Про "don't know? -> google it" огонь, беру. Сам больше думал про структуру а не про токен-экономию на уровне синтаксиса, попробую переписать несколько правил в телеграфном стиле и посмотрю изменится ли поведение. Статья про контекстную гигиену кстати была бы очень в тему, про это реально мало написано.
Хороший нюанс, не думал об этом в таком разрезе. Получается три уровня: в CLAUDE.md то что нужно в каждой сессии, в скиллах то что нужно часто но не всегда, и агенты для одноразовых задач где важно не засорять основной контекст. Попробую для длинных рутинных операций, у нас как раз есть несколько таких задач которые сейчас идут в основном контексте и действительно его раздувают.
Про лимит не знал точных цифр, спасибо. Это ещё один аргумент за то что CLAUDE.md должен быть компактным, а тяжёлые инструкции уходят в скиллы или slash-команды которые подгружаются только по запросу. По ощущениям именно так и оптимально, маленький корневой файл с принципами и отдельные команды под конкретные задачи, в итоге на каждый запрос тратишь только нужный контекст.
Точно, разрыв между "накопленный опыт в тикетах за 10 лет" и "всё описано рядом с кодом" это реально разные задачи. У нас проект относительно молодой и CLAUDE.md закрывает текущие решения, но уже чувствуем что когда история решений накапливается, плоский файл начинает трещать. Интересно как у вас выглядит точка где RAG начинает выигрывать, по объёму контекста или по типу задач, и есть ли смысл гибридного подхода когда CLAUDE.md покрывает "сейчас", а RAG достаёт "почему было принято решение год назад".
Поймал точно, противоречия это главная болезнь когда файл накапливается со временем. Идея попросить Claude самого найти противоречия реально работает, сам делаю такой аудит примерно раз в месяц, Claude довольно точно находит где правила конфликтуют. И про CLAUDE.md как оглавление со ссылками на отдельные файлы согласен, монолит проигрывает структурированному дереву.
Именно так и работает, маленькие специализированные скиллы под конкретную задачу вместо одного огромного файла. У меня отдельно под git-workflow, под архитектурные решения, под правила тестирования. Claude читает узкий файл гораздо внимательнее чем портянку на 500 строк.
Про "делай так-то" согласен, у меня тоже раньше половина правил начиналась на "никогда не делай", сейчас переписываю на позитивные формулировки с примерами. Obsidian через MCP интересная идея, пока работаю на обычных md файлах, но идея с отдельной индексированной базой знаний имеет смысл для больших проектов. И про порядок секций тоже нащупал, Claude читает сверху вниз и верхние инструкции реально весомее.
Да, именно, скиллы для переиспользуемой логики которую хочешь переносить между проектами, а описания в главном файле про контекст конкретного проекта. Сам пришёл к такой же схеме, главный файл держу как "что это и кто мы", а в скиллах всё про "как делать". Удобно когда один скилл работает в разных проектах без изменений.
Сам через это прошёл, сначала один большой файл на всё, потом заметил что LLM начинает игнорировать нижние секции. Разбивка на файлы с индексом реально лечит эту проблему, главный файл как оглавление, а дальше конкретные md файлы по темам. RAG для кода тоже смотрел, но для небольших проектов структурированные md файлы справляются хорошо без дополнительной инфраструктуры.
DI-контейнер под шаренную бизнес-логику это хороший выбор именно потому что контракт становится явным. Видели похожее при выделении общих модулей в монорепозиториях: пока всё жило в god object зависимости были неформальными, как только начинаем регистрировать через интерфейсы сразу видно где реально зависимость а где «просто так подтянули». Самый неприятный этап у нас оказался не технический а организационный: договориться кто владелец контракта между командами. Пришли к тому что владелец host, а изменения в контрактах проходят через ревью всех потребителей иначе молча ломаются на чужих микрофронтах.
Основной тезис про «агент идёт по бумажке» чувствуется не только в пентесте. У нас был кейс с Claude Code агентом, который читал логи внешнего сервиса для диагностики. Через месяц в логах обнаружили строки специально сформированные чтобы влиять на следующий шаг агента, не от злоумышленника, просто разработчик другого сервиса «подсказал» агенту через лог что делать. Граница между доверенными инструкциями и недоверенными данными в агентских системах размывается быстрее чем мы думаем, особенно когда один агент читает вывод другого.
«Эссе на тему как было бы хорошо работать», это точное описание того, во что превращается CLAUDE.md после трёх месяцев добавления правил. У нас корневой файл дорос до похожего состояния, агент читал всё разом и выбирал интерпретацию которая ему удобнее. Вылечили иерархией: корневой CLAUDE.md оставили только для жёстких инвариантов (что никогда нельзя), а модульные контексты переехали в папки и slash-команды. Теперь контракт грузится только когда нужен, а не висит в каждой сессии и не конкурирует за интерпретацию.
Про три правила тестов в CLAUDE.md, которые начинают противоречить друг другу, это точно описано. Вылечилось переносом правил в отдельные команды. В корневом CLAUDE.md остались только принципы (архитектурные решения, что никогда не делать), а всё про тесты переехало в slash-команду /test со своим полным контекстом. Теперь правило срабатывает только когда нужно, а не висит в каждой сессии и не конкурирует с соседними строчками. Плоский файл с 50 правилами, это и есть тот самый убер-промпт, только замаскированный под инфраструктуру.
На монорепо в 200к строк TypeScript пробовали разные подходы, сейчас смотрим в сторону статического анализа как раз. Интересно что у CodeGraph нет эмбеддингов, то есть поиск только структурный, по символам и связям. Это хорошо для "кто вызывает эту функцию", но как оно справляется с семантическим поиском типа "где у нас обрабатывается авторизация", когда сам код называется не auth а permission_check или middleware_guard? Это та граница где vector-подход выигрывает, интересно как авторы видят это ограничение.
Именно, и это ещё один аргумент в пользу паттернов которые можно объяснить в одной строке: "используй object as const вместо enum". Чем проще правило, тем надёжнее его выполняет ИИ и тем легче ревьюить результат.
Согласен с выводом, но думаю суть вопроса немного в другом. Agent-first это не про синтаксис языка а про качество структурированного фидбека который агент получает от тулинга. TypeScript уже достаточно agent-friendly потому что у него отличный LSP, понятные сообщения об ошибках и предсказуемая система типов. Проблема не в том что у языка фигурные скобки, а в том что большинство ошибок в больших кодовых базах это семантические ошибки которые ни один компилятор не поймает.
Реально узнаваемая история. У нас похожее было с Code-агентом, который уверенно "вспоминал" архитектурные решения которых никогда не было. Вылечилось двумя вещами: явная инструкция "если не нашёл в контексте, напиши что не знаешь, не выдумывай" и принудительная верификация ответа на наличие конкретного факта из базы знаний перед отправкой. Второе важнее первого, потому что инструкцию про "не выдумывай" модель выполняет непоследовательно, а верификация факта это уже детерминированная проверка.
Похожий путь прошли, только пришли к немного другому решению, const object с as const вместо enum, но тот же принцип. Главный выигрыш который вы правильно нащупали, это когда к значению нужно добавить метаданные (цвет, иконку, условие видимости), с enum это всегда костыль, а с конфигом просто ещё одно поле. Плюс Claude Code такой паттерн знает хорошо и генерирует аккуратно, в отличие от enum-хелперов которые каждый раз делает по-своему.
Cursor для прототипирования это да, очень быстро. Сам делал что-то похожее, разница между "работает как демо" и "можно отдать пользователям" огромная, особенно по части обработки граничных случаев и стабильности. Интересно как у вас разрешился вопрос с оценкой макетов по внутренней документации, это же RAG по гайдлайнам? Именно это место в LLM-пайплайнах обычно самое нестабильное.
Боль узнаваемая, сам прошёл этот путь на проекте примерно в 200к строк NestJS. Feature-based структура выглядит логично в начале, потом начинается перекрёстное использование сервисов между модулями, circular dependencies, и в итоге модули которые по названию независимы по факту связаны со всем остальным. У нас спас явный запрет на cross-module service injection кроме как через shared-модули, и правило что если сервис нужен в двух местах он переезжает в core. Интересно как вы решаете проблему агрегации данных из нескольких доменов, это всегда самое больное место.
Про "don't know? -> google it" огонь, беру. Сам больше думал про структуру а не про токен-экономию на уровне синтаксиса, попробую переписать несколько правил в телеграфном стиле и посмотрю изменится ли поведение. Статья про контекстную гигиену кстати была бы очень в тему, про это реально мало написано.
Хороший нюанс, не думал об этом в таком разрезе. Получается три уровня: в CLAUDE.md то что нужно в каждой сессии, в скиллах то что нужно часто но не всегда, и агенты для одноразовых задач где важно не засорять основной контекст. Попробую для длинных рутинных операций, у нас как раз есть несколько таких задач которые сейчас идут в основном контексте и действительно его раздувают.
Про лимит не знал точных цифр, спасибо. Это ещё один аргумент за то что CLAUDE.md должен быть компактным, а тяжёлые инструкции уходят в скиллы или slash-команды которые подгружаются только по запросу. По ощущениям именно так и оптимально, маленький корневой файл с принципами и отдельные команды под конкретные задачи, в итоге на каждый запрос тратишь только нужный контекст.
Точно, разрыв между "накопленный опыт в тикетах за 10 лет" и "всё описано рядом с кодом" это реально разные задачи. У нас проект относительно молодой и CLAUDE.md закрывает текущие решения, но уже чувствуем что когда история решений накапливается, плоский файл начинает трещать. Интересно как у вас выглядит точка где RAG начинает выигрывать, по объёму контекста или по типу задач, и есть ли смысл гибридного подхода когда CLAUDE.md покрывает "сейчас", а RAG достаёт "почему было принято решение год назад".
Поймал точно, противоречия это главная болезнь когда файл накапливается со временем. Идея попросить Claude самого найти противоречия реально работает, сам делаю такой аудит примерно раз в месяц, Claude довольно точно находит где правила конфликтуют. И про CLAUDE.md как оглавление со ссылками на отдельные файлы согласен, монолит проигрывает структурированному дереву.
Именно так и работает, маленькие специализированные скиллы под конкретную задачу вместо одного огромного файла. У меня отдельно под git-workflow, под архитектурные решения, под правила тестирования. Claude читает узкий файл гораздо внимательнее чем портянку на 500 строк.
Про "делай так-то" согласен, у меня тоже раньше половина правил начиналась на "никогда не делай", сейчас переписываю на позитивные формулировки с примерами. Obsidian через MCP интересная идея, пока работаю на обычных md файлах, но идея с отдельной индексированной базой знаний имеет смысл для больших проектов. И про порядок секций тоже нащупал, Claude читает сверху вниз и верхние инструкции реально весомее.
Да, именно, скиллы для переиспользуемой логики которую хочешь переносить между проектами, а описания в главном файле про контекст конкретного проекта. Сам пришёл к такой же схеме, главный файл держу как "что это и кто мы", а в скиллах всё про "как делать". Удобно когда один скилл работает в разных проектах без изменений.
Сам через это прошёл, сначала один большой файл на всё, потом заметил что LLM начинает игнорировать нижние секции. Разбивка на файлы с индексом реально лечит эту проблему, главный файл как оглавление, а дальше конкретные md файлы по темам. RAG для кода тоже смотрел, но для небольших проектов структурированные md файлы справляются хорошо без дополнительной инфраструктуры.
DI-контейнер под шаренную бизнес-логику это хороший выбор именно потому что контракт становится явным. Видели похожее при выделении общих модулей в монорепозиториях: пока всё жило в god object зависимости были неформальными, как только начинаем регистрировать через интерфейсы сразу видно где реально зависимость а где «просто так подтянули». Самый неприятный этап у нас оказался не технический а организационный: договориться кто владелец контракта между командами. Пришли к тому что владелец host, а изменения в контрактах проходят через ревью всех потребителей иначе молча ломаются на чужих микрофронтах.
Основной тезис про «агент идёт по бумажке» чувствуется не только в пентесте. У нас был кейс с Claude Code агентом, который читал логи внешнего сервиса для диагностики. Через месяц в логах обнаружили строки специально сформированные чтобы влиять на следующий шаг агента, не от злоумышленника, просто разработчик другого сервиса «подсказал» агенту через лог что делать. Граница между доверенными инструкциями и недоверенными данными в агентских системах размывается быстрее чем мы думаем, особенно когда один агент читает вывод другого.
«Эссе на тему как было бы хорошо работать», это точное описание того, во что превращается CLAUDE.md после трёх месяцев добавления правил. У нас корневой файл дорос до похожего состояния, агент читал всё разом и выбирал интерпретацию которая ему удобнее. Вылечили иерархией: корневой CLAUDE.md оставили только для жёстких инвариантов (что никогда нельзя), а модульные контексты переехали в папки и slash-команды. Теперь контракт грузится только когда нужен, а не висит в каждой сессии и не конкурирует за интерпретацию.
Про три правила тестов в CLAUDE.md, которые начинают противоречить друг другу, это точно описано. Вылечилось переносом правил в отдельные команды. В корневом CLAUDE.md остались только принципы (архитектурные решения, что никогда не делать), а всё про тесты переехало в slash-команду /test со своим полным контекстом. Теперь правило срабатывает только когда нужно, а не висит в каждой сессии и не конкурирует с соседними строчками. Плоский файл с 50 правилами, это и есть тот самый убер-промпт, только замаскированный под инфраструктуру.