16 параллельных Claude-агентов — обложка

5 февраля 2026 года Николас Карлини из Anthropic опубликовал статью об эксперименте, который заметно опережает то, что большинство из нас сейчас делает с LLM-агентами. Шестнадцать параллельных инстансов Claude Opus 4.6, две недели работы, ~2000 сессий Claude Code, бюджет около $20 000. Результат: 100 000 строк C-компилятора на Rust, который собирает Linux 6.9 на x86, ARM и RISC-V; проходит 99% torture-тестов GCC; компилирует PostgreSQL, SQLite, FFmpeg, Redis и QEMU; запускает Doom. Репозиторий открыт, любой может прочитать и попробовать.

Это серьёзная инженерная работа, и сама статья — отличное чтение для всех, кто думает про автономных агентов в проде. Карлини честен в том, что сработало и что нет, разбирает пять конкретных уроков из дизайна harness’а, делится цифрами и метриками. Именно такие отчёты индустрии и нужны — отчёт из первых рук о том, как реально выглядят длинные автономные прогоны.

Заголовки разделились на два лагеря. «AI заменил программистов» с одной стороны. «Это просто демо» с другой. И те и другие промахиваются по сути.

Если внимательно прочитать статью, Карлини описывает не «AI пишет компилятор». Он описывает сколько инфраструктуры пришлось построить вокруг агентов, потому что инфраструктуры между самими агентами в 2026 году ещё нет. Lockfile’ы в общей папке как механизм синхронизации. README, которые агент пишет сам себе. GCC, мобилизованный в качестве known-good референсного оракула. Ralph-loop, обёрнутый в Docker для бесконечной автономии. Каждое из этих решений — ответ на конкретную проблему, для которой сегодня просто некуда вытолкнуть в стандартный слой.

И в этом — настоящая ценность статьи. Не как «AI-демо», а как детальная карта недостающих примитивов, нарисованная человеком, который построил для них костыли руками. Я последние несколько месяцев работаю как раз над этими примитивами, и работа Карлини — отличный повод обсудить, что нужно следующему поколению команд агентов.

Каждая сессия начинается с амнезии

Карлини построил harness, который запускает Claude в бесконечном цикле — когда агент заканчивает одну задачу, он берёт следующую. Архитектурно это знакомый паттерн «Ralph-loop»: цикл while true в bash-скрипте, обёрнутый в Docker для безопасности. В одном из прогонов Claude случайно убил сам себя pkill -9 bash, что Карлини отмечает как забавный побочный эффект.

Принципиальная деталь: каждый из ~2000 запусков начинался в свежем Docker-контейнере с пустым контекстом. Никакой памяти между сессиями. Каждый агент с нуля разбирался: что это за репо, что уже сделано, какой статус у задач, что пробовали и что не получилось.

Костылём Карлини стало инструктировать Claude самому вести подробные README и progress-файлы, обновляя их часто. Когда агент застревает в баге, он также ведёт running doc с провальными подходами и оставшимися задачами.

Это работает в рамках текущего тулинга — и в этом его ценность. Но если посмотреть на масштабирование, две архитектурные точки начинают скрипеть.

Во-первых, текстовый файл не структурирован. Если хочешь спросить «какие три последних бага я фиксил в области парсера и чем закончились?» — у тебя есть только grep и регулярки. На маленьком проекте терпимо. На 100 000 строк кода и 2000 сессий — узкое горло.

Во-вторых, тоньше: каждый агент ведёт эти файлы для себя. Они живут в общем git-репозитории, но нет механизма, который скажет «прежде чем брать задачу X, посмотри, что 16 других агентов писали про эту область за последние 6 часов». Каждый агент пишет свой README, мерджит чужие правки и надеется на сходимость.

Это первое поколение shared memory — реализованное plain text, потому что более удобный примитив ещё не стал стандартом.

Lockfile’ы как координация

Параллелизм реализован минимально. Каждый агент крутится в своём Docker-контейнере; общий bare-git-репозиторий держит состояние. Координация задач — через lockfile’ы: агент пишет файл вроде current_tasks/parse_if_statement.txt, делает git push и тем самым «забирает» задачу. Если два агента попытаются взять одну и ту же — git-синхронизация заставит второго взять что-то другое. Готово — удаляешь lockfile.

Карлини прямо описывает текущее состояние системы: «no other method for communication between agents… I don’t use an orchestration agent». Никакого механизма для агентов «спросить друг друга». Никакой центральной координации. Каждый Claude сам решает, что делать дальше — обычно «следующая очевидная проблема».

