Проектирование инфраструктуры: использование Codex в мире, где первыми появляются агенты

Автор: Райан Лопополо (Ryan Lopopolo), сотрудник технического отдела

За последние пять месяцев наша команда проводила эксперимент: создание и выпуск внутренней бета-версии программного продукта с 0 строк кода, написанного вручную.

У продукта есть внутренние ежедневные пользователи и внешние альфа-тестировщики. Он собирается, развертывается, ломается и исправляется. Разница лишь в том, что каждая строка кода — бизнес-логика, тесты, конфигурация CI, документация, мониторинг и внутренние инструменты — была написана Codex. По нашим оценкам, мы создали это примерно за 1/10 времени, которое ушло бы на написание кода вручную.

Люди задают направление. Агенты выполняют.

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

Эта статья о том, чему мы научились, создавая совершенно новый продукт с помощью команды агентов: что ломалось, что давало кумулятивный эффект и как максимизировать наш единственный действительно дефицитный ресурс: человеческое время и внимание.

Мы начали с пустого репозитория git

Первый коммит в пустой репозиторий был сделан в конце августа 2025 года.

Начальный каркас — структура репозитория, конфигурация CI, правила форматирования, настройка пакетного менеджера и фреймворк приложения — был сгенерирован с помощью Codex CLI на базе GPT‑5 под руководством небольшого набора существующих шаблонов. Даже первоначальный файл AGENTS.md, который указывает агентам, как работать в репозитории, был написан самим Codex.

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

Пять месяцев спустя репозиторий содержит около миллиона строк кода, охватывающих бизнес-логику, инфраструктуру, инструментарий, документацию и внутренние утилиты для разработчиков. За этот период было открыто и объединено примерно 1 500 запросов на слияние (PR), причем небольшая команда всего из трех инженеров управляла Codex. Это означает среднюю пропускную способность в 3,5 PR на инженера в день, и, что удивительно, эта пропускная способность возросла по мере того, как команда выросла до семи инженеров. Важно отметить, что это не было производство ради производства: продукт использовали сотни внутренних пользователей, включая постоянных опытных пользователей внутри компании.

На протяжении всего процесса разработки люди никогда не писали код напрямую. Это стало ключевой философией команды: никакого написанного вручную кода.

Переосмысление роли инженера

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

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

На практике это означало работу вглубь: декомпозицию крупных целей на более мелкие строительные блоки (проектирование, код, ревью, тестирование и т.д.), подачу агенту запросов на создание этих блоков и использование их для решения более сложных задач. Когда что-то шло не так, исправлением практически никогда не был подход «постарайся лучше». Поскольку единственным способом продвижения вперед было заставить Codex выполнить работу, инженеры-люди всегда подключались к задаче со словами: «какой возможности не хватает и как сделать ее понятной и обязательной для агента?»

Люди взаимодействуют с системой почти исключительно через промпты (текстовые запросы): инженер описывает задачу, запускает агента и позволяет ему открыть pull request. Чтобы довести PR до завершения, мы даем Codex указание локально проанализировать собственные изменения, запросить дополнительные специфические рецензии у агентов как локально, так и в облаке, реагировать на любые отзывы от людей или других агентов и повторять этот цикл до тех пор, покуда все агенты-рецензенты не останутся довольны (фактически это цикл Ральфа Виггама). Codex напрямую использует наши стандартные инструменты разработки (gh, локальные скрипты и встроенные в репозиторий навыки) для сбора контекста без необходимости для людей копировать и вставлять данные в CLI.

Люди могут делать ревью pull request’ов, но это не обязательно. Со временем мы перевели практически всю работу по код-ревью в режим «агент для агента».

Повышение читаемости приложения для агента

По мере роста пропускной способности кода узким местом стала наша способность проводить контроль качества (QA) вручную. Поскольку фиксированным ограничением всегда оставались человеческое время и внимание, мы работали над тем, чтобы наделить агента новыми возможностями, сделав пользовательский интерфейс приложения, логи и метрики непосредственно понятными для Codex.

Например, мы сделали так, чтобы приложение могло запускаться для каждого отдельного дерева работы (git worktree), позволяя Codex запускать и управлять одним экземпляром на каждое изменение. Мы также интегрировали протокол Chrome DevTools в среду выполнения агента и создали навыки для работы со снимками DOM, скриншотами и навигацией. Это позволило Codex воспроизводить баги, проверять исправления и рассуждать о поведении пользовательского интерфейса напрямую.

