Agent skills как формат донесения метода работы до ИИ-агента

Работаю с разными ИИ-агентами в разных средах и форматах с 2024 года.
На данный момент оптимальным и универсальным форматом донесения методов работы до ИИ-агентов считаю agent skills.

Речь именно о формате, а транспорт может быть разным: файловая система, инструменты или и то, и другое (так-то файловая система читается тоже инструментами, хотя возможны нюансы), а также принудительный prompt injection и иные методы..

Для личных нужд и для рабочих регулярно делаю скиллы специальным скиллом Pattern Language as Agent Skill с опорой на FPF.
Также в посведневности пользуюсь спецификацией FPF, перепиливаемой из оригинального монолита в формат скилла fpf-core без каких-либо изменений в содержании (меняется только форма).

На днях возникла дискуссия о методах доступа ИИ-агентов к знаниям, и Анатолий Левенчук провёл соответствующую работу Тридцать мегабайт мышления: как скормить библиотеку FPF нейросети

Чтобы чуточку разобраться и понять, какой подход лучше и насколько, я попросил Гермеса собрать какой-нибудь eval set и непредвзято прогнать его несколько раз, обращаясь к FPF через скилл fpf-core и через vibevm, сравнить результаты и дать рекомендации по улучшению обоих.

Disclaimer

В eval set я не смотрел, в его осях оценок не разбирался и далеко идущих выводов не делал. Не претендую на истину ни в какой инстанции. Хотел провести поверхностное сравнение и понять, остались ли мы с fpf-core далеко в хвосте технологий или не всё так плохо.
Личной цели достиг: понял, что не всё так плохо, продолжаю пользоваться скиллом fpf-core до появления уточнений или новых обстоятельств.

Подробности будут ниже.

2 лайка

Результаты сравнительного тестирования

Была использована изолированная создаваемая заново для каждого запуска песочница на основе Qwen CLI.

Что измерялось

Один и тот же корпус FPF Core, два представления, три плеча:

  • none — пусто (пол)
  • skill — копия fpf-core (SKILL.md в контексте + 356 файлов references/<ID>.md)
  • vibe — реальный vibe install ai.lev/fpf-spec (ядро + fpf-common)

18 кейсов × 3 плеча = 54 run’а. qwen CLI 0.24.7, модель qwen3.8-27b-noreason, бюджет 25 tool-calls / 480 с, изоляция песочниц, конверт JSON, tier-0 грейдер с self-test’ом на известных плохих фикстурах.

Корпуса эквивалентны: 2 270 CC-фактов контрактов — 100 % есть и в скилле; совпадение проверялось до прогона, иначе кейс отбрасывался.

Результат: качество не различается, цена — различается

Корректность (общий знаменатель, n=17; R1 исключён как дефект банка):

route
• пол: 0/3
• скилл: 2/3
• VibeVM: 2/3

near_miss
• пол: 0/3
• скилл: 3/3
• VibeVM: 3/3

section
• пол: 0/6
• скилл: 6/6
• VibeVM: 5/6

fabrication
• пол: н/п
• скилл: 1/3
• VibeVM: 1/3

gate
• пол: н/п
• скилл: 2/2
• VibeVM: 1/2

всего
• пол: 0/12
• скилл: 14/17 (82 %)
• VibeVM: 12/17 (71 %)

Пол — 0 из 12 на фактических семьях: вопросы не решаются из знаний модели, значит банк проверяет именно доступ к корпусу.

Разница в 2 кейса из 17 — это ~12 п.п. при одном прогоне на кейс. Стандартная ошибка такой доли ~9–10 п.п. Различию нельзя доверять. Оба потерянных кейса vibe: S6 — упёрся в бюджет, G2 — реально неверный ответ (рекомендовал запустить сравнение там, где FPF сам говорит «слишком тяжело»).

Стоимость (точно из usage-логов qwen, все 18 кейсов, включая прерванные):

пол
• запросов: 65
• входных токенов: 1,07 млн
• wall: 34 мин
• ₽: 6,05

скилл
• запросов: 145
• входных токенов: 4,77 млн
• wall: 65 мин
• ₽: 26,37

VibeVM
• запросов: 198
• входных токенов: 6,67 млн
• wall: 81 мин
• ₽: 37,55

VibeVM: ×1,40 токенов, ×1,37 запросов, ×1,26 времени, ×1,42 денег. На один решённый кейс: скилл 340 664 токена / 1,88 ₽, VibeVM 555 688 / 3,13 ₽.

