avo
AVO — Agentic Variation Operators
Открытая воспроизводимая реализация AVO: Agentic Variation Operators for Autonomous Evolutionary Search (Chen, Ye, Xu и др., NVIDIA, 2026), запускаемая на ноутбуке.
Классический эволюционный поиск, а также системы с LLM-усилением, которые за ним последовали, раскладывают оператор вариации на фиксированный конвейер:
Vary(P_t) = Generate(Sample(P_t))Фреймворк выбирает родителей; модель порождает одного кандидата из них. AVO заменяет всю эту декомпозицию одним автономным запуском агента:
Vary(P_t) = Agent(P_t, K, f)Агент видит всю родословную P_t, базу знаний домена K и
функцию оценки f — и сам решает, что читать, что менять и когда
измерять. Он перестаёт быть генератором кандидатов и становится оператором вариации.
В этом репозитории реализован этот фреймворк, а также окружающая его механика, описанная в статье: родословная на базе git, вектор оценок с проверкой корректности, политика коммита «совпадает или улучшает», супервизор, вмешивающийся при стагнации, и графики траекторий. В комплекте идут две целевые задачи оптимизации.
Главное: это работает в той сессии, которая у вас уже есть
Драйвер по умолчанию не порождает агента и не вызывает API. Он
передаёт промпт вариации сессии Claude Code, с которой вы уже разговариваете,
и эта сессия выполняет работу. Ничего дополнительного не списывается, ANTHROPIC_API_KEY
не нужен, а агент, выполняющий оптимизацию, — это настоящий универсальный агент
для программирования — именно такой, какой использовался в статье.
Автономный режим (порождение агента на каждом шаге и запуск на несколько дней, как в 7-дневном эксперименте из статьи) тоже доступен и включён по желанию именно потому, что расходует квоту.
Related MCP server: Pi-Anvil (pi-sandbox)
Установка
git clone https://github.com/gatordevin/avo
cd avo
pip install -e ".[all]" # or: pip install -e . for the core only
avo doctorВ системе с внешне управляемым Python (Homebrew, большинство дистрибутивов Linux)
используйте virtualenv — флаг --system-site-packages переиспользует уже имеющиеся
NumPy и Matplotlib:
python3 -m venv --system-site-packages .venv
.venv/bin/pip install -e ".[all]"
.venv/bin/avo doctorТребования: Python 3.10+, git и компилятор C, если нужна цель
attention_c. numpy требуется встроенным целям, matplotlib — для
графиков. Ядро фреймворка зависит только от PyYAML.
Быстрый старт — управляйте им через уже имеющегося агента
Полный протокол, включая Codex и использование через обычный CLI, — в docs/DRIVING.md.
Claude Code
Зарегистрируйте MCP-сервер один раз, на уровне пользователя, чтобы он был доступен в любой папке:
claude mcp add avo -s user -- python3 -m avo.mcp_server
# from a virtualenv, point at its interpreter:
claude mcp add avo -s user -- /path/to/avo/.venv/bin/python -m avo.mcp_serverclaude mcp list должен показать avo — ✔ Connected. При желании установите
встроенный навык, чтобы /avo работал где угодно:
cp -r .claude/skills/avo ~/.claude/skills/avoЗатем в сессии Claude Code в любом каталоге:
Используйте инструменты avo, чтобы развивать цель game2048 в течение 10 шагов. Вызовите
avo_start_run, затем в цикле:avo_next_step, выполняйте запрошенную работу,avo_evaluate, пока не будете довольны, затемavo_submit. Если он сообщает о застое, вызовитеavo_supervisor_brief, ответьте на него и сохраните черезavo_record_supervisor.
Одиннадцать инструментов — это весь цикл:
инструмент | что делает |
| посев |
| промпт вариации: |
| запуск |
| завершение шага: оценка, затем коммит или откат по политике |
| отказ от эксперимента без траты шага |
| где находится запуск |
| вмешательство при стагнации |
| отрисовка траектории |
| что можно развивать |
Codex
Codex CLI понимает MCP и читает AGENTS.md, так что работают обе части:
codex mcp add avo -- python3 -m avo.mcp_serverAGENTS.md в корне репозитория описывает цикл и правила, которые
обеспечивают честность запуска; Codex подхватывает его автоматически при работе
в этом каталоге.
Без MCP
У каждого инструмента есть CLI-двойник, так что обычная оболочка работает не хуже — это самый переносимый вариант, подходящий для любого агента или для работы вручную:
avo start --target game2048 # seeds x0 and prints the first prompt
# ... edit runs/<id>/work/, run runs/<id>/avo-eval as often as you like ...
avo submit -m "expectimax depth 2 with a positional weight matrix"
avo prompt # the next step's prompt
avo status
avo plot -o trajectory.pngПримеры запусков
В репозитории есть два полных запуска, оба выполнены в сессионном режиме сессией Claude Code, оба включают свои тупики.
attention_decode — превосходим вендорное ядро
examples/attention-decode-run/ развивает
шаг декодирования внимания: один токен запроса против длинного KV-кэша — вычисление,
которое LLM выполняет для каждого генерируемого токена. Оценка против
mx.fast.scaled_dot_product_attention — собственного слитого Metal-ядра Apple.
0.05 → 1.14× MLX за три шага. Это тот случай, когда развитое ядро действительно превосходит вендорную реализацию, и интересно именно как:
Шаг 1 был реализацией — flash-decoding с разделением по K подняло ядро с 1.6 ГБ/с до 106 ГБ/с, примерно 95% предела пропускной способности машины. Это достигло 0.95× MLX и исчерпало рычаг: нельзя читать байты быстрее, чем их доставляет контроллер памяти.
Шаг 2 был математикой. Порог цели — это бюджет ошибки на выходе, а не точное равенство, поэтому поиск мог изменить вычисление. Измерения показали, что 99.9% массы softmax находится в ~11% ключей, поэтому ядро теперь оценивает каждый ключ, но читает V только выше порога, выбранного так, чтобы отбрасываемая масса была доказуемо меньше 0.3%. Это пересекло 1.0, потратив 2% бюджета ошибки.
Урок обобщается: как только ядро, ограниченное пропускной способностью, достигает потолка производительности, единственный оставшийся рычаг — читать меньше байтов, а это уже алгоритмическое изменение.
attention_c — собственная область статьи
examples/attention-c-run/ развивает прямое
ядро внимания на C, достигая 2.2× по сравнению с простой реализацией
NumPy/BLAS и близко к потолку NEON. Обратите внимание на честную формулировку:
этот базовый уровень — не настроенная библиотека внимания, и это ядро медленнее,
чем CPU SDPA из torch и MLX — матричные блоки AMX от Apple недостижимы из
переносимого C. В отчёте приведено полное сравнение.
Три вывода из него стоят клика:
Собственный алгоритм статьи здесь оказался неверным ответом. Черепичное ядро в стиле FlashAttention с потоковым онлайн-softmax показало худший результат дважды. При таких размерах вся голова помещается в L2, так что блокировка для локальности ничего не даёт, а пересчёт масштаба на каждый блок — чистая лишняя работа. Стоимость — арифметика, а не память.
-ffast-mathмолча ломает стандартный быстрыйexp, алгебраически сокращая трюк с округлением через добавление магической константы, на котором он основан. Проверка корректности поймала это на форме N=3; показатель пропускной способности никогда бы этого не заметил.Запуск вынудил исправить цель. Оценка сырых ГФЛОП/с на ноутбуке, выполняющем другую работу, — это не измерение: идентичный код давал 44–76 ГФЛОП/с за двадцать минут.
eval.pyтеперь замеряет время NumPy/BLAS-эталона в том же процессе, вперемежку с кандидатом, и оценивает отношение.
game2048 — развитие политики для игры
examples/game2048-run/ — это полный запуск из 8 шагов
цели game2048, выполненный в сессионном режиме сессией Claude Code. В каталоге
хранится неотредактированный вывод: развитая политика, рабочие заметки оператора,
полная траектория, созданные им инструменты скрининга и его тупики.
876 → 43 826 — в 50 раз больше посева, в 14 раз сильнее самого сильного базового уровня. Игры, достигающие 2048: 0% → 77%. Лучшая плитка: 512 → 8192. Apple M5, один поток, только стандартная библиотека.

