Что ИИ поменял в моей схеме? Приращение вместо целого проекта

—

от автора

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

Пример за минуту

Я попросил модель добавить в карту проекта новую проверку — “повторная доставка сообщения не должна создавать второй файл”. Ответ модели пришёл в виде списка из четырёх пунктов.

Два из них это то, что я просил — новая проверка и её связь с очередью. Ещё два в виде галлюцинаций. В одной срок хранения файла тихо вырос с 24 до 72 часов. В другой из описания очереди пропала оговорка о том, что провайдер пока не выбран.

Список правок: нужное - отмечено, а изменённый срок и удалённая оговорка - нет

Список правок: нужное — отмечено, а изменённый срок и удалённая оговорка — нет

Нужное я отметил, а лишнее нет, после чего нажал «Применить отмеченное». На карте появился новый узел, а срок и оговорка остались прежними. Этот пример можно открыть в браузере: ответ модели там уже ждёт проверки.

Откуда взялась задача

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

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

Полный файл — это снимок. Мне же нужна разница: что добавили, изменили или убрали.

Какой же подход в работе с изменениями — выбрать? Confluence или git?

Confluence хранит историю страницы на сервере. Любые две версии можно сравнить и откатиться. Пользоваться просто, но правки попадают на страницу сразу и без проверки. К тому же сервера у PlyLoom — нет.

Git хранит историю от каждого участника и умеет принимать предложения правок через pull request. Предложение не попадёт в основную ветку, пока его не примут. Для правок от модели это то, что нужно. Но построчное сравнение для графа не годится: передвинул карточку и в JSON меняются десятки строк.

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

Пакет и приращение

Проект — это файл .plyloom целиком. Его хранят, пересылают коллегам, кладут в репозиторий. Новую карту с нуля модель присылает проектом.

Приращение — это список правок к известной версии. Так приходят доработки. Правка выглядит так:

{"plyloom":"changes","version":1,"base":"a3f9c2…","title":"Уточнить роли","ops":[  {"op":"add_node","node":{"id":"loc","name":"Локализация отчёта","kind":"entity","sheets":["context"]}},  {"op":"set","node":"goal.export","field":"body","to":"новый текст","was":"старый текст"},  {"op":"add_edge","edge":{"from":"loc","to":"goal.export","kind":"ref"}}]}

Самое полезное поле здесь — was, прежнее значение. Если в проекте уже стоит другое, пункт помечается как конфликт. Поэтому ответ модели можно применить, даже если я успел поправить карту, пока она думала. Всё нетронутое встанет само, а спорные места будут на виду.

Одна страница для обмена

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

  • делаем новую карту или дорабатываем открытую;

  • работаем с моделью или с коллегой;

  • отдаём всю карту или один лист с соседями.

«Работа с ИИ»: что открыто, переключатели и схема обмена

«Работа с ИИ»: что открыто, переключатели и схема обмена

Промт собирается из двух частей. Первая описывает формат обмена, вторая — задачу. Для задачи есть заготовки вроде «Ответить на открытые вопросы» или «Найти противоречия». Текст заготовки виден целиком, и его можно поправить перед копированием.

Проверка в два захода

Ответ модели вставляется как есть, текст вокруг JSON не мешает. Правки показываются списком по листам. Изменённый текст виден по словам: удалённое зачёркнуто, новое выделено.

Экран правок: пункты по листам, конфликт не отмечен

Экран правок: пункты по листам, конфликт не отмечен

Конфликты по умолчанию не отмечены. Заменить значение можно, но только сознательно. Если один пункт зависит от другого, например связь ведёт к новому узлу, без второго он не применится.

Проверка идёт в два захода. Сначала я решаю по списку, что стоит взять в режиме брифа, и нажимаю «Применить отмеченное». Неотмеченное отклоняется. Применённые правки появляются на карте и остаются отмеченными, как исправления в Word: новые узлы обведены зелёным, изменённые — жёлтым.

После применения: новый узел зелёный, изменённые жёлтые

После применения: новый узел зелёный, изменённые жёлтые

Второй заход проходит на карте, среди соседних узлов. Здесь видно то, чего не видно в списке: подходит ли новый узел по смыслу и не пропала ли связь. По каждому узлу можно нажать «Принять» или «Отклонить». Для всех сразу внизу есть полоса с кнопками «Принять все» и «Отклонить все». Отклонение возвращает и удалённое, а правки сделанные после — не трогает. Также всегда можно просто «Принять все», но надеюсь это не будет происходить часто — “доверяй но проверяй”

Полоса правок и решение по одному узлу

Полоса правок и решение по одному узлу

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

Сравнение по смыслу

У каждого узла постоянный ID, поэтому сравнивать карты можно по содержанию. PlyLoom замечает:

  • новые, удалённые и переименованные узлы;

  • новое значение атрибута;

  • смену типа связи;

  • появление узла на листе или уход с него.

Передвинутые карточки по умолчанию не показываются, для них есть отдельная галочка.

Модели иногда перенумеровывают ID. Без защиты такая правка выглядела бы как «удалить всё и добавить заново». Поэтому узел с новым ID, но с тем же типом и названием считается прежним, если такая пара одна. Связь устанавливается по связям и типу.

Что хранится в файле

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

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

Копия коллеги: только его правки, совпавшее отмечено конфликтом

Копия коллеги: только его правки, совпавшее отмечено конфликтом

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

Как я проверял сравнение

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

  1. Список правок превращает карту A в карту B и обратно без остатка.

  2. Если две копии менялись независимо, конфликты появляются только там, где обе стороны трогали одно и то же.

На генерации 500 вариантов для каждой карты эти проверки нашли несколько ошибок, которые руками я бы не поймал. Например, у узла терялся основной лист, а при сравнении не переносился порядок вкладок. Всё это исправлено до релиза.

Что дальше

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

Попробовать можно на сайте без установки — пример с правками уже ждёт проверки. Подробнее о функции — в статье на сайте. Если сравнение где-то ведёт себя странно, или нашли баги — просьба о них сообщать!

ссылка на оригинал статьи https://habr.com/ru/articles/1091266/