Главная / Статьи

Почему журналы действий агента не соответствуют статье 12: записи решений, причинно-следственные связи и происхождение

Журналы действий агентов не соответствуют требованиям статьи 12 Закона ЕС об ИИ. Решения ИИ-агентов следует записывать в виде устойчивых объектов с причинно-следственными связями, цепочкой хэшей, указывающей на происхождение, и фиксированными правилами.

Издатель: REACTAPP.TOP14 мин чтения3244 слов

Источники: Your AI Agent Will Not Survive Article 12

В августе 2026 года вступил в полную силу правил, последствия которого ещё не ощутили большинство инженерных команд. Статья 12 Закона ЕС об ИИ предусматривает, что системы ИИ высокого риска должны технически обеспечивать автоматическую запись событий на протяжении всего их срока существования, причём возможности отслеживания должны соответствовать цели системы. Статья 26 налагает на оператора соответствующую обязанность: хранить эти журналы записей не менее шести месяцев, а при необходимости по другим законам — дольше.

Инженер, читающий этот текст, замечает странное несоответствие: цель чётко сформулирована, тогда как требуемый формат едва упоминается. Цель заключается в возможности восстановления отдельного решения после его принятия. Продукты типа APM этого не обеспечивают, поскольку они созданы для других целей. Векторные хранилища также не способны этого сделать.

Время выбрано крайне неудачно, поскольку сотрудники только что перестали отвечать на вопросы и начали принимать решения. Они утверждают расходы, изменяют масштабы инфраструктуры, обрабатывают страховые требования, отклоняют заявки и соглашаются на освобождение средств. Каждое из этих действий — это решение, которое кто-то в конечном итоге может попросить компанию обосновать, и в большинстве современных организаций честным ответом будет то, что они не могут этого сделать.

Дело о незначительных суммах, показавшее проблему заранее

До появления соответствующего регулирования и до того, как сотрудники смогли принимать решения, трибунал в Британской Колумбии опробовал ту же слабость в меньших масштабах. Это остается наиболее ясным из имеющихся примеров.

Бабушка Джейка Моффатта умерла в ноябре 2022 года. В тот же день он зашел на сайт Air Canada, чтобы забронировать билет в Торонто, и, не зная, как работают тарифы для семей, потерявших близких, обратился за помощью к чат-боту авиакомпании. Бот сообщил, что он может сразу купить билет по полной цене и затем, в течение 90 дней, запросить возмещение в виде скидки для семей, потерявших близких. Прежде чем полагаться на это, Моффатт поступил разумно — сделал скриншот ответа. Затем он совершил бронирование, полетел, присутствовал на похоронах и подал заявку.

Air Canada отклонила его заявку. Такой политики не существовало, и бот ее выдумал.

Следующий этап является наиболее важным. В Трибунале по гражданским разбирательствам авиакомпания утверждала, что не может нести ответственность за слова своего чат-бота, называя его отдельным субъектом, ответственным за собственные действия. Член трибунала Кристофер Риверс назвал это утверждение примечательным и отметил, что авиакомпания так и не объяснила, почему кто-то должен его принимать. Чат-бот является частью веб-сайта, и компания несет ответственность за свой веб-сайт. Air Canada выплатила 812,02 канадских долларов.

Эта сумма незначительна. На самом деле важен ноль — количество документов, которые Air Canada могла бы предоставить, чтобы доказать, почему ее собственная система сказала то, что сказала. Единственным постоянным доказательством во всем слушании была скриншот клиента.

Эта же проблема со временем усугубилась. В апреле 2025 года бот поддержки в Cursor придумал правило, ограничивающее использование подписки одним устройством. Клиенты начали отменять подписки, и компания узнала об этом лишь потому, что один из сооснователей обнаружил соответствующий пост на Reddit. Схема осталась прежней, но масштабы проблемы увеличились, а темпы развития ускорились, причем никакого трибунала не потребовалось.

Теперь представьте, что эта же слабость в доказательствах представлена регулятору в связи с агентом, отвечающим за перевод денег.

Отладка и подотчетность — это разные задачи

Большинство технологических стеков никогда не делает здесь значимого различия.

Возможность наблюдения ориентирована на выполнение процессов. Она фиксирует, что делал процесс во время одной итерации: периоды его работы, вызовы инструментов, количество токенов, попытки повтора и время задержки. Эти данные собираются выборочно, истекают после определенного периода хранения и относятся к конкретному запросу. Это идеально подходит для выявления ошибок в обычный рабочий день.

Ответственность ориентирована на конкретную область деятельности. Она фиксирует, к каким выводам пришла организация, на основании каких доказательств, согласно какой политике, и что произошло в дальнейшем. Она должна сохраняться при миграциях фреймворков, устаревании моделей, пересоздании индексов, реорганизации и уходе двух сотрудников.

В других частях бизнеса это является обычной практикой. Изменения в производственной среде никогда не воссоздаются на основе журналов приложений, поскольку запись о изменении содержит информацию об авторе, заявке и одобрении. Финансовое положение также никогда не воссоздаётся на основе HTTP-логов, поскольку существуют бухгалтерские записи. Заказы, платежи, одобрения и развертывания представляют собой стабильные объекты, у каждого из которых есть жизненный цикл, ответственный за него и правило хранения.

Решения агентов — единственный вид значимых событий, которые по-прежнему остаются в неструктурированном виде, без какой-либо системы контроля.

Версия в 3 часа ночи

Такой подход к описанию соответствия стандартам заставляет казаться нештатные ситуации чем-то экзотическим, хотя на самом деле они вполне обычны, поэтому конкретный пример помогает.

