Перейти к содержанию
Публикация AiManual

PlyLoom и LLM: как применять правки к карте знаний через приращения и diff вместо перезаписи проекта

PlyLoom применяет правки к карте знаний приращениями: LLM возвращает список правок с прежним значением поля was, поэтому конфликт с параллельным изменением видн

Коротко

Что будет в материале

  1. 01

    Проблема: почему перезапись всего проекта через LLM ломает карту знаний

  2. 02

    Что такое приращение и как оно устроено в PlyLoom

  3. 03

    Двухэтапная проверка правок: сначала бриф, потом карта

  4. 04

    Сравнение версий: почему построчный diff не работает для графов

PlyLoom дорабатывает карту знаний не перезаписью файла, а приращениями: LLM возвращает список правок к известной версии. Каждая правка содержит прежнее значение поля was, поэтому параллельное изменение карты не затирается молча, а превращается в видимый конфликт. Проверка идёт в два захода: сначала список правок в режиме брифа, затем каждая правка на самой карте среди соседних узлов, с кнопками «Принять» и «Отклонить».

Такой подход вырос из конкретной боли. Пока карта была в первой версии, схема «приложить к промту весь проект, попросить изменения, заменить файл ответом модели» работала. Со второй версии модель начала терять узлы, сокращать цитаты и править то, о чём её не просили. Автор проекта описывает этот опыт в публикации на Habr.

Проблема: почему перезапись всего проекта через LLM ломает карту знаний

Проект в PlyLoom - это файл .plyloom целиком: его хранят, пересылают коллегам, кладут в репозиторий. Пока карта маленькая, схема с полной заменой работает. На большом JSON она разваливается по трём причинам: модель может потерять узлы, сократить цитаты или изменить поля, которых в задаче не было.

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

Галлюцинации LLM при доработке карты: примеры и последствия

Тихие правки опаснее явных ошибок, потому что не выглядят ошибкой. В примере, который приводит автор, запрос касался проверки «повторная доставка сообщения не должна создавать второй файл». Модель вернула список из четырёх пунктов. Два относились к делу, а два оказались галлюцинациями: срок хранения файла вырос с 24 до 72 часов, и из описания очереди пропала оговорка о том, что провайдер пока не выбран.

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

Что такое приращение и как оно устроено в PlyLoom

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

Что возвращает LLMЧто происходит с остальными узламиЧто видит пользователь
Проект целиком, файл .plyloomПереписываются все: возможны потерянные узлы, сокращённые цитаты и правки сверх задачиНовую версию файла, которую нужно сравнить вручную
Приращение, список правокНе меняются, пока пользователь не применит конкретную правкуСписок правок и кнопки «Применить», «Принять», «Отклонить»

Аналогия с git здесь ближайшая по смыслу. Приращение похоже на патч, только не для текстового файла, а для графа: набор операций, которые применяются к конкретной версии. Автор прямо описывает заимствование: простые термины взяты у Confluence, логика предложений правок и отпечатков версий у git. Пользователь видит кнопки «Сравнить», «Применить», «Принять» и «Отклонить».

Структура правки: поле was и его роль

В каждой правке хранится прежнее значение поля was. Это снимок того состояния, которое модель видела, когда готовила изменение. Перед применением система сверяет was с текущим значением поля в карте.

Совпадение означает, что поле не менялось, и правку можно применить. Расхождение означает конфликт: пока модель готовила ответ, карта уехала вперёд. Если кто-то уже поменял срок хранения с 24 на 48 часов, а модель предлагает перейти с 24 на 72, система покажет конфликт, и решение останется за пользователем: принять новое значение, оставить своё или разобраться, какая версия верна.

Механизм не даёт параллельным изменениям молча перезаписать друг друга. Срабатывает он на уровне поля отдельного узла, а не всего файла, поэтому конфликтов оказывается ровно столько, сколько реально затронуто правками.

Двухэтапная проверка правок: сначала бриф, потом карта

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

Режим брифа: как отметить нужное и отклонить лишнее

В режиме брифа пользователь видит предложенные правки текстом, отмечает галочками нужные и нажимает «Применить отмеченное». Отклонённые пункты не применяются.

В примере с проверкой повторной доставки это дало ровно тот результат, который нужен: из четырёх пунктов отмечены два, и после нажатия «Применить отмеченное» на карте появился новый узел, а срок хранения и оговорка о провайдере остались прежними. Схема напоминает pull request, но без git-жаргона: те же действия описаны понятными кнопками.

Проверка на карте: оценка правки в контексте соседних узлов

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

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

Сравнение версий: почему построчный diff не работает для графов

Построчное сравнение для графа не годится: стоит передвинуть карточку, и в JSON меняются десятки строк, хотя смысл графа тот же. Классический diff в такой ситуации показывает шум: перестановки, сдвиги и переформатирование, за которыми теряются настоящие изменения.

Поэтому в PlyLoom сравнивают не строки, а структуру: узлы сопоставляют по постоянным ID, а версии помечают отпечатками SHA-256.

Постоянные ID узлов: как отслеживать изменения без привязки к строкам

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

Для приращений это критично. Правка ссылается на узел по ID, поэтому адресация не зависит от того, где узел оказался в файле.

Отпечатки SHA-256 для версионирования

Отпечаток SHA-256 даёт компактный идентификатор состояния карты. Если отпечатки двух версий совпадают, файлы идентичны и детальное сравнение не нужно. Если различаются, есть смысл запускать сопоставление по узлам и смотреть, что именно поменялось.

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

Отказ от журнала правок в файле: причины и альтернативы

В доступном фрагменте статьи автор не раскрывает, почему журнал правок не хранится внутри файла .plyloom, и какие альтернативы он рассматривал. Поэтому дальше только то, что подтверждается источником, и следствия из описанной архитектуры.

Известно, что проект - это один файл .plyloom, который хранят, пересылают коллегам и кладут в репозиторий. Приращения и отпечатки версий существуют отдельно от содержимого карты. Логичное следствие такой схемы: файл остаётся рабочим документом, а версионирование ложится на систему контроля версий, как это устроено в git, откуда PlyLoom и взял логику предложений правок и отпечатков.

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

Проверка сравнения на случайно сгенерированных правках учебных карт

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

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

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

Итоги: кому подходит подход PlyLoom и какие у него ограничения

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

Ограничения стоит держать в голове. LLM по-прежнему может предлагать нежелательные правки, и два этапа проверки остаются обязательными, а не формальностью. Постоянные ID нужно поддерживать: если узлы пересоздаются с новыми идентификаторами, сопоставление версий теряет смысл. Конфликты по полю was разрешает пользователь, автоматического слияния нет. История правок не хранится внутри файла .plyloom, поэтому без репозитория или другого внешнего хранилища версий откатиться будет некуда.

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

Первоисточник: Что ИИ поменял в моей схеме? Приращение вместо целого проекта (Habr).

Подписаться на канал