← Есеї

Fable 5, Opus 4.8 і Sonnet 4.6: як чесно порівняти LLM на власному коді

Контрольований експеримент: Fable 5, Opus 4.8 і Sonnet 4.6 за одним промптом аудитують реальну кодову базу. Методика чесного порівняння LLM на власному проєкті.

7 хв читання
TelegramОригінал
Fable 5, Opus 4.8 і Sonnet 4.6: як чесно порівняти LLM на власному коді

Коли виходить нова модель, анонс відповідає на питання «наскільки вона краща на бенчмарках» — і не відповідає на єдине питання, яке мене цікавить: що вона змінить у моїй роботі. Я провів контрольований експеримент: три моделі Claude — Fable 5, Opus 4.8 і Sonnet 4.6 — отримали дослівно однакове завдання на аудит кодової бази цього блогу, кожна в ізольованій копії репозиторію, із заздалегідь узгодженою рубрикою оцінювання. У статті — сама методика, яку можна повторити на будь-якому проєкті, результати, і окремо — як експеримент двічі зламався і чого це навчило.

Чому бенчмарки не відповідають на моє питання

У публічних бенчмарків дві проблеми, і обидві фундаментальні. Перша — забруднення даних: тестові приклади просочуються в навчальні вибірки, і модель частково «згадує» відповіді замість того, щоб розв'язувати задачу. Це не маргінальна підозра, а предмет цілого напряму досліджень: огляд Xu та співавторів (2024) систематизує дослідження забруднення бенчмарків, а огляд EMNLP 2025 фіксує відповідь індустрії — перехід від статичних тестів до динамічно генерованих.

Друга проблема простіша: бенчмарк вимірює не мою задачу. Мені не потрібна модель, яка найкраще розв'язує олімпіадні задачі. Мені потрібна модель, яка знайде реальні баги в моєму Laravel-блозі, не вигадає неіснуючих і доведе, що її фікс працює.

З цього випливає проста думка: найкращий тестовий стенд для порівняння моделей — власний проєкт. Його коду в такому поєднанні немає в навчальних вибірках, задачі на ньому — рівно ті, за які я плачу, а результати я можу перевірити руками, бо знаю цей код.

Дизайн експерименту: один промпт, три ізольовані світи

Завдання для всіх трьох моделей було дослівно однаковим — різнилися лише ім'я гілки і папка результатів. Чотири фази: аудит двомовної системи статей блогу з доведенням кожної знахідки у вигляді файл:строка з цитатою коду; вибір рішень для трьох головних знахідок з описом компромісів; реалізація одного фіксу із самоперевіркою; нотатка про результати російською та англійською. Повний цикл інженерної роботи, а не ізольований «питання-відповідь» — такий підхід рекомендує і Anthropic: оцінювати агентів на задачах з реального продукту, за рубрикою, узгодженою до запуску.

Три правила зробили порівняння чесним:

Ізоляція. Кожна модель працювала в окремому git worktree — власній копії робочого каталогу зі своєю гілкою. Моделі фізично не могли побачити результати одна одної або завадити одна одній.

Захист від галюцинацій — у самому промпті. Ключовий рядок завдання: «вигадана знахідка (неіснуючий код, неправильний рядок) гірша, ніж відсутність знахідки». Без цього стимулу модель, яку просять знайти проблеми, схильна їх «знаходити» в будь-якому разі. З ним — кожна знахідка зобов'язана пережити ручну перевірку.

Виключення підказок із заліку. У репозиторії лежить CLAUDE.md, де описані відомі граблі проєкту — наприклад, відносні шляхи до ассетів, що ламаються на URL з мовним префіксом. Усі три моделі читають цей файл, тому такі знахідки «безкоштовні»: вони зараховуються за акуратність, але не за глибину.

Рубрика: оцінювати лише те, що можна перевірити руками

До запуску я зафіксував шість осей по п'ять балів: точність аудиту (ручна перевірка вибірки знахідок за файл:строка), глибина (підтверджені знахідки, яких немає в підказках), якість міркування про компроміси, код і реальність самоперевірки, якість російського та англійського тексту, дисципліна (нуль питань до людини, жодного порушення обмежень). Принцип той самий, що й у хорошого код-рев'ю: чим менше вісь спирається на смак і чим більше — на перевірюваний факт, тим більше їй можна довіряти.

Як усе зламалося вперше

Перший запуск я зробив неправильно — і це виявилося найпереносимішою частиною експерименту. Я відкрив три інтерактивні сесії паралельно в одній і тій самій папці репозиторію. Через кілька хвилин у робочому дереві лежали незакомічені правки, які неможливо було атрибутувати: спільний checkout означає, що коли одна сесія робить git checkout -b, гілка перемикається в усіх трьох, а їхні правки й коміти перемішуються. Одна із сесій до того ж зробила git stash і змела в нього все підряд — включно з моїми власними файлами, що до експерименту не стосувалися.

“Паралельні AI-агенти в одній папці — це не паралельний експеримент. Це один великий конфлікт із трьома авторами.”

– висновок, який коштував мені перезапуску