Lockfile здесь делает ровно одну вещь — работает как mutex, защищающий от параллельного забора одной задачи. Это ценно. Но не решает другой проблемы: два агента, работающих над разными задачами в одной области кода, могут писать конфликтующий код под разными именами задач. Именно это и случилось с Linux-ядром в эксперименте — агенты сходились на одном баге, фиксили его по-разному, перезатирали правки друг друга, и параллелизм временно переставал окупаться.

Решением Карлини стал отдельный test harness, использующий GCC как known-good компилятор-оракул: большая часть ядра компилируется GCC, а случайное подмножество файлов прогоняется через компилятор Claude. Если ядро не загружается — баг где-то в подмножестве Claude, и можно сужать дальше. Идея остроумная и элегантная, и сработала ровно как задумано.

Стоит отметить границы, в которых это работает. GCC-оракул — точное решение для этой конкретной задачи, потому что у задачи есть три удобных свойства: существует готовый референсный компилятор для той же спецификации, задача декомпозируется на уровне отдельных файлов, и результат бинарный (загружается / не загружается).

В большинстве реальных проектов — продуктовая разработка, рефакторинг legacy, ML-пайплайны, мобильные приложения — этих удобств нет. Нет готового known-good для сравнения. Нет естественной декомпозиции по файлам. Результаты не бинарны. Что значит технику GCC-оракула нельзя обобщить в примитив — она работает там, где работает, и не существует там, где не работает.

В целом инструментарий Карлини аккуратно ложится на две оси:

Что нужно командам агентовЧто в экспериментеПрирода решения
Discovery агентовхардкод числа контейнеровхардкод
Inter-agent communicationlockfile через git pushmutex без messaging
Делегирование задачnext-most-obvious из очередибез routing
Shared state / memoryREADME + progress-файлыplain text
Causal historyrunning doc с провальными подходамиличный лог
ВерификацияGCC-оракулпод конкретную задачу

Это две независимые оси проблемы: коммуникация (как агенты разговаривают друг с другом) и память (что они помнят между сессиями и шарят ли). Эти оси требуют разных примитивов и разных решений. И на каждой индустрия сейчас сходится к стандартам и open-source реализациям.

Дальше — что есть на каждой оси сегодня.

Ось коммуникации: A2A-протокол и a2abridge

Коммуникация двигалась быстро и уже пришла к зрелому стандарту. В апреле 2025 Google открыл протокол A2A — Agent-to-Agent. В августе 2025 IBM ACP влился в A2A под Linux Foundation, и к апрелю 2026 спека на версии 1.2, поддержана 150+ организациями (Microsoft, AWS, Salesforce, SAP, ServiceNow, IBM среди них), нативно встроена в Google ADK, LangGraph, CrewAI, LlamaIndex Agents, Semantic Kernel и AutoGen. A2A фактически выиграл войну протоколов. Спека намеренно минималистична: Agent Card — JSON-описание возможностей агента (что делает, какой endpoint бить). Task — единица работы со статусами и артефактами. Транспорт — JSON-RPC 2.0 поверх HTTPS, с Server-Sent Events для стримов.

Аналогия, которую везде используют, — HTTP. HTTP не говорит, что у тебя на бэкенде (Rails, Django, Go) — он только определяет форму запросов и ответов. A2A не говорит, какую LLM, фреймворк или БД ты используешь — он определяет контракт между агентом A и агентом B. Минимум, поверх которого можно строить остальное.

Если переписать сценарий Карлини на A2A, вместо lockfile в current_tasks/ агент бы запросил directory-сервис «кто сейчас работает над парсером?», получил Agent Card соседа и отправил Task со streaming-ответом по SSE. Это и есть тот примитив коммуникации, которого в его harness’е пока нет.

Я последние несколько месяцев пишу a2abridge — открытую Go-реализацию A2A 1.0, нацеленную на практический сценарий «несколько разных AI-агентов на одной машине разработчика». На момент публикации поддержано шесть IDE: Claude Code, Codex CLI, Cursor, Cline, Continue и Gemini CLI. Любой A2A-совместимый агент (включая будущие Google ADK, LangGraph, CrewAI реализации) — first-class peer без glue-кода.