Diagram titled

Мы сделали то же самое и для инструментов мониторинга (observability). Логи, метрики и трассировки предоставляются Codex через локальный стек мониторинга, который является эфемерным для каждого конкретного дерева работы. Codex работает с полностью изолированной версией приложения, включая его логи и метрики, которые удаляются после завершения задачи. Агенты могут запрашивать логи с помощью LogQL, а метрики — с помощью PromQL. Имея такой контекст, такие промпты, как «убедитесь, что запуск службы завершается менее чем за 800 мс» или «ни один спан в этих четырех критических пользовательских сценариях не превышает двух секунд», становятся вполне выполнимыми.

Diagram titled

Мы регулярно наблюдаем, как отдельные запуски Codex работают над одной задачей более шести часов (часто в то время, когда люди спят).

Мы сделали знания репозитория системным источником истины

Управление контекстом — одна из самых больших проблем при обеспечении эффективности агентов в крупных и сложных задачах. Один из самых ранних уроков, которые мы усвоили, прост: дайте Codex карту, а не инструкцию на 1000 страниц.

Мы попробовали подход с «одним большим AGENTS.md». Он потерпел предсказуемую неудачу:

  • Контекст — дефицитный ресурс. Огромный файл с инструкциями вытесняет саму задачу, код и соответствующую документацию, в результате чего агент либо упускает ключевые ограничения, либо начинает оптимизировать не то, что нужно.
  • Избыток указаний становится отсутствием указаний. Когда всё «важно», не важно ничего. В итоге агенты занимаются локальным сопоставлением паттернов, вместо того чтобы ориентироваться целенаправленно.
  • Он мгновенно устаревает. Монолитное руководство превращается в кладбище устаревших правил. Агенты не могут понять, что еще актуально, люди перестают его поддерживать, и файл тихо превращается в источник проблем.
  • Его сложно проверить. Единый массив текста не подходит для механических проверок (покрытие, актуальность, владение, перекрестные ссылки), поэтому рассинхронизация неизбежна.

Поэтому вместо того, чтобы относиться к AGENTS.md как к энциклопедии, мы используем его как оглавление.

База знаний репозитория находится в структурированном каталоге docs/, который рассматривается как системный источник достоверных данных. Короткий файл AGENTS.md (около 100 строк) внедряется в контекст и служит в первую очередь картой с указателями на более глубокие источники информации в других местах.

Plain Text

1
AGENTS.md
2
ARCHITECTURE.md
3
docs/
4
├── design-docs/
5
│ ├── index.md
6
│ ├── core-beliefs.md
7
│ └── ...
8
├── exec-plans/
9
│ ├── active/
10
│ ├── completed/
11
│ └── tech-debt-tracker.md
12
├── generated/
13
│ └── db-schema.md
14
├── product-specs/
15
│ ├── index.md
16
│ ├── new-user-onboarding.md
17
│ └── ...
18
├── references/
19
│ ├── design-system-reference-llms.txt
20
│ ├── nixpacks-llms.txt
21
│ ├── uv-llms.txt
22
│ └── ...
23
├── DESIGN.md
24
├── FRONTEND.md
25
├── PLANS.md
26
├── PRODUCT_SENSE.md
27
├── QUALITY_SCORE.md
28
├── RELIABILITY.md
29
└── SECURITY.md

Структура хранилища знаний внутри репозитория.

Документация по дизайну каталогизируется и индексируется, включая статус проверки и набор базовых принципов, определяющих принципы работы, ориентированные на агентов. Архитектурная документация предоставляет карту верхнего уровня доменов и многослойности пакетов. Документ качества оценивает каждый продуктовый домен и архитектурный слой, отслеживая пробелы с течением времени.

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

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

Мы обеспечиваем это механически. Специализированные линтеры и задачи непрерывной интеграции (CI) проверяют, чтобы база знаний была актуальной, правильно связанной перекрестными ссылками и структурированной. Периодически запускаемый агент «ухода за документацией» сканирует устаревшую или неактуальную документацию, которая не отражает реальное поведение кода, и открывает пулл-реквесты с исправлениями.

