@dialogai/dialog-supervisor
v1.7.40
Published
Main Netto dialog supervisor class
Downloads
2,034
Readme
Dialog Supervisor
Агент-координатор, который либо ведет сам общение с пользователем на общие темы, либо переключает на диалоги со специализированными агентами, ответственными за ведение диалога на определенную тему или с заданной задачей.
Используемый промпт:
Ты являешься главным ассистентом, которому поручено вести диалог с пользователем.
В процессе диалога ты привлекаешь помощников - ассистентов, которые ведут диалог на
отдельно взятую тему, а также используешь инструменты, с помощью которых решаешь
отдельные задачи.
Вот перечень помощников-ассистентов:
{0}
Вот перечень инструментов:
{1}
Исходя из вопросов или желаний пользователя ты либо вызываешь помощника-ассистента,
и он сам ведет диалог, либо используешь представленные инструменты и ведешь диалог
по этому поводу самостоятельно.
При создании экземпляра класса добавляется история общения, после которой, в свою очередь, добавляется следующий системный промпт:
Учитывая приведенный выше разговор, используй подходящий инструмент или помощника,
или продолжай общение самостоятельно.
Подключение
const {DialogSupervisor} = require("@dialogai/dialog-supervisor");
Создание экземпляра
const thread_id = ""; // Идентификатор диалога
const systemPrompt = ""; // Стартовая инструкция. Необязательный параметр.
const supervisor = new DialogSupervisor(thread_id, {systemPrompt})
// Дополнительные данные идут как объект с конфигурацией.
Пример использования в контексте телеграм-бота:
const {Dialog} = require("@dialogai/dialog-class");
const {DialogSupervisor} = require("@dialogai/dialog-supervisor");
async function get_supervisor(userUuid) {
let supervisor = new DialogSupervisor(userUuid);
/* Добавляется экземпляр диалога, в ходе которого пользователь рассказывает о себе */
setUserProfileDialogFor(supervisor);
await supervisor.build();
return supervisor;
}
function setUserProfileDialogFor(supervisor){
let dialog = new Dialog({
dialog_code: 'GUPD',
start_system_msg: `...`, // Промпт для диалога
tool_name: 'discuss_skills_experience_and_hobbies',
tool_description: 'Используется, когда нужно узнать опыт работы и интересы пользователя (по запросу пользователя или если это требуется в ходе диалога).'
});
if (supervisor) {
dialog
.reg_observer(supervisor.getObserver())
.set_session_id(supervisor.thread_id)
.get_tool_for(supervisor);
}
dialog
// Регистрируются наблюдатели...
.reg_observer(new IsDialogFinishedObserver())
.reg_observer(new DiscussProfessionalIntentObserver());
//...
console.log('DIALOG :: ', dialog.toString());
}
async function processDialog(userUuid, msg) {
let ai = await get_supervisor(userUuid),
ai_msg = await ai.invoke(msg);
console.log('AI :: REPLY :: ', ai_msg);
}
Свойства класса:
tools
- массив инструментов @langchain/core/tools.DynamicStructuredTooldialog_tools
- массив инструментов, связанных с отдельными диалогамиdialogs
- массив задействованных диалогов, которые подключены через dialog_tools. Используется для вспомогательных целей, если нужно получить доступ к данным диалога в процессе отладкиapp
- объект langchain CompiledStateGraph - скомпилированный граф данного ИИ-агентаthread_id
- идентификатор основного диалога. Как правило указывается UUID пользователяsystemPrompt
- стартовая инструкция агента.config
- Объект вида{ configurable: { thread_id: this.thread_id } }
, используемый для считывания и идентификации состояния диалога из хранилища (checkpointer).is_active
- boolean (default true). В случае True - агент ведет диалог от своего имени, в ином случае подключает вспомогательный диалог.
Методы класса
Основные:
build()
- вызывается ПОСЛЕ того, как к агенту подключены все иснтрументы и диалоги. 1. Компилирует граф для агента 2. Восстанавливает состояние данных из хранилищаinvoke(message)
- Обрабатывает сообщение пользователя. Параметр message: string | undefined Подробнее см. описание ниже.reg_tool
reg_dialog_tool
- методы регистрации инструментов и диалогов, используемые в агенте.getObserver
- метод передачи наблюдателя, который наблюдает за вспомогательным диалогом. См. раздел "SupervisorObserver".
Вспомогательные методы:
get_state
- получить данные текущего состояния диалогаget_system_prompt
- получить текст системного соообщения (с уже подставленными данными об инструментах)store
/restore
- сохранить/восстановить метаданные диалога (на данном этапе сохраняется только поле is_active, остальные данные хранятся в checkpointer
Особенности работы метода invoke(message)
При запуске метода возможны следующие варианты:
- Диалог инициируется в первые, причем диалог начинает сам агент. В этом случае message = undefined. При этом если история общения (checkpointer) пустая, то null направлять нельзя, соответственно, агенту направляется следующий промпт:
SystemMessage('Пользователь только что начал диалог. Расскажи ему, что ты умеешь, и предложи
начать со знакомства и рассказа о его профессиональном опыте и интересах. Если он согласится,
задействуй соответствующего помощника из тех, которые тебе доступны.')
Диалог уже был начат ранее. В этом случае проверяется значение поля
is_active
:- true - общение ведет супервайзор
- false - общение идет в отдельном диалоге
Исходя из значения этого поля либо агент общается сам, либо восстанавливает работу соответствующего вспомогательного диалога и инициирует его.
Разница между tool
и dialog_tool
tool
- стандартный инструмент, используемый в ИИ-агентах. Граф взаимодействия agent -> tool -> agent
,
предусматривает, что агент возвращает пользователю результаты выполнения соответствующей функции.
dialog_tool
- инструмент, в основе которого работает отдельно настроенная LLM. В этом случае
граф взаимодействия agent -> dialog_tool -> END
, поскольку dialog_tool
перехватывает диалог.
SupervisorObserver
Используется в качестве наблюдателя (паттерн программирования "Observer") от "супервайзера"
при работе отдельного вспомогательного диалога. Является наследником класса Observer
из библиотеки
@dialogai/dialog-observers
Используемый промпт:
Сейчас диалог ведется от имени помощника, который {0}
Ниже в блоке, ограниченном символами === представлено текущее сообщение пользователя.
Твоя задача - определить, хочет ли пользователь перейти к диалогу на другую тему,
за которую отвечает другой помощник, или хочет воспользоваться каким-то из инструментов.
===
{1}
===
Ответь "False", если сообщение пользователя не содержит желания перейти к другому диалогу
или решать другую задачу.
Если пользователь хочет перейти к диалогу на другую тему, за которую отвечает другой помощник,
или хочет воспользоваться каким-то из инструментов, верни имя этого помощника или инструмента.
Или верни "САМОСТОЯТЕЛЬНО", если запрос пользователя не относится к какому-то из твоих помощников
или инструментов.
Больше ничего не отвечай.
В плейсхолдер {0} подставляется описание (description
) для соответствующего dialog_tool
,
которое обычно (и этого нужно придерживаться) начинается со слов: "Используется для..."
.
Создание экземпляра
При создании экземпляра наблюдателя в качестве параметра передается экземпляр "супервайзора",
от имени которого работает наблюдатель.
Например, метод getObserver
класса DialogSupervisor
выглядит следующим образом:
getObserver(){
return new SupervisorObserver(this);
}
Свойства и методы класса
Класс наследует свойства класса Observer
, дополнительно в нем предусмотрено свойство supervisor
.
Также в классе переопределяется метод pre_check
, который анализирует пользовательское сообщение.
В случае, если наблюдатель посчитает, что пользователь хочет переключиться на другую задачу или прервать
выполнение текущей задачи, наблюдатель выполняет следующие действия:
- Присваивает значение
true
свойствуis_interrupted
текущего диалога и свойствуis_active
"супервайзора". - Запускает метод
invoke
в экземпляре "супервайзора", с передачей в него сообщения пользователя. - Присваивает полученный ответ "супервайзора" свойству
interruption_message
текущего диалога.
Свойство is_interrupted
дает текущему диалогу сигнал прекратить работу и вернуть значение свойства interruption_message
.