AutoHarness: слой навыков для Claude Code, который учится сам
📂 Исходный код на GitHubПлагин для Claude Code на чистом Python, который превращает ваши рабочие сеансы в навыки. Собирает новый SKILL.md из эпизода работы, обновляет существующий вместо копии, объединяет похожие навыки под одним зонтиком и убирает те, к которым никто не возвращался. Умеет встроить указатель своих навыков в начало каждой сессии и ведёт журнал решений по каждому навыку.
Обычно навыки для агента пишут вручную: кто-то придумал правило, оформил его в SKILL.md и положил в .claude/skills/. Через месяц таких файлов двадцать, половина из них повторяет другую, а третью никто ни разу не открыл. AutoHarness решает эту проблему сам: он ставится плагином в Claude Code, разбирает ваши рабочие сеансы и сам пишет по ним навыки, обновляет их, когда вы их правите, объединяет похожие в один и убирает те, к которым перестали возвращаться.
Название стоит расшифровать. В исследованиях по ИИ harness — это вся обвязка вокруг модели: системный промпт, инструменты, цикл агента, память о проекте. Модель одна и та же, а обвязка каждый раз пишется заново под новое поколение моделей. Авторы AutoHarness берут один кусок этой обвязки — слой навыков — и пробуют сделать его самообслуживающимся. Свою задумку они проверяют на CORE-Bench: на их счёт результат вырос с 42% до 78% при той же модели (статья HAL).
Что именно он делает
- Учится на реальной работе. Отдельного сбора данных и прогона обучающей выборки нет. Каждый кусок вашей работы превращается в навык из той сессии, которую вы и так вели. Отражение срабатывает само, когда сеанс сделал достаточно вызовов инструментов, а команда
/learnзапускает его по требованию. - Группирует, а не копит. Новый эпизод не всегда добавляет файл. Рефлектор сравнивает его с уже накопленными навыками и объединяет те, что описывают одну и ту же ситуацию. При объединении он записывает, какой навык вобрал в себя какой, — поэтому слияние никогда не путается с удалением.
- Держит свою библиотеку перед моделью. В начале каждой сеанса Claude Code получает сгруппированный список навыков, которые написал AutoHarness. Родной механизм подсказок хоста при этом не трогают — список просто добавляется поверх.
- Проверяет себя на использовании, а не на бенчмарке. Навык выживает, если его позже действительно читают: доля загрузок от числа запросов, в течение которых он был доступен. Никакого внешнего оракула и никаких токенов на отдельный прогон.
- Трогает только свои навыки. Под руку попадают лишь те
SKILL.md, которые он создал сам через плагин. Всё, что вы писали сами или ставили извне, остаётся нетронутым. - Хранит доказательства. Каждое создание и обновление попадает в журнал навыка вместе со сценарием и решением. Из этих записей потом можно собрать бенчмарк на настоящей работе.
Установка
Нужен python3 в PATH: AutoHarness написан целиком на Python и не зависит ни от одной сторонней библиотеки. Без интерпретатора его хуки и MCP-сервер просто не сработают.
Команды вводятся в поле ввода Claude Code:
/plugin marketplace add tigerless-labs/autoharness
/plugin install autoharness@autoharness
Дальше — /reload-plugins или перезапуск. Настраивать ничего не нужно: сразу после установки плагин начинает наблюдать за сеансами и складывает выученные навыки в .claude/skills/ в фоне.
Обновление идёт из терминала, и важно соблюсти порядок:
claude plugin marketplace update autoharness
claude plugin update autoharness@autoharness
После этого Claude Code нужно перезапустить: новая версия кэшируется, а не подхватывается на лету. Сначала обновляется каталог — иначе команда обновления смотрит на устаревший локальный список и радостно пишет, что у вас уже последняя версия.
Удаление останавливает работу плагина, но не стирает его результаты: навыки и состояние лежат вне плагина. Если нужно удалить и их, снесите каталог состояния (~/.claude/autoharness/ для общего слоя, <repo>/.claude/autoharness/ для проекта) и сами навыки в .claude/skills/. У каждого навыка AutoHarness есть метка в журнале, так что свои файлы вы не перепутаете.
Как устроен конвейер
Всё, что делает плагин, оседает на диск обычными файлами, поэтому разобраться можно простым чтением файлов. Схема лежит в pipeline.mmd.
| Узел | Роль |
|---|---|
| CAP — захват | Тупой канал на хуках: забирает каждый ход (ввод пользователя, ответ агента, работа инструментов), убирает секреты на выходе и ссылается на журнал хоста вместо копирования. Здесь же живёт триггер — он считает вызовы инструментов, и ход, который перевалил порог, заканчивается фоновым отражением. Содержимое на этом шаге не оценивается. |
| REF — отражение | Читает эпизод, сравнивает с текущим списком навыков и решает: добавить, объединить, поправить, удалить вспомогательный файл или снести. Выдаёт намерение: тело, дельту или путь, плюс причину и доказательство. Новый урок, противоречащий старому навыку, обязан переписать устаревший в том же заходе. Только предлагает: прав на запись у него нет. |
| promoter — проверка и запись | Единственный, кто пишет на диск. Проверяет намерение в памяти (безопасность, структура, журнал, полнота, авторство) и при успехе атомарно переименовывает файл в живой каталог навыков. Описание нового навыка должно успеть назвать свой триггер до обрезки в указателе. Каждое решение попадает в отчёт: что легло и что отклонили. |
| IDX — указатель | Собирает список для старта сеанса: навыки AutoHarness по категориям, по одной обрезанной строке с пометкой слоя. Архивные и ваши собственные навыки исключены. Вместе со списком едет строка о прошлом заходе, чтобы отклонённое предложение было видно. |
| MNG — жизненный цикл | Без фонового демона: пересчитывается один раз в начале сеанса. Ранжирует навыки по доле использования — число загрузок делённое на число запросов с момента появления навыка. Мера относительная к возможностям, поэтому закрытый ноутбук никого не «состаривает». Три сигнала держат раздельно: загрузка (модель вызвала навык) — единственное, что входит в долю; просмотр (сеанс заглянул в каталог навыка) — ценность для подсказок, но не следование правилам; патч — навык улучшали, поэтому загрузка после него читается как повторное использование после доработки. Новые навыки сидят на испытательном сроке: их вспоминают как обычно, но не считают против лимита и не выбрасывают. Архивируют, а не удаляют: вернуть каталог на место — значит воскресить навык со всей историей. |
| curator — сортировка | Более редкий проход по библиотеке целиком: читает её как одно целое и складывает похожие навыки под зонтики. Такое решение один эпизод принять не может. Перед началом делает снимки обоих деревьев навыков: слияние — единственная операция, которую атомарное переименование не отменит. |
| LED — журнал | Накопительный файл рядом с навыком: почему он появился или изменился, с доказательством и отметкой последнего отражения. Вынесен из тела навыка, чтобы текст подсказок оставался чистым. |
Настройка
Все настройки — переменные окружения с разумными значениями по умолчанию. Менять их имеет смысл, только если вы хотите ускорить или замедлить обучение.
| Переменная | По умолчанию | Что делает |
|---|---|---|
AUTOHARNESS_REFLECT_EVERY_N |
50 |
Период отражений, посчитанный в вызовах инструментов, а не в ходах. Меньше — учится быстрее и плодит больше дочерних сеансов. |
AUTOHARNESS_CONSOLIDATE_EVERY_N |
250 |
Тот же счётчик для куратора. Заметно реже, чем отражения: отжать библиотеку в один файл — не то же самое, что выучить урок. |
AUTOHARNESS_DIGEST_EXCHANGES |
20 |
Сколько ходов до начала эпизода сжимается в краткий пересказ для рефлектора. |
AUTOHARNESS_CARRIER |
bundle |
Что несёт отражение. bundle — обезличенное окно плюс пересказ свежему субагенту. fork — возобновляет и форкает только что закончившуюся сессию, чтобы рефлектор читал настоящий разговор на тёплом кэше родителя. |
AUTOHARNESS_INDEX_SUSPENDED |
0 |
Поставить 1, чтобы перестать добавлять указатель. Остальное продолжает работать, так что это и способ измерить пользу указателя, и выключатель для тех, кому жалко тратить на него контекст. |
AUTOHARNESS_CAPACITY_PROJECT |
50 |
Потолок на зрелые навыки проектного слоя. Он же ограничивает указатель в начале сеанса. |
AUTOHARNESS_CAPACITY_GLOBAL |
20 |
То же для общего слоя — меньше, потому что такой навык грузится в каждом проекте. |
AUTOHARNESS_SNAPSHOT_KEEP |
5 |
Сколько снимков дерева навыков куратор хранит перед слиянием. |
AUTOHARNESS_GRADUATION_SUSPENDED |
0 |
Поставить 1, чтобы не архивировать ничего за неиспользованием. |
Полный список — в разделе Configuration README. Задаются переменные либо в шелле (export AUTOHARNESS_REFLECT_EVERY_N=10), либо в карте env файла .claude/settings.json. Хуки читают окружение на каждом событии, так что изменение подхватывается со следующего сеанса.
Что появляется на диске
Каталог состояния выглядит так:
ls .claude/autoharness/
requests # счётчик запросов слоя — знаменатель для MNG
session-<id> # вызовы инструментов до следующего отражения
offset-<id> # байтовая отметка, где кончилось прошлое окно
intents/ # предложения навыков, ждущие промоутера
runs/<run-id>.json # что предложено, что легло, что отклонили и почему
last_run.json # строка отчёта для следующего старта сеанса
snapshots/ # архивы дерева навыков перед слиянием
Сам навык выглядит так:
.claude/skills/<name>/
SKILL.md # сам навык — обычный формат, ничего своё
.ledger.jsonl # LED: почему появился или изменился
.sidecar.json # счётчики жизненного цикла для MNG
references/evidence-*.md # вырезанный кусок сеанса, обосновавший запись
scripts/ templates/ ... # необязательные файлы, которые принёс рефлектор
Запись в журнале — одна строка JSON на событие:
{"action": "create", "reason": "User asked about the correct command to update a plugin ...", "evidence": "references/evidence-21cd22cc.md"}
{"action": "patch", "reason": "User discovered /reload-plugins is required in-session ...", "evidence": "references/evidence-1a4ec51d.md"}
Доказательство — это настоящий обезличенный кусок сеанса, который научил навык, сохранённый по содержимому, так что модель никогда не придумывает имена файлов.
Если вы повторите тот же сценарий с поправкой («пропущен шаг»), в следующем заходе навык не размножится: изменится его SKILL.md, а в журнал добавится строка patch.
Чем отличается от похожих подходов
| Без ограничений | Автоправка офлайн (Self-Harness) | Таймер и демон (hermes-agent) | AutoHarness | |
|---|---|---|---|---|
| Ограничивает слой навыков | Нет | Да | Да | Да |
| Сигнал проверки | Нет | Оценка на отложенной выборке | Простой по календарю | Следование правилам при работе |
| Что запускает очередной заход обучения | — | Офлайн-пакет | Простой и прошедшие дни | Работа внутри сеанса |
| Показывает свою библиотеку модели | Нет | Нет | Да | Да |
| Нужен бенчмарк или оракул | Нет | Да | Нет | Нет |
| Нужен постоянно запущенный демон | Нет | Нет | Да | Нет |
Итог
AutoHarness не пишет код за вас и не отвечает за архитектуру. Он берёт одну узкую задачу — не дать библиотеке навыков разрастись в свалку — и решает её на вашей же работе. Ничего настраивать не нужно, демона нет, а каждый созданный и удалённый навык можно прочитать глазами в .claude/skills/.
Лицензия MIT, исходники открыты. Авторы признают, что дизайн Hermes повлиял на их решение обойтись без демона и проверять навыки по реальному применению. Отдельный разбор от AI Insider на YouTube авторы не проверяли, но выложили: https://www.youtube.com/watch?v=TM6tGpug1Hc