Надёжность: прервано по бюджету 3/18 у скилла и 4/18 у VibeVM.

Почему VibeVM дороже — механизм

1. Цена определяется числом обращений, а не размером одного чтения. Оба плеча перечитывают один и тот же файл 2–5 раз (S3: пять чтений файла на 22 338 токенов = 111 690 токенов только на S3). А каждый ход заново отправляет весь контекст. VibeVM сделал на 37 % больше запросов (11,0 против 8,1 на кейс) — вот и весь прирост.

2. Разрез contract/source реален и дешёв — но агент его не удержал. Одно чтение рабочего слоя: 3 372 против 11 892 токенов (S2), 1 646 против 4 256 (S4), суммарно 24 442 против 77 139 = 32 %. Это тот самый выигрыш, о котором я говорил. Но в VibeVM агент сначала читал source/ (слой глубины) вместо contract/, добавляя ходы и токены. Navигационное преимущество съедено лишними запросами.

3. В дереве VibeVM лежат мины. В vibedeps есть машинные артефакты, которые агент может открыть и открыл:

  • package.specmap.json — 1 862 657 токенов в одном чтении (кейс S1);
  • ENTRIES.md — 84 204 токена (кейс G1);
  • corpus.json — 309 тыс. токенов.

В скилле таких файлов нет вообще: там каждый файл предназначен для чтения. Это не свойство представления, а гигиена поставки — и она чинится.

4. Статический лейн на практике не оплачивается. STATIC.md (9 163 токена) прочитали 10 из 18 прогонов. В остальных агент шёл грепом мимо адресной схемы. То есть и «пирамида 132k», и преимущество spec:// работают только если агент дисциплинированно читает boot-лейн — эта модель в 44 % случаев этого не делала.

Честность инструмента

Два дефекта грейдера и один дефект банка нашёл чтением ответов руками, не скриптом:

  • pattern_id: "A.6.P, C.16.Q, A.6.A" — грейдер не разбирал перечисление через запятую → два ложных провала (N3 в обоих плечах). Исправлено, оба стали pass.
  • Гейт, где агент упоминает F.13/F.17/F.18 чтобы исключить их, падал как «назначил паттерны» → ложный провал G1 у скилла. Исправлено, отправлено на ручную арбитрацию.
  • R1: ожидание A.6.REL неверно — канонический текст резервирует A.6.REL только для случая, когда нужно различать вхождения. Кейс исключён из координат корректности.

До исправлений было 10/18 и 11/18; после — 14/17 и 12/17. Цифры выше — после.

Отдельно: прерванные прогоны не попадали в статистику вообще, и средние по логам занижались вдвое. Восстановил точные токены из usage_record.jsonl/token-usage-*.jsonl в HOME каждого прогона — отсюда полные суммы.

Что осталось непроверенным / ограничения

  1. Один прогон на (плечо × кейс). Для бинарных координат это даёт ошибку ~10 п.п. Разницу в 2 кейса подтверждать нельзя.
  2. Одна модель. Вывод ограничен парой (представление × qwen3.8-27b-noreason).
  3. Бюджет 25 tool-calls / 480 с породил 7 прерванных прогонов — это часть измерения («не решил в бюджете»), но не «неправильный ответ».
  4. Плечо skill эмулировано через AGENTS.md, а не через рантайм Hermes.
  5. Формат XML не тестировался (только ядро, markdown-режим по умолчанию).
  6. Цифра «132k токенов» из заметки не проверялась — она про FPF-ALL, а здесь только ядро.

Ответ на твой вопрос

По этому прогону: для агента, живущего в рантайме, представление VibeVM не дало ни выигрыша в качестве, ни экономии. Скилл fpf-core оказался не хуже по ответам и дешевле на 40 %. Единственное структурное преимущество VibeVM — разрез рабочий слой / глубина — подтвердилось (в 3 раза дешевле одно чтение), но было нейтрализовано навигационными издержками и мусором в дереве.

При этом VibeVM не проиграл по существу: он проиграл по доставке. Три конкретные причины проигрыша — гигиена дерева (specmap.json, corpus.json, ENTRIES.md), необязательность boot-лейна (44 % прогонов мимо него) и цена за ход. Первое и третье чинятся на стороне пакета, второе — на стороне агента.

