Название Краткое описание
Главная
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:

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

Пример скрипта на получение описания чувств персонажей:

Поскольку мы даём подробную инструкцию и пример, сетка мало косячит. Дальше мы объединяем результаты запросов с разными инструкциями и показываем результаты всего этого юзеру в чат.

Несколько нюансов:

  1. Последующие запросы будут видеть предыдущие, чтобы снизить уровень галлюнов, когда в разных ветках рассуждений сетка додумывает по разному
  2. Результаты всех вызовов будут находиться в одном сообщении. Для примера - если у вас для саммари используется 5 разных запросов, то сообщение для саммари будет создано после первого запроса и после этого будет обновлено 4 раза. При этом часть форматтинга делается самими макросами, чтобы упростить запросы к LLM
  3. Стриминг не поддерживается, увы. Но вы будете видеть обновление системного сообщения после завершения отработки отдельных запросов

Я пока это скорее рассматриваю как демонстрацию подхода, а не как готовое решение. Наверняка и список инструкций можно более грамотный придумать, да и сами инструкции лучше описать. Впрочем, тут многое от типа вашего РП зависит.

Как это работает?

В коллекции три основных скрипта (синие) и несколько скриптов для запросов деталей у LLM (красные), число которых как угодно можно расширять, при желании.

Основной скрипт для запуска - "Stepped Summary ✨" - именно его вы должны вызывать с нижней панели.

Данный скрипт вызывает скрипт "SteppedSummary.InitSummary", а, затем, несколько раз вызвает скрипт "SteppedSummary.ContinueSummary".

Оба скрипта InitSummary и ContinueSummary принимают два аргумента:

  • label - заголовок, который будет использован для данной секции summary
  • llm_script - имя скрипта, который будет вызываться чтобы получить кусочек summary

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

Шизотеория

Недокументированной фичей STscript (языка макросов, встроенного в таверну) является возможность создавать свои функции, принимающие произвольные аргументы.

Пример простой функции с аргументами:

1
2
3
4
5
6
7
8
9
/gen
Pause your roleplay. According current status, {{arg::character}} wears {{arg::clothing}}. Explain in single sentence why {{arg::character}} wears {{arg::clothing}} at current moment.

Follow next rules:
- Do not mention any other clothes, talk only about {{arg::clothing}}
- Answer in Russian language

Example:
Алиса обернулась полотенцем, поскольку только что вышла из душа.

Вызов функции:
/run character=John clothing=pants MyScripts.GetCharClothing

Благодаря такому подходу, можно проводить декомпозицию комплексных скриптов. Меня же это изначально интересовало по той причине, что я хотел поэкспериментировать с мультизапросами - разбивкой сложных CoT-блоков на несколько отдельных запросов.

Я исхожу из аксиомы, что для LLM проще описать одну конкретную вещь (например - одежду), чем сразу думать о многих вещах (например - отношения чаров + расположение + одежда + чувства + мысли + etc).

В самом экстримальном случае разбивки, я просил одним скриптом дать мне сперва список чаров на сцене в формате json-массива, затем итерировался по каждому чару и просил дать список его текущей одежды в формате json-массива. А затем просил для каждой пары чар-одежда выдать детальное описание про данный элемент одежды и почему чар носит этот элемент одежды прямо сейчас. Эксперимент интересный, но я пока не смог придумать этому практическое применение. Но зато какое сочное описание панцу в деталях оно генерирует!

В основном тестил на гемме с русским языком. Возможно, если поменять язык/сетку/семплер и т.п. результаты будут отличаться.

Я столкнулся с несколькими проблемами при таком подходе:

  1. Сложно составить инструкцию, которая гарантированно вернёт json-массив без дополнительных элементов - сетка так и норовит вставить в начало конструкцию вида "Да, конечно, вот список текущих персонажей в формате json". Или же обрамляет ответ ```json``` конструкцией. Как результат - если последующие макросы ожидают массив на входе, то всё ломается. В теории это можно было бы решить префиллом, засовывая [" в начало ответа сетки, но я не нашёл как это можно реализовать для /gen команды в таверне.
  2. При просьбе отдавать результат в формате JSON, LLM чаще ошибается, по сравнению с ответами на естественном языке. То есть формат ответа ["white T-shirt", "black pants"] приводит к большим уровням галлюнов по сравнению с "Джон сейчас носит **белую футболку** и **чёрные штаны**".
  3. При слишком дотошном уровне декомпозиции заметно растёт уровень галлюнов. Условно, если вы попросите в деталях описать трусы вайфу, LLM может брякнуть что на ней нет ничего кроме трусов, хотя контекст к этому не располагает. Возможно, что это можно пофиксить правильными инструкциями.

Проблему описанную в пункте 2, в теории, можно решить при помощи Grammar, но это будет работать только для рабов жоры. Другая проблема в том, что таверне очень слабо реализована поддержка этой фичи.

Edit Report
Pub: 07 Oct 2024 23:35 UTC
Edit: 08 Oct 2024 11:47 UTC
Views: 327