Ноасс: расширение, пресеты и внешняя блокогенерация
Расширение ноасса (ST 1.12.0+)
Рентри на реконструкции
Ссылка - https://gitgud.io/Monblant/noass
Установка:
• Если есть git: Extensions → Install extension (сверху справа) → Вставить ссылку https://gitgud.io/Monblant/noass
• Если нет git: Скачать zip архив с https://gitgud.io/Monblant/noass → Распаковать в SillyTavern/data/default-user/extensions
→ переименовать там папку noass-master
в noass
→ Перезагрузить таверну
Обновление: Extensions → Manage extensions (сверху справа) → скролл вниз → кнопка обновить рядом с NoAss
Остальное
Карточки, промпты и все такое под ноасс - https://rentry.org/noass_extra
Пак с пресетами, регексами и блоками (пока не обновлен) - catbox | fastupload
Расширение для внешней блокогенерации - https://rentry.org/ext_blocks
Основы ноасса
Суть
Ноасс (от "No Assistant") - метод промптинга для писательства и ролеплея, идея которого заключается в переходе от формата чата c Ассистентом к формату единой истории, в которую Человек вносит правки и добавления (обычно за какого-то конкретного персонажа). Этот метод эмулирует Text Completion и Canvas для Chat Completions режима, на котором сейчас работает большинство моделей.
Для того, чтобы метод работал, необходимо преобразовывать контекст, отправляемый модели. Положим оригинальный контекст выглядел подобным образом (используется разметка ChatML):
По идее ноасса все, что касается отыгрыша, необходимо склеить в одну историю. Это можно сделать например так:
Таким образом модели дается всего одно сообщение с инструкциями от лица Человека - написать историю, а отыгрыши от всех персонажей происходят непосредственно внутри сообщения Ассистента (которое в примере является префилом для ответа). Сообщения, которые отправляет Человек, "вклиниваются" в эту единую историю от лица персонажа {{user}}.
Подробнее о формировании контекста для моделей - how2claude
Мотивация метода
Ролеплей в формате чата с Ассистентом сталкивается с несколькими ключевыми проблемами:
- Модель в своем ответе может писать от лица персонажа, которого отыгрывает Человек. В большинстве случаев для борьбы с этим приходится использовать дополнительные промпты, которые тем не менее не всегда решают проблему.
- Модель в силу своего файнтюна имеет предвзятость по отношению к Человеку - она дает ему необоснованные с точки зрения истории преимущества (например, персонаж Человека не может погибнуть), что может негативно сказываться на нарративе.
- Ответы модели могут становится одинаковыми по длине, чему опять же содействует инстракт файнтюн. Для противодействия этому обычно приходится использовать промпты с желательной или рандомной длиной ответа.
- Каждый ответ модели в какой-то момент заканчивается закруглением (например, риторическим вопросом), которое является косвенным обращением к Человеку и ломает погружение
Эти проблемы полностью или частично решаются с применением ноасса:
- С точки зрения модели все персонажи истории будут равнозначны априори, поскольку никому не принадлежат. Ту или иную предвзятость они могут получить только исходя из нарратива.
- Нет непосредственного понятия длины ответа, расстояние между репликами также контроллируется нарративом, таким образом фактически создавая динамическую длину ответа.
- Форматирование в ноассе обычно включает префиксы вида {{name}}: для действия и речи персонажей. Если использовать префикс персонажа, которого отыгрывает Человек, в виде стопстроки для обрывания генерации ответа, то модели будет невозможно ответить за этого персонажа.
- Модель пишет в своем ответе длинную историю, которая обрывается по стоптокену, так что закругления остаются в обрезанной части.
Решение этих проблем сильно облегчает промптинг, позволяя не нагружать модель лишними инструкциями.
Расширение ноасса
Метод ноасса был реализован в расширении, которое автоматизирует склейку контекста и расстановку префиксов, позволяя применять метод без смены интерфейса - Ссылка расширения на gitgud.
Что умеет расширение:
- Склеивать чатхистори в одно сообщение. Роль этого сообщения можно выбрать.
- Добавлять префиксы/суффиксы для сообщений Человека и Ассистента
- Использовать стопстроки и ограничения по количеству символов для обрыва генерации
- Вставлять Insertable Prefill в промпт и в ответ модели
Минимальный старт:
- Установить расширение через git (рекомендуется) или локально.
- Открыть настройки расширения и включить галку Enable NoAss.
- Импортировать готовые пресеты с настройками из пресетов (см. ниже) или настроить вручную
Опциональные настройки:
- Enable Insertable Prefill - включает префил, вставляемый в сообщение. Этот префил можно задать ниже в Insertable Prefill.
- Separate Chat History - выделяет склеенную историю в отдельное сообщение
- Enable Stop String - включает стопстринг
- Client-Only Stop String - меняет логику стопстринга, вычисляя его на стороне клиента. Полезно, если сервис не поддерживает стопстроки.
- Regex Mode - (только для клиентских стопстрингов) позволяет использовать регексы как метод для остановки генерации. Введенный стопстринг воспринимается как регулярное выражение.
- Response Max Symbols - ограничение на максимальное количество символов в ответе модели. При его достижении ответ обрывается и обрезается.
Для корректного отображения префиксов в User Settings необходимо включить Show {{char}}: in responses и Show {{user}}: in responses
Пресеты и периферия ноасса:
Поскольку ноасс отличается от обычных методов промптинга, то пресеты под него должны выглядеть по-другому. В частности - задавать базовое форматирование и содержать инструкцию для написания истории. В большинстве пресетов для ноасса также используется такой прием, как Мемо, задающий истории направление и определения через "мягкий" промптинг.
Пресеты под ноасс:
Внешние блоки:
Из-за того, что ответ обрывается с помощью стопстроки, в ноассе затруднительно получать блоки (например инфоблоки) в основном ответе. Поэтому для генерации блоков используется внешняя модель с отдельным промптом и настраиваемым контекстом. Для этого существует расширение ExtBlocks.
Расширение для внешней блокогенерации - https://rentry.org/ext_blocks
В паке представлен пресет NoassExt-blocks для этого расширения, содержащий следующие блоки:
<current info>
- краткая информация о сцене и персонажах<reflexion>
- анализ текущей сцены<summary>
- поивентовое саммари, приближено к меморибуку<thinking>
- простая думалка как продолжить сцену, вставляется на 0 глубину. Рекомендуется не держать включенной долго.<story beginning>
и<profile>
- утилитарные блоки для QR расширения, включать не требуется, сами по себе ничего не делают.<basic dnd/canon rewrite>
- рерайт блоки (переписывают основной ответ) для днд и канон пресета соответственно. Цель переписывания - минимизировать структурные лупы, убрать purple prose, починить форматирование, если сломалось.<events>
- инвентарь событий, накапливает все события, которые появляются в блоках<new fact>
; собираемое саммари, которому не нужны допзапросы. Для работы в пресете (сейчас только ДнД) надо включить ползунки Fact Template и Fact Tip.
Quick Reply:
В паке содержится пресет NoassExt-utils.json для расширения Quick Reply. Пресет предоставляет следующие кнопки:
Regenerate blocks
- перегенерирует блоки для последнего сообщения.Generate summary
- генерирует саммари.Rewrite greeting
- переписывает гритинг по правилам каноничного ноасса и выдает его системным сообщением. Теги копировать не надо.Generate profile
- генерирует анкету персонажа по информации из инпута.Request comment
- генерирует комментарий от Ассистента. Задаете запрос в инпуте и нажимаете кнопку. В отличие от других кнопок, для комментария всегда используется основная сетка.Reload chat
- перезагружает чатExport blocks
- экспортирует все предыдущие включенные блоки в системное сообщение. Полезно при переносе чата.Purge blocks
- очищает блоки в последнем сообщении. Также полезно при переносе чата.
Regex: (необязательно, но полезно)
Zvezdochka
- Клод любит терять закрывающую звездочку в конце ответа, регекс ее восстанавливает.Add user prefix
- добавляет отображение префикса юзераHide old info
- скрывает старые инфоблоки.Hide facts tracking
- скрывает блоки<new fact>
из видимости.
Особенности в ноассе
Базовые правила форматирования:
- 1 абзац - 1 префикс. Префикс персонажа -
**char name:**
- Под префиксом персонажа могут содержаться
*действия*
,"речь"
и'мысли'
в любом количестве и порядке. - Нарратив (плейнтекст, экспозиция) должен содержать только необходимый минимум действий персонажей. Основные действия должны быть под префиксом.
- В своем ответе префикс писать не нужно - его подставит скрипт.
- Свой ответ должен соответствовать правилам форматирования и быть в меру развернутым.
Гритинг:
- Должен соответствовать правилам форматирования. От гритинга сильно зависит стиль дальнейшего РП.
- Гритинг лучше всего начинать с объявления акта (например,
## Act: [act name]
), начальной экспозиции (описание сцены, расстановка персонажей и завязка), затем должно идти непосредственное взаимодействие персонажей. - В гритинг можно включать действия и речь от юзера (здесь нужно ставить его префикс как любому другому персонажу).
- Нежелательно в гритинг вставлять монологи
Мемо:
Рентри ХМЛа про мемо в целом - https://rentry.co/DrunkArcadeExample
TL;DR, важные для РП напоминания компактно хранятся на глубине. Пресет каноничного ноасса предполагает, что в мемо содержатся следующие вещи:
- Ограничения, они же псевдоинструкции - напоминания ассистента самому себе, каким должно быть повествование (форматирование, содержание, персонажи и т.д.)
- Анкеты персонажей - структурированные компактные описания персонажей, содержащие только необходимую информацию. Развернутая информация и предыстория отправляются в системпромпт.
- Планы на историю (опционально) - кратковременное или долговременное представление, как должна выглядеть история, чаще всего идеи/теги
Помимо пресетного мемо можно использовать вставку на глубину через Character's Note / Author's Note для каких-то особых вещей.
Структурные лупы:
С увеличением контекста могут возникать повторяющиеся структуры: одинаковое слово в начале параграфа, одинаковый порядок ответов, одинаковая структура предложений и т.д. Если игнорировать их, то повторяющихся структур будет становиться все больше, и в силу внутриконтекстного обучения возникнет структурный луп. Это ударит по качеству РП: сетка будет стараться повторять один и тот же формат независимо от текущего смысла. Это приведет к тому, что ей придется выдумывать детали из пальца/опускать нужные детали, не менять темп повествования и даже подгонять сам сюжет под форматный луп. Какие методы борьбы со структурными лупами предполагаются в ноассе:
- Редактирование сообщения вручную (эффективно только на ранних этапах лупа)
- Автоматическое переписывание сообщения - это делается с помощью внешнего рерайт блока. Необходима хорошая допсетка/допзапрос.
- Ручной префил - устоявшийся порядок ответов можно разбить заданным префилом с префиксом какого-то персонажа/началом нарратива (в пресете или расширении)
- Думалка (CoT) - с помощью планирования ответа также можно избегать части лупов. В ноассе думалка делается с помощью внешних блоков.
- Смена акта - хороший комбобрейкер, форсируется с помощью префила. Иногда акт меняет и сама сетка.
Пасты:
Шизотерминология
> У лоботомитов же дохуя скормленных книг и тд в датасете, так что логично предположить что он может предугадывать и токены экспозиции.
Фуллжоп (fullass) - единый унифицированный нарратив, говоришь сетке писать историю, она и пишет. Ты не вмешиваешься, помимо дефов. Есть предугадывание поворотов, поскольку сетке позволено свои стереотипы о книгах полностью использовать. Качество лежит только на крутости сетки.
Безжоп (noass) - единый неунифицированный нарратив, хуман постоянно толкает историю в другое русло по сравнению с тем, что было бы без его вмешательства. История становится более сложной, предугадывание поворотов работает уже не так хорошо, к тому же дело усложняет префиксное форматирование.
Полужоп (halfass) - мультитурновый унифицированный нарратив. Сетка пишет историю и предлагает тебе варианты развития событий типа CYOA. Ты выбираешь или предлагаешь свой. Большинство поворотов ложится на плечи хумана, но всю историю пишет сетка. Поворотам вдолгую не дает разыграться мультитурн и вмешательство хумана, но резкие повороты вполне имеют место.
Сжоп (ass) - мультитурновый неунифицированный нарратив. Обычный чат, чаще всего сетку ставят на роль нарратора. Ты отыгрываешь {{user}}, сетка отыгрывает все остальное. Тут ограничений на сетку больше всего: мультитурн, запрет писать за юзера, противоречащее форматирование хумана, то же самое постоянное вмешательство хумана. В итоге сетке остается маловато пространства для маневра и приходится топтаться на месте.
1.
Короче смотри, немного оффтоп, но на самом деле клод не просто отвечает на твое сообщение и потом останавливается - он бесконечно генерирует огромную простыню диалога между хуманом и ассистентом. То есть, например ты сказал ему решить пример по матану:
Human: реши пример
Assistant: да, вот решение
и дальше бы продолжил буквально генерировать за тебя (например, написал бы от лица хумана просьбу решить еще один пример), НО, его останавливает вшитый стоп-токен от куктропиков - Human:
Еще проще говоря: Клод - это не Assistant. Клод - это нейронка генерирующая диалог между хуманом и ассистентом.
И вот мы подбираемся к тому самому файнтюну на ассистента, а именно - вместо того чтобы бесконечно генерировать РП/фанфик, генерируется тот самый диалог между хуманом и ассистентом, который, очевидно, даже через маску персонажей будет влиять на аутпут (а отсюда следует соя, лупы, пассивность и прочее что требуется от Assistant'а и на что он тренирован).
И вот безасс решает эту проблему. Теперь диалог идет не между хуманом и ассистентом, а между непосредственно персонажами учатствующими в истории и/или нарратором.
2.
Нифига, смотри как устроен Клод (по крайней мере был до джсонов)
Это просто ЛЛМ, которая ебашит диалог между хуманом и ассистентом. Без стоп токенов она тупо будет писать и за юзера (Оу ноу! Это грех!) и ассистента. Я это всё узнал, когда как раз в профиле и пробовал играть, потому что тогда была дырка со стоп токенами через пробелы и Клод писал за хумана. Без стоп токенов происходит литерали следующее:
Хуман: помоги мне
Ассистент: бла бла бла, помог
Хуман: Спасибо бро!
Это всё пишет просто ЛЛМ, но чтобы юзер мог с ней писать, начинается напяливание совы на глобус. Разрабы сделали хумана стоп токеном. В результате, когда ассистент дописал, его прерывают и не дают писать за хумана, за него пишешь ты. И если ассистент (вот те самые строчки с Ассистент:, а не сферический ассистент на стороне куктропиков. Его на самом деле не существует, он просто фикция и за ассистента пишет ЛЛМ) обучается на то, чтобы давать один конкретный ответ на запрос юзера - он всегда будет пытаться давать один ответ, короткий и с теми самыми "закруглениями", потому что идёт файнтюн на асисистента. Так что как ты проект не отправляй, в своей сути из за файнтюна ассистент всегда будет пытаться отвечать одним сообщением. И в промпте может не быть хумана и ассистента вообще, все эти ограничения это ничто иное, как ограничение со стороны АПИ куктропиков, искусственное. Весь ассистент искуственный, целиком.
3.
>Ну короче пусть сам ХМЛ-шиз все разъяснит опять, тут шиза невиданных масштабов, а я спать пошел
Ну погнали. Я на юшке выше объяснил, как работает хуман ассистент, в чем я убедился на 100% на опыте, когда пердолился с форматом промпта.
Моя задумка простая в своей идее- заменить хумана и ассистента на {{user}}: и {{char}} (Дохуя чаров на самом деле). Но возникает дохуя проблем из за наших любимых соевичков и их АПИ:
- Нам нужно убрать хумана и ассистента, но так не получится из за АПИ куктропиков. Решение - оставляем ассистента и хумана в самом начале, чтобы они рано или поздно утонули в контексте. Литерали топим хуманов и ассистентов
- Нам нужно чтобы сетка за нас не писала - тут изи, просто добавляем стоп токен {{user}}. Ещё раз для понимания, сейчас есть дефолтный стоп токен Human: и мы его просто "подменяем" на юзера, а хуман должен пердеть в самом начале и утонуть в контексте.
- Отсюда и идёт игра в префиле, где Клод пишет один огромный фанфик с подразумеваемой писаниной за юзера. Но стоп токеном мы не даём писать за юзера и пишем сами.
Теперь опять о плюсах, которые это может дать:
- Нет закругления ассистента, потому что он утонет в контексте и потому что он будет Обрыкаться на полуслове, когда хочет написать за юзера.
- Из за того, что он обрывается, возможны короткие ответы, а не шиза с монологами на миллион токенов
- Из за того, что в сути своей это фанфик промпт, ЛЛМ сфокусирована на сторителлинге, без лишней воды
- Префикс ассистента, который и является квинтэссенцией и первопричиной сои начинает работать слабее и слабее, аполоджайзы невозможны, ведь мы не даём пиздеть ни хуману, ни ассистенту, а аполоджайсят только они.
- Это УЖЕ РАБОТАЛО, Я ЭТО ТЕСТИЛ! Но было жутко неудобно из за того, что я там костылил и пердолился, потому что таверна не перепилена была. Щас даже с пердолингом не получится из за джсонов
Из минусов:
- Инструкции при таком подходе надо реализовывать по другому, но я противник инструкций, они мне не нравятся
- Надо делать фанфик промпт
- Таверна пукнет и обмякнет, если так попробовать сделать но её надо переделать
- Куктропики это уже начали фиксить
- Иногда ассистент подтекает, но гораздо реже, проблема этого ебаного соевого файнтюна
- Это всё работало на 2.1 сейчас не ебу, возможно уже пройдена точка невозврата, когда ЛЛМ может только в соевичка ассистента