0: Всем привет с вами, Сергей Трощенков. И в сегодняшнем туториале хотелось бы вас погрузить в обновлённый фреймворк лонгчен. На протяжении 24 года я снимал целую серию роликов.
1: По работе с ллм как раз на базе этого фреймворка, но вот этой осенью случились достаточно существенные обновления во фреймворке, о которых стоит нам с вами пого.
2: Говорить, если вы раньше не создавали своих собственных агентов или ллм приложений, не взаимодействовали с ллм по апишке.
3: Я вам настоятельно советую, прежде чем погружаться в этот ролик, посмотреть предыдущий мастер класс с конференции ai journey под названием создай своего 1.
4: Ii агента это вам поможет погрузиться в тематику получше, если вы новичок, ну а после мастер класса вам уже будет проще раз.
5: Браться и в материале этого туториала. Если же вы опытный разработчик, то давайте вместе с вами продолжим. Что же нового нас встречает в
6: В ланкене заявляется, что теперь главная абстракция это функция криейт эйджен.
7: Она позволяет создавать агентов по так называемому реакт паттерну. Что это означает? Реакт расшифровывается как ризонинг и acting, то есть в
8: Внутри этого агента есть 2 основных компонента, собственно модель, которая принимает решение, что делать на следующем.
9: Шаге. Стоит ли обратиться к какому-то внешнему инструменту из числа доступных этому агенту, или стоит выдать окончательный ответ пользователю и
10: 2 вот компонент acting, он состоит из некоторого перечня доступных инструментов.
11: Инструменты возвращают модели, свои результаты работы, которые воспринимаются вот этим ризонинг компонентом.
12: Как наблюдение здесь под ризонингом, понимается не то, что обязательно рассуждающая модель, а просто тот факт, что ллма
13: Выступает в качестве органа, принимающего решения. И, соответственно, мы с помощью такого агента можем решать различные задачи.
14: Подавая на вход запросы, предполагающие использование каких-то внешних инструментов и решение поставленной задачи на протяжении нескольких
15: Итераций, в ходе которых модельная часть агента, вот эта ризонинг, часть выбирает тот или иной инструмент, получает результаты его выполнения.
16: Принимает вновь решение и так выполняется до тех пор, пока модель не решит, что собрала достаточно сведений для полноценного ответа. И вот этот полноценный
17: Wet возвращается уже пользователю надо сказать, что в абстракциях ланчей, а как прошлых версий, так и вот обновлённой, текущей.
18: Мы имеем дело с различными сообщениями пользовательский запрос это human месседж ответ модели как в виде окончательного ответа отправляемого пользова.
19: Так и ответа, предполагающего запуск 1 из доступных инструментов, какой-нибудь поиск в интернете, обращение к внутренней.
20: Базе знаний все что угодно да, это будет определённого вида месседж и tool месседж у нас это наблюдения, возвращаемые от инстру.
21: В нашу модель вот такая диаграмма. Мы будем с вами реализовывать сегодня примеры в рамках этой диаграммы.
22: Мы с 4 инструментами представим себе, что у нас агент, который работает с скьюлайт базой данных и в рамках работы с этой
23: Скьюлайт базой у него есть 4 instrumental, ну, по сути отвечающие за crud функциональность, допустим, в базе данных есть 1 лишь таблица, содержащая.
24: Информацию о каких-то задачах. Допустим, это просто некий трекер задач команды и соответ
25: Соответственно, есть 4 инструмента, которые создают задачу, показывают список задач, позволяют изменить текущий статус задачи или удалить задачу. Ну а каждая
26: Запись о конкретной задаче обладает идентификатором, имеет текстовое описание, может иметь 1 из статусов туду инпро.
27: Да, может обладать некоторым приоритетом просто в виде целого числа. Ну и может обладать неким дедлайном, но это не обязательное поле, вот на основе
28: Такого сперва базового агента, а потом некоторой дополнительной функциональности. Мы и рассмотрим текущие возможности, лангена. Для этого мы, собственно, перейдём уже к такой более практической
29: Части установим необходимые библиотеки я все выполняю в google, коллаборатор в google, коллаборатор на самом деле уже добавили новый ланчей там, по моему, даже на текущий момент.
30: Ланчей 1, точка 1 точка 0 версии ну и добавлю сборку ланкей GigaChat, которая как раз исполь.
31: Для совместимости с лонгчен 1 0 её тоже мы устанавливаем для того, чтобы выполнить работу с базой.
32: Данных, собственно, нам необходимо эту базу данных иметь. Давайте посмотрим, что у меня сейчас пустая папка и никакого файлика с базой данных нет. Мы создадим
33: Сейчас вот базу данных для этого у нас будет специальная функция init db, которой мы воспользуемся 1 раз. Вот она здесь у нас вызывается, в которой.
34: Создастся просто наша табличка под задачи. Ну и также мы будем использовать функцию подключения к базе данных. Эта функция у нас будет фигурировать внутри наших инструментов в дальнейшем. Что ж, давай.
35: Выполним эту ячейку кода и обнаружим, что у нас появилась пустая база данных таскс диби. Далее далее перейдём к созданию фун.
36: Функционала нашего агента начнём мы с того, что создадим 4 instrumental необходимых для агента, для этого мы будем создавать фун.
37: Функции эти функции мы будем оборачивать в специальный декоратор тул. Ну и помним, что раз это инструменты для агента, то по
38: Всего прочего, хорошо нужно документировать наши вот эти инструменты, поскольку вот это докстрингов, её описание будет попадать в контекст.
39: Модели для того, чтобы инструктировать её о том, как инструментами пользоваться. Вот у нас есть инструмент для добавления задачи, как уже говорил, внутри каждого инструмента.
40: Мы будем подключаться к базе данных, ну и функционал для того, чтобы добавить задачу простой эскью лайт запрос. Далее запрос, который
41: Демонстрирует, что задача добавилась и возвращение строки, форматированной для того, чтобы проинформировать агента, что задача успешно создала.
42: Ну и аналогичным образом создаются остальные функции, инструменты, перечень задач. Мы смотрим вот таким образом.
43: Возвращается нам здесь список из задач с информацией о их статусе, приоритете и так далее. Также у нас есть функция для обновления 100.
44: По задаче, как мы видим, здесь примерно тоже самое. Ну и функция по удалению конкретной задачи из базы данных тоже у нас здесь
45: Представлено мы видим, как здесь будут выполняться запросы с командой delete.
46: И выводиться. Строка о том, что та или иная задача удалилась или не была найдена, так тоже, может быть, несколько секунд занимает создание инструментов, оборачивание их в
47: Специальный декоратор. Ну и дальше, собственно, нужно создать непосредственно агента. Для этого у нас вот представлен следующий код, мы будем использовать модель GigaChat.
48: Модель от гига чата, что мы здесь задействуем, помимо всего прочего, нам для того, чтобы создать агента
49: С памятью понадобится чек поинтер мы передадим в абстракцию криейт эйджент модель, инструменты и этот самый чек.
50: Кроме того, поскольку мы будем работать с чек поинтером, нам нужно добавлять при каждом вызове конфигурацию, в которой будет содержаться тред ай.
51: И то есть идентификатор диалога, связывающий разрозненные состояния агента в единый такой общий диалог. Давайте выполним эту ячейку.
52: И также в отдельной ячейке у меня записан, записана переменная, отвечающая за сам самого агента, сам объект агента.
53: Её можно вызвать в отдельной ячейке. Тогда у нас отрисуется схема, очень похожая на ту, что я показывал в
54: Нарисованном виде чуть ранее единственное отличие здесь то, что в виде пунктирной стрелки также показано соединение между узлом тулс и узлом.
55: Model вообще обычно в вот этой нотации схем, рисуемых с помощью мермет в Ланграф, теперь и в лангене.
56: Пунктирные линии предполагают условный переход, то есть вот почему стрелочки пунктирные в направлении n узла и в направлении тулс узла из модал в принципе.
57: Понятно, потому что есть развилка, можно пойти таким образом, можно пойти таким образом, что означает пунктирная стрелка между тулс и modaal не совсем.
58: Всем понятно. Вот здесь некоторое расхождение с классическим реактом встречается, но потом мы увидим, что там и более экзотичные варианты.
59: У нас тоже будут встречаться, значит ну, агента мы создали, но пока что никак им не пользовались, то есть не производили обращение к нему давайте мы это исправим, для этого возьмём и через метод invoke.
60: Вызовем агента, передав ему в виде human месседжа ну вот здесь он записан не в виде объекта того класса human месседж, а в виде словаря.
61: Состоящего из Роли, но все равно это пользовательское сообщение. Мы видим, что роль у нас юзер и контент собственно того текста, на основе которого, который выступит как Пронт и будет передан в модель.
62: Что мы здесь видим? Здесь достаточно много текста написано, суть которого заключается в том, что мы передаём в рамках 1 промта сразу несколько задач на
63: Добавление в таблицу конкретно 3 задачи. Давайте посмотрим, как справится с этим у нас агент.
64: Вот мы видим, что ему требуется некоторое время для того, чтобы выполнить добавление всех 3 задач. Ну и чтобы визуализировать, мы вот таким образом через метод прити,
65: Текст можем наглядно показать, что же там происходило в агенте. Мы видим, что вот такой запрос по добавлению 3 задач был закинут.
66: В агента и агент вот в своих, э, мессенджерах начинает действовать, начинает вот эту стадию ризонинг, он принимает решение о том, что нужно
67: Вызвать инструмент по добавлению задачи с определёнными параметрами. Таким образом, добавляет 1 задачу в
68: Ответ от instrumental получает наблюдение о том, что такая-то задача с такими-то параметрами была добавлена, следом происходит ещё 1.
69: Обращение к инструменту, добавление ещё задачи тоже ответ, тоже добавление, ещё задачи. Снова ответ. И после этого мы видим, что не сразу
70: Обращается агент к пользователю, а решает, что ему нужно посмотреть, действительно ли все задачи добавились. Поэтому он вызывает инструмент, лист, таск, да, чтобы посмотреть, что же
71: Там есть, получает ответ и уже на основании этого ответа формирует окончательный ответ для пользователя. Мы видим, что в итоге у нас все
72: Заканчивается эй ай мессенджер, направленным для пользователя. Дальше мы встретим примеры, что на самом деле не всегда будет у нас заканчиваться. Эй.
73: Месседже, но об этом мы посмотрим дальше. Но, по крайней мере, вот чистый реакт агент у нас получился без
74: Каких-либо сложностей. Мы можем проверить, что действительно этот react агент отработал, и это все не галлюцинации. Хотя, ну понятно, что рабо.
75: Инструментов, это уже не даёт ему поводов для таких Наглых галлюцинаций, но также вот у нас тут есть функция, делающая запросы к
76: Базе данных без использования ллм. Вот мы можем увидеть, что действительно внутри нашей базы данных 3 задачи, о которых говорилось в запросе пользователя. То есть агент у нас
77: Справился, но это у нас был такой, скажем, ванильный реакт агент. Давайте посмотрим, какие возможности для более тонкой настройки этого
78: Шаблона реакт агента есть в ланчей. Возможно, многие из вас слышали про термин контекст, инжениринг, и нужно сказать, что новый обновлённый ланген как раз-таки
79: Во многом базируется на использовании тоже этой концепции контекст, инжениринг, и поэтому предполагается, что мы контекст, инжениринг будем активно.
80: Использовать для тонкой настройки нашего агента, что понимается под контекст инжинирингом. На самом деле под контекст инжинирингом понимается то, что агент выполняет по
81: Поставленную пользователем задачу в некоторое количество Шагов. И на каждом этапе на каждом шаге нужно для того, чтобы получать нужный результат, нужно
82: Снабжать агента правильным контекстом, подавать ему на вход правильную исходную информацию. И тогда мы будем получать на выходе правильные ответы. Значит, ну и для того,
83: Чтобы вот манипулировать контекстом в рамках ланчей. А подчеркну сейчас, что речь именно про ланген, на самом деле, контекст, инжениринг это
84: Более широкое понятие и другие фреймворки могут, значит, работать с контекст инжинирингом по своему. Здесь у нас предполагается, что мы можем управлять контекстом на 3 уровнях.
85: У нас есть model контекст у нас есть tool контекст и у нас есть lifecycle контекст значит что же из себя представляет контекст модели это означает, что мы можем каждый раз?
86: Когда происходит запрос к модели, перехватывать то содержимое, которое предполагается к отправке в модель, и модифицировать его, каким образом можно менять сообщения си.
87: Системные сообщения текущего запроса, там как-то ужимать контекст, убирать из перечня предыдущих сообщений что-то лишнее и так далее мы можем
88: Давать не все инструменты, а давать только те инструменты, которые нужны для данного шага конкретного. Мы можем определять, какой структуры должен выдаваться.
89: Ответ. Ну и некоторые другие манипуляции относятся у нас к вот этому модал контексту. Некоторые примеры мы посмотрим. Также мы можем манипулировать, да, это вот
90: Мы манипулируем тем, что приходит на вход модели, причём это не перманентные изменения вот этого контекста, а это именно то, что мы перехватываем и подкладываем в обраще.
91: Модели, но оно не сохраняется, как правило, в истории диалога, в истории сообщений. Это важно понимать. Ну это мы все посмотрим, когда у нас происходит
92: Все-таки вызов какого-нибудь инструмента, то мы можем оперировать вот этим тул контекстом. Значит, что здесь подразумевается далеко не все, что tre
93: Для нормальной работы того или иного инструмента можно отдать на откуп ллм. Мы знаем, что какую-то персональную информацию, да, там ключи.
94: Доступа к тем или иным инструментам, ещё какие-то вещи. Во первых, ллм не всегда может их хорошо заполнять, во вторых, не всегда безопасно ей передавать, а лучше вообще не передават.
95: Поэтому вот добавление вот этих сущностей при вызове инструмента так, чтобы ллм даже не подозревала, что
96: При работе инструмента это как-то используется вот мы посмотрим как с этим можно работать и есть lifecycle контекст это
97: Ставка в наш граф на некоторых этапах каких-то дополнительных стадий обработки это могут быть какие
98: Стадии проверки того контента, который, не знаю, идёт на вход инструмента, например, или ответов инстру.
99: Мента, подаваемых в модель и так далее. То есть сюда относятся какие-нибудь гардрейл, удаление персональных данных и многое мно.
100: Другое вот для того, чтобы манипулировать контекстом, но не внутри узла модели, не внутри узла тулс все, что посерединке, как правило.
101: Предполагает создание дополнительных узлов для графа. Мы это тоже увидим. Как правило, их относят к лайфсайкл контекст. Ну, несколько подробнее про это.
102: Вы можете почитать как вот здесь, в блокноте, так и в документации, где-то тут, мне кажется, ссылочка и на документацию про это все должна быть. Ну и
103: Также важной вещью, с которой вы столкнётесь важной абстракцией в рамках контекст инжениринга, будет middle ware, понятие middle ware.
104: Которая предполагает, что мы создаём некоторую прослойку. Перехватчик для обработки контекста существует.
105: 2 основных реализации вот этих мидл вееров. 2 основных разновидности, что мы можем создавать обёртки для обращения к модели, для обращения к инструментам для
106: Обращение к агентам, там вот есть и таким образом манипул манипулировать, то есть не создавая отдельные новые ноды, и есть мидлверы, которые не стесняясь, добавляют
107: В виде отдельной ноды к графу, изменяя вот классическую архитектуру, реакт паттерна. Ну все, мы это посмотрим постепенно. Давайте мы
108: Рассмотрим сперва на примере контекста модели, на примере того, что мы будем подкладывать системный промт с схемой нашего нашей базы данных.
109: Именно при обращении к модели, при этом внутри истории сообщений вот этого системного промта появляться не будет. И сделаем мы это за счёт вот этого мидл Вера.
110: Который будет создан с помощью специального декоратора, которым мы обернём специальный метод, специальную функцию, да, которую создадим.
111: Создадим функцию, когда мы вот делаем такие обёртки для middleware, на вход этих обёрток мы должны подавать специальные объекты, мол,
112: Requests это в принципе сущность, которая содержит весь контекст и всю необходимую там служебную информацию о запросе, который отправляется.
113: Модель. И также нас будет интересовать объект модул респонс, который в виде такой обёртки колоба тоже. Да, с module.
114: Quest и модул респонс подаётся внутрь вот этой функции, выполняющей роль мидера. Значит, как это работает давайте посмотрим.
115: На код, что мы на вход подаём по сути, все необходимое для запроса, по сути это функция перехватчик и phonk.
116: Модификатор вот того контекста, который подаётся на вход модели. Мы здесь самостоятельно описываем логику вот этого перехвата.
117: Мы берём переменную со схемой нашей базы данных и подставляем её в системный промт. А системный промт
118: Подставляем в начало списка сообщений. То есть, по сути, он оказывается перед пользовательским запросом. Ну а при последующих
119: Обращениях к модели, да, поскольку у нас цикл неопределённое количество раз, который выполняется каждый раз вместо запроса без системного промта, у нас получается, добавляется вот этот
120: Системный пром с описанием таблицы в нашей базе данных. Ну и дальше получается, переписывается перечень сообщений, да, в
121: Module реквесте и обновлённый вот этот вот модел реквест таким образом у нас уходит в нашего агента каким образом это прописано? А вот таким образом, что
122: Мы добавляем ещё 1 атрибут к нашему агенту миддл very middle ware может содержать в себе целый список различных вот этих.
123: Промежуточных модификаций контента, поэтому он записывается в виде списка. Ну а в остальном все как обычно, мы таким образом собираем агента, ну,
124: И, допустим, мы просим добавить ещё 1 задачу. Помним, что у нас в базе данных сейчас 3, и добавить таким образом 4 задачу для нашего
125: Агента. Значит, давайте посмотрим, как это будет выглядеть. Вот у нас сперва выводятся сообщения, это те сообщения, которые в
126: У нас формируются, да, вот этот список сообщений и мы можем посмотреть, как выглядит этот же список сообщений, но
127: Именно в истории сообщений мы видим, что у нас в итоге выполнялся цикл работы агента. Несколько раз первичный запрос. Вот мы видим, что пользовательский
128: Prompt у нас уходил, уходили, уходил системный промт, дальше все пополнялось другими сообщениями, сообщениями от ллм, сообщениями, от инструмента.
129: При том, что в итоговой истории сообщений никакого вот этого системного промта.
130: Давайте двигаться дальше. Посмотрим, как ещё можно модифицировать контекст модели. Можно уменьшить количество доступных инструментов. Ну,
131: Вот давайте посмотрим как это может быть реализовано, представим, что в agent мы передаём контекст в виде, ну как бы дополнительных параметров, можно сказать.
132: Что это некое окружение при запуске агента добавляется, которое, например, содержит информацию о режиме работы нашего агента. Пусть у него
133: Несмотря на то, что есть 4 доступных инструмента физически, в зависимости от того, в каком режиме он работает режиме планирования или режиме выполнения применения.
134: У него в контексте перехватывается и обновляется список инструментов. Ну вот допустим, что при планировании у него нет инструментов для модификации.
135: Базы данных, у него есть возможность только посмотреть список доступных инструментов. Ну и вот мы видим такую обёртку мидл эр, которая предполагает, что
136: Мы из вот этого окружения берём информацию о том, какой режим работы у нашего агента. И если этот режим предполаг
137: Планирование, то мы оставляем лишь 1 доступный инструмент. Ну и также на самом деле подбрасываем, подсовываем системный промт, но можно было
138: Бы и без системного промта все это реализовать, потому что просто у агента была бы доступна только 1 Тула. Ну давайте.
139: Добавим ещё и системный промт. И вот мы видим, что в результате деятельности вот этого Мидлер у нас переписывается список сообщений с добавленным, получается системным промтом и
140: Список инструментов и все это помещается в соответствующее значение мидл вер при создании нашего нового агента, то есть физически
141: Значит, передаётся все 4 instrumental, но по факту агент в режиме плэн будет видеть только 1 инструмент, а вот plan у него.
142: И apply режим зависит от того, что мы передадим в контекст скима, да, вот эти дополнительные параметры, которые у нас будут фигурировать так?
143: Смотрим, видим, что при этом структура нашего графа агента не поменялась. Ну, потому что наш мидл вер представляет из себя все равно обёртку над
144: Обращением к модели, да, вот мы видим, что это рэп модал кол, поэтому ничего не меняется. Ну и давайте проверим, как это работает. Попросим удалить последнюю
145: Задачу из списка задач, при том, что режим у нас. Пусть будет плэн. Посмотрим, что на это будет делать агент.
146: Нужно несколько секунд вот мы видим, что в plan mode.
147: Агент пытается посмотреть список задач, видит, что в конце у него проверить структуру бд задача, но удалить он её не может.
148: Тогда посмотрим, сможет ли удалить задачу, то есть точно такой же пользовательский запрос у нас поступит, но если контекст агента предполагает режим.
149: Apply, все остальное остаётся у нас точно таким же, даже, даже конфиг мод у нас тот же самый конфиг, то есть это тот же самый тред. Мы сейчас
150: Видим, что здесь у нас уже была попытка удалить, но тогда мы были в режиме плэн и, соответственно, ни
151: Чего не получилось, мы кидаем точно такой же запрос внутри этого же контекста и видим, что теперь агент у нас удачно выполняет.
152: Поставленную задачу и задача по проверке структуры бд успешно удаляется.
153: Итак, мы посмотрели, как в рамках контекста модели можно подменять сообщения, можно подменять список инструментов. Есть ещё 1.
154: Интересный способ модификации контента модели это получение структурированного ответа это уже не middleware, а по сути такой structure.
155: Когда мы хотим получить ответ от модели окончательный в виде джейсонки с определёнными полями. Ну вот, давайте попробуем полу.
156: Получить информацию о задачах, которые есть в базе данных в виде определённой структуры, пусть у нас задачи возвращаются в виде списка.
157: С некоторым описанием от агента, в то время как каждая задача будет иметь тоже свою структуру.
158: Для того, чтобы реализовать вот этот track черт аутпут в лэлэка, во фреймворках, которые работают с ллм, активно использую.
159: Пайдентиком модели, позволяющие вот в виде классов описывать, какие структуры нам нужны на выходе. Ну вот, давай.
160: Мы эти структуры зададим и построим агента, который будет отличаться тем, что у него появится вот этот параметр, респонс формат, в который
161: Мы, собственно, подставим интересующую нас структуру, внутри которой будет ещё и другая структура. Такая вот некоторая вложенность у нас получится, а заодно давай.
162: Посмотрим, как будет выглядеть получившийся агент, вот он уже будет достаточно серьёзно отличаться от классического реакт паттерна.
163: Видим, что здесь у нас дополнительные какие-то переходы между узлами. Откуда они берутся давайте я кратко скажу и потом мы по
164: Смотрим, как это будет работать. Мы видим, что из узла тулс у нас есть отдельная стрелочка в узел n. Это связано с тем, что на самом деле вот тот
165: Класс в виде айдентикой модели, которую мы создали, он на самом деле будет таким своего рода дополнительным тулом, который будет автоматически подкладываться в контекст.
166: В конце работы агента, когда агент принимает решение о том, что больше он ни в какие Тулы не пойдёт, а будет писать окончательный ответ для пользователя именно
167: Тогда, значит, он получит вот этот вот инструмент для того, чтобы выполнить его, да, ну, заполнить необходимые значения и
168: Мы увидим, что последним сообщением, которое вернётся пользователю, будет не ai месседж, а именно tool месседж с вот этой необходимо.
169: Структурой, значит, большинство моделей для надёжности получения вот этого стракера аутпут как раз используют подход, когда интересующая структура получается.
170: Из такой квази Тулы квази инструмента, но есть и модели, поддерживающие нативную генерацию структурированного ответа, специально для них реализована. Вот.
171: Какая петля из узла модели обратно в этот же узел модели это, по сути, ретрай ретрай на случай, если структура с 1 раза нормально не получится. То есть
172: При валидации вот этой структуры, что она не соответствует формату, происходит повторная попытка генерации. Ну а в остальном, наверное, у нас граф не
173: Отличается. Давайте посмотрим, как это отрабатывает на практике. Давайте мы закинем задание агенту добавить задачу в нашу таблицу с определённым
174: Там параметрами и посмотрим, как это отработает. То есть у нас должен появиться структурированный ответ на выходе в виде тул мессе.
175: Давайте посмотрим. Да, действительно, в конце, после добавления мы видим тул месседж, в котором explanation, что было сделано.
176: И список задач. Задача такая-то задача другая, задача 3 и так далее. То есть вот у нас инструмент отра.
177: Работал, да, вот этот вот структурированный ответ как инструмент отработал ещё 1 замечание относительно нативно поддерживающих моделей. Вот структурированный ответ это open аевский.
178: Наверное, модели в 1 очередь, если вы попробуете подключить open и i к вот таким образом описанным инструментам, вот как у нас в виде просто
179: Обёртки тул над функциями питоническим, там может вылезти ошибка, что эти инструменты не проходят валидацию. Опять же, там по
180: Пайдентику там лучше Тулы описывать тоже через айдентикой классы, но это немножко отход в сторону, просто имейте ввиду что mode.
181: Или open eye могут быть немножко привередливее к тулам именно в случае, если вы будете подключать к ним структурированный ответ. Вот двигаемся дальше, да.
182: У нас на очереди примеры с контекстом инструмента, как я уже сказал, для работы инструментов часто может
183: Быть необходимо передавать в инструменты какие-то параметры, но не средствами модели, не модель должна заполнять все чувствительные поля.
184: Поэтому в instrumental реализован такой вид абстракции, как tool рантайм, который мы будем подставлять в инструмент.
185: И модель не будет видеть вот всех тех параметров, которые передаются в рамках этого рантайма. И кроме того, за счёт вот этих
186: Дополнительных параметров мы можем тоже там внутри выстраивать определённую логику. Ну давайте рассмотрим это на примере пусть мы модифицируем нашу такую наиболее чувствительную
187: Наверное, функцию инструмент delete task давайте представим, что у нас есть 2 вида пользователей с различными правами. У нас, допустим, есть пользователи прос.
188: Юзеры и есть администраторы. И у, и тех, и тех, в принципе, может быть режим, уже знакомый нам.
189: Допустим, plan и apply, и механика, пусть у нас будет такая, что у нас. Ну, давайте я, может быть, лучше в коде непосредственно покажу.
190: У нас, если мы имеем дело с админом, функция delete, сталкиваясь с тем, что администратор имеет мод плен.
191: При 1 запросе к функции delete task будет изменять вот этот вот режим на apply и выводить сообщение, что
192: Если агент действительно хочет удалить ту или иную задачу, он должен повторно ещё раз вызвать тот же инструмент с теми же параметрами.
193: И поскольку там режим уже поменяется с plan на apply, то уже сработает удаление без каких-либо проблем, а обычный пользователь с модом плэн.
194: Ничего сделать не сможет. В плане удаления ему будет возвращено сообщение о том, что у него нет прав для выполнения этой операции. Что нам для
195: Выполнение вот этого демо примера понадобится. Помимо того, с чем мы уже сталкивались. Давайте мы вот эти дополнительные параметры относительно пользователей будем хра.
196: В отдельном стородже. То есть, по сути здесь у нас будет такая своего рода долгосрочная память. Причём, в принципе можно реализовать и чтобы агент
197: В ходе своего взаимодействия с пользователем эту память пополнял. Но в рамках вот этого простого примера мы единовременно пропишем, что у нас есть 2 пользователя. И вот 1
198: 1 из них администратор, а другой из них обычный пользователь, и сохраним это в некую долгосрочную память, которую мы будем вызывать из не из
199: Модели, а вызывать из инструмента. Ну и перепишем логику нашего инструмента. Делит таск. В чем будет отличие, что по
200: Помимо того параметра, который, да, аргумента, который будет у нас заполняться моделью, а именно это идентификатор задачи, которую нужно удалить, ещё подспудно будет передаваться вот этот вот Тула тайм кот.
201: Который у каждого пользователя будет свой. И дальше у нас описывается вот как раз логика, что если пользователь у нас просто юзер, то у него нет никакого права на
202: Ему будет просто возвращено сообщение о том, что у него нет прав. А вот если у нас администратор и у него режим плэн, то у него вот этот режим.
203: При 1 обращении поменяется на apply, я такую механику использовал, чтобы вот как раз продемонстрировать способность инструментов перезаписывать вот эту долгосрочную память.
204: И возвратится сообщение, что с теми же параметрами надо ещё раз вызвать. Если агент действительно уверен в необходимости удаления задачи. Ну вот давайте посмотрим.
205: Как это отработает для агентов с различными правами, да, для различных, как бы, пользователей. Вот мы создаём агента с чекпоинтом, с контекстной
206: Схемой там просто у нас будет указан как бы id пользователя. Вот тут у нас были созданы 2 пользователя с разными правами.
207: И давайте, собственно, создадим агента, посмотрим, как будет выглядеть граф нашего агента. Он выглядит как обычно. Давайте проверим как обычный пользователь.
208: Сперва сможет отработать задание по удалению задачи из базы данных он должен, по идее, попробовать использовать
209: Инструмент и получить сообщение о том, что у него нет на это прав. Давайте проверим, посмотрим.
210: Так что мы видим сначала мне нужен полный список задач. Покажи мне список. Вот он вызывает список, видит, пытается удалить, но ему приходит
211: Сообщение от инструмента, что у него нет прав. И с этой информацией он возвращается к пользователю. А теперь давайте попробуем тоже самое провернуть с again.
212: Пользователем, да, у которого есть админские права.
213: Вот что мы здесь видим, мы видим, что происходит у нас происходит, у нас тоже запрос списка пытается удалить.
214: Ему приходит информация о том, что он в режиме плэн и что ему нужно ещё раз попробовать для того, чтобы действительно подтвердить факт необходимости удаления. Он ещё раз выпол.
215: Запрос и на этот раз удаление проходит успешно. То есть мы и с помощью Тула, по сути, переписали вот эту вот долгосрочную память о режиме, в котором работает агент и
216: Выполнили задачу по удалению. Вот таким образом мы разобрались с чтением и записью контекста, который не должна видеть модель, но который
217: Чрезвычайно важны для механики работы инструментов. И вот это хороший, в принципе, подход, что у вас доступы зависят от
218: Того, какого уровня у вас как бы пользователь, какие права должны быть у пользователя, такие права должны быть и у агента, которому он поручает задачи в ваш
219: Информационных системах. Ну ладно, надеюсь это понятно. И давайте рассмотрим ещё 1 важный вид контекста. Это контекст вот между узла
220: Получается модели и инструментов, что туда можно подставлять промежуточные какие-то этапы обработки. Например, мы можем
221: Да, какие-то ограничения поставить. Давайте мы рассмотрим реализацию ограничений на примере такого важного компонента, как human in the loop хьюман ин зе лууп, да, добавление.
222: Пользователя, который подтверждает правильность там выбранного инструмента. Это очень важно. Ну и, наверное, точно пользователь должен был бы у
223: Подтверждать вызов инструмента по удалению задач. Но давайте мы сегодня практически не задействовали ещё 1 инструмент это вот
224: По изменению статуса. Давайте у нас пользователь будет подтверждать изменение статуса по задачам и это как раз-таки то, что будет у нас делать.
225: Human in the loop. Для этого в ланкене есть готовый мидлвеер, так и называется human in the loop мидлвеер, в параметры которого можно задать.
226: Следующие вещи можно задать. Какие решения можно принимать, как правило, там 3 на выбор. И вот можно взять все 3 или взять какое-то меньшее.
227: Количество. Ну вот я взял 2, это апруф и реджект. То есть подтвердить, значит, вызов инструмента по обновлению состояния за
228: Дачи или отказать в вызове этого инструмента. Ну и также описывается, для каких это инструментов будет использоваться. Ну вот.
229: Мы берём и прописываем здесь, для каких это не должно использоваться. То есть вот для 3 оно прописывается как false. То есть если агент будет вызывать любую из этих любой из этих 3 инструментов.
230: Human in the loop не выскочит, а вот если будет, соответственно, инструмент, который апдейт, вот он наткнётся на прерывание.
231: В ходе которого нужно получить подтверждение от пользователя, ну и, в общем то, это добавляется как middleware, на вид ничего сложного каза.
232: Бы по human in the loop есть отдельный раздел в документации на сайте лонгчена, но несмотря на то, что вот здесь как бы ничего не произошло, если мы посмо.
233: Смотрим, как выглядит у нас агент, его граф, точнее, мы увидим, что вот эти именно life cycle контекст мидл.
234: Они, как правило, представляют собой отдельные вот такие узлы внутри графа, ну и помимо того, что это
235: Отдельные узлы у них ещё и дополнительные дополнительные стрелочки таким образом появляются. То есть что мы здесь видим, что в принципе из модели у нас все
236: И её месседжи, получается, пойдут через вот этот мидл вер, который фильтрует. Значит, что из ответов можно отправить в tools без подтверждения, что нужно полу.
237: Подтверждение от пользователя. Или если пользователь даст отказ, то нужно отправить обратно в модель. Ну а что представляет из себя конечный ответ пользователю?
238: Который нужно отправить в узел n. Вот такая примерно логика. Ну и давайте посмотрим, как это все встраивается, встраивается. Это
239: Средством класса команд. Это важная тоже такая абстракция в Ланграф, которая позволяет добавлять какие-то условные переходы.
240: Дополнительные. Ну и здесь как это будет работать? Давайте смотреть, что мы осуществляем запуск нашего агента в ходе
241: Запуска. Значит здесь у нас запрос заключается в том, что нужно все задачи, какие есть в базе данных, пометить как выполненные.
242: И если мы в ходе работы агента натыкаемся на интерапт, то происходит следующее действие.
243: В цикле, можно сказать, да, происходит обработка вот этого интерапта. Будет выводиться инпут для того, чтобы человек
244: Выбрал подтвердить или отклонить предлагаемое действие, а действие у нас будет как раз по изменению статуса той или иной задачи, и это будет выпол.
245: Несколько раз, поскольку у нас там несколько незавершённых задач в базе, соответственно, давайте тоже посмотрим, как это будет выполняться. Вот мы видим, что после
246: Подтверждение у нас будет происходить снова запрос к нашему агенту. Ну и что мы видим? Вот у нас произошло 1 прерывание в ходе выполнения действия.
247: По апдейту мы видим, что это у нас таск айди 2. Есть такая задача, и нас, соответственно, просят подтвердить или не подтве.
248: Давайте будем подтверждать все там их 3 или 4 задачи. Ага, вот мы столкнулись со следующим интераптом тоже давайте подтвердим.
249: Так, 3 раз. Ну и посмотрим, там 3 их или 4 неподтверждённых.
250: Ага, вот у нас, в принципе, 3 получилось неподтверждённых задачи. И если посмотреть, что происходило в списке сообщений, мы увидим, что вот у нас исходный
251: Запрос от пользователя в ответ на него агент запросил список задач, увидел, что у него в наличии 3 незавершённых задач.
252: И, соответственно, по очереди каждую из них он вызывал, да, инструмент по обновлению статуса этот инструмент, соответственно, триггерил у нас хьюман.
253: In the loop ожидалось подтверждение от пользователя, пользователь все подтверждал, и в итоге все задачи были выполнены.
254: И мы имеем состояние дан по всем 3 задачам. Ну а если мы бы отклонили какую-то задачу, эта информация бы тоже пришла в агента и
255: Соответственно, он бы учитывал это при дальнейших своих действиях. Ну а как мы видим, что без каких-то отклоне, ну, отказов?
256: Подтверждая каждую задачу, мы, в общем то, не видим никаких изменений в списке сообщений. Агент ничего, таким образом даже может
257: Не подозревать о том, что его действия на самом деле подтверждаются пользователем. Ну вот это буквально 1 пример для вот этого общего контекста.
258: Lifecycle контекст, там есть ещё примеры, посмотрите обязательно документацию, например, примеры на суммаризации.
259: Просто, поскольку они не очень в тему, как мне показались, наших кейсов с работой по базе данных я суммаризации включать не стал из документа.
260: Но, тем не менее, это тоже важный и показательный пример. В принципе, все, что я вам хотел сегодня рассказать и показать, показал, надеюсь, что вот этот, но
261: Unchain вас заинтересовал, вам стало понятнее, ну и вы готовы проводить свои собственные эксперименты, внедрять агентов в свои процессы, ну?
262: Если остались какие-то вопросы или если вы увидели что-то ещё интересного в документации по лангену милости, прошу в комментарии. Спасибо, что выдержали это.
263: Был достаточно длинный туториал. Надеюсь, что