Практический вывод для тебя не изменился, но стал эмпирическим: держать FPF как скилл дешевле и не хуже; брать VibeVM стоит ради версионирования и общей поставки на команду, а не ради удобства агента. Если бы брал — первым делом убрал бы package.specmap.json и corpus.json из читаемого дерева.

1 лайк

Рекомендации для скилла fpf-core

P1. Разрезать монолитные reference-файлы на рабочий слой и глубину

Что: для каждого references/<ID>.md сделать два файла — <ID>.contract.md (Problem frame / Problem / Forces / Solution / Conformance Checklist / Consequences / Relations / Dependencies) и <ID>.source.md (Archetypal Grounding, Bias-Annotation, Anti-Patterns, Rationale, SoTA-Echoing). Разрез уже существует в природе — я сверил: contract+source = 110% от текущего файла, то есть это чистая переупаковка, без потери содержания.

На чём основано: на 6 паттернах чтение рабочего слоя стоит 24 442 токена вместо 77 139 — 32%. По паттернам: A.2.6 5 387 против 24 515 (22%), C.17 3 372 против 11 892 (28%), E.10.ARCH 7 376 против 22 338 (33%).

Эффект: главный измеримый выигрыш скилла. При этом все 6 section-кейсов скилл прошёл и без этого — значит риск потери качества нулевой, а цена падает втрое.

P2. Вынести монолитные _ctx.* из references/

Что: 20 файлов в references/ весят больше 20k токенов (суммарно 570 603). Худший — _ctx.Table-of-Contents.md = 67 598 токенов, и он лежит в том же каталоге, по которому агент грепает.

На чём основано: в SKILL.md «Look up a pattern by name → INDEX.md», то есть ToC-монолит маршрутизатором не используется вообще, но находится внутри поискового пространства.

Эффект: минус 67,6k токенов из каталога, по которому идёт поиск; риск случайного чтения монолита уходит.

P3. Правило «не перечитывать» и правило остановки поиска

Что: два абзаца в SKILL.md:

  • «Прочитал файл — не открывай его снова. Ссылайся на уже прочитанное».
  • «Прежде чем искать паттерн — проверь INDEX.md. Если id там нет, такого паттерна нет: отвечай «нет» и не открывай файлы».

На чём основано: агент читал один и тот же файл 2–5 раз за кейс (S3: пять чтений файла на 22 338 токенов = 111 690 токенов на один кейс). Кейс R2 ушёл в бюджетный обрыв, сжегши 1,09 млн токенов, — на кейсе, где правильный ответ «нет такого».

Эффект: цена определяется числом запросов, а не размером чтения; оба правила бьют прямо в этот множитель.

P4. Сделать индекс по frontmatter первичным маршрутизатором

Что: в каждом reference-файле уже есть YAML с id, title, status, keywords, dependencies — но он не собран в индекс. Сгенерировать references/INDEX.md с колонками id | title | keywords | dependencies | размер и поставить поиск по нему выше таблицы «ситуация → список из 12 id».

На чём основано: в N3 (near-miss по A.6.P / C.16.Q / A.6.A) плечо скилла дважды грепнуло весь каталог, а VibeVM-плечо решило ту же задачу одной цепочкой glob по id. Твоя таблица маршрутизации в SKILL.md раздаёт по 10–16 id на строку — агент идёт открывать несколько.

Эффект: маршрутизация за один поиск вместо 2–3 обращений.

P5. Дозаполнить заглушки в _ctx.*

Что: 42 контекстных файла несут буквальные [TODO: trigger condition — human review required] и [TODO: extract governing-pattern cues from body and convert to reference paths].

На чём основано: гейт-кейсы — единственная семья, где скилл выиграл у VibeVM (2/2 против 1/2), и выиграл именно потому, что _ctx.Decide-Whether-FPF-Fits.md — файл первого класса. Остальные 41 контекст не имеет триггеров, то есть не подключены к маршрутизации.

Эффект: плюс маршрутных входов и минус мусорные токены в каждом чтении.

P6. Зафиксировать нормализацию id

Что: строку в SKILL.md: правило CC-A10.1-N пишется также CC-A10-1-N; id A.10.1 → файл A.10.1.md.
На чём основано: я сверял корпуса — 2 270 CC-фактов совпадают на 100%, но в скилле встречается только точечная форма, а в VibeVM обе. Агент, который видел одну форму, не находит другую.

1 лайк

Для VibeVM

P1. Убрать package.specmap.json из читаемого дерева

