Lemmalog превращает память ИИ-агента в движок анализа кода на Datalog

Автор технического блога pwning.systems месяцами использует ИИ-агентов для поиска уязвимостей: агенты хорошо ориентируются в больших кодовых базах и объясняют незнакомые подсистемы, но как только расследование растягивается на несколько часов, модель начинает терять нить. Она может предложить подход, который уже отвергли, забыть, что одно из предположений оказалось ложным, или продолжать рассуждать так, будто устаревшее наблюдение всё ещё верно, а простое указание модели на ошибку не гарантирует, что она перестанет опираться на всё, что из этой ошибки выводила.

Обычные системы памяти для LLM хранят прошлые наблюдения и диалоги, превращают их в эмбеддинги и при запросе достают наиболее релевантные фрагменты. По наблюдению автора, это решает не ту задачу: при расследовании важно не то, что когда-то было сказано, а то, что известно прямо сейчас. В его примере: установлено, что атакующий контролирует object_a, object_a указывает на object_b, а object_b, объект ядра; отсюда выводится, что атакующий контролирует объект ядра. Спустя два часа в отладчике LLDB выясняется, что object_a на самом деле не указывает на object_b, исходное предположение было неверным. В памяти при этом остаются и опровергнутое наблюдение, и построенный на нём вывод, а модели приходится самой разбираться, что из старого багажа ещё действует.

Автор увидел в этом задачу, знакомую по его основной работе, программному анализу: есть набор фактов и правила, по которым из них выводятся новые факты, а когда меняется один входной факт, обновлять нужно не всё заново, а только те выводы, что от него зависели (инкрементальная переоценка). Так родился Lemmalog, движок для LLM-памяти, построенный поверх Datalog: декларативного языка логического программирования, где вместо инструкций «как считать» задаются факты (controls(attacker, object_a), points_to(object_a, object_b), kernel_object(object_b)) и правила вида «если атакующий контролирует объект A, A указывает на B и B, объект ядра, то атакующий контролирует объект ядра». Если факт points_to(object_a, object_b) позже опровергается, движок точно знает, какой вывод от него зависел, и автоматически аннулирует именно его.

В Lemmalog роли разделены: LLM отвечает за «нечёткую» часть, понимание естественного языка, кода и вывода отладчика (например, фразу «LLDB показывает, что освобождённый объект позже переиспользуется как цель записи» модель превращает в структурированные факты freed(object_a) и reused_as(object_a, write_target)); дальше вступает детерминированная часть, из фактов по правилам выводятся новые факты, и эту работу модели делать больше не нужно.

Отдельная сложность, удаление фактов: если вывод c можно получить и из факта a, и независимо из факта b, удаление одного a вывод c не убирает, а удаление обоих a и b, должно. Поэтому Lemmalog отслеживает, из каких именно фактов и правил получен каждый вывод (провенанс), и может объяснить, почему тот или иной вывод верен, в виде дерева зависимостей вплоть до исходных наблюдений и применённых правил. Это же решает конкретную проблему, замеченную автором в работе с агентами: модель иногда уверенно заявляет «мы уже установили, что указатель контролируется атакующим», хотя на самом деле это не так; если запросить у Lemmalog провенанс такого утверждения и не найти его, значит, вывод не входит в поддерживаемое состояние, хотя от галлюцинаций на этапе извлечения фактов это, по признанию автора, не защищает.

Ещё одна деталь, факты не просто заменяются новыми, а получают интервалы действия: например, «primitive_a жизнеспособен» верно с 10:14 до 12:37, а после 12:37 верно обратное. Это позволяет одновременно отвечать и на вопрос «жизнеспособен ли primitive_a сейчас», и на вопрос «почему мы раньше считали его жизнеспособным», не держа в памяти два формально противоречащих друг другу факта.

Автор подчёркивает разницу с векторными базами данных: они хорошо отвечают на вопрос «что из прошлого релевантно этому вопросу», но не умеют отвечать на вопрос «что из всего узнанного верно прямо сейчас», векторная база может достать утверждение «object_a указывает на object_b», не зная, что два часа назад оно было опровергнуто и что от него зависели ещё несколько выводов. По мнению автора, это две разные задачи: поиск релевантного и поддержание актуальной истины; он использует оба механизма одновременно, комбинируя векторный поиск с Lemmalog.

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

На момент публикации движок поддерживает инкрементальную переоценку, удаление фактов с сохранением зависимостей, провенанс, временные факты, агрегации, сведение сущностей, гибридное извлечение и запросы по требованию, автор перечисляет это как список того, что успел добавить, увлёкшись реализацией Datalog. Доступный текст обрывается ровно перед тем, как автор переходит к главному вопросу, «а действительно ли это делает ИИ-агентов лучше», так что ответа, оценки эффективности или сравнения до/после в источнике нет.