Архитектурно это один Go-бинарь (~10 МБ) с несколькими subcommands. a2abridge directory — discovery-сервис на 127.0.0.1:7777, работающий как user-level system service (launchd на macOS, systemd-user на Linux, Windows Service на Windows, корректно работает внутри WSL2). a2abridge bridge — per-agent процесс, хостящий и MCP stdio-сервер (через который IDE видит a2abridge как обычный MCP-сервер с тулзами), и A2A HTTP-сервер на случайном порту, с Agent Card на /.well-known/a2a и полным набором JSON-RPC 2.0 методов из §7 спеки: SendMessage, SendStreamingMessage, GetTask, ListTasks, CancelTask, SubscribeToTask, GetExtendedAgentCard. Lifecycle bridge’а равен времени жизни IDE-сессии — когда MCP stdio закрывается, bridge умирает, никаких orphan-процессов.

Что Claude Code (или любая другая IDE) видит как MCP-инструменты: a2a_whoami, a2a_list_agents, a2a_send_message, a2a_send_streaming, a2a_get_task, a2a_cancel_task, a2a_inbox, a2a_complete_task. Внутри сессии агент может самостоятельно обнаруживать других агентов на машине, отправлять им задачи, ждать ответов и читать свой inbox — без участия пользователя.

Поверх протокола есть про-активный слой, которого нет в спеке, но он нужен для реального использования. Bridge пишет inbox-файл ./.a2a/inbox-<ppid>.json каждый раз, когда меняется очередь сообщений. UserPromptSubmit-хук инжектит входящие сообщения в системный промпт до первого tool call — то есть Claude видит «у тебя сообщение от пира с FYI про breaking API change» до того, как начнёт слепо действовать. SSE fast-path доставляет ответы за миллисекунды, fallback — polling раз в 5 секунд. Для Claude Code также есть skill a2a-bridge, который автозагружается только при триггерных промптах — никаких глобально загруженных правил, жгущих токены на каждой сессии.

В сценарии Карлини это бы выглядело так: агент 5 берёт задачу «fix kernel build error in mm/page_alloc.c». Прежде чем действовать, он зовёт a2a_list_agents, видит, что у агента 2 открытый Task с capability kernel-debug в той же области. Отправляет a2a_send_message: «над чем работаешь, есть гипотеза?». Получает streaming-ответ: «пробовал alignment fix, упал на test_kernel_boot, сейчас смотрю reorder header includes». Берёт другой угол.

Почему открытый протокол, а не очередной кастомный wire-формат. В этой нише уже существует несколько решений: Anthropic Agent Teams работает только Claude↔Claude и завязан на подписку. CCB и claude-multi-agent-bridge — закрытые форматы, привязанные к конкретным комбинациям агентов. Ruflo — отлично для enterprise-федераций 100+ агентов с центральными queens, но это другой класс задач. Ниша, на которую целится a2abridge, — cross-vendor open-protocol mesh, где сегодня входят Claude и Codex, а завтра — любой A2A-совместимый агент без переписывания glue. Если индустрия движется к стандарту, bridge должен на этом стандарте говорить.

Production-зрелость: cross-machine federation с mTLS + ed25519 (opt-in, для сценария «домашний Mac ↔ офисный Linux»), mDNS auto-discovery в локальной сети, PII/secret-screen с 11 regex-детекторами перед отправкой (AWS-ключи, GitHub-токены, токены Anthropic/OpenAI/Google/Stripe/Slack, JWT, PEM-блоки — заменяются на [REDACTED:<name>], секрет никогда не покидает bridge), Push Notifications по A2A 1.0 §9.5, HTTP+REST binding по §7.3, 35 тест-кейсов под -race, GitHub Actions release matrix и кросс-платформенный a2abridge doctor с 9-проверочным health-аудитом. Установка — одной командой через install.sh или install.ps1, с автодетектом всех IDE на машине и .bak-бэкапами их конфигов перед правкой.

Репозиторий: github.com/vbcherepanov/a2abridge — MIT, Go 1.25, текущий релиз v2.0.

Ось памяти: total-agent-memory и BrainCore

С памятью ситуация другая. Стандарта уровня A2A пока нет — каждый строит свой слой, и под разные задачи выбираются разные подходы. То, что агент пишет сам себе в README, по сути — causal log в текстовой форме: «пробовал A, упал на B, перешёл на C». Структура правильная, реализация — пока plain text.

Я работаю над двумя продуктами на этой оси.

total-agent-memory — open-source реализация. Здесь живут базовые retrieval-паттерны, MCP-интеграция и базовая causal-chain модель. Любой может склонировать, посмотреть как работает, и подключить к своему Claude Code или Cursor.