Через двадцать минут после выпуска система начала возвращать ошибки типа 5xx при попытке вывода средств. Специалист по анализу ошибок сравнил уровень ошибок с временными рамками выпуска, не обнаружил никаких сигналов тревоги от инфраструктуры и отнес происшествие к регрессии после выпуска. Специалист по устранению проблем откатил версию, после чего количество ошибок вернулось к норме. Специалист по выпускам снова открыл очередь развертывания. Кто-то оставил лайк в канале обсуждения инцидентов, и команда прекратила работу над проблемой. Всего прошло одиннадцать минут, и обзор инцидента не проводился, поскольку проблема, казалось, решилась сама собой.

Но вина лежала не на выпуске. У поставщика платежных услуг, работающего на последующих этапах, наблюдалось ухудшение качества услуг, которое как раз восстановилось примерно в момент отката. Связь между этими событиями была случайной, и сотрудники придумали правдоподобную версию произошедшего.

Правда всплывает в октябре, когда повторяется та же схема, и кто-то задаётся вопросом, не была ли у апрельского инцидента та же коренная причина. Пора это проверить.

К этому времени следы уже устарели и были удалены в июне. Шаблон запроса был переписан дважды. Когда изменилась модель встраивания, индекс поиска был пересоздан, поэтому фрагменты руководства, которые агент читал тогда, — это не те, которые он бы использовал сегодня. Версия модели, указанная в заголовке запроса, уже снята с эксплуатации. Остаётся только чат-сообщение, заканчивающееся эмодзи в виде поднятого большого пальца.

На этот вопрос невозможно ответить. Никто не был небрежен. Ничто в системе изначально не было создано для хранения ответа.

Почему улучшенная память это не решит

Обычный импульс — обратиться к слою памяти, который, как правило, представляет собой векторный хранилище. Но это решает совершенно другую проблему.

Метод встраивания поиска хорошо справляется с одним вопросом: что выглядит так же? Однако он не может указать, во что верил система в 14:02 определённого дня, какой ранее вывод привёл к этому, откуда взялся тот или иной факт, или действительно ли была выполнена операция, предусмотренная правилами.

Существует также более тонкая проблема. Результаты поиска не остаются воспроизводимыми со временем. При повторном использовании корпуса с более новой моделью при одинаковом запросе возвращается другой набор результатов, поэтому то, что считалось записью, незаметно меняется. Лог-файл, который можно бесшумно переписать путём обновления зависимостей, уже не является настоящим лог-файлом.

Каждый слой отвечает на свой собственный вопрос:

  • Векторный поиск: какие элементы выглядят так же?
  • Граф знаний: с чем он связан?
  • Происхождение: откуда он взялся и остаётся ли он действительным?
  • Записи решений: что было решено и по каким причинам?
  • Причинно-следственные связи: какое событие повлияло на какое?
  • Правила: какая политика определяет исход?
  • Временное состояние: каковы были характеристики системы 14 марта?

Для подлинного расследования вида «почему это произошло» необходимы почти все эти элементы. Только один из них представляет собой хранилище векторов.

Преобразование решения в объект

Именно здесь стоит обратить внимание на Semantica. Это слой на Python с лицензией MIT, расположенный под фреймворком агентов, который рассматривает контекст как граф, а не просто блок текста-запроса. Создание графа, выводы и происхождение данных являются детерминированными, без участия больших языковых моделей, что важно, когда результат должен служить доказательством.

Основная идея проста. Решение становится чем-то, что намеренно записывается, а не чем-то, что просто добавляется в журнал событий.

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 канадских долларов. На слушаниях компания не смогла объяснить, как вела себя её собственная система, и опиралась на мысль о том, что ответственность за программное обеспечение лежит на кого-то другом. Защита рухнула, несмотря на то, что речь шла лишь об одном билете и одном пассажире, потерявшем близкого, который пытался записать переписку.

Сегодня сотрудники быстрее всех утверждают, тратят, внедряют и отклоняют запросы, при этом никто не делает скриншотов этих действий. Сначала необходимо составить запись, прежде чем кто-либо попросит её. Вопросы всегда возникают в самый неподходящий момент, и к тому времени ответ уже либо хранится в базе данных, либо навсегда теряется.

Связанные статьи

  • Создание мини-ассистента ИИ с нуля с использованием агентов, инструментов и навыков — небольшой проект на Python, который направляет запросы агентам, вызывает инструменты калькулятора и преобразователя единиц измерения, запускает навык подведения итогов и отправляет обработанный запрос в большую языковую модель.
  • Agent Harnesses: стандарт папок для хранения навыков и ссылок — как инструмент harness расширяет возможности агентов с помощью файла HARNESS.md, каталогов навыков и ссылок, постепенного отображения информации и вложенной структуры для крупных агентов.
  • Почему агентам с длительной работой нужна машина состояний: роли лидера, рабочего и верификатора — Четыре причины сбоев цикла одного агента при выполнении длительных задач и способы их устранения с помощью команды из лидера, рабочего и верификатора, управляемой детерминированным движком, а также когда его можно пропустить.
  • Почему голосовые агенты звучат как роботы: каскады, обнаружение очереди и фреймворк TEN — Как каскадные конвейеры STT-LLM-TTS создают паузы и некорректные прерывания, четыре типа голосовых агентов и как фреймворк TEN обрабатывает обнаружение очереди и параллельные графы.
  • Почему ИИ-агенты терпят неудачу в реальных условиях: объяснение принципов инженерии Harness — Агенты застывают на уровне 70% эффективности, когда проблема кроется в системе, окружающей модель. Рассматриваются понятия промптов, контекста, а также принципы инженерии Harness, шесть уровней этой системы и разделение на генератор и оценщик.