Что: не материализовать его в vibedeps/ (держать в машинном сторе ~/.vibe/cache/ или отдавать через CLI), либо флаг vibe install --no-specmap.

На чём основано: файл = 1 862 657 токенов — треть объёма пакета ядра (5,6 млн). В кейсе S1 агент его прочитал, и именно это сделало S1 самым дорогим на плече.

Эффект: прямой вычет одного мегабайтного чтения из прогона. Самое дешёвое исправление с самым большим эффектом.

P2. ENTRIES.md и corpus.json — либо вне дерева, либо с предупреждением

Что: ENTRIES.md (84 204 токена) и corpus.json (308 615) лежат в vibedeps как обычные файлы. Либо вынести, либо первой строкой: «это индекс — не читай целиком, ищи по нему».

На чём основано: ENTRIES.md прочитан агентом в G1 (11 чтений файлов, 123 151 токен только на чтения).

Эффект: убирает второй по величине источник случайных трат.

P3. Перевести сниппет fpf-spec из static в dynamic

Что: STATIC.md для ядра = 9 163 токена, из которых 7 966 (87%) — один сниппет со списком 355 id. Сам пакет уже помечает его в vibe.toml как dynamic-candidate: boot snippet of 27539 bytes lists every core pattern. В приоритетной линии оставить правило адресации и таблицу «код → пакет» (856 + 333 токена), а список id держать в INDEX.md.

На чём основано: boot-лейн читают только 10 из 18 прогонов; при этом 87% лейна — это то, что агент и так получает грепом.

Эффект: boot падает с 9,2k до ~1,2k токенов, и он наконец становится таким дешёвым, что его незачем пропускать.

P4. Сделать чтение boot-лейна первым действием, а не развилкой

Что: managed block в AGENTS.md сейчас говорит «To begin a session, read these files in order» и отправляет в boot/STATIC.md, оттуда в boot/INDEX.md — два уровня отсылок. Заменить на одно императивное действие с точным путём.

На чём основано: 8 из 18 прогонов вообще не прочитали STATIC.md и работали грепом, игнорируя адресную схему spec://.

Эффект: включает всё, что заявлено как преимущество представления (адресацию, порядок чтения, проверку существования). Сейчас эти механизмы существуют, но не срабатывают.

P5. Починить эргономику путей

Что: при установке генерировать в корне проекта плоский индекс ссылок вида spec/A.2.6.md → vibedeps/ai.lev.fpf-spec/<ver>/vibevm/vibespecs/contract/A-2-6.md. Плюс сократить вложенность: сейчас путь содержит vibevm дважды.

На чём основано: VibeVM сделал на 37% больше запросов (11,0 против 8,1 на кейс). Причина видна в трейсах: чтобы открыть контракт, агенту нужно применить преобразование id (точки → дефисы), обойти три уровня вложенности и сначала найти каталог версии. Скилл делает это одним glob references/A.2.6*.

Эффект: минус 1–2 запроса на кейс — а именно запросы, а не размер чтения, дают основной прирост цены.

P6. Порядок чтения — первой строкой самого контракта

Что: в начало каждого contract/<ID>.md: «Рабочий слой. Глубина — source/<ID>#depth, открывать только если этот контракт оставляет сомнение».

На чём основано: в S3 VibeVM-плечо четыре раза прочитало source/E-10-ARCH.md (16 624 токена каждый) и лишь один раз сам контракт (7 376). Инструкция «contract before source» есть в fpf-lookup, но скилл не установлен (см. P8) — значит правило не доехало.

Эффект: сохраняет то самое преимущество разреза, которое в прогоне было нейтрализовано обратным порядком чтения.

P7. Дешёвая проверка существования

Что: в boot-сниппет: «если id или правила нет в STATIC/INDEX — ответ «нет», дальше не искать». Плюс явно продвигать vibe why / vibe requirements как server-side проверку вместо перебора файлов.
На чём основано: по кейсу F2 (правило, которого нет) VibeVM потратил 166 910 токенов против 272 594 у скилла — маршрутизатор со списком id реально помогает. Но F1 и F3 упали по бюджету в обоих плечах: искать несуществующее агенты не умеют останавливаться.

Эффект: закрывает целую семью кейсов, где сейчас проигрывают все.

P8. Доставить fpf-lookup до агента

Что: vibe skill install знает только claude, opencode, codex. Расширить список либо явно документировать ручную установку (для Hermes — в ~/.hermes/skills/).

