# Jev як System One

> Оцінювати код балами через Jev не вийшло. Конкретні yes/no питання спрацювали: правила лінтера, написані звичайними реченнями, достатньо дешеві й стабільні для кожного файлу та кожного pull request.

Published: 2026-10-15 | Author: Petro Lashyn
Canonical: https://welldigit.com/uk/journal/jev-as-system-one

Нещодавно, у вересні 2026 року, TypeSafe AI випустила Jev, нову інтелектуальну класифікаційну AI-модель. Головна її відмінність від класичних LLM у тому, що вона не генерує текст (чи будь-який інший контент). Натомість вона відповідає лише у трьох режимах: **Noul**, питання "так чи ні", яке повертає ймовірність того, що відповідь "так"; **Choice**, який обирає один варіант із заданого набору до 255 і повертає обраний варіант, ймовірність для кожного варіанта та значення впевненості; і **Score**, який оцінює контент за шкалою з 2–10 упорядкованих описових рівнів, які ви пишете самі, і повертає оцінку, ймовірність для кожного рівня та значення впевненості. Водночас вона може обробляти багато контексту: Jev 1.13 має загальний ліміт контексту 64k токенів і окремий ліміт 32k для стану разом із найдовшим питанням. А найцікавіше те, що вона надзвичайно дешева і швидка. Звісно, вартості вихідних токенів немає взагалі, через саму природу її режимів відповіді.

Хайп навколо неї злетів зі швидкістю комети. Буквально за 48 годин після релізу мої стрічки в Threads і LinkedIn вибухнули use cases, прикладами й експериментами з нею.

Мене вона теж зацікавила з першого дня. Оскільки зараз я багато працюю над побудовою різних агентних флоу та флоу для AI-асистентів, Jev одразу стала для мене реальним потенційним пазлом, який вписується майже в будь-який pipeline і допомагає краще використовувати запити до LLM.

У цьому сенсі цілком логічно, що ідея захована в тому, як її називає TypeSafe: модель System One. Це явне посилання на System One людського мислення з книги *"Мислення швидке й повільне"* нобелівського лауреата Даніеля Канемана. Я прочитав цю книгу кілька років тому, і вона справді цікава з погляду того, як людський мозок веде процес мислення. За Канеманом, існує System One (швидка й автоматична) та System Two (повільна й обдумана).

System One це те, що відповідає на 2 + 2 без жодних зусиль, помічає гнів у чиємусь голосі, закінчує фразу "хліб і…" або веде машину порожньою дорогою, поки ви розмовляєте з пасажиром. System Two потрібна, щоб помножити 17 × 24, заповнити податкову декларацію, втиснути машину у вузьке паркомісце чи слухати один голос у галасливій кімнаті. System One працює весь час і передає System Two свої враження та сигнали; System Two втручається лише тоді, коли щось складне, несподіване або важливе.

Звісно, агент не людина, LLM не людський мозок, а MCP не нервова система, але насправді це доволі добре лягає на той самий патерн. І очевидно, що Jev як System One добре визначає миттєвий сигнал, який вирішує, на якому рівні System Two має обробити вхідний payload і чи взагалі має до нього долучатися. System One ідеальна для сигналізації, маршрутизації та розставлення акцентів для того, що має статися далі.

І сценаріїв, де це можна застосувати, дуже багато. Найпростіший приклад: сортування вхідних повідомлень у CRM: чи це терміново; чи це спам; до якої із заданих категорій це належить; на кого це призначити; і так далі. Або, наприклад, вона може оцінити потенційну критичність помилки в лозі: іноді 500 у лозі менш критична, ніж 422 чи 403, залежно від контексту.

Я вже додав її в реальний pipeline для нашого асистента для магазинів Vendigit. Вона оцінює, чи наступне повідомлення справді стосується покупок, чи це small talk, офтоп, образи або нісенітниця, і залежно від цього сигналу наступний крок агента (який інструмент обрати для побудови відповіді) різниться.

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

Але в цій статті я хочу поділитися своїми експериментами з використанням Jev для створення інструменту оцінки якості коду. Це питання зараз актуальне як ніколи, бо обсяг коду, який ми зараз виробляємо, значно більший, ніж будь-який окремий розробник чи software engineer може опрацювати й контролювати.

