Наткнулся на один AI-психоз под страшным названием «монорепа». Люди на полном серьёзе складывают разные проекты физически в один git-репозиторий — потому что им кажется, что так агенту проще «ходить по файлам» и понимать общий контекст большой корпоративной системы. И под постом десятки комментариев: о да, мы теперь тоже стали так делать, отличный механизм, все довольны.
Блять, люди, вы ёбанулись совсем?
Вы приняли фичу из коробки за магию LLM
Давайте объясню, что вы на самом деле видите, когда любуетесь, как агент «читает ваш проект».
То, что вы наблюдаете глазами — как агент читает файлы с диска — это просто tool. Встроенный тул вашего приложения, который модель дёргает, чтобы вызвать шелл-команды: сделать ls по каталогу, read какого-то файла. Никакой магии, никакого «модель мыслит вашим репозиторием».
Это не откровение LLM и не единственный каноничный вариант работы. Одна из фичей из коробки. Просто так проще осваивать ИИ, когда ты увидел его в первый раз: ого, он ходит по моему проекту и читает файлы, вау!
И вот из этого «вау» рождается вывод: а давайте нахерачим все наши проекты в один каталог, как удобно блять будет агенту! Боже.
Проблема даже не в том, что это некрасиво. Проблема в том, что вы принимаете необратимое архитектурное решение — ломаете границы репозиториев, историю, права доступа, CI, владение кодом — ради удобства демонстрации, которого на самом деле не существует. Вы платите реальную цену за воображаемую выгоду.
Модели насрать, откуда взялся файл
Ключевой момент: модели всё равно, откуда пришёл текст файла.
Программный интерфейс tool_use у модели стандартизирован. Модели всё равно, откуда реально, физически читается файл. Прямо с диска в текущем каталоге. Или из другого каталога. Или из удалённого git-репозитория. Или из sftp-подключения. Или вообще по http откуда-то по сети.
Для модели это всего лишь контент. А контент вы можете подать ей любым способом.
Следствие такое: «где физически лежит код» и «что видит модель» — две разные вещи, которые абстракция tool_use уже давным-давно развязала за вас. Источник контента и способ его подачи модели — не одно и то же. Модель не ходит по вашему диску. Она вызывает тул, который возвращает ей текст. Откуда этот тул взял текст — деталь реализации, спрятанная от модели полностью.
А раз так — физическая монорепа ради агента решает проблему, которой нет. Вы соединили два проекта на уровне файловой системы, чтобы решить задачу, которая живёт на уровне интерфейса инструментов. Это как переклеить обои в квартире, потому что тебе неудобно переключать вкладки в браузере.
Как надо, если очень нужен соседний контекст
Допустим, вам и правда необходимо, чтобы модель видела код соседних проектов. Это нормальная задача.
Подключаете элементарный MCP с readonly-доступом до соседних каталогов — или до общего gitlab/github — и получаете абсолютно тот же эффект. Модель так же дёргает тул, так же получает контент соседнего проекта, так же «понимает общий контекст». Только без необходимости физически сваливать всё в кучу.
Для модели результат тот же, но репозитории остаются разделёнными. Ваши репозитории остаются собой: раздельная история, раздельные права, раздельные пайплайны, чистые границы владения. Доступ агента к чужому контексту задаётся конфигурацией — конфигурируемой подачей, а не свойством вашего дерева каталогов.
Читаемость с диска — это дефолт, который вам показали первым, потому что его проще всего объяснить новичку. Это не потолок и не канон. Самый примитивный из способов подачи контента, а вы возвели его в архитектурный принцип.
Что именно вы ломаете
Вот что ломается при физическом объединении репозиториев ради агента.
| Что ломается | Как выглядит повреждение |
|---|---|
| История коммитов | Изменения проекта A тонут в потоке изменений проекта B. git log теряет смысл. Бисект по одному проекту тащит мусор из другого. |
| Права доступа | Команда проекта B получает доступ к коду проекта A. Ревью кода — мимо. NDA — мимо. |
| CI/CD | Пайплайн пинается на каждое изменение любого проекта. Сборка замедляется. Изоляция тестов — под вопросом. |
| Владение кодом | CODEOWNERS превращается в кашу. Кто за что отвечает — непонятно. |
| Границы развертывания | Проекты, которые могли деплоиться независимо, связаны. Релиз одного тянет за собой другой. |
Эти издержки появляются только ради чтения файлов из одного каталога. Ради того, чтобы агент, который и так умеет читать файлы откуда угодно через стандартизированный интерфейс, читал их из одного каталога вместо нескольких.
Не ломайте репозитории под галлюцинацию удобства
Коротко: это плохое архитектурное решение. Никогда не делайте таких решений — не режьте архитектуру ради демонстрационного эффекта, который вам померещился магией.
Источник контента и способ его подачи модели — разные слои. tool_use их уже развязал. Физическая монорепа «чтобы агенту было удобнее» — карго-культ: вы копируете внешний ритуал, не понимая механики под ним.
Если нужен доступ к соседним репозиториям без объединения — подать агенту соседний контент без ломки границ — настройте отдельный readonly-tool/MCP для чтения нужных репозиториев.