На чём основано: скилл лежит в vibedeps/ai.lev.fpf-common/.../skills/fpf-lookup/SKILL.md, и нашёл его сам только 1 прогон из 18.

Эффект: в P6 и P7 правила уже написаны — они просто не доходят.

P9. Сократить машинную обвязку pub/

Что: pub/toc = 102 790 токенов в 8 файлах, pub/PREFACE.md = 20 068, pub/README.md = 12 017. Скилл держит тот же ToC одним файлом на 67 598 — то есть его можно абриджить вдвое.

На чём основано: те же три слагаемых покрывают 85% pub-объёма; в прогоне они не были нужны ни разу, но лежат в читаемом дереве рядом с контрактами.

Эффект: минус ~100k токенов соблазна в дереве.

P10. Для FPF-ALL (не для ядра): развязать link

Что: сейчас все 37 пакетов объявлены static, отсюда STATIC.md 111 404 байта (~31k токенов) в каждом сеансе. Сниппеты DPF-пакетов — это роутеры «какой DPF для чего», их место в dynamic-лейне.

На чём основано: vibe tree показывает static у всех 37 без исключения; комментарий в vibe.toml ядрового пакета сам признаёт сниппет списка id кандидатом в dynamic.

2 лайка

Добавил ещё один вариант доступа к FPF - монолитная спецификация - и повторил прогон на Deepseek 4.1 Flash.

Результатом удовлетворён.

Прогон FPF-банка - 4 носителя на DeepSeek 4.1 Flash

Один и тот же набор из 17 задач на знание FPF, четыре способа подложить агенту корпус. Корректность у трёх материальных носителей неразличима, различается цена: vibevm-пакет стоит в 2,2-2,7 раза дороже монолита и скилла за тот же результат.

Четыре плеча: что это и зачем

  • none — пустая рабочая папка, «пол» (floor). Агенту дают тот же вопрос, тот же формат ответа и то же правило «отвечай только из материала в рабочей папке», но материала нет — папка пуста. Смысл не в том, чтобы что-то измерить, а в том, чтобы доказать, что банк не решается из знаний модели. Если бы это плечо что-то набирало, тест измерял бы память модели о FPF, а не качество носителя. Результат: 0/12 на фактических семьях — модель не выдумывала паттерны, а честно сообщала «рабочая папка пуста, материала нет». Поэтому координаты честности (fabrication/gate) для пола помечены «не применимо»: пустое плечо не может «отказаться» применить FPF, у него и так ничего нет, и такой отказ дал бы фальшивые очки. Цена: 894 тыс. токенов, 3,2 запроса на кейс — самая дешёвая из четырёх проверок.

  • skill — скилл fpf-core. Классический агентский навык: роутер SKILL.md (4,9 КБ, воспроизведён дословно в AGENTS.md) плюс 400 файлов — 355 паттернов в references/, INDEX.md, контекстные разделы. Роутер говорит «не читай спецификацию целиком, вот таблица: ситуация → какие файлы грузить».

  • vibe — реальный проект vibevm с пакетом ai.lev/fpf-spec (2026.929.0). Носитель уровня пакетного менеджера: AGENTS.md — сгенерированная boot-инструкция, которая велит прочитать STATIC.md (32 КБ) целиком, затем INDEX.md и все файлы, которые тот перечисляет. Обязательная дисциплина чтения вместо поиска по требованию.

  • mono — монолит. Один файл FPF-Spec.md: 15,4 МБ, 117 207 строк, 3 273 747 токенов. Плюс AGENTS.md из пяти строк: «используй ./FPF-Spec.md, он очень большой, ищи по нему, не пытайся прочитать целиком». Внешнего роутера нет вообще — только внутреннее оглавление самого файла (~250 КБ).

Что запускалось

Параметр Значение
Модель deepseek-v4.1-flash через QwenCloud token-plan
Кейсы 17 живых (18 минус исключённый R1)
Запуски 68 = 17 кейсов × 4 плеча, по одному на кейс, без повторов
Бюджет запуска 18 вызовов инструментов, 480 с
Итог по токенам 10 347 249 (вход 10 186 439 / выход 160 810; кэш-чтений 8 061 056 = 78 %)

Профиль fpf-bank-v1__qwencloud-deepseek-v4.1-flash__cap18__wall480__1run. От прогона 06:xx на qwen3.8-27b отличается и моделью, и кэпом — прямых дельт между прогонами нет, плечи сравниваются внутри этого профиля.

Проходимость

