Symphony — OpenAI выложила оркестратор, который превращает Linear в очередь для AI-агентов
Если ты гоняешь по три-пять Codex-сессий параллельно, переключаясь между вкладками Chrome и терминалом, у OpenAI для тебя плохая новость. Они только что показали, как этого делать вообще не нужно.
TL;DR: Symphony это open-source оркестратор от OpenAI на Elixir. Он сам мониторит твою доску в Linear, для каждого тикета поднимает изолированный workspace, запускает Codex-агента, проверяет CI и закидывает PR. 17.1K звёзд за два месяца, Apache 2.0, а внутри — JSON-RPC 2.0 поверх stdio и Phoenix LiveView в качестве дашборда.
5 марта 2026 OpenAI тихо выложила Symphony на GitHub. Без громкого анонса, без поста в блоге Sam Altman. Просто репо с пометкой "low-key engineering preview". К концу апреля собралось 17.1K звёзд, 1.4K форков и вышла официальная статья, в которой OpenAI признаётся, что у них самих внутри это даёт +500% к мёржам PR.
Цифра, конечно, маркетинговая, без бейзлайна и условий замера. Но идея под ней лежит интересная: вместо "AI помогает кодить" мы переходим к "AI берёт тикет и сам несёт PR на ревью".
Что делает Symphony
По описанию это похоже на тысячу других штук с GitHub. На деле нет. Symphony работает не как CLI и не как IDE-плагин. Это long-running daemon, который висит в фоне и каждые 30 секунд опрашивает твою Linear-доску. Увидел тикет в состоянии "Ready for Agent", поднял для него изолированный workspace, склонировал репу, запустил Codex с твоим WORKFLOW.md в качестве промпта.
Дальше начинается самое интересное. Агент не просто пишет код. Он обязан принести proof of work:
- зелёный CI
- ответы на review-комменты
- анализ сложности изменений
- видео-walkthrough, как фича работает в реальном продукте
Только когда proof принят, Symphony мёржит PR. Если что-то отвалилось, включается exponential backoff с 10 секунд до 5 минут, и идёт новая попытка. Если хост умер, задача переедет на другой SSH-воркер.
Первое впечатление, когда я разобрался в архитектуре: это не игрушка. Это продакшен-сервис, который OpenAI явно гоняет внутри сама.
Зачем тут Elixir
Самый частый вопрос на Hacker News был именно этот. На тикет в r/elixir набежал весь комьюнити с лозунгом "yes, finally". Выбор языка тут не случайный. Symphony должен крутить десятки изолированных, долгоживущих процессов с retry-логикой, а BEAM (виртуальная машина Erlang/Elixir) для этого создавался буквально 30 лет назад в Ericsson, чтобы их телефонные станции не падали.
Архитектура по слоям:
- Policy Layer: твой
WORKFLOW.mdв репозитории. Промпт, runtime-настройки, всё под git - Coordination Layer: Orchestrator (GenServer), который поллит Linear и раздаёт задачи
- Execution Layer: AgentRunner-ы, по одному на каждый активный тикет
- Integration Layer: Linear через GraphQL
- Observability Layer: Phoenix LiveView дашборд с токенами, retry-очередью, sparkline-графиками throughput
Communication между Symphony и Codex идёт по JSON-RPC 2.0 через stdio. Никакого HTTP, прямой межпроцессный обмен.
// Symphony → Codex: Start a turn { "method": "turn/start", "id": 3, "params": { "prompt": "You are working on MT-123: Add rate limiting...", "threadId": "thread-abc-123" } } // Codex → Symphony: Tool call request { "method": "item/tool/call", "id": 100, "params": { "tool": "linear_graphql", "arguments": { "query": "mutation { issueUpdate(id: \"...\", input: {stateId: \"...\"}) { success } }" } } }
В этом протоколе агент сам управляет состоянием тикета. Не Symphony двигает тикет с "In Progress" на "In Review", а сам Codex через свой linear_graphql-тул. Symphony просто читает Linear, чтобы понять, что делать дальше.
Как поднять у себя
Минимум, что понадобится:
# Клонируем git clone https://github.com/openai/symphony.git cd symphony/elixir # Ставим зависимости (нужен Elixir + Erlang) mix deps.get # Конфиг WORKFLOW.md в твоём репозитории # + LINEAR_API_KEY в env # + Codex auth в ~/.codex/auth.json # Запускаем mix run --no-halt
WORKFLOW.md это сердце системы. Туда ты пишешь промпт, который агент получит для каждого тикета. Туда же кладутся runtime-настройки (concurrency, sandbox-policy, approval-policy). Файл лежит в репозитории, версионируется вместе с кодом, ревьюится через PR. Если кто-то хочет поменять правила работы агентов, пишет PR в WORKFLOW.md.
Sandbox-policy у Codex три:
read-only: агент только читаетworkspace-write: агент пишет только в свой workspacefull-access: без ограничений (на свой страх и риск)
Плюс отдельная штука: path validation, который ловит directory traversal (../../../etc/passwd) и symlink-эскейпы. То, чего обычно не хватает в самописных оркестраторах.
Подводные камни
Перед тем как ставить это в продакшен, посмотри, во что ты ввязываешься.
Это reference implementation, а не продукт. OpenAI прямо пишет: "We don't plan to maintain Symphony as a standalone product." В документации Mintlify есть и более жёсткая формулировка: "prototype software intended for evaluation only". Идея такая: смотри на спеку, форкай, переписывай под себя. Ставить апстрим в прод опасно.
Только Codex полноценно поддерживается. Anthropic и Google интеграции community-contributed, неполные и местами сырые. На v1.1.0 завезли Kata CLI, через которую можно подцепить Claude Code и Gemini, но это уже сообщество запиливает, не OpenAI. Если ты на Claude, посмотри сначала на Cyrus (см. альтернативы ниже).
Требует harness engineering. OpenAI это формулирует мягко, но суть жёсткая: репо должно быть структурировано так, чтобы агент мог сам себя проверить. Hermetic test suites, модульная архитектура, автоматизированные guardrails. Если у тебя legacy-проект без тестов, Symphony там просто застрянет на этапе proof of work, потому что доказывать рабочесть будет нечем.
Elixir в команде есть? Reference implementation на BEAM. Дебажить продакшен на языке, на котором никто в команде не пишет, это отдельная боль. OpenAI предлагает альтернативу: попроси Codex реализовать спеку в твоём языке (TypeScript-форк, например, уже есть в discussions). Но тогда ты получаешь LLM-сгенерированный оркестратор, который никто не ревьюил вживую.
Нельзя дёрнуть агента в полёте. В обычной Codex-сессии ты видишь, что он не туда пошёл, и пишешь "стоп, давай иначе". В Symphony такого нет: тикет идёт в работу, и обратно его уже не отозвать. Хочешь скорректировать, закрывай тикет и заводи новый. Для амбигуозных задач, где половина решения проявляется в процессе, это не работает. OpenAI сама признаёт, что ambiguous problems и работа, требующая суждения, всё ещё остаются за интерактивным Codex.
Цифра +500% это directional metric. Без бейзлайна, без условий, без размеров команды. На Hacker News пользователь exclipy разнёс саму спеку как "inscrutable agent slop", где вместо объяснения системы перечислены поля базы данных. Доля правды есть: SPEC.md местами читается так, будто Codex его и сгенерировал.
Альтернативы
Если идея с тикет-оркестрацией зашла, но Symphony не подходит:
-
Cyrus: мульти-модельный аналог. Поддерживает Claude Code, Codex, Cursor, Gemini. Работает не только с Linear, но и с GitHub, GitLab, Slack. BYOK по токенам. Если ты уже на Anthropic, это твой выбор, потому что Symphony с Claude дружит криво.
-
ComposioHQ/agent-orchestrator: TypeScript, MIT, 6.5K звёзд. Делает чуть больше, чем Symphony: сам разруливает merge-конфликты, фиксит CI, проводит код-ревью. По сути та же идея, но без Elixir-зависимости.
-
StrongDM Attractor: комплементарный, не альтернативный. Symphony создаёт outer loop (тикет → workspace), Attractor отвечает за inner loop (детерминистичный workflow внутри агента: property testing, fault injection, fuzzing поверх Playwright). Если связать оба, получится система, в которой агент не просто пишет код, а проходит все твои harness-проверки до мёржа.
Вердикт
Если у тебя команда на Linear + Codex + монорепо с приличным CI, ставь немедленно, форкай и переписывай WORKFLOW.md под себя. OpenAI не зря выложила это вместе со статьёй про harness engineering: вместе они дают рабочий конвейер.
Если у тебя Claude Code, иди к Cyrus, не мучайся с community-интеграциями Symphony. Если legacy без тестов, Symphony тебе пока не поможет, разбирайся сначала с harness'ом.
И на чём бы ты ни остановился, помни главное: бутылочное горлышко теперь не в коде, а в том, как ты формулируешь тикет. Команды, которые научатся писать чёткие спецификации, обгонят тех, кто будет старательно набирать символы в редакторе.
Как попробовать
- Поставь Elixir и Erlang:
brew install elixir(на Mac) - Получи Linear API key (Settings → API → Personal API keys)
- Склонируй:
git clone https://github.com/openai/symphony.git && cd symphony/elixir - Прочитай
elixir/README.md, скопируйWORKFLOW.mdв свою репу, заполни промпт под свой стек - Создай в Linear состояние "Ready for Agent", переведи туда тестовый тикет
- Запусти
mix run --no-halt, откройhttp://localhost:4000, смотри, как агент работает
Лень разбираться с Elixir? Спека SPEC.md language-agnostic, попроси Claude Code или Codex реализовать её в твоём любимом стеке. Symphony специально так и задумана.