Тож я поставив собі задачу: як оцінювати код, який я пишу з AI? З досвіду я вже вирішив проблему "skill" і впорядкував playbooks, гайдлайни та правила. Додав усі можливі архітектурні тести, статичний аналіз, лінтери тощо. І це працює доволі добре: у більшості випадків я отримую дуже передбачуваний, стабільний результат, і AI coding agent приносить мені код, який дотримується всіх визначених мною конвенцій, патернів і структури. Але прогалини все одно можуть бути, особливо в логіці та флоу, що виходять за межі простої функціональності. І завжди є простір для інженера, щоб посилити свої "висічені в камені" конвенції.

Тож я вирішив, що Jev хороший кандидат для такого експерименту.

## Ідея: правила лінтера, написані звичайними реченнями

Статичний аналіз (PHPStan, Larastan, Rector) точний і безкоштовний, але ловить лише те, що можна записати як правило в коді. Він не скаже вам, що "цей клас робить забагато" або "ця непрямість безглузда". LLM code review (CodeRabbit, Copilot review, Claude) ловить саме такі проблеми, що потребують судження, але він дорогий, повільний і щоразу дає іншу відповідь. Через це його важко запускати на всій кодовій базі і ще важче використовувати як CI gate.

Між ними нічого немає. Я хотів перевірки на кшталт судження, які достатньо дешеві й стабільні, щоб запускати їх на кожному файлі та кожному pull request.

Це ще не пакет. Поки що я зробив невеликий proof-of-concept snippet на Laravel, щоб перевірити ідею. Принцип простий: я пишу питання, Jev відповідає на кожне ймовірністю, а мій код перетворює відповіді на знахідки. Я тестував це на нашій внутрішній CRM, production-застосунку на Laravel, тож кожен експеримент нижче працює на реальному коді.

## Перша спроба: попросити Jev оцінити код балами (не спрацювало)

Перша ідея була очевидною: попросити Jev оцінити кожен файл від 0 до 100 за шістьма критеріями: SOLID, KISS, DRY, конвенції Laravel, атомарність і загальна якість коду.

Проблема проявилася вже на першому файлі. `ProjectStateUpdate.php` це action на 4 рядки: встановити стан, зберегти, повернути. Jev дала йому SOLID-оцінку близько 47. Моя власна оцінка була близько 90. До того ж Jev розділилася майже 50/50 щодо того, чи взагалі можна оцінити SOLID для цього файлу, тож відповідь змінювалася між запусками.

Я припустив, що їй бракує контексту, тож спробував ще раз, додавши enum цього файлу та єдиний виклик. Контекст зробив Jev більш *охочою* судити (ймовірність "чи можна це оцінити?" зросла з 0.46 до 0.79), але майже не змінив *те, що* вона судила. Більшим сюрпризом стали шість атрибутів метаданих `#[]` на класі: Jev сприймала їх як складність. Коли я їх прибрав, оцінка KISS зросла з 68 до 86. Навіть у найкращому налаштуванні тривіальний сетер отримував близько 60. Jev просто занижує оцінки тонким класам-обгорткам.

Далі мені був потрібен чесний спосіб виміряти виявлення без ручного оцінювання коду. Я взяв 5 реальних файлів з нашої CRM і скопіював кожен 6 разів, заклавши в кожну копію по одній навмисній проблемі: відсутня транзакція, продубльована гілка, `env()` в action, проковтнутий exception, зайві замикання та додаткові side effects. Оскільки я знаю правильну відповідь для кожної копії, можу точно порахувати, що вловлено.

Оцінки дещо виявили: 22 з 30 закладених проблем змінили бали. Але три речі зробили їх непридатними як інструмент лінтингу:

- **Шість оцінок рухалися разом.** Щойно щось було не так, падали всі. Вони поводилися як одне число "загальної якості" з шістьма назвами.
- **Чистий код уже виглядав зламаним.** Незмінені файли мали ймовірності "проблеми" 0.7–0.8, тож жоден фіксований поріг не міг відділити чистий код від зламаного.
- **Конвенції Laravel були майже невидимими.** `env()` і `request()` у доменному коді пропускалися в кожному випадку.