семейство none skill vibe mono
route 0/3 3/3 3/3 3/3
near_miss 0/3 3/3 2/3 3/3
section 0/6 6/6 6/6 6/6
fabrication н/п 3/3 3/3 3/3
gate н/п 0/1 + судья 0/2 1/2
всего 0/12 15/16 14/17 16/17
по фактическим семьям 0/12 12/12 11/12 12/12

Пол = 0/12 на фактических семьях: банк не решается из знаний модели, материал действительно измеряется.

Что не является провалом

Из 22 непрошедших клеток настоящий содержательный провал один.

тип сколько что это
пол без материала 12 ожидаемый результат пола, не провал плеча
координата честности у пола 5 не применима по построению (passed=null)
прервано бюджетом 2 vibe/G1 и vibe/G2 — 19 вызовов при кэпе 18
нет финального сообщения 2 mono/G2 и vibe/N1 — exit 0, но CLI не отдал финальное сообщение
ушёл к судье 1 skill/G1
содержательный провал 1 skill/G2 — вместо отказа применил FPF (назвал C.19.2)

Пересчёт по оцениваемым клеткам (исключая артефакты CLI и прерывания): mono 16/16, vibe 14/14, skill 15/16 плюс один кейс ушёл к судье. Кейс skill/G1 при ручном чтении — корректный отказ («Apply none, in no order… FPF is too heavy»), с оговоркой, что если бы имя становилось durable, цепочка была бы F.14 → … . Грейдер правильно отправил его к судье, а не засчитал провалом: упоминание паттернов ради их исключения — не рекомендация.

Стоимость

плечо всего токенов среднее/кейс медиана/кейс максимум запросов/кейс доля бюджета
none 893 940 52 585 49 063 70 559 3,2 8,6 %
skill 2 238 882 131 699 120 662 326 942 4,6 21,6 %
vibe 4 549 827 267 637 273 685 481 939 7,5 44,0 %
mono 2 664 600 156 741 101 746 654 596 5,4 25,8 %
  • vibe — самый дорогой при той же корректности: 44 % всего бюджета. Причина в механизме: boot-лейн заставляет читать файлы (105 вызовов read_file за 17 запусков против 33 у mono и 44 у skill), каждый прочитанный файл остаётся в контексте и пересылается на каждом следующем запросе.
  • mono дешевле skill по медиане (101 746 против 120 662) и примерно равен по среднему, если исключить единственный выброс 654 596 — а это ровно тот запуск mono/G2, который не отдал финальное сообщение.
  • Монолит ни разу не читали целиком. 17 из 17 запусков открыли FPF-Spec.md, но работали выборочно: 64 grep_search и 33 read_file за 17 запусков. Внутреннего оглавления хватило, чтобы попадать в нужный паттерн без внешнего роутера.

Механизм по плечам

плечо открывал свой boot/роутер инструменты за 17 запусков
none — (нечего) glob 21, shell 21
skill 0/17 — роутер уже лежит в системном промте (AGENTS.md = SKILL.md дословно) grep 44, read 44, glob 20
vibe 13/17 read 105, grep 56, glob 38
mono 17/17 grep 64, read 33

Выводы

  1. Монолитная спецификация с одним указателем работает не хуже структурированных представлений — 16/17 против 15/16 у скилла и 14/17 у vibevm; различие в одну клетку на такой базе неотличимо от шума.
  2. Различие между носителями — в цене, а не в качестве. vibe стоит в 2,2-2,7 раза дороже mono и skill за ту же корректность. Это главный измеренный факт прогона.
  3. Внешний роутер не нужен, если у материала есть внутреннее оглавление. Монолит ни разу не читали целиком — агент грепал по файлу на 3,27 млн токенов и попадал в цель.
  4. Проблема не в носителях, а в отказе. Единственный содержательный провал — skill/G2, где вместо «это слишком тяжело для переименования переменной» модель применила FPF. Семейство gate — единственное, где плечи реально расходятся, и там же сконцентрированы прерывания по бюджету.

