Skip to main content
Glama
gatordevin
by gatordevin

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: AgentPrism Workflows

Установка

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_server

claude 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.

Одиннадцать инструментов — это весь цикл:

инструмент

что делает

avo_start_run

посев x_0, оценка, замер базовых показателей, открытие родословной

avo_next_step

промпт вариации: P_t, индекс K, контракт для f

avo_evaluate

запуск f на рабочем дереве — бесплатно, вызывайте сколько угодно раз

avo_submit

завершение шага: оценка, затем коммит или откат по политике

avo_revert

отказ от эксперимента без траты шага

avo_status / avo_lineage

где находится запуск

avo_supervisor_brief / avo_record_supervisor

вмешательство при стагнации

avo_plot

отрисовка траектории

avo_list_targets

что можно развивать

Codex

Codex CLI понимает MCP и читает AGENTS.md, так что работают обе части:

codex mcp add avo -- python3 -m avo.mcp_server

AGENTS.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:

политика

счёт

посев x_0 (первый легальный ход)

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 — паритет с библиотекой. Оценка отношения, а не сырых ГФЛОП/с, делает бенчмарк нечувствительным к тому, что ещё делает машина, — абсолютная пропускная способность на общем ноутбуке колеблется сильнее, чем стоит большинство оптимизаций.

ядро

оценка

посев x_0 (наивное, материализует полную матрицу N×N)

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.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI-powered code review and improvement, including analysis, refactoring suggestions, and automatic test generation, with an optional agentic loop for iterative refinement.
    MIT
  • A
    license
    B
    quality
    A
    maintenance
    Local-first Agent OS that wraps Claude Code, Codex CLI, and other coding agents in a replayable Seed → Ledger → Runtime contract, driven by an interview → seed → execute → evaluate → evolve workflow loop.
    34
    5,634
    MIT

View all related MCP servers

Related MCP Connectors

  • Adaptive plan/build/review cycles for AI coding assistants, persisted across sessions.

  • Cross-agent artifact workspace with provenance across Claude Code, Codex, Cursor, LangGraph.

  • Persistent cloud development environments that coding agents create, run and test software in.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gatordevin/avo'

If you have feedback or need assistance with the MCP directory API, please join our Discord server