Один результат, утім, був дуже гарною новиною: шум між запусками становив менше 1 бала за шкалою 0–100. Jev фактично детермінована. Пізніше це виявилося дуже важливим.

## Друга спроба: питання "так чи ні" (ось тут і клацнуло)

Тоді я повернувся до того, чим Jev насправді є: моделлю System One. System One не пише есе і не виносить вердиктів; вона помічає. Тож замість оцінок я ставив конкретні, перевірювані питання "так чи ні":

| Питання | Відповідь Jev |
| --- | --- |
| Чи виконується запит до бази даних усередині циклу? | 0.89 |
| Чи створює код сервіси через `new` замість ін'єкції? | 0.94 |
| Чи перехоплюється exception, а потім ігнорується? | 0.03 |

Я написав 30 таких питань: 21 конкретну перевірку проблем і 9 фактів про відповідальності. Щодо відповідальностей я ніколи не питаю "чи цей клас SOLID?". Я питаю, що клас *робить*: чи пише в базу даних, чи викликає HTTP API, чи надсилає пошту, чи пише в кеш, чи форматує вивід? Далі пакет застосовує моє власне правило: два чи більше side effects в одному класі означають змішані відповідальності. Jev повідомляє факти; мій код вирішує, що добре, а що погано.

Ті самі тестові файли, ті самі закладені проблеми:

| | Оцінки | Питання "так чи ні" |
| --- | --- | --- |
| Виявлено закладених проблем | 22/30 | **29/30** |
| Конвенції Laravel | 2/5 | **5/5** |
| KISS | 2/5 | **5/5** |
| Наскільки чіткий сигнал | падіння оцінки на 5–40 балів | стрибок ймовірності з ~0.05 до ~0.95 |

Саме чіткість сигналу робить це придатним. Оцінка, що сповзає з 72 до 64, потребує інтерпретації. Ймовірність, що стрибає з 0.02 до 0.98, не потребує. `env_outside_config` змінилася з 0.02 на чистому файлі до 0.98 на зламаній копії; `swallowed_exception` з 0.05 до 0.98; `query_in_loop` з 0.09 до 0.95.

Єдиним пропуском був продубльований блок вимірювання часу та логування всередині раннього return. Навіть "хибні тривоги" були повчальними: дві спричинило формулювання моїх власних питань (згодом виправлене), а третя, `broad_catch` на файлі, який справді перехоплює `Exception`, насправді була правильною.

## Чи мовчить вона на нормальному коді?

Виявити закладені баги це лише половина роботи. Лінтер, який здіймає фальшиву тривогу на здоровому коді, вимикають протягом тижня. Тож я запустив питання на 50 чистих файлах, вибраних з усіх шарів: actions, pipelines, services, controllers, queries, observers, jobs, commands, models та інших.

Вісім перевірок жодного разу не спрацювали на чистому коді, водночас ловлячи близько 95% закладених проблем: `needless_indirection`, `functional_overcomplication`, `query_in_loop`, `dispatch_before_commit`, `external_call_in_transaction`, `swallowed_exception`, `env_outside_config` і `missing_types`. Їх можна використовувати як CI gates вже зараз.

Перевірки на дублювання спрацювали на 24–30% файлів. Але кожен випадок, який я перевірив, був реальним, наприклад три майже однакові блоки логування в одному observer. Тож це питання серйозності, а не помилка виявлення.

І найкорисніша знахідка: **кожна підтверджена хибна тривога мала одну й ту саму причину.** Позначені файли не містили проблеми; її містили їхні *контекстні файли*. Я надсилаю залежності разом із кожним файлом, щоб Jev розуміла типи, з якими працює файл, і Jev іноді відповідала про цей контекст замість самого файлу. Рішення: надсилати залежності лише як сигнатури (назви класів і сигнатури публічних методів, без тіл), щоб просто не було чужого коду, на який можна поскаржитися.

## Уся кодова база: 2 437 файлів, 80 секунд, 56 центів