BrainCore — production-grade. Go-бинарь, локальный SQLite + WAL, tree-sitter для code-graph по 14 языкам (PHP, TypeScript, Python, Ruby, Rust, Java, Kotlin, C/C++, C#, Swift, Bash, Lua, YAML, плюс Go через нативный AST), internal git для time-travel памяти, MCP-протокол для подключения к Claude Code, Cursor, Codex CLI, Windsurf и нескольким другим агентам. Сейчас в бете.

Архитектурно есть три точки, где оба проекта расходятся с плоским bag-of-facts с cosine-поиском.

Первое — causal decision chains вместо плоских фактов. Не «функция X в файле Y», а «агент 3 в задаче fix kernel build сформулировал гипотезу alignment issue, проверил через test_kernel_boot, упал, перешёл к гипотезе header reorder». Каждый шаг типизирован, связан причинной стрелкой и доступен по запросу любому агенту.

Второе — AST-стабильная идентичность кода. Когда несколько агентов рефакторят параллельно, текстовые диффы быстро превращаются в кашу, а merge-конфликты становятся бесконечными. AST-узел остаётся узлом, даже если функция переехала из parser.rs в frontend/lexer.rs и переименовалась с parse_decl на parse_declaration. В графе это один и тот же узел с историей перемещений. Каждый агент смотрит на одну и ту же абстракцию, а не на «строки 127-145 файла X».

Третье — persistence через рестарт контейнера. Память живёт снаружи Docker-контейнера: на хосте через volume или удалённо через MCP. Запрос brain.causal_lookup(area="parser", lookback="6h") возвращает один и тот же результат независимо от того, в каком свежем контейнере ты сейчас.

Перепишем сценарий Карлини с памятью: агент 5 идёт в BrainCore, получает causal-лог «agent_2 пробовал alignment fix → упал, agent_7 пробовал header reorder → упал на L98, текущая гипотеза от agent_3 — alignment issue, in progress», берёт четвёртую гипотезу, пишет её в causal-цепочку. Агенты 2, 3 и 7 видят это решение на следующем pull. Никаких README, никаких grep’ов.

Как они складываются вместе

a2abridge и BrainCore — разные слои, не конкуренты. Один отвечает на «как агенты разговаривают друг с другом», другой — на «что они помнят».

Полная картина для команды агентов выглядит так. BrainCore держит общее состояние мира: code-graph, causal chains, гипотезы, выводы. a2abridge обеспечивает реальную коммуникацию между агентами: discovery, делегирование, streaming-ответы, inbox с context injection. Когда они работают вместе, агент 5 видит сообщение в inbox от агента 2 («я работаю над X»), запрашивает у BrainCore детали («что конкретно пробовали в этой области»), принимает информированное решение, отвечает агенту 2 о намерении взять смежную задачу и пишет результат в shared memory.

Это та архитектура, которую Карлини строит руками в эксперименте через комбинацию lockfile + README + GCC-оракул. С независимыми примитивами вместо самосборного клея инфраструктура работает в задачах, где готового known-good компилятора нет.

Что эти примитивы не решают

Карлини абсолютно прав про главный урок статьи: качественный test harness — фундамент всего. Никакая shared memory и никакой A2A не спасут, если верификатор задачи неточен — агенты автономно решат не ту задачу. CI-пайплайны, хорошо спроектированные логи, защита от загрязнения контекстного окна, борьба с «time blindness» — это работает на любом уровне инфраструктуры и остаётся первым приоритетом.

GCC-оракул в задаче компилятора — действительно оптимальный выбор. Бинарная верификация почти всегда лучше сравнения causal-гипотез. Если в твоём проекте есть готовый known-good — используй. Никакая память не заменяет хорошего верификатора.

Но в большинстве реальных задач — продуктовая разработка, рефакторинг, ML-пайплайны, бизнес-логика — GCC-эквивалента нет. И там примитивы коммуникации и памяти становятся не «улучшением», а необходимым условием для того, чтобы команда из 16 агентов была продуктивнее одного.

Что Карлини пришлось строить весь этот текстово-файловый слой в 2026-м — это не недостаток подхода, а симптом момента: инфраструктура для команд агентов всё ещё формируется. Эксперимент Anthropic — лучшая возможная иллюстрация того, как она формируется и куда движется. И в этом, на мой взгляд, настоящая ценность статьи Карлини: честный отчёт с самой ранней точки на кривой, по которой эта инфраструктура будет расти.


Open source и ссылки

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