Який збій виправляти далі: розбір ActiveSaddler
Обв’язка агента виправила помилку з лапками в командному рядку, а наступні десять запусків витратила на задачі, які й так проходить.

Обв’язка агента виправила помилку з лапками в командному рядку, а наступні десять запусків витратила на задачі, які й так проходить. Жоден крок не зламаний, але бюджет змарновано. Ця задача планування лежить в основі препринта ActiveSaddler, опублікованого на arXiv 1 жовтня.
Коротко
Факти дослідження: ActiveSaddler обирає, які навчальні сценарії визначають автоматичні правки обв’язки. Зразки збоїв є «руками» нестаціонарного бандита: метод оцінює очікуваний прогрес для кожного й балансує повернення до відомих слабкостей із дослідженням нових сценаріїв. На GAIA2 заявлено 59,8% Pass@1 на тесті проти 55,4% у того самого оптимізатора з фіксованим перемішаним порядком. На Terminal-Bench 2.0 - 80,0% проти 72,5%. ↗

Цифри та їхній обсяг
Тестова вибірка GAIA2 - 300 задач, Terminal-Bench 2.0 - 40. Значення - середні за трьома тестовими запусками: 59,8 ± 1,0 на GAIA2 (звичайний агент 53,6, GEPA 54,2, Meta-Harness 54,2) і 80,0 ± 2,5 на Terminal-Bench 2.0 (ручний Terminus-KIRA 69,2). Головні прирости 4,4 і 7,5 пункта виміряно проти того самого оптимізатора з порядком сценаріїв, зафіксованим заздалегідь. Автори наводять також незалежний запуск GAIA2 з тим самим висновком і приріст +3,0 пункта при застосуванні методу до GEPA (з 54,2% до 57,2%). ↗
Сорок тестових задач
Це мій аналіз, а не твердження статті. На 40 задачах одна задача - 2,5 пункта, тож 7,5 пункта за розміром дорівнюють трьом задачам у середньому за запусками. Сигнал корисний, але тонкий. Результат GAIA2 на 300 задачах стійкіший, і приріст 4,4 пункта - те, на що я б орієнтувався. Жоден із них не каже про поведінку методу на закритій кодовій базі, іншій базовій моделі чи вже добрій обв’язці. ↗
Як збої стають «руками»
Кожна «рука» - зразок збою, виділений із невдалих траєкторій, наприклад повторювана помилка збирання команди, а не категорія чи окрема задача. Абляції показують, що вибір важливий: категорії замість зразків знижують результат на Terminal-Bench 2.0 на 10,8 пункта, окремі сценарії - на 6,7, а без пріоритизатора чи контролера дослідження результат повертається до фіксованого порядку. Моє прочитання: виграш дає пам’ять про невдалу правку й повернення до зразка, із частиною бюджету на пошук нових зразків.
Іграшковий тест, який я написав
Я написав вигаданий приклад обліку й виконав його локально: сім виправних збоїв у чотирьох зразках, шість запусків. Заданий порядок, що починається з уже розв’язаного зразка, виправляє 3; вибір найбільшого нерозв’язаного зразка виправляє 6. Перевіряється й те, що одна задача з 40 зсуває оцінку на 2,5 пункта. Вхідні дані вигадані. Вони ілюструють ідею розподілу й не є доказом про ActiveSaddler.
Обмеження та безпека
Автори пишуть, що це дослідницька робота на публічних і синтетичних даних, яку не оцінювали як виробничу систему чи з погляду безпеки. Вони зауважують, що згенерована правка обв’язки може змінювати підказки, інтерфейси інструментів, збирання команд чи потік керування, не торкаючись ваг моделі, і радять мінімальні права, пісочницю, змагальні перевірки та явний розгляд змін, що торкаються дозволів. У статті сказано, що код і сайт проєкту будуть доступні; випуск я не перевіряв, нічого не завантажував і метод не запускав. Це препринт arXiv v1.
Іграшковий тест у коді
# Invented toy: two ways to spend 6 rollouts on failure patterns.
remaining = {"quoting": 4, "paths": 2, "timeouts": 1, "stale-docs": 0}
def fixed(order, budget):
left = dict(remaining); fixed_n = 0
for name in order[:budget]: # one pass in a preset order
if left[name]:
left[name] -= 1; fixed_n += 1
return fixed_n
def adaptive(budget):
left = dict(remaining); fixed_n = 0
for _ in range(budget): # always target the largest unresolved pattern
name = max(left, key=left.get)
if left[name]:
left[name] -= 1; fixed_n += 1
return fixed_n
order = ["stale-docs", "stale-docs", "timeouts", "paths", "stale-docs", "quoting"]
a, b = fixed(order, 6), adaptive(6)
assert (a, b) == (3, 6)
print("preset order repaired", a, "of 6; adaptive repaired", b, "of 6")
# 1 test task on a 40-task split moves the score by 2.5 points.
assert 100 / 40 == 2.5