Улучшения приходят дискретными скачками, разделёнными плато, что соответствует рисунку 5 из статьи. Две плоские версии — это чисто работа над пропускной способностью, которая купила бюджет, потраченный следующим шагом, — та же роль, что и изменение v19→v20 с безветвевым пересчётом масштаба в статье.
Самый большой единичный прирост (+50.5%) не был оптимизацией. Бенчмарк оценивал накопленные очки игры; эвристика измеряла только то, насколько выживаемо выглядит доска, поэтому ничто в поиске не знало, что слияние двух 256 даёт 512 очков. Четыре шага работы над пропускной способностью дали +27% в сумме; один шаг проверки того, что на самом деле оптимизируется, дал +50%.
Что входит в комплект
game2048 — развитие политики для игры
Развивайте agent.py в самого сильного игрока в 2048, какого сможете, при жёстком
бюджете времени на размышление. Оценка — геометрическое среднее среднего счёта игры
по четырём блокам из двенадцати детерминированных сидов. Превышение бюджета в 120 с
даёт ноль, а не «чуть меньше», — поэтому глубина поиска, стоимость функции оценки
и отсечения конкурируют друг с другом, и этот компромисс и есть задача.
Измерено на Apple M5:
политика | счёт |
посев | 876 |
случайный базовый уровень | 1 076 |
базовый уровень эвристики угла | 2 565 |
жадный базовый уровень на один ход | 3 132 |
Сильные игроки на expectimax набирают десятки тысяч. Приведённый выше запуск достиг 43 826.
attention_c — развитие ядра, собственная область статьи
Развивайте ядро прямого внимания одинарной точности на C:
O = softmax(QKᵀ/√D)V, причинное и непричинное, D = 64. Проверка — согласие
с эталоном float64 по восемнадцати формам, включая простые и сдвинутые на единицу
длины последовательностей, так что ядро, неправильно обрабатывающее хвост,
проваливается, а не тихо получает хороший результат.
Оценка — ускорение относительно NumPy/BLAS-эталона, замеренного в том же процессе, геометрическое среднее по четырём длинам последовательностей × двум режимам маскирования. 1.0 — паритет с библиотекой. Оценка отношения, а не сырых ГФЛОП/с, делает бенчмарк нечувствительным к тому, что ещё делает машина, — абсолютная пропускная способность на общем ноутбуке колеблется сильнее, чем стоит большинство оптимизаций.
ядро | оценка |
посев | 0.19× |
базовый уровень NumPy/BLAS — «cuDNN» этой установки | 1.00× |
развито за 3 шага (отчёт) | 2.11× |
База знаний охватывает формулировку онлайн-softmax, выбор размера блоков и черепицы, векторизацию CPU, многопоточность и то, как опрашивать хост-машину, а не предполагать архитектуру ISA. Чтобы превзойти BLAS, нужно большинство из них.
Как это работает
Каталог запуска
runs/<run-id>/
work/ the candidate x_t — a standalone git repo whose history IS the lineage
.avo/scores.jsonl every committed version's full score vector
kb/ the knowledge base K, copied in so paths are stable
avo-eval f, as a zero-argument shim the agent can call at will
NOTES.md scratch space that survives across steps
trajectory.jsonl every step, accepted or rejected
rejected/ the diff of each rejected candidate, kept for the record
logs/ evaluator and agent logsПревращение родословной в git-репозиторий означает, что агент просматривает P_t
инструментами, которые он уже знает, — git log, git show v7:attention.c,
git diff v6 v7 — вместо специального API. Каждая принятая версия — это коммит
с тегом vN, в сообщении которого хранится вектор оценок.
Политика коммитов
Раздел 3.2 статьи: кандидат коммитится только если он проходит проверку корректности и совпадает или улучшает лучший закоммиченный результат на данный момент. Всё остальное откатывается, а его diff архивируется — он остаётся частью внутренней траектории поиска агента, но никогда не попадает в родословную.
Корректность — это порог, а не измерение. Кандидат, не прошедший его, получает ноль
независимо от того, что он показал (§3.1). В attention_c это означает, что ядро,
которое в 10 раз быстрее и численно неверно, стоит ровно столько же, сколько то,
которое не компилируется.
Вектор оценок
f(x) = (f_1(x), …, f_n(x)) — по одному числу на каждую конфигурацию бенчмарка, а среднее геометрическое является максимизируемым скаляром. Именно это делает движение по конфигурациям диагностическим: изменение, которое помогает n1024 и вредит n128, — это блокирующая проблема, а не выигрыш, и один лишь обобщённый показатель скрыл бы её.
Супервизор
В §3.3 статьи: длительные автономные прогоны дают сбой двумя способами — агент застревает, когда исчерпывает текущую линию атаки, или входит в непродуктивные циклы правок, которые продолжают проваливаться. После N шагов без нового рекорда (по умолчанию 3) AVO останавливается и запрашивает перенаправление: реввью всей траектории, предложледнее океискрёт траекторию и предлагает несколько конкретных, отчётливо различных направлений оптимизации. Перенаправление внедряется в следующий вариационный промпт как сильный априори и потребляется ровно одним шагом.
В сессионном режиме супервизор — это та же сессия, только в другой роли, и это достаточно дёшево, чтобы реально использовать. В автономном режиме это отдельный прогон агента с намерением только для чтения.
Траектория
avo plot воспроизводит рисунок 5/6 из статьи: текущее геометрическое среднее как ступенчатую функцию, заполненные кружки на каждом новом рекорде, пунктирные кривые для каждого конфигурации, а базовые значения горизонтальными линиями. Та же оговорка, что и в статье: показана очищенная последовательность, а не внутреннее дерево поиска, просматриваемое между коммитами.
Автономный режим
Чтобы воспроизвести установку из статьи, где оператор — это порождённый агент и никто не наблюдает:
avo run --target attention_c --backend claude_cli --max-steps 40 --time 12h
avo run --resume runs/attention_c-20260321-091500 --time 24hБэкенды: claude_cli (Claude Code headless — ближайший аналог агентs/статьи), api (самодостаточный цикл агента на Messages API, для людей, у которых только API-ключ), agent_sdk (внутрипроцессно через claude-agent-sdk) и mock (команда шелы, для проверки механики без модели).
Это расходует квоту или кредиты на каждом шаге. Сессионный режим — нет.
Добавление собственного таргета
Таргет — это директория с target.yaml, стартовая программа, база знаний и эвизитор. Эвалюатор — любой исполняемый файл на языке people; весь контракт — один JSON-объект на stdout:
{"correct": true,
"metrics": {"config_a": 1520.3, "config_b": 1477.0},
"error": null,
"notes": "shown to the agent"}correct — это шုဧз. metrics — это вектор результатов. Оптимизируемый скаляр — это их среднее геометрическое, если только не задан явный primary.
name: my_target
description: One line, shown in `avo targets`.
seed: seed # copied to work/ as x_0
knowledge_base: kb # copied to the run dir as K
entrypoint: kernel.c # informational, used in prompts
evaluate:
command: ["python3", "{target}/eval.py", "--workdir", "{workdir}"]
timeout: 30m
baselines: # optional, measured once before evolution starts
command: ["python3", "{target}/eval.py", "--baselines"]
score:
direction: maximize
agent:
goal: |
What the agent is actually trying to do, and what the trade-offs are.Полный контракт — в docs/TARGETS.md, минимально работающий пример — в tests/fixtures/toy/.
База знаний заслуживает серьёзных усилий. Это K в данном контексте; K — это K в Agent(P_t, K, f), и разница между агентом, который заново открывает тiling с нуля за десять шагов, и тем, кто доходит до этого за два.
Что действительно воспроизводится, а что нет
Верно воспроизведено:
формула оператора
Vary(P_t) = Agent(P_t, K, f)— настоящая агент-программист с редактированием файлов, доступом к оболочке и постоянной памятью, без внесённых изменений задачина датьоднотехнология? эволюция с непрерывной линией и git-состоянием (§3.3)
шлюз корректности и n-мерный вектор результатов (§3.1)
политика поведения «совпадает или лучше», из которой прямые строки ошибочных попыток исключаются (§3.2)
вмешательство супервизора при застое и непродуктивных циклах (§3.3)
агрегирование по евmetryческому среднему по конфигурациям бенчмарка и графики траекторий (рис. 5/6)
Не воспроизведено намеренно:
Аппаратное обеспечение. В статье attention- ядра развиваются на GPU B200, cuDNN и FlashAttention-4 контексты.
attention_c— та же задача на CPU, вместе с NumPy/BLAS. Оптимизацияльные приёмы переносятся по типу (tiling, online softmax, векторизация, планирование), но не по масштабируемости.Масштаб. В статье более семи дней, 40 коммитных версий, 500+ изученных направлений. Перidge в сессионном режиме на 10–20 шагов — это демонстрирация, а не восповизводство.
Структура популяции. Как и в статье, здесь реализован only single lineage case, чтобы изолировать оператора. Режим на основе архивов и островов совместим с формулировкой, но не реализован.
Структура репозитория
src/avo/
types.py Score, LineageEntry, the correctness gate, geomean
config.py target specs and run configuration
lineage.py P_t as git history
scoring.py f as an external process
knowledge.py K
prompts.py the variation and supervisor prompts — the whole framework/agent interface
run.py run state: seed, evaluate, commit policy, trajectory
session.py driver: the session you already have is the operator
loop.py driver: unattended, spawns an agent per step
mcp_server.py the same operations as MCP tools (no dependencies)
cli.py the same operations as subcommands
plot.py Figure 5/6
agents/ backends for unattended mode
targets/
game2048/ policy evolution under a time budget
attention_c/ kernel evolution — the paper's domain, on a CPU
examples/
attention-decode-run/ beats Apple's own fused kernel by changing the maths
attention-c-run/ CPU kernel evolution, with an honest baseline caveat
attention-metal-run/ GPU prefill — every CUDA instinct measured worse
game2048-run/ policy evolution — 50x the seed
docs/
PAPER_MAP.md every section of the paper, and where it lives in the code
TARGETS.md the evaluator contract
DRIVING.md how to drive a run from Claude Code, Codex, or a shell
AGENTS.md cross-agent instructions (read automatically by Codex)
.claude/skills/ the `/avo` skill for Claude CodeЦитирование
Это независимое воспроизведение. Цитируется оригинальная статья:
Распространяется по лицензии Apache-2.0. Не является аффилированным с NVIDIA и не одобрено со стороны NVIDIA.
This server cannot be deployed
Maintenance
Related MCP Connectors
Run AI agent evaluations on your own model keys, and publish runs others can review and re-run.
Adaptive plan/build/review cycles for AI coding assistants, persisted across sessions.
Coding agents build full-stack apps in persistent workspaces and share them by link.
Persistent cloud workspaces for AI agents: run commands, edit files, use git and a browser.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables bounded, multi-phase coding workflows inside Codex that plan, implement, independently review, repair, and verify repository changes, with an inline dashboard for inspecting runs.MIT
- AlicenseNot gradedqualityBmaintenanceEnables delegating coding tasks to sandboxed agents, returning changes as auditable diffs for human review before applying or discarding them.1MIT
- AlicenseAqualityBmaintenanceEnables coding agents to run persistent, budgeted work sessions with dependency graphs, human decision queues, required validation, and clean handoffs for autonomous or human-in-the-loop execution.16MIT
- AlicenseAqualityAmaintenanceEnables MCP-compatible clients to delegate multi-step coding tasks to an autonomous subagent that reads outlines, applies validated patches, manages workspace memory, and returns structured results with rollback and cost tracking.12Apache 2.0