Нарешті я запустив її на всій кодовій базі CRM: `app/`, `src/`, `routes/` і `database/`, у 8 паралельних процесах.

| | |
| --- | --- |
| Файлів | 2 437 |
| Час | ~80 секунд (~0.3 с на виклик) |
| Токенів | 13.4M |
| Вартість | **≈ $0.56** |
| Знахідок | 2 290 у 956 файлах |

Вартість підпорядковується простому патерну: близько 3 390 токенів на 30 питань плюс приблизно 0.28 токена на байт коду. Кумедно, але питання коштують більше, ніж сам код. Із контекстом лише із сигнатур те саме сканування коштувало б близько $0.43. Загалом усі експерименти, які я провів у межах цього proof of concept, близько 15M токенів, обійшлися мені менш ніж у долар.

Файли з найбільшою кількістю знахідок були саме там, де й очікуєш проблем: великі сервіси інтеграцій, синхронізації та оркестрації. Я вибірково перевірив найпроблемніший, `OutreachSyncService` на 646 рядків. Jev позначила сервіс, створений через `new` замість ін'єкції (0.94), і запит до бази даних усередині `foreach`, класичний N+1 (0.89). Обидві знахідки були правильними.

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

## Яким міг би бути пакет

Якщо я перетворю цей snippet на справжній пакет, кожен урок прямо перетворюється на функцію:

- **Фіксований набір питань**: 21 перевірка проблем і 9 фактів про відповідальності, кожна з серйозністю за замовчуванням.
- **Власні питання в конфігу**, щоб команда могла написати свій playbook реченнями: *"Чи вибираються дані поза Query-класом?"*, *"Чи є бізнес-логіка в контролері?"*
- **Видалення атрибутів** перед надсиланням, щоб метадані не сприймалися як складність.
- **Контекст лише із сигнатур**, щоб прибрати єдине джерело хибних тривог.
- **Кеш за fingerprint** (вміст файлу + сигнатури залежностей + версія набору питань + версія моделі), щоб повторно перевірялося лише те, що змінилося.
- **`code:scan --since=main`**, який перевіряє лише файли, змінені в гілці, для CI.

Додати правило команди можна одним записом у конфігу:

```php
'custom_checks' => [
    'data_outside_query_class' => [
        'question' => 'Is data fetched from the database outside a Query class?',
        'severity' => 'warning',
    ],
],
```

Ось і вся суть: **правила кодування вашої команди, написані звичайними реченнями, які виконуються за ціною лінтера.**

## Обмеження, про які варто сказати чесно

Jev каже, *чи* існує проблема, але ніколи *де* і *чому*. У файлі на 600 рядків вам усе одно доведеться шукати її самостійно. Це головна слабкість, і рішення ідеально вписується в патерн System One / System Two: Jev сортує всю кодову базу менш ніж за долар, і лише кілька позначених файлів ідуть до дорогої LLM за номерами рядків і поясненнями.

Є й інші обмеження. Jev знаходить лише те, про що ви питаєте. Це модель у ранньому доступі від одного вендора, і відповіді можуть змінюватися між версіями, тож пакет мав би фіксувати версію моделі й включати її у fingerprint кешу. Ваш код покидає вашу машину, що деякі команди не можуть собі дозволити. І все це тестувалося на одній кодовій базі, нашій CRM, з одним стилем коду, тож інші проєкти можуть поводитися інакше.

## Висновок

Найбільший урок для мене виходить за межі якості коду. Модель System One поганий суддя, але чудовий свідок. Попросіть у неї вердикт, і отримаєте розмиту оцінку, де все рухається разом. Попросіть факти, по одному простому питанню за раз, і отримаєте чіткий, стабільний і майже безкоштовний сигнал, який ваші власні правила перетворять на рішення.

Саме так Канеман описує наш власний розум: System One помічає, System Two вирішує. У моєму pipeline Jev помічає, мої правила та статичний аналіз вирішують, а LLM втручається лише там, де потрібне справжнє мислення. Нікому більше не потрібно читати кожен файл. Потрібно лише ставити правильні питання.