Главная цель — понятность для агента

По мере развития кодовой базы структура принятия проектных решений в Codex также нуждалась в развитии.

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

С точки зрения агента, всё, к чему он не имеет доступа в контексте во время работы, фактически не существует. Знания, хранящиеся в Google Документах, чатах или головах людей, недоступны для системы. Всё, что он может видеть — это локальные для репозитория версионируемые артефакты (например, код, файлы markdown, схемы, исполняемые планы).

Diagram titled

Со временем мы поняли, что нам нужно передавать в репозиторий всё больше и больше контекста. Обсуждение в Slack, которое помогло команде прийти к единому архитектурному паттерну? Если оно недоступно для агента, оно для него не существует — точно так же, как оно было бы неизвестно новому сотруднику, пришедшему через три месяца.

Предоставление Codex большего контекста означает организацию и предоставление правильной информации, чтобы агент мог анализировать ее, а не перегрузку специальными инструкциями. Точно так же, как при адаптации нового члена команды к принципам работы с продуктом, инженерным нормам и командной культуре (включая предпочтения в отношении эмодзи), предоставление этой информации агенту приводит к более согласованным результатам.

Такой подход прояснил множество компромиссов. Мы отдавали предпочтение зависимостям и абстракциям, которые можно полностью осмыслить внутри репозитория. Технологии, которые часто называют «скучными», как правило, проще моделируются агентами благодаря возможности компоновки, стабильности API и представлению в обучающей выборке. В некоторых случаях было дешевле заставить агента повторно реализовать подмножества функциональности, чем обходить непрозрачное поведение внешних публичных библиотек. Например, вместо подключения стандартного пакета в стиле p-limit мы реализовали собственную вспомогательную функцию для сопоставления с поддержкой параллелизма: она тесно интегрирована с нашей инструментальной системой OpenTelemetry, имеет 100% покрытие тестами и ведет себя именно так, как ожидает наша среда выполнения.

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

Соблюдение архитектуры и стандартов качества

Сама по себе документация не поддерживает слаженность полностью сгенерированной агентом кодовой базы. Соблюдая инварианты, а не занимаясь микроменеджментом реализации, мы позволяем агентам выпускать код быстро, не подрывая фундамент. Например, мы требуем, чтобы Codex разбирал структуры данных на границе, но не предписываем, как именно это делать (модели, судя по всему, нравится Zod, но мы не навязывали эту конкретную библиотеку).

Агенты наиболее эффективны в средах со строгими границами и предсказуемой структурой, поэтому мы построили приложение вокруг жесткой архитектурной модели. Каждый бизнес-домен разделен на фиксированный набор слоев со строго проверяемыми направлениями зависимостей и ограниченным набором допустимых связей. Эти ограничения обеспечиваются механически с помощью пользовательских линтеров (сгенерированных Codex, конечно же!) и структурных тестов.

На диаграмме ниже показано правило: в рамках каждого бизнес-домена (например, настроек приложения) код может зависеть только «вперед» через фиксированный набор слоев (Типы → Конфигурация → Репозиторий → Сервис → Среда выполнения → Интерфейс). Сквозные задачи (авторизация, коннекторы, телеметрия, флаги функций) внедряются через единый явный интерфейс: Провайдеры. Всё остальное запрещено и контролируется механически.

Diagram titled

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

На практике мы применяем эти правила с помощью пользовательских линтеров и структурных тестов, а также небольшого набора «инвариантов вкуса». Например, мы стадически принудительно используем структурированное логирование, соглашения об именовании схем и типов, ограничения на размер файлов и требования к надежности для конкретных платформ с помощью кастомных правил линтинга. Поскольку правила линтинга написаны нами, мы пишем сообщения об ошибках так, чтобы внедрять инструкции по устранению проблем прямо в контекст агента.

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

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

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

Человеческий вкус непрерывно возвращается в систему. Замечания к код-ревью, рефакторинг пулл-реквестов и баги, с которыми сталкиваются пользователи, фиксируются в виде обновлений документации или кодируются напрямую в инструменты. Когда документации оказывается недостаточно, мы переносим правило в код.

Пропускная способность меняет философию слияния веток

По мере роста пропускной способности Codex многие традиционные инженерные нормы стали контрпродуктивными.