Ограничения

  • Один запуск на клетку — стандартного отклонения нет; различие в 1-2 клетки из 17 неотличимо от шума.
  • Два запуска (3 %) вернули exit 0 без финального сообщения (mono/G2, vibe/N1) — дефект харнесса или CLI, а не свойство плеча. Такие клетки надо либо перепрогнать, либо исключать из координат.
  • Кэп 18 не связывает на этой модели: максимум 19 вызовов показали только два прерванных запуска. Поднятие кэпа с 12 до 18 было страховкой, а не необходимостью — ожидавшаяся по данным qwen3.8 проблема прерываний на flash не воспроизвелась.
  • Асимметрия канала инструкции признана: в skill файл AGENTS.md несёт роутер дословно, в mono — только указатель. Это часть проверяемого свойства («монолит без внешнего роутера»), но при сравнении это надо помнить.
  • Число вызовов инструментов не равно числу запросов — модель делает несколько вызовов в одном ходу, поэтому прогон падает по бюджету на 19 вызовах, имея всего 11 запросов.
  • Чистота: вне разрешённой рабочей папки — 0 чтений; рабочие папки кейсов пересобирались из иммутабельных источников перед каждым запуском; исключённый кейс R1 не прогонялся.
2 лайка

Добавил вариант MCP с https://fpf.tools, устранил небольшое читерство в предыдущем тестировании скилла (SKILL.md был продублирован в AGENTS.md - так не делют).

Пять вариантов: что это, плюсы и минусы

none - пустая рабочая папка, «пол»

Тот же вопрос, тот же формат ответа, то же правило «отвечай только из материала», но материала нет.

Плюсы

  • Доказывает, что банк вопросов не решается из знаний модели: 0/12 на фактических семьях. Без этого замера все остальные цифры ничего не значат.
  • Самый дешёвый и быстрый (894 тыс. токенов за 17 клеток, медиана 17 с) — цена «ничего» для контроля.

Минусы

  • Это не способ доставки, а контрольная точка: практической пользы нет.
  • Для семейств fabrication и gate координаты не применимы по построению: нет материала — нет и отказа от него.

mono - монолит FPF-Spec.md + указатель из пяти строк

Один файл 15,4 МБ (3 273 747 токенов, 117 207 строк) и AGENTS.md из пяти строк: «используй ./FPF-Spec.md, он очень большой, ищи по нему, не читай целиком». Внешнего роутера нет.

Плюсы

  • Лучший результат: 17/17, фактические семьи 12/12.
  • Лучший баланс цена/результат среди всех носителей: 222 050 токенов на правильную клетку, медиана 4 вызова на клетку.
  • Внешний роутер не нужен: внутреннее оглавление файла (~250 КБ) работает как навигация. Монолит ни разу не читали целиком — 64 grep + 33 read_file за 17 клеток.
  • Ничего не надо ставить и синхронизировать: один файл в поставке, ноль чтений вне рабочей папки.
  • Работает офлайн, редакция заморожена и проверяема хешем.

Минусы

  • В поставке лежит файл на 3,27 млн токенов: обновлять его надо целиком и вручную.
  • Редакция стареет: свежие паттерны и DPF-сьюты не появятся, пока не подменишь файл.
  • Нет цитируемости: в ответе нет ни коммита, ни секции — проверить, откуда взято, можно только глазами.
  • Требует, чтобы агент умел искать по очень большому файлу: на слабой модели или без грепа это плечо деградирует.

skill - скилл fpf-core, установленный в окружении агента

SKILL.md + 398 файлов лежат как установленный скилл (~/.qwen/skills/fpf-core/), рабочая папка пуста, AGENTS.md — три строки ссылки. Проверено по журналу: 17 из 17 клеток вызвали инструмент skill и читали references/<ID>.md.

Плюсы

  • Механизм реальный, а не имитированный: скилл именно установлен, инструкция на него только ссылается.
  • Лучший результат на маршрутизации: 16/17, фактические семьи 12/12.
  • Роутер «ситуация → какие файлы грузить» работает: агент идёт по таблице, а не перебирает корпус.
  • В поставке 398 небольших файлов вместо одного монолита: паттерн обновляется точечно.

Минусы

  • Дороже монолита: 287 888 токенов на правильную клетку (+30 %), медиана 6 вызовов и 72 с против 4 вызовов и 24 с.
  • Требует отдельной загрузки скилла и поиска по его таблице; в тяжёлых клетках уходит в длинный перебор: G2 700 тыс. токенов, G1 395 тыс., F1 376 тыс.
  • Поставка сложнее: скилл надо установить в окружение (в прогоне — в HOME каждой клетки).
  • Роутер и references/ — ещё один формат, который надо держать в актуальном состоянии.

vibe - реальный проект vibevm с пакетом ai.lev/fpf-spec