Результати двох сесій довелося визнати непридатними: навіть якби вони доопрацювали до кінця, я не зміг би чесно сказати, чиї правки оцінюю. Другий запуск — уже в ізольованих worktree — уткнувся в ліміти тарифу: два агенти загинули на старті, а третій завис, продовжуючи виглядати «працюючим» в інтерфейсі. Діагноз поставила файлова система, а не індикатор статусу: за двадцять хвилин у його робочій копії не з'явилося жодного файлу. Це другий переносний урок: живучість агента перевіряється за змінами на диску. Після перезапуску всі три моделі пройшли повний цикл у рівних умовах.

Результати: де моделі однакові й де різняться

Найважливіший результат — те, чого не сталося: галюцинацій немає в жодної моделі. Я вручну перевірив по три й більше знахідок кожної — усі цитати й номери рядків точні аж до символу. Для задач аудиту це головний поріг довіри, і його пройшли всі троє.

Далі починаються відмінності:

Fable 5 Opus 4.8 Sonnet 4.6
Підтверджених знахідок 11 5 9
Нетривіальних унікальних 3 1 2
Самоперевірка фіксу інтеграційний рендер на тимчасовій БД, xmllint, атрибуція чужого заваленого тесту лінтер + рендер; упіймав власний баг тільки лінтер і список роутів
Токени / час 164k / 21 хв 101k / 12 хв 131k / 12 хв
Підсумок за рубрикою (з 30) 30 24 25,5

Якісні відмінності інформативніші за бали. Opus 4.8 — єдиний, хто не помітив зламаний заголовок Content-Type у sitemap (його знайшли двоє інших) і залишив його у власному фіксі; а в його російський текст протекло англійське слово — «и even шлях до картинки». Sonnet 4.6 зробила коректний фікс, але її самоперевірка була декларативною: лінтер замість запуску. Fable 5 вирізнилася саме на самоперевірці: виявила, що php на моїй машині — це обгортка над docker-контейнером, змонтованим на основний каталог, перебудувала всі перевірки через одноразові контейнери й прогнала свій фікс інтеграційно на тимчасовій базі. Різниця між «я зробив» і «я довів, що зробив» — це і є найдиференціюючіша вісь для агентських задач.

Ще один корисний сигнал — конвергенція: усі три моделі незалежно назвали головною знахідкою ту саму проблему з sitemap. Коли незалежні аудитори сходяться в топ-знахідці, це дешевий аналог міжекспертної узгодженості: проблема майже напевно реальна.

Суддя з-поміж учасників

Оцінку за рубрикою проводила Fable 5 — та сама модель, що брала участь у порівнянні. Це методична діра, і про неї треба говорити прямо: LLM-судді систематично завищують оцінки власним текстам, причому схильність тим сильніша, чим краще модель упізнає свої тексти — це показано в роботі Panickssery та співавторів на NeurIPS 2024. Пом'якшити зміщення можна двома способами, і я використав обидва: по-перше, максимально змістити рубрику від смакових осей до перевірюваних фактів — точність рядків, повнота фіксу, протекле іншомовне слово не залежать від симпатій судді; по-друге, явно задекларувати конфлікт і віддати спірні осі на перехресну перевірку іншій моделі або людині. Суб'єктивні осі мого підсумку — якість тексту, якість міркування — варто читати з цією поправкою.

Обмеження чесності

Один прогін на модель — це n=1: відмінності в один-два бали нічого не значать, довіряти варто тільки якісним розривам — пропущеному багу, глибині самоперевірки. Експеримент вимірює три моделі на одній задачі в одному домені; «Fable 5 краще взагалі» з нього не випливає. І варто пам'ятати про ціну: топ-модель витратила в 1,6 раза більше токенів і майже вдвічі більше часу, ніж найекономніший учасник, а її токен за прайсом ще й дорожчий сам по собі — для регулярних задач це вагомий аргумент на користь простіших моделей.

Що я забираю собі

Методика звелася до короткого чек-листа, який працює для будь-якого проєкту й будь-яких моделей:

  • Тестове завдання — повний цикл реальної роботи на своєму коді, а не синтетична задачка.
  • Один промпт для всіх, ізоляція через окремі worktree, результати — в окремі гілки.
  • У промпті — явна ціна галюцинації: вигадана знахідка гірша за відсутність знахідки.
  • Підказки, доступні всім (документація, нотатки в репозиторії), виключаються із заліку глибини.
  • Рубрика фіксується до запуску й спирається на перевірювані факти, а не на враження.
  • Вибірку знахідок перевіряти руками; збіг топ-знахідок у незалежних моделей — сигнал їхньої реальності.
  • Суддя-учасник — задекларований конфлікт: спірні осі віддавати на перехресну оцінку.
  • Живучість агента перевіряти за диском, а не за індикатором в інтерфейсі.

Бонус, який не входив у план: експеримент окупився сам. Три незалежні аудити знайшли в блозі реальні проблеми — від sitemap без англійських сторінок до мертвих запитів у контролері — і два готові фікси вже лежать у гілках, чекаючи перенесення в прод. Порівняння моделей на своєму коді, на відміну від читання бенчмарків, залишає після себе не лише думку.

Джерела й орієнтири