Репозиторий функционирует с минимальным количеством блокирующих проверок при слиянии. Пулл-реквесты живут недолго. Нестабильные тесты (флейки) часто устраняются последующими запусками, а не блокируют прогресс на неопределенный срок. В системе, где пропускная способность агентов намного превосходит человеческое внимание, исправления стоят дёшево, а ожидание обходится дорого.

Это было бы безответственно в условиях низкой пропускной способности. Здесь же это зачастую правильный компромисс.

Что на самом деле означает «созданный агентом»

Когда мы говорим, что кодовая база создана агентами Codex, мы имеем в виду абсолютно всё в этой кодовой базе.

Агенты создают:

  • Код продукта и тесты
  • Конфигурации CI и инструменты для релизов
  • Внутренние инструменты для разработчиков
  • Документацию и историю проектирования
  • Инфраструктуру для оценочного тестирования
  • Комментарии к код-ревью и ответы на них
  • Скрипты, управляющие самим репозиторием
  • Файлы определений производственных дашбордов

Люди всегда остаются в процессе (human-in-the-loop), но работают на другом уровне абстракции, нежели раньше. Мы расставляем приоритеты в работе, переводим отзывы пользователей в критерии приемки и проверяем результаты. Когда агент испытывает трудности, мы воспринимаем это как сигнал: определяем, чего именно не хватает (инструментов, защитных механизмов, документации), и возвращаем это в репозиторий, причем исправление всегда пишет сам Codex.

Агенты напрямую используют наши стандартные инструменты разработки. Они подтягивают отзывы с ревью, отвечают прямо в строках кода, отправляют обновления и часто выполняют squash-слияние собственных пулл-реквестов.

Повышение уровня автономности

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

Получив единую подсказку (промпт), агент теперь способен:

  • Проверить текущее состояние кодовой базы
  • Воспроизвести зарегистрированный баг
  • Записать видео, демонстрирующее сбой
  • Реализовать исправление
  • Проверить исправление в работе приложения
  • Записать второе видео, демонстрирующее устранение проблемы
  • Открыть пулл-ревест
  • Реагировать на замечания агентов и людей
  • Обнаруживать и устранять сбои сборки
  • Обращаться к человеку только тогда, когда требуется экспертная оценка
  • Выполнить слияние (merge) изменений

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

Энтропия и сборка мусора

Полная автономность агентов также порождает новые проблемы. Codex тиражирует паттерны, которые уже существуют в репозитории — даже несовершенные или неоптимальные. Со временем это неизбежно приводит к дрейфу кода.

Сначала люди решали эту проблему вручную. Наша команда тратила каждую пятницу (20% недели) на очистку от «ИИ-шлака». Естественно, это не масштабировалось.

Вместо этого мы начали внедрять то, что называем «золотыми принципами», прямо в репозиторий и создали регулярный процесс очистки. Эти принципы представляют собой бескомпромиссные механические правила, которые поддерживают читаемость и согласованность кодовой базы для будущих запусков агентов. Например: (1) мы предпочитаем общие пакеты утилит самописным вспомогательным функциям, чтобы инварианты оставались централизованными, и (2) мы не зондируем данные в стиле YOLO — мы проверяем границы или полагаемся на типизированные SDK, чтобы агент не мог случайно построить логику на угаданных структурах. С определенной периодичностью запускается набор фоновых задач Codex, которые сканируют репозиторий на предмет отклонений, обновляют оценки качества и открывают целенаправленные пулл-реквесты на рефакторинг. Большинство из них можно проверить менее чем за минуту и слить автоматически.

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

Чему мы всё ещё учимся

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

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

Одно стало ясным: создание программного обеспечения по-прежнему требует дисциплины, но эта дисциплина проявляется скорее в каркасе (scaffolding), чем в самом коде. Инструменты, абстракции и циклы обратной связи, поддерживающие кодовую базу в согласованном состоянии, приобретают всё большее значение.

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

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

Автор

Ryan Lopopolo

Благодарности

Особая благодарность Виктору Чжу (Victor Zhu) и Заку Броку (Zach Brock), внесшим свой вклад в публикацию, а также всей команде, создавшей этот новый продукт.

Полный текст статьи читайте на OpenAI