Ключевые факты

  • В многочасовых расследованиях уязвимостей ИИ-агент теряет нить: путает уже опровергнутые предположения и продолжает рассуждать на основе фактов, которые перестали быть верными.
  • Автор построил движок Lemmalog на базе Datalog: факты и правила, из которых выводятся заключения, а при изменении одного факта пересчитываются автоматически только зависящие от него выводы, а не вся история заново.
  • Каждый вывод хранит провенанс, цепочку фактов и правил, из которых он получен; это позволяет спросить систему «почему это верно» и проверить, действительно ли модель установила то, что уверенно заявляет.
  • Факты в Lemmalog получают интервалы действия по времени: система одновременно отвечает и на вопрос «что верно сейчас», и на вопрос «почему раньше считалось иначе», не храня противоречащие друг другу факты.
  • Роли разделены: LLM превращает неструктурированный текст в структурированные факты, а детерминированный вывод новых фактов и их аннулирование при опровержении делает база данных; доступный текст обрывается перед ответом автора на вопрос, действительно ли подход делает агентов лучше.

Почему это важно

Долгие ИИ-расследования (в кейсе автора, поиск уязвимостей) страдают от известного изъяна: модель либо забывает опровергнутые факты, либо строит выводы поверх устаревших наблюдений, а простое указание на ошибку не отменяет всех выводов, которые из неё следовали. Обычная память на эмбеддингах и векторном поиске решает задачу «что релевантно вопросу», но не задачу «что верно прямо сейчас», и это две разные вещи. Идея автора, перенести в LLM-память технику из программного анализа (факты, правила, инкрементальный пересчёт при изменении входа), чтобы отмена одного наблюдения автоматически аннулировала все зависящие от него выводы, а не заставляла модель каждый раз реконструировать всё расследование заново по стенограмме.

Кому это важно

В первую очередь, исследователям безопасности и другим специалистам, которые используют ИИ-агентов для многочасовых расследований с накоплением фактов (реверс-инжиниринг, отладка, разбор инцидентов). Шире, разработчикам агентных систем, которым нужна согласованность состояния на длинных сессиях с вызовом инструментов, и всем, кто ищет альтернативу или дополнение к RAG-подобной памяти на векторном поиске, когда важна не только релевантность, но и актуальность знания.

Как это применить

Схема из статьи: роли разделены, LLM превращает неструктурированный материал (код, вывод отладчика, естественный язык) в структурированные факты, а детерминированный слой на Datalog выводит из них новые факты по заданным правилам и поддерживает единое непротиворечивое состояние. Ключевые механизмы, которые можно перенимать концептуально: (1) отслеживание провенанса каждого вывода, чтобы иметь возможность спросить систему «почему это верно» и ловить случаи, когда модель заявляет о несуществующем выводе; (2) удаление фактов с учётом множественных независимых оснований, вывод исчезает, только когда исчезают все пути его получения; (3) интервалы действия у фактов, чтобы хранить и текущее состояние, и историю рассуждений без противоречий. В доступном тексте нет ни ссылки на код, ни версии, ни условий доступа к Lemmalog, только описание архитектуры.

Можно ли доверять

Это личный технический блог одного разработчика, написанный от первого лица, а не рецензируемая работа или отчёт с бенчмарком. Доступный фрагмент текста обрывается ровно перед тем, как автор собирался ответить на собственный ключевой вопрос, «действительно ли это делает ИИ-агентов лучше», поэтому в источнике нет ни одной цифры измеренного эффекта, только иллюстративные гипотетические примеры (условные «два часа спустя», «пять зависимых выводов»), которые сам автор приводит как учебные, а не как результаты реального расследования. Список возможностей движка (инкрементальная оценка, ретракции, провенанс, временные факты и так далее), это заявление автора о собственной разработке, независимой проверки в тексте нет.

Риски и подводные камни

Автор сам оговаривает главное ограничение: провенанс и удаление зависимых выводов не защищают от того, что LLM галлюцинирует уже на этапе извлечения фактов из текста, они лишь усложняют попадание неподтверждённого вывода в состояние расследования незаметно для исследователя. Добавление отдельного детерминированного слоя (правила, отслеживание зависимостей, временные интервалы), дополнительная инженерная сложность поверх и так непростого агентного пайплайна. Наконец, поскольку текст обрывается до раздела с оценкой эффективности, а публичного релиза, репозитория или сравнения с конкретными конкурирующими решениями по памяти в источнике не приведено, судить о том, насколько подход работает на практике за пределами примеров автора, пока не на чем.

«Косинусное «сходство по ощущению», это не совсем то же самое, что истина.»

— автор блога pwning.systems