- Autogen-conveyer
- Класс агентов ClI_Agent
- Два варианта реализаци класса CLI_Agent
- Типизация агентов autogen
- Агент повышения точности
- Обмен универсальными агентами autogen
- Conveyer2Autogen
- Conveyer2Autogen pipeline
- разбор пайплана Conveyer2Autogen
- Ссылочная модель общения агентов
- Conveyer2Conveyer
- Результаты работы
Autogen-Conveyer - полностью автоматизированный подход, позволяющий создать многоуровневую систему для выполнения комплексных задач колоссального спектра направленности, составными частями которой являются отделы агентов-LLM (групповые чаты autogen) направленные на определённые задачи.
Также Autogen-Conveyer не разделим от функционального подхода: "1 отдел - 1 функция" и "1 агент - 1 подфункция". Точности данного подхода также способствует и грубая форматизация информации (вплоть до шаблонизации результата каждой подфункции). Именно это даёт нам возможность пользоваться Autogen-Conveyer как многоуровневыми системами нейросетей с высокой точностью и безграничным спектром задач.
Доступ подфункций к интегрируемым инструментам просто поражает. Например, с помощью Autogen-Conveyer можно легко реализовать систему где один отдел имеет доступ к LLAVA и с помощью подфункций анализирует подаваемое на вход изображение/видео, а далее передаёт полученную информацию в отдел OSINT обработки где может реализовать поиск всей возможной подноготной информации от простых метаданных до координат местности изображённой в медиа и все это лишь на публичных источниках (лишь в целях обучения/ознакомления). Это лишь пример с двумя отделами, а их может быть безграничное количество.
Мы же решили использовать Autogen-Conveyer для автоматической генерации групповых чатов autogen (отделов) с правильно прописанными промтами, инструментами и function call и все это лишь по простому запросу пользователя. Наша основная проблема в реализации Autogen-Conveyer - это получение (парсинг) результатов отделов (групповых чатов). Мы представляем реализацию решения данной проблемы как output_parser в langchain LCEL. Но у нас есть и своя идея. Мы можем использовать специального агента который будет выводить результат отдела вместе с тегом @final если все участники чата согласны, что это является финальным результатом. Если сообщений с этим тегом больше одного, то мы можем обращаться к этому агенту повторно запрашивая финальный результат. Это решение может свести парсинг огромной истории группового чата до примитивного поиска сообщения с словом "@final"
CLI_Agent - это класс агентов для постоянного анализа группового чата autogen и выполнения определенных функций при срабатывании условий. Эти функции делятся на два типа: &command_name
и !edit_memory
.
В памяти агента класса CLI_Agent может содержаться информация, которая должна считаться истинной для чата, в котором он участвует. Агент данного класса может использовать команду в формате !edit_memory <старое значение><новое значение> @Agent_name
, чтобы обратиться к обработчику команд и изменить в памяти определённого агента информацию, которая расходиться с той что находиться в его памяти. Таким образом, агент CLI_Agent может поддерживать точность и актуальность информации в групповом чате.
Если команда !edit_memory
является заготовленной, то &command_name
- это пользовательские команды. Например в конвейере Conveyer2Autogen есть отдел создания списка ролей. Мы тестировали этот отдел и нам всегда приходилось корректировать его работу писав на фидбэках: "выведи список полностью", "эта роль является лишней", "в списке слишком мало ролей - добавь ещё". Эту проблему решил Regulatory agent класса CLI_Agent использовавший пользовательские команды:
&cleared_out
- обозначает, что список написан неправильно и не касается задачи пользователя&add_more
- обозначает, что список слишком короткий и его нужно увеличить&only_list
- обозначает, что агент вывел что-то ещё кроме списка, что следовало исправить
Пользователь точно также может описать агенту класса CLI_Agent свои условия срабатывания и точно также получать верные результаты!
При использовании autogen очевидно, что правильным подходом является "один агент - одна функция", а поэтому есть два варианта реализации класса CLI_Agent.
1. Обработчик находиться изначально в AssistantAgent:
2. Обработчик является отдельным классом агентов:
Исходя из нашего опыта использования autogen - агенты бывают двух типов:
Всё чаще и чаще стали появляться исследовании о влиянии определенных манипуляций/мотиваций в промтах на качество ответа LLM. Мы решили собрать все промты из этих исследований (начиная с "От этого зависит моя карьера..." до "Сейчас май...") и создать агента, что будет подстраиваться под каждую роль в чате и перед тем как она что-то напишет улучшать её результат с помощью подобного "Франкенштейна". Мы назвали этого агента "Мотиватор" и используем его по сей день в autogen. Но этот агент точно требует доработки так как мы все понимаем, что даже одного слово в промте может испортить результат, а поэтому нужно досконально проанализировать комбинации промтов которые мы брали из исследований, а также их полезность, так как например шаблон "...я заплачу тебе 200$ за то что ты сделаешь это правильно" пришлось убрать так как он лишь ухудшает результат и автор этого шаблона ошибся в своей работе о чем писал в соц.сетях.
Раз даже у нас получилось сделать агента универсального типа, что может повысить точность группового чата autogen, то почему бы самому autogen не реализовать платформу где пользователи могут предлагать своих универсальных агентов, а лучшие результаты будут выкладываться официально либо на самой платформе либо на странице github.
Conveyer2Autogen - позволяет пользователю получить целый групповой чат autogen с правильно прописанными и протестированными промтами, интегрированными утилитами в агентов, а также function call. Также Conveyer2Autogen из-за своей простоты подхода "prompt --> answer и ничего лишнего" имеет свой TUI. Мы считаем это очень важной деталью так как это позволит большему количеству людей познакомиться с autogen и начать им пользоваться без написания кода
- Этот pipeline не точен так как должен быть больше как минимум в два раза так как мы должны использовать функциональный подход: "один агент - одна функция".
Здесь всё интуитивно понятно на входе промт пользователя, а уже на выходе список ролей. Здесь как раз таки видно как примерно будут встраиваться Regulatory Agent (класса CLI_Agent) и Motivator в групповые чаты autogen.
- Пример реализации в TUI:
Далее сгенерированный список названий агентов поступает в отдел подбора класса и хоть может показаться, что это достаточно простой процесс, ведь почти все классы будут одинаковые - на самом деле это не так. Также мы рассматриваем добавление RetrieveUserProxyAgent и RetrieveAssistantAgent в список подбора с возможностью автоматического заполнения RAG с помощью LLM_web_search, SerpAPI или других подобных инструментов.
- Пример реализации в TUI:
Этот пункт должен находиться в самом начале вместе с вводом промта от пользователя, но из-за технических неполадок он здесь (очевидно, что без доступа к llm пункт 1 и 2 невозможен..). В этом пункте мы не используем групповой чат autogen, а лишь запрашиваем API ключ и вставляем его в llm_config. Важно заметить, что API ключ не обязательно должен быть от ChatGPT, он также может быть и от textgen-webui, а поэтому пользователь может использовать и open-source модели. Также уже разработан вариант сборки мультимодельных конфигураций.
Как вы видете в этот отдел данные поступают уже в формате:
________________________________________
| 1. AgentName | llm_config | Class name |
| N. AgentName | llm_config | Class name |
|________________________________________|
Очень важные нюансы, что не удалось отобразить в pipeline:
- Prompt engineer пользуется определенными правилами для написания промтов. Вот часть этих правил:
- Prompt engineer заполняет определенные универсальные шаблоны. Например:
Обозначание личности: <вставь сюда имя агента>, "ты находишь в групповом чате по" <опиши здесь задачу группового чата в котором находиться агент>
...и т.д.
Такие шаблоны могут быть просто огромными их мы обычно называем: промт-структуры и они достаточно сильно повышают точность так как ограничивают ответ LLM в строгих рамках.
- Мы хотим проводить комплексный анализ промта с помощью promptfoo, prompt-testing-framework, prompttools, promptimize для огромного скачка точности.
Как вы видете в этот отдел данные поступают уже в формате:
_________________________________________________
| 1. AgentName | llm_config | Class name | prompt |
| N. AgentName | llm_config | Class name | prompt |
|_________________________________________________|
Очень важные нюансы, что не удалось отобразить в pipeline:
- Если нужный инструмент не был найден в RAG - пользователь может дать нам его код в txt файле и мы правильно интегрируем его
- Поиск и интеграция инструмента производится не для каждого агента - мы не должны перебарщивать с ними
Данный отдел состоит из нескольких подотделов:
- анализ нужен ли агенту function call
- поиск function call и его добавление
- написание function call и его добавление
Данные в этот подотдел поступают в формате:
___________________________________________________________________
| 1. AgentName | llm_config | Class name | prompt | tool (optional) |
| N. AgentName | llm_config | Class name | prompt | tool (optional) |
|___________________________________________________________________|
Всё показано достаточно примитивно и без половины вспомогательных агентов так как мы считаем, что этого достаточно для простого ознакомления.
Как раз-таки здесь мы видим что подотделы можно использовать при срабатывании определенных условий. Любой отдел не готов к любым данным, но если типов данных всего два, то почему бы не сделать два подотдела для работы с каждым.
это финальный этап любого конвейера, а именно в этот данные поступают в формате:
______________________________________________________________________________________________
| 1. AgentName | llm_config | Class name | prompt | tool (optional) | function call (optional) |
| N. AgentName | llm_config | Class name | prompt | tool (optional) | function call (optional) |
|______________________________________________________________________________________________|
Именно здесь мы запускаем чат для пользователя где он может получить свой идеальный ответ.
Нам очень сильно мешал тот факт, что лишь один агент пишет одному (при чем соблюдая определенную очередь) - это очень сильно замедляет процесс работы группового чата поэтому в более больших отделах мы добавили "ссылочную модель" каждому агенту. Что такое ссылочная модель? Грубо говоря это абстракция для агента о том как обращаться в одном сообщении сразу к нескольким людям используя @ чтобы отмечать каждого по нику. Лишь это маленькое дополнение в разы увеличило производительность и эффективность чата. Сюда конечно можно прикрепить огромное количество скриншотов, но все работает примерно по одному шаблону:
Role_Name (to chat_manager):
@Role_name_2 ....text...
@Role_name_3 ....text...
@Role_name_4 ....text...
Это хорошая альтернатива орекстратору, но для её работаспособности нужно откатить pyautogen до версии 0.1.14
Если Conveyer2Autogen позволяет нам получить лишь один отдел (групповой чат), то по задумке Conveyer2Conveyer позволяет нам получить огромное количество отделов и связать их для передачи данных вплоть до сборки.
Например, запрос пользователя это сделать полноценную игру на python. Под полноценной я подразумеваю не только python скрипт, но и например звуковое сопровождение, хорошее визуальное оформление, проработанный сюжет и т.д. Очевидно, что обычный групповой чат autogen (всего лишь один отдел) не способен справиться с этой задачей. Полуавтоматический инструмент Conveyer2Conveyer должен быть способен предоставить пользователю n-количество уже готовых отделов и выстроенную цепочку их взаимосвязей вплоть до сборки. В примере с полноценной игрой на python, Conveyer2Conveyer должен предложить пользователю отделы разработки кода, музыкального сопровождения (с инструментом link1 или link2), интерфейса (link3), сюжета и т.д. Это всего лишь 4 отдела (не считая отдела сборки) осознание того что под запрос пользователя Conveyer2Conveyer может предложить и 20 и 30 отделов просто поражает.
Реализация Conveyer2Autogen и Conveyer2Conveyer может являться большим шагом для autogen, а в особенности для autobuild, но лишь маленьким шагом для IntelliLex. Для нас эти два инструмента являются лишь способами автоматического создания конвейеров/отделов в огромных комплексных системах нейросетей. Да, это огромная оптимизация процессов которая может сократить целые месяцы работы всего лишь до одного вечера. Также это привличение новых пользователей для autogen и в целом популяризация этой технологии так как не нужно писать код, а чтобы получить желаемый результат достаточно написать свой запрос и вставить API ключ. Но LLM стремительно развиваются с каждым днём и каков смысл если их мощности мы не используем в полную силу? Я бы даже сказал, что почти и не используем так как ста отделовую систему можно построить и на одном mistral-7b из textgen-webui! Опираясь на законы Натана Мирвола из доклада microsoft "ACM97: The Next 50 Years of Computing" мы можем смело заявить, что по аналогии развитие LLM не эффективно без развития операционной части его использования. Мы улучшаем лишь одну ногу хотя наша задача это бег и в нем очевидно задействуются обе ноги. В наших планах еще много грандиозных проектов на технологии конвейеров/отделов, а поэтому я могу смело заявить, что это большой шаг для autogen и маленький шаг для IntelliLex.