Название | Краткое описание |
---|---|
Главная | |
System Lorebook | Lorebook как более гибкая альтернатива System Prompt |
Stepped Thinking | Вызов нескольких вспомогательных инструкций перед генерацией основного ответа персонажа |
Stepped Summary | Генерация Summary несколькими последовательными запросами |
Прочие скрипты |
Stepped Summary
Основные скрипты
Импортировать через Extensions -> Quick Reply.
Версия | Примечения |
---|---|
v1 (26/09/24) | Включает в себя несколько запросов: получение списка текущих персонажей и их отношений (GetRelations), расположение персонажей (GetPositions), текущая одежда (GetClothings), чувства (GetFeelings), мысли (GetThoughts), планы (GetPlans), возможные направления истории (GetDirections). Примеры даны на русском и указана команда, что ответы должны быть на русском. При желании, можно в инструкции добавить команду, чтобы они не описывали мысли/планы за {{user}} - в опубликованной версии такой инструкции нет. |
Regex на скрытие
Импортировать через Extensions -> Regex.
Версия | Примечения |
---|---|
Any Details | Скрывает <details> блоки |
Summary Details | Скрывает <details type="summary"> блоки |
Что это?
Аксиома
Чем сложнее ваша инструкция, тем сильнее галлюцинируют LLM.
Мы можем разбить одну сложную инструкцию на несколько простых и вызывать их последовательно, что заметно улучшает аналитические возможности LLM.
Данный набор скриптов составляет Summary текущего ролеплея посредством нескольких отдельных запросов, вызываемых последовательно. Результат будет добавлен напрямую в чат от имени System.
Пример на gemma-2-27b-it.i1-Q6_K:
Ключевое в этом подходе то, что вместо одной поверхностной инструкции для описания нескольких разных сущностей (расположение персонажей, их одежда, мысли, чувства, намерения, и т.п.), мы будем делать несколько углубленных инструкций для каждой сущности и вызывать их по отдельности. И сетка будет это лучше обрабатывать, т.к. ей нужно будет фокусироваться на одной сущности, а не сразу на всём.
Пример скрипта на получение описания чувств персонажей:
Поскольку мы даём подробную инструкцию и пример, сетка мало косячит. Дальше мы объединяем результаты запросов с разными инструкциями и показываем результаты всего этого юзеру в чат.
Несколько нюансов:
- Последующие запросы будут видеть предыдущие, чтобы снизить уровень галлюнов, когда в разных ветках рассуждений сетка додумывает по разному
- Результаты всех вызовов будут находиться в одном сообщении. Для примера - если у вас для саммари используется 5 разных запросов, то сообщение для саммари будет создано после первого запроса и после этого будет обновлено 4 раза. При этом часть форматтинга делается самими макросами, чтобы упростить запросы к LLM
- Стриминг не поддерживается, увы. Но вы будете видеть обновление системного сообщения после завершения отработки отдельных запросов
Я пока это скорее рассматриваю как демонстрацию подхода, а не как готовое решение. Наверняка и список инструкций можно более грамотный придумать, да и сами инструкции лучше описать. Впрочем, тут многое от типа вашего РП зависит.
Как это работает?
В коллекции три основных скрипта (синие) и несколько скриптов для запросов деталей у LLM (красные), число которых как угодно можно расширять, при желании.
Основной скрипт для запуска - "Stepped Summary ✨" - именно его вы должны вызывать с нижней панели.
Данный скрипт вызывает скрипт "SteppedSummary.InitSummary", а, затем, несколько раз вызвает скрипт "SteppedSummary.ContinueSummary".
Оба скрипта InitSummary и ContinueSummary принимают два аргумента:
- label - заголовок, который будет использован для данной секции summary
- llm_script - имя скрипта, который будет вызываться чтобы получить кусочек summary
Скрипты InitSummary и ContinueSummary очень похожи. По смыслу, они просто вызывают llm_script и объединяют результаты различных частей саммари в новом сообщении.
Шизотеория
Недокументированной фичей STscript (языка макросов, встроенного в таверну) является возможность создавать свои функции, принимающие произвольные аргументы.
Пример простой функции с аргументами:
Вызов функции:
/run character=John clothing=pants MyScripts.GetCharClothing
Благодаря такому подходу, можно проводить декомпозицию комплексных скриптов. Меня же это изначально интересовало по той причине, что я хотел поэкспериментировать с мультизапросами - разбивкой сложных CoT-блоков на несколько отдельных запросов.
Я исхожу из аксиомы, что для LLM проще описать одну конкретную вещь (например - одежду), чем сразу думать о многих вещах (например - отношения чаров + расположение + одежда + чувства + мысли + etc).
В самом экстримальном случае разбивки, я просил одним скриптом дать мне сперва список чаров на сцене в формате json-массива, затем итерировался по каждому чару и просил дать список его текущей одежды в формате json-массива. А затем просил для каждой пары чар-одежда выдать детальное описание про данный элемент одежды и почему чар носит этот элемент одежды прямо сейчас. Эксперимент интересный, но я пока не смог придумать этому практическое применение. Но зато какое сочное описание панцу в деталях оно генерирует!
В основном тестил на гемме с русским языком. Возможно, если поменять язык/сетку/семплер и т.п. результаты будут отличаться.
Я столкнулся с несколькими проблемами при таком подходе:
- Сложно составить инструкцию, которая гарантированно вернёт json-массив без дополнительных элементов - сетка так и норовит вставить в начало конструкцию вида
"Да, конечно, вот список текущих персонажей в формате json"
. Или же обрамляет ответ ```json``` конструкцией. Как результат - если последующие макросы ожидают массив на входе, то всё ломается. В теории это можно было бы решить префиллом, засовывая["
в начало ответа сетки, но я не нашёл как это можно реализовать для /gen команды в таверне. - При просьбе отдавать результат в формате JSON, LLM чаще ошибается, по сравнению с ответами на естественном языке. То есть формат ответа ["white T-shirt", "black pants"] приводит к большим уровням галлюнов по сравнению с
"Джон сейчас носит **белую футболку** и **чёрные штаны**"
. - При слишком дотошном уровне декомпозиции заметно растёт уровень галлюнов. Условно, если вы попросите в деталях описать трусы вайфу, LLM может брякнуть что на ней нет ничего кроме трусов, хотя контекст к этому не располагает. Возможно, что это можно пофиксить правильными инструкциями.
Проблему описанную в пункте 2, в теории, можно решить при помощи Grammar, но это будет работать только для рабов жоры. Другая проблема в том, что таверне очень слабо реализована поддержка этой фичи.