
Теорія швидко черствіє, якщо звіряти її лише з власними статтями. Цього тижня я взяв три відкриті репозиторії — від Роберта «Дядька Боба» Мартіна, лабораторії HKUDS та інженерів DeepSeek — і розібрав їхню документацію та код крізь лінзу фреймворку TRACE і контрактів виконання RAC. Кожен із трьох авторів намацав важливий вузол агентної інженерії: вхідні повноваження, оцінювання стратегії або перевірку коду на виході. І кожен показав, де саме закінчується достатність окремого вузла.
Чому я поліз у чужий код
Коли півроку тому я викладав препринт TRACE, а згодом — статтю про контракти гарантування під час виконання (RAC), головна теза звучала жорстко: високий сумарний бал не дає агенту права на дію. Якщо обов’язкова перевірка каже «ні» або повертає $\bot$ (UNDETERMINED — перевірка не змогла дати достатнього результату), висока оцінка мовної моделі не компенсує прогалину.
Довкола цієї тези побудовано чотири шари TRACE:
- L1 — детерміноване ядро (парсери, компілятори, фізичні межі, хуки середовища);
- L2a / L2b — спеціалізовані ML-моделі та ізольовані LLM-валідатори;
- L3 — станова оркестрація, планування і маршрутизація;
- L4 — людина-оператор із вимірюваним навантаженням і каліброваним наглядом.
Найцікавіша перевірка такої декомпозиції настає тоді, коли інші інженерні команди будують власні системи для суміжних задач. Станом на початок листопада значну увагу спільноти зібрали три відкриті репозиторії (сумарно понад 36 тисяч зірочок на GitHub):
unclebob/ub-mode(~7,3 тис. ★) — агентний скіл і набір CLI-утиліт від Роберта Мартіна.HKUDS/AgentPilot(~8 тис. ★) — ітеративний контур покращення програм через зовнішній стан політики без оновлення ваг моделі.deepseek-ai/dsh-superagent-prototype(~21 тис. ★) — дослідницький прототип фонового координатора агентів від команди DeepSeek Harness.
Я провів змістову звірку їхньої документації та ключових модулів коду. Нижче — які конкретні механізми там працюють, де проходять межі їхнього застосування у високоризиковому контурі і що з цього розбору взято в екосистему TRACE (із чітким поділом на те, що вже реалізовано в нашому рантайм-гейті tracegate, що специфіковано для впровадження, і що запропоновано в дослідницькі плани).
1. Дядько Боб вимикає «рій»: unclebob/ub-mode
Ще навесні 2026 року Роберт Мартін експериментував із swarm-forge — важкою багатоагентною оркестрацією для Claude Code. До осені він переглянув потребу в жорсткому керуванні роєм для більшості задач. Натомість з’явився компактний репозиторій ub-mode: інструкція SKILL.md і три утиліти командного рядка на Clojure (crapper, dryer, mutator).
Логіка Мартіна прозора: десяток агентів, які сперечаються між собою у чаті, витрачають токени і розмивають відповідальність, тоді як один агент у коридорі швидких детермінованих перевірок працює чистіше й дешевше. У термінах TRACE це рух у бік економності моделі (Model Parsimony): там, де справляється детермінований аналізатор шару L1, будувати багатоагентний рій на шарі L3 — зайві накладні витрати.
Подивімося на три утиліти Мартіна:
crapperрахує індекс CRAP (Change Risk Anti-Patterns) на кожну функцію, поєднуючи її цикломатичну складність $C(m)$ із часткою покриття тестами $\text{cov}(m) \in [0, 1]$: $$\text{CRAP}(m) = C(m)^2 \cdot (1 - \text{cov}(m))^3 + C(m)$$ Умова вub-mode— $\text{CRAP}(m) < 10$. Якщо функція має складність $C = 8$ і нульове покриття, її CRAP дорівнює $72$. За покриття $70,%$ індекс становить приблизно $9{,}73$, тож функція проходить поріг. Якщо ж складність дорівнює $10$, навіть стовідсоткове покриття дає CRAP = 10; самими тестами пройти суворий поріг уже неможливо — функцію спершу треба спростити.dryerшукає структурне дублювання коду і вимагає усунення дублікатів зі схожістю $\ge 0{,}8$.mutatorзапускає мутаційне тестування й вимагає вбити всіх живих мутантів.
Де проходять межі такого підходу?
Перша межа — розділення повноважень. Сам ub-mode оформлено як інструкцію в системному промпті (SKILL.md). Агент сам вирішує, коли викликати утиліти, сам інтерпретує їхній вивід і сам записує собі в Action Log, що перевірки пройдено. У термінах RAC це порушення Інваріанта I1 (керована політика не може сама собі виписувати дозвіл на дію) та вразливість самозвітності (C8). Якщо агент пропустить виклик або зріже кут при переповненні контексту, усередині самого скіла немає зовнішнього виконавця, який примусово заблокує дію.
Другу межу влучно сформулював Ґрейді Буч у публічній дискусії з Мартіном: можна мати стовідсоткове покриття тестами, $\text{CRAP}$ нижче порога і нуль живих мутантів, але код при цьому робитиме не те, що потрібно предметній області.
І тут важливо прямо зафіксувати принципове обмеження не лише ub-mode, а й нашого власного підходу RAC: тризначна логіка ${1, 0, \bot}$ не розпізнає автоматично вимогу, якої немає в контракті. Значення $\bot$ (UNDETERMINED) спрацьовує тоді, коли визначена в контракті перевірка не змогла виконатися або дати достатній результат (наприклад, відсутній звіт покриття, не парситься AST або вхідні параметри вийшли за межі області дії інваріанта) — у такому разі гейт зупиняє автоматичний дозвіл і передає рішення людині. Проте якщо предметну вимогу взагалі не сформулювали в специфікації чи інваріантах, вона залишиться невидимою і для crapper, і для автоматичного гейта RAC. Тризначна логіка захищає від ілюзії успіху при збої чи неповноті заданого вимірювання, але проблему повноти специфікації все одно розв’язує інженер на шарі L4.
Статус у TRACE та tracegate:
- Реалізовано раніше: примусовий запуск валідаторів поза промптом агента, поріг покриття (
INV-COVERAGEуtracegate/envelope/invariants/coverage.py) і мутаційна перевірка чутливості тестів на змінених символах (discriminationуtracegate/validation/mutation.py). - Специфіковано за підсумками розбору: підготовлено технічну специфікацію інваріанта CRAP із налаштовуваною межею для інтеграції у зовнішній гейт
tracegate(деталі — у внутрішньому технічному мапінгу TRACE): без нових залежностей, поверх наявного парсингу змінених AST-символів і звіту.tracegate/coverage.json. Якщо звіт покриття для зміненого файлу відсутній, перевірка має повертатиUNDETERMINED.
2. Що насправді вчиться у HKUDS/AgentPilot
Другий репозиторій — HKUDS/AgentPilot (разом із вбудованим протоколом оцінювання RSI Arena). Автори вийшли з гучним заголовком у README.md: «9B Strategy Model Beats 284B» на задачниках AIME та Terminal-Bench 2.1.
Статичний огляд документації (arena/docs/evaluation.md) та коду показує важливе розрізнення між заголовком і фактичною архітектурою.
По-перше, ваги мовної моделі в AgentPilot заморожені: там немає ні градієнтного кроку, ні LoRA, ні RL-оптимізатора. Те, що автори називають навчанням, відбувається на шарі L3 — між батчами оновлюється зовнішній стан політики: або детермінована статистика бандита KL-UCB (policy/ucb/parent.py), або текстова пам’ять уроків (textual policy memory), яку поповнює, переглядає й списує мовна модель.
По-друге, між описом експериментів і кодом формального запуску є прогалина відтворюваності. У arena/docs/evaluation.md заявлено пропозер Qwen 3.5 9B та воркер DeepSeek V4 Flash, тоді як у файлах research_setup.py і formal.py жорстко прописано пропозер qwen/qwen3.8-27b (reasoning = xhigh) та воркер z-ai/glm-5.3-flash. З репозиторію неможливо встановити, якою саме конфігурацією отримано опубліковані числа. Заявлені прирости (+8/36 на AIME, +12/49 на Terminal-Bench 2.1) походять з одного запуску й одного фінального заміру; по-задачних парних результатів і повторів між запусками не наведено. За спільного тестового спліту висновок парного тесту залежить від того, скільки задач фінальний варіант виграв і програв: приріст +8 сумісний і з рахунком 8/0 ($p=0{,}008$), і з рахунком 12/4 ($p=0{,}077$) за двостороннім точним знаковим тестом. Тож стійкість приросту не встановлена. Подвоєний бюджет дій (20 проти 10), нижча стартова точка на TB2.1 (22/49 проти 27/49) і відсутність абляції між KL-UCB та розміром пропозера також ускладнюють атрибуцію результату.
Водночас, якщо відкласти заголовки README і подивитися в модулі пошукового стану, допуску й винагороди, всередині виявляється дуже охайно спроєктований шар прийняття рішень L3:
- Захист стану за моментом відсічки (
cutoff_safe_facts). КласSearchStateBuilder(search/state.py) збирає стан лише з фактів, доступних до моменту рішення; оновлення відбуваються на бар’єрах між батчами, а кожен вибір записуєDecisionTraceіз детермінованим розв’язанням нічиїх (seeded_argmax). - Парне порівняння зі стиснутою нижньою межею. У
evaluation/paired.pyтаevaluation/admission.pyкожен нащадок порівнюється зі своїм предком на тих самих валідаційних задачах за оцінкою: $$L = \hat{\Delta},\frac{n_{\mathrm{eff}}}{n_{\mathrm{eff}} + \kappa} - k \cdot \text{SE}(\hat{\Delta}), \qquad \kappa = 2,; k = 1$$ - Розділення допуску в архів і винагороди бандита. Модуль
evaluation/admission.pyвикористовує м’якше правило non-inferiority ($L \ge -\text{margin}$), щоб допустити нейтрального кандидата в пул для подальшого пошуку, аevaluation/reward.pyвимагає суворішого superiority ($L > \text{margin}$), щоб зарахувати крок як успіх уKL-UCB. Крім того, передача закритого тестового спліту (EvidenceTier.SEALED_C) у класифікатор винагороди програмно кидає виняток. - Skip semantics для збоїв апаратури. Функція
classify_effectivenessуevaluation/reward.pyвідділяє невдалу ідею від збою воркера, таймауту чи порушення меж: такий прогін переводиться у пропуск (skip) і не збільшує лічильник спостережень Бернуллі.
Зіставмо четвертий пункт із тризначною логікою гейтів ${1, 0, \bot}$ у RAC. Це корисна структурна аналогія, але не тотожність: обидва механізми відрізняють негативний результат від відсутності надійного результату, проте мають різні наслідки. У AgentPilot skip-семантика керує оновленням оцінки в пошуку: збій інфраструктури не штрафує стратегію нулем (хоча самі пропуски теж можуть спотворювати оцінювання, якщо їхня частота залежить від стратегії — наприклад, коли важчий алгоритм частіше спричиняє таймаути). У RAC значення $\bot$ (UNDETERMINED) керує авторизацією: відсутність надійного результату перевірки не оновлює середній бал, а блокує дозвіл на дію.
Щодо текстової пам’яті політики (textual policy memory): у AgentPilot мовна модель додає, переглядає й списує уроки, які керують вибором напрямів модифікації (D2) та дій (D3) у наступних ітераціях. Кожен урок має посилання на дію-джерело (source_action_id), умови застосовності й потребує свіжого підтвердження. Сама собою зміна такої пошукової евристики в офлайновому стенді не означає зміни повноважень або правил безпеки. Проблема для високоризикового контуру виникає тоді, коли самомодифікація без участі людини (шар L4 в AgentPilot відсутній) і без журналу причин кожної ревізії (UTC) переноситься на правила, що визначають межі дозволеної дії або умови чинного схвалення.
Ще одне відкрите питання в AgentPilot стосується ізоляції оцінювача: запис воркера обмежено дозволеними коренями (runtime/research_worker.py) і режимом codex exec --sandbox workspace-write, але читання файлової системи на рівні ОС цим режимом не блокується — тож якщо еталонні тести чи верифікатори лежать на тому самому хості, захист від витоку на читання потребує окремої перевірки.
Статус у TRACE та tracegate:
- Запропоновано в план лінії
TRACE × Prime Agent: парне правило промоції кандидатів (non-inferiority $L \ge -\text{margin}$ для допуску в пул, superiority $L > \text{margin}$ для закріплення), бар’єрне формування стануcutoff_safe_factsта тип-рівневе блокуванняSEALED_C(зафіксовано у внутрішньому технічному мапінгу TRACE). - Додано до чек-листа аудиту L1: явне розрізнення write isolation та read isolation для середовищ, де виконується агент-воркер.
3. Коли дозвіл прив’язано до версії правил: dsh-superagent-prototype від DeepSeek
Третій репозиторій — deepseek-ai/dsh-superagent-prototype на TypeScript, випущений командою DeepSeek Harness як дослідницький прототип до їхнього есе «Exploring Super-agent Design: Towards a More Autonomous Agent System». Його автори сформулювали головний операційний принцип у docs/000-philosophy.md:
«Take as little human attention as possible, and give as much value as possible.»
Це безпосередньо перетинається з проблемою дефіциту уваги оператора на шарі L4 у TRACE. Як інженери DeepSeek реалізують економію уваги в коді?
По-перше, вхідні події з GitHub та Feishu проходять через детерміновану перевірку допуску (src/policy.ts) до того, як запускається модель-маршрутизатор: нерелевантні або неавторизовані події відсіюються правилами без виклику LLM. По-друге, для проактивних дій передбачено шкалу режимів off → observe → auto (docs/002-authorization.md, функція admitsInferred у src/policy.ts): у дефолтному режимі observe система оцінює тригер і записує в SQLite рішення «прийняв би» (would accept), але не запускає воркерів і не редагує код, поки команда не перевірить поведінку правила.
Найцікавіший для нас механізм лежить у моделі авторизації (docs/001-domain.md, docs/002-authorization.md, модулі src/policy.ts та src/core/engine.ts). Коли вхідна подія проходить допуск (gate), транзакційний рушій src/core/engine.ts створює задачу (Ticket) разом із незмінним об’єктом Mandate, який фіксує чотири атрибути:
- хто ініціював дію (
originating identity); - дозволений обсяг (
scope); - силу повноважень (
authorization strength); - активну версію політики (
policy version).
Коли відкладена або призупинена задача має відновити роботу, функція revalidate у src/policy.ts повторно звіряє її Mandate із чинною конфігурацією правил (settingsPolicy). Якщо за цей час команда змінила або послабила правило — старий мандат автоматично втрачає чинність, і задача не продовжується без нової авторизації. Сам агент змінити свій Mandate через текст у промпті чи коментарі не може: межу тримає код хост-рушія.
Ця конструкція дуже близька до поля rule_version у векторі доказів $e_t$ (рівняння 3 у нашій статті про RAC) і до ідеї версіонованого дозволу, яку ми зараз розгортаємо у скелеті Policy Letter «Approval Must Expire» для журналу ACM AI Letters (AILET). Інженери DeepSeek прийшли до прив’язки мандата до policy_version та автоматичного відкликання при зміні правил зі свого боку — розв’язуючи задачу координації фонових агентів над репозиторієм.
Які межі має dsh-superagent-prototype при переносі у високоризиковий контур?
По-перше, прототип декларує економію людської уваги як філософію, але не вводить для неї кількісних метрик. У коді немає розрахунку RBI (Review Burden Index — метрики шару L4 у TRACE, що фіксує частоту передач людині за одиницю часу разом із середнім часом розгляду випадку й зіставляє сумарне навантаження рецензента з пропускною здатністю нагляду), немає обліку частки перекриттів рішення людиною (OvR), співвідношення сигнал/шум панелі (SNR) чи похибки калібрування роутера (CE). Перехід із тіньового режиму observe в автоматичний auto виконується вручну, без статистичного порога над накопиченими рішеннями. По-друге, маючи чіткий вхідний контроль (Mandate), прототип не ставить вихідного верифікаційного гейта на сам код, який повертає воркер, а сесії воркерів виконують команди з правами користувача хост-ОС (docs/003-execution.md).
Статус у TRACE та tracegate:
- Використано як порівняльний приклад версійної прив’язки мандата у скелеті Policy Letter «Approval Must Expire» для ACM AI Letters та у внутрішньому мапінгу лінії RAC.
Зведена картина: повноваження на вході → оцінювання стратегії → перевірка результату
Якщо поставити три розглянуті репозиторії в послідовність виконання задачі, добре видно, яку саме ділянку маршруту закриває кожен із них і де виникають прогалини на стиках.
| Інструмент (осінь 2026) | Сильний механізм у коді | Межі застосування у високоризиковому контурі | Що і в якому статусі взято в TRACE / tracegate |
|---|---|---|---|
deepseek-ai/dsh-superagent-prototype (DeepSeek Harness) | Вхід: детермінований допуск (src/policy.ts), шкала off → observe → auto, незмінний Mandate із прив’язкою до policy_version та авто-відкликанням (revalidate, src/core/engine.ts) | Немає вимірювання навантаження й якості нагляду L4 (RBI, OvR, SNR, CE); ручний перехід observe → auto; відсутній вихідний верифікатор коду воркера та ОС-пісочниця | Використання в дослідженні: приклад для аналізу версійної прив’язки дозволу у скелеті Policy Letter Approval Must Expire для ACM AI Letters |
HKUDS/AgentPilot (HKUDS) | Середина циклу (L3): стан cutoff_safe_facts (search/state.py), парне порівняння (paired.py), розведені пороги NI (admission.py) і superiority (reward.py), skip semantics для збоїв апаратури | Стійкість опублікованих приростів не встановлена (1 seed, без по-задачних таблиць, 2× бюджет, розбіжність 9B у док vs 27B у research_setup.py); немає шару L4; не обмежено читання хоста у workspace-write | Запропоновано в план: парний допуск NI/superiority, бар’єр SEALED_C і cutoff_safe_facts для лінії TRACE × Prime Agent; перевірка read isolation у чек-листі L1 |
unclebob/ub-mode (Р. Мартін) | Вихід (L1): детерміновані CLI-утиліти якості коду (crapper із межею CRAP 10, dryer $\ge 0{,}8$, mutator) замість мультиагентного рою | Утиліти викликає й логує в Action Log сам агент за інструкцією в промпті SKILL.md (порушення I1 / C8); не бачить вимог, відсутніх у специфікації | Специфіковано для tracegate: підготовлено ТЗ інваріанта CRAP із налаштовуваною межею на змінених AST-символах поверх уже реалізованих у tracegate INV-COVERAGE та мутаційного гейта discrimination |
Подивіться на цю тріаду вздовж маршруту дії:
- Повноваження на вході (
dsh-superagent-prototype): перевіряє, хто й за якою версією правил (policy_version) дозволив запуск задачі, і відкликає мандат, якщо правила змінилися. - Оцінювання стратегії в середині циклу (
AgentPilot): підтримує чистий за часом відсічки стан пошуку (L3), порівнює зміни попарно на спільних задачах і не змішує падіння інфраструктури з оцінкою самої ідеї. - Перевірка результату на виході (
ub-mode): ставить жорсткі детерміновані пороги складності, дублювання й мутаційної стійкості коду (L1) замість розмов між агентами.
Водночас таке зіставлення показує, що структурна подібність окремих вузлів сама собою не створює гарантій безпеки. Навіть якщо з’єднати всі три механізми й додати append-only журнал доказів із ланцюгом хешів, варто пам’ятати дві речі:
- Журнал — не примус. Ланцюг хешів дає змогу перевірити внутрішню узгодженість записів. Щоб виявити повне переписування журналу з перерахунком хешів, потрібне незалежно збережене контрольне значення або інший захист сховища. Сам журнал не блокує дію: це робить зовнішній рантайм-гейт і хук середовища перед дією.
- Формальна перевірка — не повнота специфікації. Тризначна логіка ${1, 0, \bot}$ чесно зупиняє систему, коли визначений у контракті перевіряльник не дав надійної відповіді, але вона не здатна вгадати предметну вимогу, яку інженер забув внести в контракт. Саме тому у високоризикових системах неможливо прибрати шар L4 — людину з вимірюваним навантаженням (
RBI), правом перекриття (OvR) і відповідальністю за зміст самих правил.
Усі три детальні розбори з посиланнями на модулі та документацію додано до відкритої бібліотеки споріднених підходів TRACE. Робочі мапінги доступні в репозиторії проєкту.
Посилання та матеріали
- TRACE Framework (оглядова стаття): S. Zabolotnii, TRACE: A Metrologically-Grounded Engineering Framework for Trustworthy Agentic AI Systems in Operationally Critical Domains, arXiv:2605.03838.
- Runtime Assurance Contracts (RAC): S. Zabolotnii, Trust Is Not a Score: Runtime Assurance Contracts for High-Risk AI Agents, arXiv:2609.39717 · код і корпус механізмів: GitHub · Zenodo DOI: 10.5281/zenodo.23410711.
- Бібліотека споріднених інженерних підходів TRACE (
/library): traces.solutions/library. - Розібрані репозиторії:
- Robert C. Martin (
unclebob),ub-mode - HKUDS,
AgentPilot - DeepSeek AI,
dsh-superagent-prototype
- Robert C. Martin (