Чому журнали агента не задовольнять вимогам статті 12: записи рішень, причинно-наслідкові зв’язки та походження
Журнали діяльності агентів не відповідатимуть вимогам статті 12 Закону ЄС про ШІ. Реєструйте рішення агентів ШІ як стабільні об’єкти з причинно-наслідковими зв’язками, послідовністю джерел у форматі хешів та фіксованими правилами.
У серпні 2026 року набула повної сили норма, наслідки якої ще не відчули більшість інженерних команд. Стаття 12 Закону ЄС про ШІ передбачає, що системи ШІ високого ризику повинні технічно дозволяти автоматичне записування подій протягом усього їхнього життєвого циклу з можливістю відстеження, пропорційною меті системи. Стаття 26 покладає на того, хто впроваджує систему, відповідний обов’язок: зберігати ці журнали принаймні шість місяців, або довше, якщо це вимагають інші закони.
Інженер, який читає цей текст, помічає дивну нерівновагу. Мета сформульована дуже чітко, тоді як необхідний формат ледве згадується. Метою є можливість реконструювати пізніше окреме рішення. Продукт типу APM цього не забезпечує, оскільки він створений для інших цілей. Векторний сховище також цього не забезпечує.
Час обрано невдалий, адже представники компанії щойно припинили відповідати на запитання та почали діяти. Вони схвалюють витрати, змінюють розміри інфраструктури, обробляють страхові заявки, відхиляють кандидатів та схвалюють їх відпуск. Кожне з цих рішень — це те, що хтось зрештою може попросити компанію пояснити, і в більшості сучасних організацій правдивою відповіддю буде те, що вони не можуть цього зробити.
Справа про незначну суму, яка попередила про проблему
До появи регуляції та до того, як представники змогли почати діяти, трибунал у Британській Колумбії перевірив цю саму слабкість у невеликих масштабах. Це залишається найяснішим наявним прикладом.
Бабуся Джейка Моффатта померла у листопаді 2022 року. Того ж дня він відвідав веб-сайт Air Canada, щоб забронювати рейс до Торонто, і, не знаючи, як працюють тарифи для втрати близької людини, звернувся за допомогою до чат-бота авіакомпанії. Бот сказав, що він може негайно придбати квиток за повною ціною та звернутися з проханням про знижку за тарифом для втрати близької людини з урахуванням минулого, протягом 90 днів. Перш ніж покладатися на це, Моффатт зробив розумний крок — зробив скріншот відповіді. Потім він здійснив бронювання, полетів, відвідав похорон та подав свою заявку.
Air Canada відхилила його заявку. Такої політики не існувало, і бот її вигадав.
Наступна частина є навчальною. У Трибуналі з цивільних рішень авіакомпанія стверджувала, що не може нести відповідальність за слова свого чат-бота, описуючи його як окрему entитет, відповідальний за власні дії. Член трибуналу Крістофер Ріверс назвав це твердження дивним та зазначив, що авіакомпанія ніколи не пояснювала, чому хтось має його приймати. Чат-бот є частиною веб-сайту, і компанія несе відповідальність за свій веб-сайт. Air Canada заплатила 812,02 канадських доларів.
Ця сума є незначною. Важливою є цифра нуль — кількість записів, які Air Canada могла б надати, щоб пояснити, чому її власна система сказала те, що сказала. Єдиним тривалим доказом усього слухання була скріншот клієнта.
Ця сама проблема з того часу посилилася. У квітні 2025 року бот підтримки в Cursor створив правило, яке обмежувало підписки одним пристроєм. Клієнти почали скасовувати підписки, і компанія дізналася про це лише тому, що один із співзасновників побачив відповідну тему на Reddit. Схема залишається ідентичною, масштаби проблеми зростають, а темпи — прискорюються, причому не було потреби у жодному трибуналі.
Тепер уявіть собі, що ця сама слабкість у доказах опиняється перед регулятором у поєднанні з агентом, який керує переказами грошей.
Виправлення помилок та відповідальність — це різні завдання
Більшість систем ніколи не роблять тут значущого розрізнення.
Оперативність спостережень зосереджена на виконанні. Вона фіксує те, що робив процес під час одного запуску: інтервали часу, виклики інструментів, кількість токенів, спроби повторного запуску та затримки. Ці дані збираються у вибірковому форматі, закінчують свою дію після певного періоду зберігання та стосуються лише однієї заявки. Це саме те, що потрібно для виявлення помилки у вівторок.
Відповідальність орієнтована на конкретну сферу діяльності. Вона фіксує, до яких висновків дійшла організація, на яких доказах, згідно з якою політикою, та що сталося після цього. Вона має залишатися стабільною під час міграцій фреймворків, виходу з ужитку моделей, перебудови індексів, реорганізації та відходу двох колег.
В інших частинах бізнесу це є звичайною практикою. Зміни в продакшені ніколи не відтворюються на основі журналів дій додатку, оскільки запис про зміну містить інформацію про автора, заявку та схвалення. Фінансовий стан також ніколи не відтворюється на основі HTTP-записів, адже існують записи в журналі. Замовлення, оплати, схвалення та розгортання є стабільними об’єктами, кожен з яких має життєвий цикл, власника та правила зберігання.
Рішення агентів є єдиним видом подій із значними наслідками, які досі залишаються у неструктурованому вигляді, без жодних механізмів контролю.
Версія о 3 годині ранку
Такий підхід до оцінки відповідності робить невдачу здається чимось екзотичним, хоча насправді це цілком звичайно, тому конкретний приклад допомагає.
Через двадцять хвилин після розгортання система почала повертати помилки типу 5xx під час процедури перевірки. Фахівець з аналізу помилок порівняв їхню кількість із періодом розгортання, не побачив жодних попереджень щодо інфраструктури та класифікував цей інцидент як регресію після розгортання. Фахівець з усунення проблем відкотив версію програми назад, і кількість помилок повернулася до норми. Фахівець з розгортання знову запустив процедуру розгортання. Хтось опублікував сигнал про успішне вирішення проблеми у каналі обговорень, і команда закінчила роботу. Усе це тривало одинадцять хвилин, і подальшого аналізу інциденту не відбулося, оскільки проблема, здавалося, вирішилася сама собою.
Але причиною проблеми було не розгортання. Постачальник платежних послуг, який працював на наступному етапі, поступово погіршував свою роботу, але випадково відновив її саме у момент відкату версії. Цей зв’язок був випадковістю, і фахівці створили надійну версію пояснення цього явища.
Правда стає відомою у жовтні, коли повторюється та сама ситуація, і хтось запитує, чи мала та подія у квітні ту саму причину. Час це перевірити.
До цього часу сліди вже застаріли та були видалені у червні. Шаблон запиту пройшов дві переробки. Коли змінився модель ембеддингу, індекс пошуку було перебудовано, тож уривки з посібника, які агент читав тоді, — це не ті, які він би отримав сьогодні. Версія моделі, зазначена у заголовку запиту, вже не використовується. Єдине, що залишилося, — це чат-розмова, яка закінчується емодзі у вигляді піднятої долоні.
На це запитання неможливо відповісти. Ніхто не був неуважним. Ніщо у системі не було розроблено для зберігання відповіді.
Чому краща пам’ять це не виправить
Зазвичай інстинкт підказує скористатися шаром пам’яті, який зазвичай є векторним сховищем. Але це вирішує зовсім іншу проблему.
Ембеддинговий пошук добре вирішує одне питання: що виглядає так само? Він не може вказати, у що вірила система о 14:02 певного дня, який ранніший висновок призвів до цього, де походить певний факт, чи справді була виконана дія, яку мала обмежити політика.
Існує ще один більш тонкий недолік. Процес пошуку не залишається відтворюваним з часом. Якщо заново використати новішу модель для обробки корпусу даних, однаковий запит поверне інший набір результатів, тож те, що раніше вважалося записом, тихо змінилося. Журнал аудиту, який можна безслідно переписати шляхом оновлення залежностей, вже не є справжнім журналом аудиту.
Кожен шар відповідає на своє власне питання:
- Векторний пошук: які елементи виглядають так само, як цей?
- Граф знань: з чим він пов’язаний?
- Походження: де він з’явився та чи залишається він дійсним?
Для справжнього розслідування типу „чому це сталося“ потрібні майже всі ці елементи. Лише один з них є сховищем векторів.
Перетворення рішення на об’єкт
Саме тут варто звернути увагу на Semantica. Це шар на Python під ліцензією MIT, який працює під фреймворком агентів та розглядає контекст як граф, а не як сукупність текстових запитів. Створення графа, міркування та визначення походження є детермінованими, без участі LLM, що має значення, коли результат має слугувати доказом.
Основна ідея проста. Рішення стає чимось, що навмисно записується, а не чимось, що просто додається до журналу подій.
from semantica.context import ContextGraph
ctx = ContextGraph(advanced_analytics=True)
decision_id = ctx.record_decision(
category="incident_triage",
scenario="Checkout 5xx elevated 20 minutes after release 2026.31",
reasoning="Error onset correlates with rollout window; no infra alerts; "
"no dependency alarms visible at time of assessment",
outcome="classified_as_release_regression",
confidence=0.83,
)
Механізм простий. Змінюється лише те, що автор змушений детально описувати. Замість вільного тексту у рядку журналу необхідно вказати категорію, сценарій, причини, результат та показник впевненості. Усе це можна буде знайти через вісімнадцять місяців, на відміну від звичайного тексту.
Розгляньмо рядок reasoning у жовтневому сценарії. У ньому зазначено, що під час оцінки не було помічено жодних сповіщень про залежності. Ця одна фраза змінює перспективу розповіді з агента, який припустився помилки, на агента, який зробив об’єктивний висновок на основі часткових даних, що вказує на прогалину у моніторингу, яку потрібно усунути. Ці дві перспективи призводять до зовсім різних нарад.
Увага щодо цього поля. Це не місце для первинної послідовності міркувань моделі, яка є нестабільною, іноді вигаданою та неможливою до обґрунтування пункт за пунктом перед сторонньою особою. Запишіть обґрунтування, за яким організація готова стояти: оброблені докази, досягнута межа, застосована політика, особа, яка скасувала рішення. Це все одно краще підходить для експлуатації.
Одна запис — це рядок журналу, ланцюг — це інфраструктура
Реальні робочі процеси агентів розгалужуються, і шкода рідко локалізується в одному вузлі. Вона проявляється у всьому, що знаходиться нижче по ланцюжку та тихо прийняло хибний висновок.
Найвідомішим прикладом до появи ШІ є Knight Capital. Через помилку під час впровадження у 2012 році залишився у експлуатації застарілий варіант коду, і протягом приблизно 45 хвилин компанія зазнала збитків у розмірі близько 440 мільйонів доларів. Ніхто не сумнівався у тому, що робив програмний забезпечення, а кожен замовлення було задокументовано. Проте ніхто не міг вручну відстежувати наслідки так швидко, як вони поширювалися.
Semantica дозволяє вказувати зв’язки між рішеннями ще під час їх написання:
triage_id = ctx.record_decision(
category="incident_triage",
scenario="Checkout 5xx elevated after release 2026.31",
reasoning="Error onset correlates with rollout window; no infra alerts",
outcome="classified_as_release_regression",
confidence=0.83,
)
rollback_id = ctx.record_decision(
category="remediation",
scenario="Contain checkout 5xx",
reasoning="Regression attributed to release; rollback is lowest-risk action",
outcome="rolled_back_to_2026.30",
confidence=0.91,
)
unblock_id = ctx.record_decision(
category="release_gate",
scenario="Resume deploy queue after containment",
reasoning="Error rate normal for 30 minutes post-rollback",
outcome="deploy_queue_reopened",
confidence=0.86,
)
ctx.add_causal_relationship(triage_id, rollback_id, relationship_type="CAUSED")
ctx.add_causal_relationship(rollback_id, unblock_id, relationship_type="INFLUENCED")
why = ctx.trace_decision_chain(unblock_id)
blast_radius = ctx.analyze_decision_impact(triage_id)
Існує три типи взаємозв’язків: CAUSED, INFLUENCED та PRECEDENT_FOR. Словниковий запас невеликий, і це прийнятно. Майже вся корисна інформація походить від однієї операції.
Коли у жовтні з’ясувалося, що триаж був неправильним, питання змінюється. Запит про те, які записи стосуються повернень після оплати, повертає сорок тисяч рядків. Запит про те, які рішення ґрунтувалися на цьому висновку, повертає короткий, обмежений список: скасування змін, повторне відкриття черги, надіслані повідомлення клієнтам, а також звіт після аналізу, якого ніхто не написав. Це свідчить про масштаб впливу суб’єктивних рішень, і саме ця операція є необхідною, коли агенти припиняють лише пропонувати рішення та починають їх втілювати.
find_similar_decisions() працює у зворотному напрямку та повертає попередні приклади. Чи стикався цей система раніше з подібним запитом та що вона робила? Саме так виявляється агент, який щороку у третю вівторок тихо суперечить сам собі – справжня невдача, яку ніхто не стежить, оскільки для неї не існує показників.
Причинність – це не походження
Ці два поняття постійно плутають, хоча вони відповідають на різні запитання. Знання про те, що рішення C ґрунтувалося на рішенні A, мало користі без знання про те, на яких доказах ґрунтувалося рішення A.
Модуль походження в Semantica дотримується стандарту W3C PROV-O. Він застарілий, але правильний.
from semantica.provenance import ProvenanceManager
prov = ProvenanceManager(storage_path="./provenance.db")
prov.track_entity(
entity_id="release_2026_31",
source="ci/pipeline_runs/2026-31/manifest.json",
metadata={"stage": "canary", "extractor": "ManifestParser", "confidence": 0.99},
)
lineage = prov.get_lineage("release_2026_31")
Два підходи до дизайну тут варто скористатися навіть тими командами, які ніколи не встановлюють бібліотеку.
По-перше, записи про походження утворюють ланцюг хешів. Кожен запис містить порядковий номер та контрольну суму, які пов’язують його з попереднім, а функція verify_chain() дозволяє з’ясувати, чи була історія змінена або записи видалені. Саме це відрізняє таблицю, яку будь-хто може без проблем UPDATE, від тієї, яка використовується як доказ.
По-друге, факти анулюються, але не видаляються. Коли щось перестає бути правдивим, його замінюють разом із особою, яка це зробила, та причиною:
prov.invalidate(
"release_2026_31",
agent_id="human_sre_lead",
reason="Error attribution corrected; degradation traced to payments provider",
)
Змінна valid=false відображає поточний стан. Журнал фіксує, що стан колись відрізнявся, хто його змінив, коли та чому. Поверніться до слухань у Air Canada та запитайте, який з цих варіантів був потрібен авіакомпанії. Відповідь очевидна.
Виведення правил за межі запиту
Ще однією перевагою є те, що Semantica містить справжні механізми міркувань: forward chaining, Rete, Datalog та SPARQL. Логіка проста: якщо організація вже знає правило, немає причин просити мовну модель імпровізувати його англійською при кожному запиті.
from semantica.reasoning import ReteEngine, Rule, Fact, RuleType
engine = ReteEngine()
engine.build_network([
Rule(
rule_id="dual_control_prod",
name="Human approval required for high blast-radius prod changes",
conditions=[
{"field": "env", "operator": "==", "value": "production"},
{"field": "blast_radius", "operator": "in", "value": ["high", "critical"]},
],
conclusion="require_human_approval",
rule_type=RuleType.IMPLICATION,
)
])
engine.add_fact(Fact("chg_014", "change", [{"env": "production", "blast_radius": "high"}]))
matches = engine.match_patterns()
Модель все ще обробляє неструктурований вхідний даний та пропонує дію. Зміна стосується перевірки, яка схвалює чи блокує цю дію: це вже не просто абзац із надією у системному запиті, який може бути обійдений через дивно сформульований виняток. Оскільки rule_id може зберігатися у записі рішення, запит про те, яка політика була застосована, перетворюється на просте пошукове запитання, а не на дискусію між двома командами.
Увага: механізм зіставлення умов є навмисно простим. Перевірте його на реальному наборі правил перед тим, як він почне використовуватися між агентом та будь-якою регульованою дією. Демонстраційний двигун правил не є засобом контролю дотримання правил, а виявлення прогалин під час аудиту — це дорогий спосіб їх виявлення.
Прості стандарти живуть довше за фреймворки
PROV-O обробляє походження даних, представлення у форматі RDF, запити SPARQL, обмеження SHACL та онтології OWL. Жоден з цих аспектів не є захоплюючим, і саме в цьому суть.
Фреймворки агентів мають період життя близько вісімнадцяти місяців. Вимоги до аудиту — ні. Оглядач у 2030 році не буде цікавитися, яка бібліотека оркестрації була популярною на момент прийняття рішення, і ніхто не хоче постійного запису, застряглого у пропрієтарному форматі експорту стартапу, який згодом змінив напрямок.
Існує також сервер MCP, який запускається за допомогою python -m semantica.mcp_server. Його інструменти включають вилучення даних, запис рішень, пошук попередніх прикладів, аналіз причинно-наслідкових зв’язків та міркування. Завдяки цьому агент записує власні рішення через звичайний виклик інструменту, і не потрібно додавати додаткові механізми логування, які агент міг би обійти.
Справжня ціна
Витрати варто озвучити прямо.
Першою витратою є створення нового сервісу з можливістю зберігання стану, включаючи його резервні копії, міграції, схему та контроль доступу. Другою є зусилля з моделювання, адже ніхто інший не може вирішити, що вважати рішенням, яке варто задокументувати. Фіксація кожного кроку створює ще один журнал подій, причому дорожчий. Занадто мала кількість записів залишає прогалини в ланцюзі саме там, де має виникнути проблема.
Існує також культурна витрата, яку часто недооцінюють. Граф рішень дозволяє дуже легко побачити, що певний агент протягом чотирьох місяців неправильно виконує певну дію. Це і є метою, проте зустріч все одно буде некомфортною.
Проєкт також розвивається швидко. Зберігайте версію, яка була перевірена. Ті, хто потребує ще не оприлюдненої версії, повинні завантажувати її з джерела, прив’язаного до конкретного коміту. Сприймайте це як інфраструктуру, а не як зручний спосіб імпорту.
Почніть з одного робочого процесу
Записувати все у графічному вигляді — це помилка. Записуйте лише те, що потребує обґрунтування.
Виберіть один процес роботи, у якому неправильне рішення може коштувати реальних грошей чи довіри. Фіксуйте рішення лише у тих моментах, коли використовується повноваження, наприклад під час схвалення, відхилення, витрачання коштів, надсилання інформації до виробництва чи надання зобов’язань клієнту. Разом із кожним рішенням зберігайте докази, на які воно ґрунтувалося, та ідентифікатор правила, якщо йшлося про детерміністичну політику. Зберігайте дані в графі асинхронно, щоб записи ніколи не залишалися на шляху, на якому користувач очікує.
Через тридцять днів спробуйте відповісти на справжнє запитання „Чому це було зроблено?“ використовуючи лише граф. Негайно з’являться прогалини, і вони не будуть такими, як прогнозувалося. Це вправа навчає більше, ніж будь-який попередній проектування схеми.
Що потрібно пам’ятати
Два роки було витрачено на пошук пояснюваності, що переважно означало спроби заглянути всередину моделі. Ця мета є хибною, і ми не наближаємося до неї. Модель залишається ймовірнісною, і жодні хитромудрі методи запитів не роблять її внутрішні механізми прийнятними там, де це має значення.
Відповідальність — це досяжна альтернатива, і кожен її елемент знаходиться поза моделлю: рішення, його причинні фактори, докази, походження, застосована політика, наслідки та подальші корекції. Усе це — звичайні структуровані дані. Такі записи зберігаються з часів подвійного бухгалтерського обліку. Ця практика просто припинилася, коли особою, яка приймає рішення, стала мовна модель, ніби це змінило призначення запису.
Якщо прибрати юридичну термінологію, вимога статті 12 є помірною. Вона не вимагає більше журналів записів. Вона просить про запис, який зберігатиме своє значення протягом трьох років після того, як ця система буде виведена з експлуатації, індекс буде побудований двічі, а автор запиту вже піде далі.
Кращим тестом, ніж регуляторний, є повторний аналіз інциденту о 3 годині ранку. Ніхто з присутніх не був винен. Співробітники зробили логічні висновки на основі наявної інформації, і інцидент було закрито за одинадцять хвилин, проте пояснення зникло вже через чверть години. Якщо звичайний вівторок може знищити здатність пояснити рішення, аудитор не буде першим, хто це помітить. Команда на зустрічі через кілька місяців поступово усвідомить, що ніхто з присутніх не знає, що сталося.
Те, що справді коштувало компанії Air Canada, — це не 812 канадських доларів. Під час слухань вони не мали жодних пояснень щодо роботи власної системи та посилалися на те, що відповідальність за програмне забезпечення лежить на комусь іншому. Захист зазнав краху, хоча йшлося лише про один квиток та одного скорботного пасажира, який намагався зафіксувати розмову.
Сьогодні співробітники швидше схвалюють, витрачають, впроваджують та відхиляють рішення, ніж хтось встигає їх перевірити, і ніхто не робить скріншотів цього процесу. Спочатку потрібно створити запис, перш ніж хтось його запитає. Питання завжди постає у найгірший можливий момент, і до того часу відповідь або вже зберігається в базі даних, або назавжди втрачається.
Пов’язана література
- Практичні нотатки: 10 найпрактичніших навичок агентів у 2026 році (та в майбутніх версіях) — Детальний огляд Практичних нотаток: 10 найпрактичніших навичок агентів у 2026 році (та в майбутніх версіях): контракти, перевірки та слоти для коду для команд, які використовують цю модель.
- Агенти, які самовдосконалюються за допомогою навичок: повторне використання, відбір, виправлення та перевірка — Чотириетапний підхід до створення агентів, які покращують власні навички: зберігання функціонального коду, удосконалення описів, пропозиція перевірених виправлень та перевірка результату перед передачею.