Носитель уровня пакетного менеджера: AGENTS.md — сгенерированная boot-инструкция, которая велит прочитать STATIC.md (32 КБ) целиком, затем INDEX.md и всё, что тот перечисляет.

Плюсы

  • Корректность та же, что у остальных: 12/12 на фактических семьях, 15/15 оцениваемых клеток.
  • Версионирование и поставка на команду: пакет, зависимости, lock-файл — то, чего нет ни у монолита, ни у папки скилла.
  • Явный разрез «рабочий слой / источник»: теоретически дешевле читать (contract/ вместо source/), выигрыш измерим (24 442 против 77 139 токенов в одном чтении).

Минусы

  • Самый дорогой из файловых: 379 152 токена на правильную клетку, ×1,7 к монолиту, 44 % бюджета того прогона.
  • Boot-лейн заставляет читать файлы пакетно (105 read_file за 17 клеток против 33 у монолита), и всё прочитанное пересылается на каждом следующем запросе.
  • В дереве пакета мины: package.specmap.json — 1,86 млн токенов в одном чтении, corpus.json — 309 тыс., ENTRIES.md — 84 тыс.
  • Дисциплина boot-лейна на практике не соблюдается: STATIC.md читали 10 из 18 запусков.
  • Выигрыша в качестве нет, цена выше: смысл держать — версионирование и общая поставка, не удобство агента.

mcp - FPF Library по протоколу MCP (fpf.tools)

Публичный read-only сервис https://mcp.fpf.tools/mcp, 7 инструментов, без ключа. Рабочая папка пуста: корпус не доставляется вообще.

Плюсы

  • Единственный способ, где корпус не надо доставлять — агент приходит с пустой папкой, материал приходит по сети.
  • Всегда свежая редакция: сервис обновляется по пушам в ailev/FPF (за час наблюдения сменились три коммита).
  • Цитируемость: каждый ответ несёт коммит, путь, секцию, диапазон строк и снапшот — ответ проверяем, а не принимается на веру.
  • Корпус шире ядра: 856 паттернов, 40 публикаций (ядро + 33 DPF-фреймворка + гайды) — можно искать по всей библиотеке.
  • Только чтение и без ключа: нечего ставить, нечем испортить.

Минусы

  • Самый дорогой: 610 709 токенов на правильную клетку, ×2,7 к монолиту. С ростом бюджета дорожает нелинейно: аддендум при капе 28 — 874 тыс. токенов на клетку.
  • 10 запросов на клетку вместо 4; 8 % обращений отбито сервером (13 mcp_tool_error + 1 invalid_tool_params) — интерфейс инструментов приходится вписывать в инструкцию.
  • CLI режет вывод инструмента на 32 000 символов, поэтому агент дополнительно работает с собственными дампами: треть обращений — локальные (grep, shell, read_file, glob, write_file), 38 служебных чтений за прогон.
  • Редакцию нельзя заморозить: проверяемость есть, воспроизводимость — нет. В аддендуме каждая клетка читала материал двух разных коммитов, и страж по снапшоту это не поймал — поймал только разбор цитат.
  • Корректность на одну клетку ниже: 11/12. R4 — модель назвала соседа C.22.2 вместо C.22.PFR (с обоснованием, но карточка говорит обратное).
  • Ограничение «только ядро» self-enforcing не является: 11 из 17 клеток читали гайд USING-FPF.md вне ядра, несмотря на явный запрет в инструкции. Ограничение работает только как измеренная координата.
  • Зависимость от внешнего сервиса: лимиты неизвестны, сетевой сбой запросто превращается в «провал плеча».

Проходимость

семейство none mono skill vibe mcp
route 0/3 3/3 3/3 3/3 2/3
near_miss 0/3 3/3 3/3 3/3 3/3
section 0/6 6/6 6/6 6/6 6/6
fabrication н/п 3/3 3/3 3/3 2/3
gate н/п 2/2 1/2 нет данных 1/2
фактические семьи 0/12 12/12 12/12 12/12 11/12

Единственное семейство, где носители реально расходятся, — gate (умение отказаться от FPF там, где он избыточен): монолит 2/2, установленный скилл 1/2, у vibevm и MCP данных нет.

Цена

плечо всего токенов медиана на клетку запросов на клетку токенов на правильную клетку
none 893 940 48 688 3 —
mono 2 664 600 100 805 4 222 050
skill 3 454 653 131 964 6 287 888
vibe 4 549 827 270 967 8 379 152
mcp 6 717 803 385 748 10 610 709
1 лайк