Перейти к содержанию

anthropic

Патчи в CI у Anthropic жили 70 дней, 29 дней и меньше суток

Claude News

Инженер Anthropic завёл во внутренней версии Claude Tag отдельную долгую сессию-сторожа: как только очередь необработанных задач переваливала за 50 000, Claude сам писал ему и продолжал прошлый разговор с того места, где они остановились. Как рассказывают в блоге Claude, тянулось это месяцами, Claude регулярно предлагал переписать сервис отбора тестов целиком, но каждый раз дело кончалось очередной заплаткой.

Коротко

  • За полгода число задач CI внутри Anthropic выросло в 25 раз, число тестов в кодовой базе выросло в 10 раз, а инженеров за это время добавили символически.
  • Сервис отбора тестов жил в одном процессе с единственным писателем истории, поэтому не шардился; при пересборке историю унесли в in-memory хранилище, где любой воркер дописывает результат в журнал и ничего не держит в памяти.
  • Распределённая схема обходится дороже в эксплуатации, а ежедневные перезапуски до неё оставляли selector со старыми данными: часть результатов listener просто не успевал записать.

Если вы не следили за темой, вот короткий контекст. Test impact analysis решает, какие тесты гонять на конкретное изменение, чтобы не запускать весь набор на каждый PR. По описанию Datadog, классический вариант опирается на покрытие и знает, какие файлы задевает каждый тест. В Anthropic сервис детерминированный: он смотрит на прошлые прогоны и релевантность пакетов.

За полгода число задач CI выросло в 25 раз

Давление считается просто. Инженеры Anthropic отгружают за квартал в 8 раз больше кода, чем в 2021–2025 годах, 80% этого кода пишет Claude, и он же заметно участвует в ревью и одобрении PR. Число тестов выросло в 10 раз, инженеров добавили символически. Итог: 25-кратный рост числа задач CI за шесть месяцев.

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

Заплатки прожили 70 дней, 29 дней и меньше суток

В октябре прошлого года сервис уже трещал, два дня подряд команду будили алерты. Первым делом удвоили ядра сервису: просто и заведомо ненадолго. Хозяина у этого куска инфраструктуры толком не было, брать его на себя никто не рвался, а у команды CI хватало других дел. Первой заплатки хватило на 70 дней.

В феврале рост упёрся в потолок снова, и сервис распараллелили: единственный писатель нужен был не на весь сервис, а на каждый пакет по отдельности, и код для разбиения состояния по шардам написал Claude. Продержалось это 29 дней.

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

Listener записывал результаты, selector решал, что запускать

Внутри две детерминированные части, которые обязаны быть в согласии. Listener записывает результаты тестов с каждого прогона CI. Selector читает эту историю и решает, какие тесты запускать на открытом PR. Вся история по каждому тесту держалась в памяти одного процесса, поэтому применять результаты мог только один писатель.

Представьте единственную кассу в супермаркете: пока очередь короткая, всё быстро, но пропускная способность упирается в одного кассира. Когда задачи CI идут по нескольку штук в секунду, listener отстаёт от очереди PR, и двадцать минут отставания превращаются в десятки тысяч не применённых обновлений.

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

Пересборка заняла три недели одного инженера

В итоге совет Claude приняли: сервису дали хранилище, точнее in-memory data store. Тяжёлую обработку, которую синглтон делал в памяти, вынесли наружу. Любой воркер listener берёт любой результат, дописывает его в журнал и идёт дальше, ничего не удерживая, поэтому воркеры получились без состояния и масштабируются горизонтально. Отдельный небольшой процесс каждые несколько секунд сворачивает журнал в историю по каждому тесту, а selector быстро достаёт нужный кусок.

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

Абсолютных чисел задач CI в тексте нет, как нет и цифры, во сколько именно распределённая схема дороже прежней. Совет закладывать в первой версии запас на 10–20-кратную нагрузку сопровождается оговоркой про бюджет, и, на наш взгляд, именно она отделяет этот рецепт от универсального. Про март авторы честно уточняют: непротестированный код в продакшн не уезжал, selector просто работал на устаревших данных и гонял заведомо флакающие и повсеместно красные тесты.

Когда сервис упрётся снова

Автор советует исходить из того, что за два квартала архитектура окажется под 25-кратной нагрузкой, и ожидает, что горизонтально масштабируемый отбор тестов станет отраслевой нормой. Проверить прогноз можно на собственном CI: считать входящие и исходящие результаты задач и смотреть, сходятся ли они. Когда распределённая схема упрётся в собственный потолок и сколько она стоит в месяц, в тексте не называется.

Читайте также

  1. Claude разбирал ошибки 500 и вышел на злоупотребление
  2. Bun на Rust собрали агентами Claude, GitHub пошёл иначе
  3. Две сессии Claude Code съели 32% месячного счёта команды
  4. Шесть правок от Claude Opus 4.6 попали в ядро Linux 7.3
  5. claude.ai разогнали в 3 раза за две недели с помощью Claude
  6. Opus 5.5 подешевел, но ломает агентов ошибкой 400

Комментарии

Пока никто не написал. Будьте первым.

Присоединяйтесь к разговору

Войдите через Google, чтобы оставить комментарий. Имя и аватар подставятся из вашего профиля Google, а комментарий появится после модерации.

Из Google мы используем только имя и аватар. Почту не сохраняем.