Давай признаем: ты чуть ли не 90% кода пишешь с помощью Claude, Codex или ещё какого-нибудь агента. Ты выпускаешь несколько MR-ов в день, пушишь несколько тысяч строк кода и быстро просматриваешь псевдокод на ревью, чтобы доказать самому себе, что это действительно ты напряг мозг и сделал задачу. Ты делаешь ровно то же, что и всегда, думая, что агент просто ускоряет цикл разработки, который ты проходил ежедневно.
Однако не покидает ощущение, что это какой-то цирк. Ты просто осознанно повторяешь действия, которые раньше имели смысл, но в глубине души фрустрируешься из-за странности происходящего.
Давай разберёмся, что мы вообще делаем и зачем.
При получении новой задачи агент каждый раз проходит следующий цикл:
-
Получить задачу.
-
Понять архитектуру.
-
Найти нужные файлы.
-
Найти похожие примеры.
-
Внести изменения.
-
Запустить проверки.
-
Исправить ошибки.
Отсюда мы видим, что агент при постановке новой задачи каждый раз «насыщается» контекстом о проекте. У агента нет опыта работы с вашим проектом: он не помнит архитектуру, не знает, в какую сторону вы двигаетесь. Он буквально каждый раз заново смотрит на ваш проект. Представьте нового разраба в команде с амнезией, который вечно проходит онбординг проекта. Следовательно, мы должны подогнать архитектуру нашего проекта для разработчика с отклонениями (AI-first).
Исторически хорошая архитектура оценивалась довольно стандартными критериями:
-
поддерживаемость;
-
расширяемость;
-
повторное использование;
-
модульность;
-
тестируемость.
За месяцы корпения над задачами опытный разраб успевает выстроить какую-никакую карту проекта в голове. При постановке новой задачи мне не нужно изучать проект: я почти мгновенно прикидываю, куда, что и как нужно добавить. Агенты пока не умеют «накапливать» опыт из-за своей архитектуры, так как у них нет явной «пассивной» фазы мышления, но это вообще отдельная тема, поэтому пока забьём.
Идея в том, чтобы видоизменить архитектуру нашего проекта так, чтобы агент каждый раз заново проходил успешный онбординг проекта и каждый раз заново понимал, как, что и где ему нужно сделать. То есть наша архитектура становится интерфейсом между агентом и репозиторием.
Harness Engineering
В начале 2026 года OpenAI представила концепцию Harness Engineering. Эта концепция изначально относится только к созданию агентов поверх LLM. Главный тезис, который она выражает: окружение, в котором работает LLM, гораздо сильнее влияет на результат, чем сама LLM. Однако этот подход активно начали экстраполировать на архитектуру разрабатываемых приложений.
Я выделил четыре свойства из Harness-методологии, которые добавил к современной архитектуре приложения:
-
Navigability (очевидность навигации).
-
Constrainability (ограниченность системы).
-
Learnability (обучаемость).
-
Verifiability (проверяемость).
Navigability (очевидность навигации)
Это свойство отвечает на вопрос: может ли агент быстро найти нужное место в проекте? Каждое неочевидное расположение какого-либо модуля для агента засоряет его контекст ненужной информацией.
Допустим, у нас есть задача: добавить отмену заказа. Представим, что эта команда выполняется в двух репозиториях с абсолютно идентичной логикой, но с разным уровнем разграничения и структуры.
Вариант: Component-Driven Architecture
components/
hooks/
services/
types/
utils/
Глядя на эту структуру, мы предполагаем, что, наверное, в components есть какое-то представление, условный CancelComponent, который использует хук useCancel, который использует сервис cancel, который использует тип cancel. И это ещё дай бог если однонаправленное распределение ответственности.
Однако в реальных проектах, будем честны, мы не находимся постоянно в идеальной точке, где всё идеально определено и задекларировано. Часто у нас имеются компоненты, которые внутри себя содержат бизнес-логику, а не чистое представление. Часто зоны ответственности размазаны по проекту.
Однако вы это понимаете, исходя из того, что уже поработали с проектом, поняли как технические, так и производственные особенности. Условно, такой-то модуль я написал криво и быстро закинул в прод, потому что так нужно было бизнесу, однако пометил, что в будущем его нужно убрать. Но сейчас не об этом.
Пока наш агент будет составлять у себя в контекстном окне мапу вашего проекта под конкретно эту задачу, ему придётся прочитать и по пути добавить очень много лишнего. Буквально посмотреть дерево импортов, увидеть где-то нарушение однонаправленности или «мягкое» разделение зон ответственности. Агент, вероятно, предположит, что стоит также прочитать файлы, напрямую не относящиеся к задаче, но способные повлиять на её выполнение. Из-за этого мы буквально засоряем мусором контекстное окно.
Вариант: FSD
features/
cancel-order/
Как только мы обозначили задачу, агент сразу по папке может предположить, что всё нужное находится внутри… и он будет прав. Даже если у нас FBD, то даже в таком случае агент отлично справится с поиском нужного контекста для выполнения задачи.
Именно поэтому feature-oriented-архитектуры сегодня выглядят значительно привлекательнее, чем несколько лет назад: не потому, что они моднее, а потому, что они уменьшают стоимость поиска контекста.
Важно понимать, что речь необязательно идёт о Feature-Sliced Design. Любая архитектура, которая локализует бизнесовую функциональность, обладает этим свойством. Отдельно напишу статью про сравнение FSD и Clean Architecture: там есть свои особенности при работе с агентом, и каждый из этих видов даёт свои преимущества.
Constrainability (ограниченность системы)
Это свойство нашей новой архитектуры должно помогать агенту отвечать на следующие вопросы:
-
Что является публичным API?
-
Что считается внутренней реализацией?
Для решения этих вопросов нам отлично поможет жёсткий ESLint. Чем больше ограничений, тем лучше. Нужно ограничить, какие слои могут импортировать какие слои. Жёстко ограничить, что условный /shared не может импортировать ничего извне, так как это наименьшая единица реализации, и так далее по зонам ответственности. Желательно перевести warn в error, чтобы активнее бить по рукам нашего крудошлёпа из Купертино.
Также стала ярко выраженной роль TypeScript и Zod для рантайма. На уровне AGENTS.md нужно вообще запретить декларировать тип any в любом проявлении, а при возможности обозначить union-типы, дабы максимально ограничить работу агента. Лучше иметь несколько похожих, но очень узких реализаций типов, нежели один общий.
Learnability (обучаемость)
Это свойство почти не обсуждается в традиционной архитектуре. Я пришёл к выводу, что при необходимости в каждой feature (напоминаю, что у нас в проекте используется FSD) нужно писать собственный AGENTS.md, где описан эталонный пример реализации в репозитории. Или же можно даже указать сторонние реализации в виде ссылки на репозиторий или просто отдельно взятые куски кода.
Также отлично работают тесты, так как после их прочтения мы явно понимаем ожидаемое поведение от реализации того или иного компонента.
Также отлично работает Storybook.
Основная идея заключается в том, чтобы вместо длинной документации агент мог ориентироваться на реальные рабочие решения внутри проекта.
Verifiability (проверяемость)
До появления агентов тесты воспринимались как инструмент контроля качества. Теперь они выполняют ещё одну функцию: становятся языком общения между репозиторием и агентом.
После каждого изменения агент задаёт системе один и тот же вопрос: всё ещё работает? Ответ должен быть максимально объективным.
TypeScript
↓
ESLint
↓
Unit Tests
↓
Integration Tests
↓
Playwright
↓
Build
Что с этим делать на практике?
Проверить свой файл AGENTS.md на актуальность описанной там архитектуры и стайлгайда. Далее описать, что ESLint должен жёстко ограничивать импорты. Затем добавить, что в проекте не должно быть никаких any, при возможности использовать union-типы, описать дизайн-систему и запретить создание новых дизайн-компонентов без прямого аппрува.
После этого просим нашего выродка Сэма Альтмана провести аудит и даём ему пару итераций на исправление базовых косяков. Уже в дальнейшем ты повернёшь свою голову под нужным углом и начнёшь понимать, как описывать свой же проект читаемым для агента.
В идеале в папку каждой фичи нужно добавить свой AGENTS.md, где описаны юзкейсы, приведены примеры и добавлены строгие запреты.
Уверен, что ты со мной не будешь согласен, поэтому прошу поиздеваться надо мной в комментариях. Просто мнения и свои наблюдения за изменением разработки тоже пиши.
Литература
-
OpenAI. Harness engineering: Leveraging Codex in an agent-first world. https://openai.com/index/harness-engineering/
-
OpenAI. Unlocking the Codex Harness. https://openai.com/index/unlocking-the-codex-harness/
-
Martin Fowler. Harness Engineering for Coding Agent Users. https://martinfowler.com/articles/harness-engineering.html
-
Martin Fowler. Context Engineering for Coding Agents. https://martinfowler.com/articles/exploring-gen-ai/context-engineering-coding-agents.html
-
Zhong, Zhu et al. AI Harness Engineering: A Runtime Substrate for Foundation-Model Software Agents. https://arxiv.org/abs/2605.13357
-
GitHub. Spec Kit. https://github.com/github/spec-kit
Автор: clearmodern


