Transcription
Я представлюсь через мгновение, но мне хотелось бы немного узнать о вас. Итак, вы видите, что на экране представлены два бренда. Это OpenAI agents SDK, в частности, и Temporal. Я работаю в Temporal. Я расскажу о себе через секунду. Мне интересно, сколько человек сегодня используют OpenAI agents SDK? Хорошо, примерно четверть из вас. Есть ли другие фреймворки для агентов? Хорошо, примерно та же часть из вас. Похоже, есть довольно много тех, кто еще не использует фреймворк для агентов. Так что я немного расскажу вам об этом. Хорошо, следующий вопрос. Сколько человек работают с Temporal? Не очень много. Отлично. Я научу вас кое-чему. Итак, сегодня мы поговорим об обеих этих технологиях. Я буду говорить о них по отдельности, но также уделю много времени их совместному использованию. Спойлер: у нас есть интеграция между двумя продуктами, над которой Temporal и OpenAI работали вместе. И вы увидите, что это действительно очень здорово. Итак, позвольте мне очень кратко представиться. Меня зовут Корнелия Дэвис. Я разработчик-адвокат здесь, в Temporal. Я думаю, большая часть моей карьеры прошла в области распределенных систем. Так что мне очень повезло быть в Pivotal, работая над Cloud Foundry с начала 2010-х годов. Так что я была там во время движения к микросервисным архитектурам, распределенным системам и подобным вещам. Есть ли здесь люди, работавшие с Cloud Foundry? О, всего несколько. Итак, для тех из вас, кто не знает Cloud Foundry, Cloud Foundry была ранней контейнерной технологией на рынке. Она была инкубирована как проект с открытым исходным кодом в VMware, и она использовала образы контейнеров, Linux-контейнеры, оркестрацию контейнеров, конечную согласованность — все это еще до появления Docker и задолго до появления Kubernetes. Так что мне очень повезло, что я была там в начале этого движения к платформам, которые поддерживали этот более гибкий, распределенный подход к работе. И поскольку я так много времени провела в мире микросервисов, я также написала эту книгу.
Итак, сегодня мы поговорим об OpenAI agents SDK. Затем я дам обзор Temporal. Я проведу много демонстраций и покажу вам репозитории. Если вы хотите следить за мной, вы можете взять репозитории. Обе мои демонстрации были изменены сегодня утром, поэтому они находятся в ветках, а не в основных ветках, но я это очень четко обозначу. Там будет много демонстраций, а затем я перейду к комбинации OpenAI agents SDK и Temporal вместе, и мы также проведем там больше демонстраций. И затем я немного расскажу об оркестрации агентов в общем смысле. Итак, это блокнот, который я сегодня не буду использовать. Я провела этот воркшоп ранее на этой неделе и решила, что для аудитории AIE он был слишком базовым. Тем не менее, если вам интересно, вы можете перейти туда. Он проведет вас через него. Он настроен с помощью Jupyter Notebooks, вы можете запустить его в Code Spaces на GitHub, и вы можете запустить свой первый агент OpenAI agents SDK. Затем вы можете запустить свое первое приложение Temporal 101, а не агент, а Temporal-приложение. Затем вы можете пройти весь путь по повестке дня. Но это довольно базово, и я решила, что для этой аудитории мне хотелось бы сделать что-то более продвинутое. Так что сегодня мы этого использовать не будем. И я только что подготовила некоторые из этих демонстраций сегодня утром.
Итак, без дальнейших церемоний, это будет самая короткая часть презентации: я дам вам введение в OpenAI agents SDK. Он был запущен, кажется, примерно в мае. Я не буду читать вам эти слайды, и, чтобы вы знали, куда мы движемся, я буду использовать некоторые слайды, потому что я из тех людей, которые считают, что картинки действительно помогают. У меня здесь много диаграмм, но мы также потратим много времени на пошаговое рассмотрение кода. Я не думаю, что мне нужно определять, что такое агент. Я скажу вам, что лично я провожу различие между GenAI-приложениями и тем, когда они становятся агентами: когда мы даем LLM агентность, когда LLM сами решают поток приложения. Для меня это и есть агент. И такие фреймворки, как OpenAI agents SDK, разработаны, чтобы облегчить вам начало работы с ними. И на самом деле, мы увидим контраст с двумя основными демонстрациями, которые я покажу вам сегодня. Он доступен как на Python, так и на Typescript. И вот самое базовое приложение. Итак, вы видите, что мы определили агента. Мы дали ему имя и дали ему инструкции, а остальное он взял по умолчанию. Другие вещи, которые взяты по умолчанию, — это, например, сама модель. Я не знаю, какая модель по умолчанию сейчас. И тогда все, что вам нужно сделать после этого, это, по сути, запустить его. И всякий раз, когда вы видите runner.run, это соответствует агентному циклу. И мы будем говорить об агентном цикле несколько раз на протяжении всей презентации. Каждый раз, когда вы видите один из этих runner.runs, это его собственный агентный цикл. И когда мы дойдем до оркестрации позже, вы поймете, почему я делаю это различие. Как я уже сказала, здесь все очень просто, но есть много других опций, которые вы можете настроить в конфигурациях агента, которые управляют работой агентного цикла. У вас могут быть передачи управления. Мы поговорим об этом. Я уточню это позже. Но вы можете установить защитные ограждения. Вы можете добавить инструменты. И мы увидим, что оба моих примера сильно зависят от агентности LLM и его решений о том, какие инструменты использовать. Так что я покажу вам инструменты. Так что здесь гораздо больше возможностей, и я покажу вам примеры по мере продвижения. И действительно, это картина того, о чем я говорю: каждый из этих runner.runs, по сути, имеет цикл, который постоянно возвращается к LLM. И после вызова LLM он принимает решения. И если LLM, например, сказал: «Я хочу, чтобы вы вызвали какие-то инструменты», он их вызовет. А затем он возьмет вывод из инструментов и направит его обратно к LLM и продолжит. И LLM решает, когда он закончил следовать системным инструкциям, и мы увидим это.
Итак, это базовый обзор фреймворка агентов, и существует множество фреймворков агентов. Поскольку очень немногие из вас знают Temporal, я немного замедлюсь и расскажу вам больше о Temporal. Итак, Temporal — это проект с открытым исходным кодом. Он существует около пяти-шести лет. Так что, да, он значительно предшествует буму Gen AI, в котором мы сейчас находимся. Он предназначен для распределенных систем, а чем являются AI-приложения, если не распределенными системами? Так что оказывается, что Temporal прекрасно подходит для этой категории AI-вариантов использования. Сейчас он используется во многих не-AI вариантах использования. Например, каждый Snapchat проходит через Temporal. Каждое бронирование Airbnb проходит через Temporal. Заказы Pizza Hut, Taco Bell проходят через Temporal. Есть много других, которые я не помню. OpenAI Codex работает на Temporal. Так что теперь мы переходим к AI-вариантам использования. Codex работает на Temporal. Генерация изображений OpenAI работает на Temporal. Это два, о которых я могу вам рассказать. Это два, которые публично известны. Так что у нас есть много других, lovable работает на Temporal. Так что мы определенно добиваемся прогресса, много используем в сфере AI. Я рассказала вам, кто его использует, но позвольте мне рассказать, что это такое. Это распределенные системы как бэкэнд-сервис. Я думаю, все знакомы с понятием Redis как бэкэнд-сервиса, Kafka как бэкэнд-сервиса или базы данных как бэкэнд-сервиса. Итак, у меня есть мои приложения, которые работают, и я использую эти бэкэнд-сервисы для обслуживания, ну, для выполнения части моего приложения. Temporal — это бэкэнд-сервис. Он обеспечивает долговечность распределенных систем. Я объясню это яснее по ходу презентации. Что это значит, так это то, что вы, как разработчик, программируете счастливый путь. Вы программируете свою бизнес-логику. И бизнес-логика, которую мы будем программировать сегодня, — это AI-агенты. Так что вы можете сказать: «Знаете что, я хочу вызвать LLM. Затем я хочу взять вывод из LLM и, возможно, вызвать другие API, а затем вернуться к LLM». И вам не нужно строить логику, которая говорит, что произойдет, если LLM будет ограничен по скорости. Что произойдет, если мой нижестоящий API временно недоступен? Что произойдет, если мое приложение выйдет из строя? Вам не нужно программировать ничего из этого. Мы делаем это за вас. И я покажу вам несколько изображений, как это работает, через мгновение. Итак, есть Temporal-сервис, который является бэкэнд-сервисом. И способ подключения к бэкэнд-сервису — через SDK. И поэтому SDK находится рядом с вашей бизнес-логикой. Так что вы можете программировать свою бизнес-логику. И способ создания вашей бизнес-логики: вы оборачиваете определенные функции. И это позволяет SDK сказать: «О, подождите. Вы совершаете вызов нижестоящего API. Я вмешаюсь и предоставлю вам некоторую услугу. Я предоставлю вам повторные попытки. Если этот нижестоящий сервис будет успешным, я запишу это для вас. Я запишу ответ для вас, чтобы в случае, если что-то произойдет, и нам придется снова пройти через поток, я смогу просто получить результат, который вы вызвали ранее. Что это означает, например, если вы использовали Temporal для обеспечения долговечности ваших агентов, когда вы находитесь на 1350-м обращении к LLM, и ваше приложение выходит из строя, без проблем. Мы отслеживали каждый вызов LLM и ответ, и вы не будете повторно сжигать эти токены. Вот что это значит. Вот что означает долговечность в этой области. Мы официально поддерживаем семь различных языков программирования, но Apple всего пару недель назад выпустила Swift SDK. Так что поддержка есть практически на любом языке. Есть также экспериментальные вещи на Closure и подобных. Я сказала, что это проект с открытым исходным кодом. Подавляющее большинство имеет лицензию MIT. Осталось немного Apache 2 из Java SDK. Так что очень-очень разрешительные лицензии, и те из вас, кто не знает истории: Temporal был форком проекта, созданного в Uber под названием Cadence. Кто-нибудь знает Cadence? Да. Итак, несколько человек знают Cadence. Cadence — практически каждое приложение, работающее в Uber, работает на Cadence, и это потому, что они могут программировать счастливый путь, а вся долговечность просто обрабатывается за вас. Так что это своего рода обзор того, что такое Temporal.
Итак, есть два фундаментальных абстракции. Есть еще несколько других, но две фундаментальные абстракции, о которых вам нужно знать как разработчику, — это активность. И активность — это просто кусок работы. Это работа, которая либо совершит внешние вызовы. Так что это работа, которая может потерпеть неудачу. Это много работы, которая может потерпеть неудачу. Или если вы выполняете много работы, которую вы не хотите повторять в случае возникновения проблем, вы можете поместить ее в активность. Так что это такие вещи, как снятие со счета, внесение на счет. Мы перейдем к AI-вариантам использования через мгновение. Итак, это активности. Вы оборачиваете это. О, и я не упомянула, но SDK — это не просто тонкие обертки, которые находятся поверх REST API. Это SDK, где, как вы можете себе представить, обеспечение долговечности в распределенных системах означает, что все те алгоритмы, которые, как вы думали, вам пришлось реализовать, такие как забота о параллелизме и кворуме и все такое прочее, — все это реализовано в Temporal, и поэтому наши SDK содержат много этой логики. Сервис в основном занимается хранением данных. Так что в SDK много интеллекта. Итак, эти активности, если вы сказали: «Вот моя работа. Вот тяжелая работа или что-то, что идет наружу. Давайте добавим декоратор активности», то SDK говорит: «О, хорошо, я предоставлю вам особое поведение». Затем вы оркестрируете эти активности вместе в вашей бизнес-логике. И то, что мы называем этими оркестрациями, — это рабочие процессы (workflows). Итак, и вы увидите, что происходит, когда вы объединяете активности и рабочие процессы — именно тогда происходит настоящее волшебство. Есть некоторый уровень волшебства в активностях, и на самом деле мы только начинаем выпускать то, что мы называем автономными активностями. Так что вы сможете использовать активности без рабочих процессов и получить там некоторые преимущества долговечности. Так что происходит всякая эволюция. Но тип волшебства, о котором я говорю, когда вы объединяете рабочие процессы и активности, заключается в том, что я наложила кучу значков. Я наложила эти маленькие значки повторных попыток. Итак, вы указываете в логике рабочего процесса конфигурацию повторных попыток. Так что вы можете решить, будете ли вы использовать экспоненциальную задержку, будете ли вы использовать неограниченные повторные попытки, будете ли вы ограничиться пятью повторными попытками, будет ли у вас максимальное окно между повторными попытками. Вы можете настроить все это. И как только вы это сделаете и оркестрируете эти вещи вместе, теперь у вас есть повторные попытки. И вы увидите код через минуту, просто вызывая эти активности. Мне не нужно реализовывать логику повторных попыток. Мне не нужно реализовывать какую-либо другую логику. Это просто происходит для меня. Так что у меня есть повторные попытки. У меня также есть эти маленькие очереди. То, что выглядит для вас как единое приложение, — я вызываю это, затем вызываю это, затем вызываю это — каждый раз, когда вы вызываете активность, каждый раз, когда вы возвращаетесь из активности в основной рабочий процесс, все это осуществляется через очереди, так что то, что выглядит как простое монолитное приложение, уже превращается в распределенную систему. Так что вы можете развернуть множество экземпляров этих приложений и масштабироваться, просто развертывая больше экземпляров. Вам не нужно управлять очередями Kafka или чем-либо еще. Все это встроено. Я разговаривала с кем-то на этой неделе здесь, на AI Engineers, который является пользователем открытого исходного кода, фактически нашим клиентом, и я спросила его: это относительно небольшой стартап, и я спросила: «Почему вы выбрали Temporal?» И он сказал: «Потому что мы пытались построить все это с очередями Kafka, и в итоге мы тратили все наше время на операции с Kafka и 25% времени на бизнес-логику. Когда мы переключились на Temporal, мы тратим 75% времени на бизнес-логику, и они используют Temporal Cloud». Я не упомянула нашу бизнес-модель: у нас есть этот сервис, который мы предлагаем как SaaS. Так что они используют Temporal Cloud. Так что они, по сути, перешли с 25/75 на 75/25, перейдя сюда. Им больше не нужно управлять очередями Kafka или Redis или чем-либо еще. И говоря о Redis, вы видите в верхнем правом углу управление состоянием. И одна из вещей, которые мы делаем, — это отслеживаем, где вы находитесь в процессе выполнения вашего приложения. Мы делаем это, записывая состояние. Опять же, каждый раз, когда вы совершаете вызовы к активности и возвращаетесь, мы записываем это. По сути, это event sourcing. Вот что мы делаем. Это не только событийно-ориентированные архитектуры, но и event sourcing как услуга. Так что вы можете это делать. Итак, мы храним все это состояние, чтобы, если что-то пойдет не так, и я продемонстрирую это, мы увидим, как что-то идет не так, — оно продолжит с того места, где остановилось, потому что мы просто пройдемся по истории событий и продолжим с того места, где остановились. Так что эти маленькие значки, которые я показала, наложенные на логическую диаграмму, я отвечу на ваш вопрос через секунду. На самом деле, все эти сервисы находятся здесь, в сервисе. Так что они все долговечны. Так что это не то, что они живут в процессе, а живут здесь, в сервисе. У вас есть вопрос? >> Не уверен, что это релевантно. Многие агенты обрабатывают потоковые данные. Так что я хотел посмотреть, поможет ли это. >> О, отличный вопрос. Итак, да, вопрос был в том, что многие агенты, которых я создаю, работают с потоками. Вы занимаетесь потоками? И ответ на данный момент — простое нет, мы не занимаемся. Но это одна из вещей. И мой коллега сзади, Йохан, — глава отдела AI-инженерии. Так что поговорите с ним, поговорите с любым из нас. Это одна из двух приоритетных задач, над которыми мы сейчас работаем. Другая — хранение больших полезных нагрузок. Если у меня не будет возможности поговорить об этом здесь во время воркшопа, подойдите к одному из нас. Мы можем рассказать вам об этом. Вы можете представить, что такое хранение больших полезных нагрузок. Это то, что вы работаете с LLM, вы будете передавать большие объемы данных. Вместо передачи по значению, передавайте по ссылке. Вот что такое хранение больших полезных нагрузок. Это Йохан. >> Я просто упомяну, что есть много людей, использующих обходные пути. >> Верно. >> Потоковая передача в продакшене сегодня в масштабе. Так что я рад поговорить об этом, но будет более интегрированное решение. >> Да. Так что я просто повторю то, что сказал Йохан, на случай, если вы не смогли услышать. Итак, у нас есть клиенты, которые создали поддержку потоковой передачи поверх Temporal, но мы встраиваем ее нативно. Так что, да. Так что вы можете сделать это сегодня. Это просто немного больше работы. Это не счастливый путь. Итак, хорошо. С этим я хочу провести демонстрацию. Это будет моя первая демонстрация, которую я перенесу сюда. Посмотрим, смогу ли я вернуть свой экран. Хорошо. Итак, если вы хотите следить за мной, первое, что я сделаю, это перейду сюда, и я увеличу размер шрифта. Я укажу вам на два репозитория. Это на самом деле второй репозиторий, но то, что у меня сейчас на экране, — это если вы хотите начать с Temporal, очень просто, вам не нужно использовать Temporal Cloud. Вы можете просто запустить Temporal-сервис. Так что бэкэнд-сервис вы можете просто запустить локально на своей машине. Так что вы можете сделать это, используя curl. Вы можете установить его через Homebrew. А затем, чтобы запустить этот локальный сервер, вы можете просто сказать temporal server start dev. И теперь у вас есть Temporal-сервис, работающий локально. И все мои приложения здесь просто подключаются к моему локальному хосту. И мы увидим UI через мгновение. Я вернусь к этому репозиторию через мгновение. Репозиторий, который я собираюсь продемонстрировать вам, — это этот. И, извините, я не знаю, как увеличить размер шрифта, но вы можете видеть, что организация и репозиторий здесь — организация — temporal io. Там же вы найдете весь открытый исходный код Temporal. И тогда у нас есть что-то под названием AI Cookbook, и это один из примеров. Я фактически расширила пример сегодня утром, но вы найдете, что ветка, которую мы будем демонстрировать здесь сегодня, называется agentic loop de branch. Так что, если вы хотите вернуться и посмотреть на это позже самостоятельно, вот что мы будем смотреть. Хорошо. С этим, давайте перейдем к моему правильному терминалу. И вот где я буду запускать это, но я хочу сначала показать вам код. Хорошо. Итак, я в правильном? OpenAI. Нет. Это неправильный. Мой другой курсор. Вот оно. Это агентный цикл. Я провожу две демонстрации сегодня. И вот что вы видите здесь, слева, позвольте мне сделать его немного больше: помните, я говорила об активностях и рабочих процессах. Так что это первое, что я сделаю: я покажу вам активности. Помните, у нас были снятие и внесение, ну, такого рода вещи. Здесь, конечно, мы имеем дело с агентным циклом. Так что моими активностями будут вызов OpenAI API, еще не агентов SDK, просто OpenAI API и вызов инструментов. Итак, это мои две активности. Давайте посмотрим на первую, и вы увидите, насколько она проста. Я обещала вам счастливый путь. Это действительно так. Вот мой вызов API ответов OpenAI. Хорошо, это именно то, что вы ожидаете. Я передаю модель. Я передаю инструкции. Ввод пользователя будет поступать из моих инструментов, которые я покажу вам через мгновение. И тогда у меня есть некоторые тайм-ауты, которые я могу настроить. Это для OpenAI. Что я сделала, так это обернула это в функцию. Она принимает этот запрос. Так что все эти параметры пришли из запроса, который я передаю. И вы увидите, как я вызову это через мгновение. И вот эта аннотация. Теперь разные SDK имеют разные подходы. Например, TypeScript не требует кучи аннотаций. Он просто разбирается. Он знает, где находятся активности. Java имеет аннотации. Такого рода вещи. Но это Python. Так что вы можете видеть здесь, что у нас просто есть декоратор активности. Так что, просто имея этот декоратор, вы можете видеть, что это не сложно. Все, что вам нужно сделать как разработчику, это сказать: «Вот кусок работы, который я хочу сделать, который я хочу инкапсулировать в шаг». И вы просто ставите функцию, ставите декоратор активности. Так что я вернусь к вызывающему инструменту через мгновение, потому что здесь происходит что-то интересное. Итак, теперь, если мы перейдем к рабочему процессу, рабочий процесс также довольно прост. Итак, вот определение моего рабочего процесса. Вы видите, что это класс. Причина, по которой это класс, заключается в том, что когда вы создаете рабочий процесс, вы создаете основное приложение, которое я называю основным приложением, и именно оно имеет workflow.run. Но этот рабочий процесс также, я не буду рассматривать эти абстракции сегодня, но у нас есть несколько других абстракций, таких как сигналы. Так что для работающего рабочего процесса вы можете послать сигнал. И у нас также есть абстракция под названием обновление. Это особый вид сигнала. И у нас также есть аналог — запросы. Так что эти вещи добавляются к этому классу рабочего процесса как простые функции, аннотированные сигналом, обновлением или запросом. Поэтому у нас есть класс для рабочего процесса. И если мы посмотрим на логику здесь, вы увидите, что у меня есть while true. Так что это простое приложение — это та же картина, которую я показывала вам раньше, где я говорила, что LLM — мы просто повторяем цикл на LLM. И если LLM принимает такое решение, мы будем вызывать инструменты. Это все приложение. Но вы увидите, что я делаю пару интересных вещей с Temporal здесь. Итак, чтобы вызвать LLM, я выполняю эту активность. Так что вы можете видеть, что я передаю свою модель. Инструкции здесь, я не буду показывать вам, но вы можете увидеть все в репозитории. Полезный агент системной инструкции просто говорит: «Вы полезный агент. Если пользователь что-то говорит, и вы думаете, что вам следует использовать инструмент, дайте мне знать. Выберите инструмент. В противном случае отвечайте хайку». Вы увидите это через мгновение. Хайку — это как «hello world» в мире AI, верно? Мы все будем писать агентов. Это «hello world» в области агентов. Так что мы будем отвечать хайку. И это все. Так что мы делаем это в цикле while true. И у меня есть пара операторов печати. Вы увидите, как это работает через мгновение. Упрощающее предположение здесь. Я предполагаю, что он вызывает только один инструмент за раз. Так что я беру вывод из этого. А затем я просто смотрю на него и говорю: «Это вызов функции?» И если это вызов функции, то я обработаю этот вызов функции. Я покажу вам этот код через секунду. А затем я возьму вывод из этого вызова функции и добавлю его в историю разговора. Так что я не делаю никакого сложного инжиниринга контекста. Ничего такого. Я просто добавляю в конец истории разговора. Хорошо. Теперь обработка вызова функции также очень проста. Итак, первое, что я делаю, это добавляю ответ от LLM. Так что к тому времени, когда мы закончим этот вызов функции, мы добавим две вещи в историю разговора. Мы добавим ответ от LLM, который гласит: «Пожалуйста, сделайте вызов функции», а затем мы выполним вызов функции, а затем мы добавим результат. И я только что показала вам, где мы добавляем результат вызова функции. Итак, здесь я просто добавляю это к... И это часть «безумных» вещей. Я запускаю это приложение против API Gemini. И самая большая проблема во всем этом — это то, что форматы разные. Так что мне приходится переписывать, потому что JSON-форматы истории разговоров отличаются между разными моделями. Да, я знаю, что есть Light LLM, но я не люблю наименьшие общие знаменатели. И мне также нравится понимать, как выглядят эти форматы. Но вы можете видеть здесь, что я просто делаю некоторое уродливое парсинг, а затем я выполняю, помните, я обрабатываю вызов инструмента здесь, я выполняю активность с этим вызовом инструмента. Так что я извлек вызов инструмента из ответа от LLM, а затем я вызову эту активность, которая является execute activity, а имя элемента — это инструмент. Теперь одна из вещей, на которых я действительно настаивала здесь, — это то, что я не хотела создавать одно приложение с агентным циклом, которое делает один набор инструментов, а затем перестраивать совершенно другое, когда у меня есть другой набор инструментов. Сам агент, и мы слышали, я не помню, кто говорил об этом, но кто-то говорил об этом на сцене на этой неделе, где они сказали: «Смотрите, агентный шаблон — это довольно стандартный, и теперь мы вставляем вещи в этот стандартизированный агентный цикл», и именно это делают эти фреймворки AI, эти фреймворки агентов, и я хотела сделать это и здесь, в коде Temporal. Круто то, что у Temporal есть что-то под названием динамическая активность. Динамическая активность позволяет вызывать активность по имени, но эта активность динамически находится во время выполнения. Так что обработчик активности здесь, и я покажу вам код через секунду, по сути, возьмет это имя и скажет: «О, хорошо, я, и помните, это событийно-ориентированное. У нас есть активность, которая ждет чего-то в очереди. И поэтому вы можете настроить активность. Вы можете настроить один из наших воркеров, чтобы сказать: «Эй, это воркер, который будет просто брать что-либо из очереди активности. Неважно, как оно называется». Так что вам не нужно жестко привязываться к конкретному названию темы, например. Да. Вопрос. >> Мне нужно заранее сопоставить, какие инструменты будут доступны для агента на основе активности. >> Это отдельный вопрос, и я покажу вам этот модуль. Здесь есть модуль, который называется инструменты. Если вы видите каталог инструментов, то, как я запускаю это здесь, он загружает эти вещи во время загрузки приложения. Так что я не делаю никакого динамического загрузки, но я могу менять этот модуль инструментов, и код агента не меняется вообще. Так что я не дохожу до точки, где я реализовала реестр и делаю динамические вызовы этих вещей. Вы можете это сделать, но этот простой пример, по сути, поместил все это в отдельный модуль. И вы увидите, как этот модуль может быть заменен, потому что я загружаю его во время выполнения. Так что, упрощая, да, вы можете это сделать. Хорошо. Итак, я просто вызову активность. И давайте посмотрим, как выглядит эта активность. Это tool invoker. И поэтому вы можете видеть здесь, что у нее есть декоратор активности, как я показывала раньше, но теперь она говорит dynamic = true. Так что это означает, что этот обработчик активности будет брать все, что появляется в очереди, что не обрабатывается какой-либо другой активностью. Так что он будет брать get weather. Он будет брать get random number. Он будет брать все, что появляется там. Вам нужно зарегистрироваться. >> Вам нужно зарегистрироваться. Нет, вам не нужно регистрировать все это. Эти вещи могут быть сделаны динамически. Вам не нужно регистрировать их в воркере. И вы можете видеть здесь, что мы по сути берем это. Мы получаем имя инструмента. И тогда вы можете видеть здесь, что я фактически ищу функцию. Вы можете видеть здесь, что здесь нет названий инструментов. Он просто ищет название инструмента из словаря. И это метафорически словарь. Я покажу вам эти функции через секунду. Так что у меня есть одна функция, которая называется get tools, которая, кстати, позвольте мне вернуться к этому. Так что в OpenAI responses, нет, извините, это в рабочем процессе, когда я вызываю LLM прямо здесь. Обратите внимание, что я сделала этот вызов get tools. Я покажу вам этот вызов get tools через секунду. Он полностью вне сферы рабочего процесса и активностей. Он находится в своем собственном модуле. Я покажу вам эту функцию через секунду. Хорошо. Итак, вернемся к вызывающему инструменту. Он по сути берет имя, а затем выполняет get handler. Так что где-то здесь есть вызов get handler. Вот обработчик. >> Вы просто передали его. >> Я просто передала его. Извините. >> 17. >> 17. Спасибо. Я ценю это. Итак, вот get handler, и я покажу вам эту функцию через секунду. Так что отличный вопрос о том, насколько тесно связаны эти вещи. Позвольте мне показать вам, где эта связь сейчас. Итак, у меня есть модуль инструментов здесь, и в init я определила эти две функции. Так что у меня есть get tools, и get tools по сути просто берет список функций, и я покажу вам эти функции, и эти функции, которые мы передаем здесь, мы передаем JSON-блоки, которые передаются LLM в качестве описаний инструментов. Так что это описания инструментов. Так что, например, позвольте мне показать вам get weather. Так что, если мы перейдем сюда к get weather, вы можете видеть, что JSON-блок находится прямо здесь. И это интересно, потому что OpenAI в API completions имел публичный API, который позволял вам брать любую функцию с docstrings и генерировать JSON для API completions для инструментов. API ответов не имеет такого публичного API. Так что здесь есть предупреждение, что этот API, который я использую, который находится в этом вспомогательном инструменте. Я покажу вам вспомогательный инструмент. Где мой вспомогательный инструмент? >> Вспомогательные средства. Вот оно. Я думаю, я могла бы поместить это в инструменты. Есть ли там что-то, что говорит предупреждение. В настоящее время нет публичного API для генерации JSON-блока инструментов для API ответов. Так что я использую внутренний. Есть открытая проблема по этому поводу. Так что там просто предупреждение, что я использую внутренний. Так что, если мы вернемся туда, я использовала внутренний API, чтобы просто взять мой запрос на получение оповещений о погоде, который является моделью Pydantic, которая содержит функции и некоторую дополнительную метаинформацию. И она генерирует JSON-блок. Так что, опять же, это то, что вы видите, когда мы переходим к агенту: это то, что вы получаете с get tools: это массив JSON-блоков для каждого из инструментов. И тогда, как я уже сказала, get handler по сути имеет это. Это по сути словарь, который я реализовала как набор if-else. Так что он берет имя инструмента, а затем выбирает фактическую функцию, которая полностью независима. И поэтому этот конкретный пример имеет набор, и я продемонстрирую их вам через секунду. Он имеет набор инструментов здесь. И вы можете просто менять эти вещи. Вам все равно придется перезапускать процесс Python в данный момент, просто из-за того, как я это реализовала. Хорошо. В основном понятно. Хорошо. Позвольте мне показать вам это в действии. И вот что я делаю: я запускаю воркер. Я не буду тратить много времени, говоря о воркерах, но вы помните, что я сказала, что все это событийно-ориентировано. И поэтому есть что-то, что забирает работу из очередей событий, а затем выполняет правильные рабочие процессы и активности на основе того, что оно забрало из очередей событий. То, что делает это в Temporal, называется воркером. Так что воркер — это процесс, который вы запускаете. С этим воркером вы регистрируете активности и рабочие процессы, за которые этот воркер будет отвечать. Так что он будет искать что-то в очереди, чтобы забрать оттуда. Сам воркер многопоточный. Так что это не один воркер, один процесс. В целом люди запускают, зависит, вы можете настраивать воркер, но в целом люди запускают несколько сотен потоков. Так что вы запускаете один воркер, и это уже конкурентная многопоточная архитектура. Хорошо. Так что это солидные вещи. Temporal — это просто крутейшая штука. Это действительно распределенные системы. Хорошо. Итак, я запускаю воркер здесь, что, по сути, является местом, где вы увидите вывод из активностей и рабочих процессов. И я собираюсь запустить рабочий процесс. И давайте скажем, есть ли какие-нибудь оповещения о погоде в Калифорнии? Откуда я родом. И я думаю, что многие из вас оттуда, и, надеюсь, куда я вернусь сегодня вечером. И поэтому мы начнем. И вот что вы можете видеть здесь, как это приложение написано: по сути, я говорю, вызываю ли я инструмент. И поэтому вы можете видеть здесь, что оно сказало: «О, я сделал вызов get weather alerts». И это то, что происходит. Так что происходит вызов инструмента. И через мгновение, я знаю, что как только у нас выпадет несколько капель дождя в Калифорнии, вы знаете, повсюду оповещения. Так что вот, вот куча оповещений о погоде в Калифорнии. Вы увидите, почему я на это указываю. Это довольно забавно. Хорошо. Теперь позвольте мне показать вам, как это выглядит в Temporal UI. Итак, здесь у меня есть Temporal UI, и вы можете видеть, что я запустила кучу рабочих процессов сегодня утром. И поэтому, позвольте мне обновить. И это тот, который я только что запустила. И вот что мы видим: да, там все эти предупреждения о густом тумане. Это как бы крайность, которую мы получаем в Калифорнии. Немного тумана, немного ветра, сильные волны, опасности на пляже. Но вот что произошло. Так что вы можете видеть в Temporal UI, вы можете видеть каждую из тех активностей, которые я вызвала. Вы можете видеть, что я сделала вызов LLM. Это линия создания, которую вы видите внизу. Так что мы работаем снизу вверх. Затем вы можете видеть, что я сделала динамическую активность, но конкретно динамическая активность, которую я сделала, она не говорит «общая динамическая активность». Она говорит, что я сделала get weather alerts. И затем, как мы делаем с агентными циклами, мы берем вывод инструмента и отправляем его обратно в LLM, и получаем это. Теперь я хочу показать вам кое-что здесь. Я покажу вам другой пример. Так что я задам вопрос: есть ли какие-нибудь оповещения о погоде там, где я нахожусь? Знает ли она, где я нахожусь? И я начну это. И я очень быстро перейду сюда, и мы увидим, как это работает. И вы видите, о, я, похоже, буду слишком медленной, но я вернусь и повторю эту демонстрацию. Но вы видите, как она просто, знаете ли, принесла эти вещи. Так что, другие. У меня зарегистрировано три инструмента. У меня есть инструмент, который принимает состояние. У меня есть инструмент, который принимает IP-адрес и возвращает состояние. И у меня есть инструмент, который дает мне IP-адрес текущего компьютера. И поэтому я не подключила это так, чтобы LLM принимал эти решения просто на основе инструментов. Так что я просто предоставила эти инструменты. Но вы можете получить эту видимость в Temporal. Так что вы можете видеть, что мы начали с get IP address, затем мы получили информацию о местоположении из этого IP-адреса, затем мы получили оповещения о погоде. И вот ирония: в Нью-Йорке нет оповещений о погоде. Так что я думаю о Нью-Йорке как о месте, где погода гораздо более выражена, но, возможно, сегодня калифорнийская. У вас есть туман, но нет предупреждений о тумане. Так что вы гораздо более устойчивы, чем мы, калифорнийцы. Хорошо. Итак, я хочу показать вам еще кое-что, что я вернусь сюда. Я снова запущу это, и я постараюсь быть, я могу быть намного быстрее. Так что я нажму «ОК». И теперь я перейду сюда и нажму Ctrl+C. Никаких работающих воркеров. Мой агент не работает. Он вообще не работает. И поэтому, если мы перейдем сюда и посмотрим, как это выглядит в Temporal, и это даст вам самое четкое представление о том, что я подразумеваю под долговечностью и долговечными агентами, это то, что у меня работает этот агент, и вы можете видеть, что он сделал первый вызов LLM. Затем он получил вызов инструмента для IP-адреса, а затем он застрял. Он начал вызывать LLM, но подождите, что-то пошло не так. Сам агент не работает. И, кстати, я могла бы также провести демонстрацию, и у меня нет времени на все это сегодня, но я могла бы провести демонстрацию, где я отключила сеть. Так что я могла бы отключить сеть. И вы бы увидели здесь эту маленькую красную полосу: вы бы увидели попытку создания один, попытку создания два, попытку создания три. Я могла бы вернуть сеть, и тогда она бы прошла. Но для краткости, потому что я все еще хочу, у меня еще есть что осветить, я просто показываю вам один из сценариев сбоя. Есть тонны сценариев сбоя, которые покрыты. Так что я вернусь сюда и перезапущу воркер. И то, что мы должны увидеть, это, конечно, он продолжает. Так что он продолжил с того места, где остановился. Теперь, когда я говорю, что он продолжил с того места, где остановился, конечно, я убила процесс, в памяти больше ничего не работало. Так что, когда я вернула воркер, ему пришлось восстановить состояние приложения. Он сделал это через event sourcing. Так что именно так фундаментально работает Temporal. Есть ли вопросы по этому поводу? Да. >> Можем ли мы делегировать одного агента другому агенту? >> Можете ли вы делегировать одного агента другому агенту? Абсолютно. Сейчас у нас пока нет нативной поддержки A2A, если вы думаете об этом протоколе в частности. Но одна из вещей, которую вы, безусловно, можете сделать, это то, что агент может действовать как инструмент. И поэтому есть несколько способов сделать это. Вы можете либо иметь активность, вызывающую другого агента, либо использовать другие механизмы. У нас есть дочерние рабочие процессы и тому подобное. Я не буду рассматривать этот более продвинутый вариант использования. Но да, абсолютно. >> Пара вопросов. Одна вещь — это то, как вы кодируете, казалось, функции были очень атомарными. Была как бы одна строка, по сути. Как убедиться, что разработчики создают функции так, чтобы повторные попытки были очень частыми? >> Второй вопрос — задержка, добавленная из-за фреймворка. >> Хорошо, я отвечу. Итак, первый вопрос касается атомарности. Вы признали, что сами активности должны быть атомарными. Мы не требуем этого, мы не проверяем это, потому что мы действительно не вникаем во внутреннюю работу активностей. Мы оставляем это на усмотрение разработчиков. Но руководство заключается в том, что если они не атомарны, потому что помните, что когда мы делаем повторные попытки от вашего имени, мы не знаем, почему мы никогда не получили ответа от первого вызова. Так что мы будем продолжать повторять, пока не получим ответ. Конечно, может быть, запрос так и не дошел до активности. Может быть, он дошел, и он вызвал нижестоящую функцию, которая могла пойти не так во многих местах. Так как же убедиться, что ваши разработчики создают ваши активности атомарными? Образование. У нас нет серебряных пуль. Второй вопрос касался задержки, потому что да, я обращаюсь к серверу здесь с каждым из этих вызовов активности. И поэтому, когда мы думаем об агентах, мы, тип задержки, и Йохан, я не помню точных цифр, вы помните цифры? Я имею в виду, это крошечная задержка до сервера при каждом вызове активности. >> Это будет немного зависеть от того, где находится сервер, но это десятки миллисекунд. >> Десятки миллисекунд. Так что это довольно мало. Так что, я думаю, я слышала от нескольких клиентов, которые используют это в довольно реальном времени. Но в случае агентов, особенно агентов, которые долго работают и работают в течение минут, часов, дней, или у них есть взаимодействие с пользователем, десятки миллисекунд терпимы. Так что могут быть случаи, когда это неприменимо из-за этой задержки, но она довольно мала. Она применима в большинстве случаев. Хорошо. Хорошо. Итак, это обзор Temporal. Теперь я хочу вернуться к Agents SDK и показать вам различия и сходства. Итак, давайте вернемся сюда. Я пройдусь по нескольким картинкам. Хорошо. Итак, OpenAI Agents SDK, комбинация этих двух вещей на очень высоком уровне выглядит так. В основе лежат модели OpenAI и API OpenAI, а не SDK, а API OpenAI. Так что вы могли заметить, что я уже использовала API OpenAI, и теперь мы начнем использовать Agents SDK. И тогда у нас также есть Temporal как фундаментальный элемент. И теперь Agents SDK накладывается поверх этого. Так что это два фундаментальных компонента. Так что это не то, что Temporal сидит сбоку, или модели OpenAI сидят сбоку.
стороне. Мы фактически интегрировали эти вещи, и я дам несколько комментариев, когда мы дойдем до кода, о том, как мы осуществили эту интеграцию, и я полностью приглашу Йохана добавить к этому тоже, потому что он руководил инженерной частью интеграции здесь. Итак, теперь у вас есть SDK для агентов, и теперь вы будете использовать SDK для агентов для создания ваших агентов, для добавления защитных ограждений. Мы покажем вам трассировку. Я показал вам UI Temporal, но SDK для агентов также имеет некоторые действительно классные функции трассировки. И вы увидите, что мы интегрировали эти вещи вместе. Вы увидите, как они объединяются. И, конечно же, инструменты. Я говорил об этих временных действиях, и мы уже видели это. Я пропущу это. э, пропущу это. И вот теперь мы возьмем тот же самый пример, через который мы только что прошли. У меня будет три инструмента. Один — это API погоды, а два других — это API местоположения. И что мы будем делать? Ну, мы обернем их декораторами действий. И я покажу вам, как это выглядит в другом коде через мгновение. Мы убедимся, что у нас есть строки документации, потому что я показал вам, как API OpenAI имел внутреннюю вспомогательную функцию, которая позволяла нам генерировать JSON-блоки для описания инструментов. Так вот, SDK для агентов фактически делает еще больше для нас. Итак, вы увидите, что часть моего кода исчезла. И затем, да, и затем мы продолжим с этого. И тогда, и это будет наш цикл. Я покажу вам, когда мы дойдем до кода, что способ, которым мы создаем этот JSON-блок, является частью интеграции. Так что вы можете взять действие, и мы предоставили вам функцию под названием «действие как инструмент», которая примет действие, саму функцию. Так что вам не придется беспокоиться о сериализации самостоятельно. Никаких внутренних API. Это публичный API. Это часть интеграции. И вы вызовете «действие как инструмент», которое сгенерирует JSON-блок, и тогда у вас также могут быть свои тайм-ауты. Есть еще одна часть, которая очень важна, заключается в том, что вам нужно настроить интеграцию. Так что вам нужно, SDK для агентов сам по себе не использует Temporal, и если вы хотите использовать Temporal, вам нужно убедиться, что вы включили плагин, и я покажу вам код для этого через секунду. И тогда, конечно, мы запустим его, и мы запустим его тем же базовым способом. Хорошо. Давайте продемонстрируем это. Мы потратим гораздо больше времени на код и снова на демонстрацию. Позвольте мне вернуться к курсору. Хорошо. У меня есть четыре файла, которые я хочу вам показать. Я начну снова с действий. Вот действие получения погоды, и вы увидите, что оно стало немного проще. На нем просто декоратор действия для получения оповещений о погоде, а затем здесь функция, где оно фактически вызывает API Национальной метеорологической службы. Так что там был еще код, который выполнял некоторое форматирование, когда он делал этот вызов API для генерации JSON-блока, который исчезает, потому что у нас есть поддерживаемая функция для этого. Действия местоположения так же просты. Так что буквально это весь файл. Итак, у меня есть эти две функции с декораторами действий и мои строки документации. Так что строки документации описывают аргументы и так далее. Хорошо. Теперь что насчет самого агента? Помните, действия были просто тем, что они были инструментами, которые использовал агент. То, что я показал вам раньше, — это агентный цикл, написанный на Python, который оркестрировал вызов LLM и вызовы инструментов. Теперь, если я перейду к рабочему процессу, как выглядит мой рабочий процесс? Вот он. У меня есть, извините, вот он. Это рабочий процесс. Хорошо. И это, по сути, позвольте мне увеличить размер шрифта, потому что у меня достаточно места. Обратите внимание, что я использую SDK для агентов. Итак, я определяю агента прямо здесь, в строке 18. Я даю ему имя, ваш полезный агент, и я даю ему набор инструментов. Эти инструменты были реализованы как действия. И там вы можете увидеть, что я сделал вызов функции, которая говорит «действие как инструмент», которая генерирует JSON-блок. Вот и все. Это все, что нужно. Вот как я это реализовал. Теперь обратите внимание, что я все еще делаю это в рамках рабочего процесса, потому что помните, раньше я говорил, что у нас есть действия, у нас есть рабочие процессы. Когда вы объединяете их, вот где происходит магия. Так что помещение этого агента внутрь рабочего процесса — это то, что добавляет все эти возможности надежности. Я не буду демонстрировать недолговечную версию этого, потому что опять же, у нас сегодня ограниченное время. Но если бы я реализовал это только с помощью SDK для агентов, который является просто библиотекой Python, у меня был бы один процесс. И если бы я убил этот процесс, все бы исчезло вместе с ним. У меня нет возможности масштабировать этот процесс. И помните, у меня есть runner.run прямо здесь, верно? Так что каждый из этих исполнителей — это просто монолитный агент, верно? Это просто один процесс Python. Делая это таким образом, вы можете видеть, что если я запускаю несколько рабочих, я могу просто продолжать масштабировать это, просто запуская несколько рабочих, которые просто забирают другие вещи из очереди. >> Да. >> Работают ли передачи другим агентам? >> Работают ли передачи другим агентам? Да. И я вернусь к этому в последнем разделе, где мы будем говорить об оркестрации. Да, они работают. Абсолютно. Хорошо. Итак, теперь позвольте мне перейти к... Мне нужно достать еще одну вещь. Мне нужно достать моего рабочего. Где мой рабочий? Вот мой рабочий. потому что он находится в рабочем, где находится плагин? Йохан, помоги мне. >> Я только что передал его. О, вот он. Плагин OpenAI для агентов. Хорошо, так что это в рабочем. Помните, рабочий — это место, где происходит все выполнение. Думайте об этом как о своего рода логическом метафорическом контейнере. И часто вы запускаете рабочие процессы в контейнерах. И вот конфигурация, которую вам нужно туда поместить. Это те, и обратите внимание, что он делает такие вещи, как настройка некоторого поведения повторных попыток вокруг LLM. Вы заметите, заметили ли вы, что я не дал вам действие для вызова LLM, это делается как часть агента, но мы все равно хотим, чтобы это было надежно. И это одна из вещей, которые делает наша реализация здесь. Так что вы применяете некоторые политики повторных попыток для LLM и, по сути, говорите: «Эй, SDK для агентов OpenAI, используй эти части Temporal». Позвольте мне рассказать вам немного о том, что мы сделали в рамках интеграции. Что мы сделали, если вы вернетесь и посмотрите историю коммитов SDK для агентов OpenAI, вы найдете коммит, в котором говорится «сделать класс исполнителя абстрактным». Они сделали это для нас, потому что именно так мы реализовали, именно так мы добились этой надежности. Именно так мы смогли сделать вызовы LLM надежными вместе со всеми инструментами, которые вы только что видели. Так что у нас есть собственная реализация абстрактного класса исполнителя. Так вот как это работает. Хорошо. Итак, мы рассмотрели действия, мы рассмотрели рабочий процесс, а затем мы запускаем рабочий процесс инструментов. Так что я не думаю, что там больше нечего смотреть. Итак, давайте перейдем к этому. Позвольте мне найти мое правильное окно. Это это окно. Хорошо. Итак, что я делаю в этом окне, позвольте мне увеличить размер шрифта. Это в верхнем окне. Я выйду из этих, потому что мне нужно только два. Хорошо. Итак, в верхнем окне я снова запускаю своего рабочего. Вы видели это раньше. Так что я запускаю рабочего там. И так, там будет немного журнальных сообщений. А затем здесь я запускаю рабочий процесс. Здесь я взаимодействую с агентом. Так что я собираюсь, я только что отправил некоторые из этих вещей. О, я покажу вам репозиторий через секунду. Так что, есть ли какие-нибудь оповещения о погоде в Калифорнии? И помните код. Код — это просто этот агент, верно? Мы все еще реализовали наши действия, но код — это этот агент, и мы проверяем, и вы можете видеть вещи, которые там прокручиваются. Так что вы можете фактически видеть вызовы API к LLM. Вы можете видеть вызов API к Национальной метеорологической службе. И вот если мы вернемся к UI Temporal, это другой, он называется «рабочий процесс инструментов». Здесь вы можете видеть, что он выглядит точно так же, верно? И именно поэтому я хотел потратить время, показывая его вам с Temporal, потому что Temporal, если вы создаете эти нативные приложения Temporal, вы получаете всю эту надежность. Вы получаете эту видимость. Он выглядит точно так же, но вы использовали SDK для агентов для реализации ваших агентов, что, я думаю, просто потрясающе. Итак, давайте запустим второй. И я покажу вам репозиторий через секунду. Мы запустим этот второй пример, который заключается в том, есть ли какие-либо оповещения о погоде там, где я нахожусь. И мы перейдем сюда. Мы будем наблюдать за этим в процессе. Итак, он работает. И он работает точно так же. И я запущу его еще раз, когда он вернется. И он говорит: «Нет, ты в порядке в Нью-Йорке». Позвольте мне запустить его еще раз. Я дам ему начать. Частично продвинуться. Ctrl+C из этого. И мы вернемся сюда, и мы увидим то же самое, что видели раньше, верно? SDK для агентов надежен, что очень здорово. Я, я, я делаю это все время, но я все еще так взволнован этим. И вот он идет. Я поделюсь с вами способом интуитивного понимания того, что мы здесь делаем. Я пишу программное обеспечение более 30 лет. Да, у меня есть седые волосы, чтобы доказать это, верно? Я написал программное обеспечение, где, когда я пишу программное обеспечение, я думаю о процессах, в которых оно выполняется. Я думаю о том, что у меня есть процесс здесь, и что произойдет, если что-то случится с этим процессом, или когда я масштабирую вещи, и вещи могут не выполняться в тех же процессах, я всегда думаю о процессах с Temporal. Вы можете писать свою программу, думая о процессе как о логической сущности, и просто позволить Temporal сопоставить его с фактическими физическими процессами, которые там есть. Это особенно, это так здорово смотреть, когда вы делаете такие вещи, как «человек в цикле». Так что ранее на этой неделе я сделал еще один, я сделал еще один, один из докладов, которые я делаю, посвящен «человеку в цикле» с агентами, и одна из больших проблем «человека в цикле» заключается в том, что когда вы думаете о создании этих вещей и думаете о процессах, вы говорите: «Хорошо, мне нужно поработать некоторое время, а теперь я буду ждать человека в цикле, и это может занять секунду, это может занять минуту, вероятно, это займет часы или дни, прежде чем этот человек вернется». Что мне делать с этим процессом, который ждет этого ответа тем временем? Как вы, разработчик, должны это выяснить. С Temporal вы этого не делаете. Вы просто кодируете это так, как будто этот процесс. И кстати, архитектура рабочего процесса работает так, что если он ждет чего-то вроде ввода человека, он будет держать его в памяти некоторое время, несколько секунд, затем он вынет его из активной памяти, но он все еще находится в кэше. И через некоторое время он выйдет из кэша, и будет так, как будто вы только что убили этот процесс. Так что, когда он вернется через дни или недели, когда пользователь вернется и предоставит вам эту информацию, он просто восстановит память так, как она была, когда он ждал пользователя, и продолжит. Так что помните, я сказал, что это сбой или это могут быть другие вещи, операционные вещи, все эти типы вещей. Так что это так освобождает, как только вы начнете по-настоящему разбираться в этой штуке Temporal. Это так освобождает осознать, что мне больше не нужно думать о физических процессах. Для меня процессы просто логичны. Temporal позаботится обо всем остальном за меня. Супер крутые вещи. Хорошо, у нас осталось около 20 минут. Я пройдусь по паре слайдов, чтобы ответить на один из вопросов о передачах, и просто покажу вам еще немного контента, а затем у нас будет немного времени в последние, я не знаю, может быть, 10, 10 или 15 минут, я буду рад ответить на дополнительные вопросы, и Йохан, я уверен, тоже будет очень рад присоединиться. Хорошо. Итак, Итак, с SDK для агентов OpenAI. Это то, о чем я говорю здесь, несколько специфично для SDK для агентов, но это в целом обобщается на агентов в целом, что с SDK для агентов OpenAI. Парадокс, который они используют там, заключается в создании множества небольших агентов, которые имеют свои собственные независимые агентные циклы, а затем оркестрируют их вместе. И есть два способа оркестрировать их вместе в SDK для агентов. И я покажу вам оба через мгновение. Итак, то, что мы видим здесь на экране, — это просто пара диаграмм, например: «Хорошо, у меня есть агент триажа. У меня есть агент уточнения. Затем у меня есть человек в цикле». Это не агент. Хотя вы можете думать о человеке как об агенте в этом приложении, верно? Затем у меня есть агент инструкций, который будет создавать некоторые вещи. Затем у меня есть агент планирования. Затем вы можете видеть, что мы делаем вещи параллельно. Я не говорил об этом, но у Temporal есть все эти абстракции. Вы можете делать все, что можете написать на обычном языке программирования, вы хотите многопоточность и иметь кучу разных потоков и делать вещи параллельно, а затем ждать, пока они снова соберутся. Вы можете это сделать. Вы хотите иметь какой-то вид ожидания, который говорит: «Знаете что, как только они начнут поступать, я начну их обрабатывать». Нет проблем. Вы можете это сделать. Все, что вы можете сделать в коде, вы можете сделать с Temporal, потому что вы просто кодируете. Так что это, по сути, способ, которым это работает здесь с SDK для агентов. Я снова покажу вам эти вещи. Так что вы можете делать параллельно, вы можете иметь долгие ожидания. И вы можете иметь циклы. Я уже показал вам, что мне не пришлось создавать свою логику на Python. Логика, LLM принимали решения о том, как будет происходить поток в этом приложении. Правильно? Так что у меня просто был цикл, сам цикл как бы фиксирован, но то, что происходит в цикле, полностью определяется LLM. Так что это все вещи, которые вы можете сделать. Итак, есть два способа с SDK для агентов оркестрировать эти микроагенты. И кстати, я просто должен сказать, мне нравится термин «микроагент». Как я уже упоминал ранее, я провел много времени в мире микросервисов, и, боже мой, сколько мы из этого получили, верно? Это причина, по которой мы можем развертывать программное обеспечение несколько раз в день. Это причина, по которой мы можем масштабироваться так, как мы можем масштабироваться. Микросервисы доказали свою ценность. мы думаем, что мы увидим очень похожий парадокс, очень похожий успех, когда дело дойдет до создания агентов ИИ, инструментов MCP и всего такого. Так что мне нравится идея микроагентов, которые делают одну вещь и делают ее хорошо. Я провел достаточно времени в стране Unix, и это заставляет мое сердце петь. Так что просто код и передачи. Просто код очень прост. Это то, что я описал раньше. Так что вы можете видеть здесь, что у меня есть runner.run, я выполняю агента, я получаю результат от этого агента и передаю этот результат следующему агенту. Я могу распараллелить, я могу зациклить, я могу делать все, что хочу. Второй способ... О да, и я уже все это показал. Так что да. Да, я уже упомянул все это. Второй способ, которым OpenAI, и вы говорили об OpenAI конкретно, когда спрашивали о передачах? Да. Так что для тех из вас, кто не знает, у OpenAI есть второй способ оркестровки, который называется передачами. И вот что вы видите здесь: в моем определении агента я могу определять передачи. Эти передачи — другие агенты. Они были определены. Возможно, мне следовало бы иметь это на слайде, но у меня есть агент погоды, который определен очень похоже. У него есть имя, есть инструкции, могут быть инструменты. Так что это два агента. И все это работает с интеграцией с Temporal, но интересно то, что эти микроагенты, когда он передает агенту, он не выполняет отдельный агентный цикл. Он фактически, и это моя безумная попытка описать, что происходит здесь, заключается в том, что когда вы делаете передачу, вы фактически просто меняете контекст агентного цикла. Так что есть один единственный агентный цикл, у вас есть агент триажа, например, он решает, что он собирается перейти к доставке. Я работал в Alexa некоторое время. Так вы спросили, до скольки открыт Costco, или вы спросили, какая текущая температура? Так что это два разных агента, агент погоды и агент местной информации. И фактически вы делаете так, что этот агентный цикл принимает на себя другую личность. Вы просто переключаете контекст. И мы слышали много докладов на этой неделе о контекстной инженерии, потому что это прекрасная вещь в LLM, что они забывчивы, что вы можете просто полностью контролировать, что вы хотите, какой контекст поступает в них. Так что это работает точно так же. Так что Temporal полностью поддерживает передачи. У меня нет живой демонстрации этого. И вот и все. Хорошо. Итак, с этим у нас осталось несколько минут на вопросы. Я хочу оставить вам несколько ресурсов. Итак, то, что вы видите здесь, слева, — это QR-код для SDK Temporal Python. Вы найдете много отличной информации о нашем SDK Python, но вы также найдете каталог contrib, и именно там находится весь код интеграции с SDK для агентов OpenAI. И вы найдете там много примеров. Справа у меня не было QR-кода, потому что мои маркетологи не работают по субботам утром. Хорошо для них. Вы увидите URL-адрес. Итак, если вы зайдете в нашу документацию, docs.temporal.io. В верхней полосе вы найдете «Кулинарную книгу ИИ». У нас есть «Кулинарная книга ИИ», которая реализует множество шаблонов. Тот, который я показал вам сегодня, «Агентный цикл», находится в ветке на данный момент. Он готов к слиянию. Он был проверен, но мой рецензент фактически не дал ему одобрения, он просто проверил его и сказал: «Выглядит хорошо, но мне нужно одобрение, поэтому я не смог его слить сегодня утром». Но этот рецепт будет там. И есть ряд других. Там есть рецепт для SDK агентов OpenAI. Так что вы найдете его там. Итак, подводя итог, я не буду это затягивать, я думаю, мы тоже это прошли. Еще два ресурса, которые я хочу вам оставить: слева вы найдете наш блог, где мы описываем интеграцию SDK агентов OpenAI и Temporal. Так что это блог слева. Другое, что вы заметите, это то, что у меня там есть блог Pydantic. И эта идея привнесения надежности в эти иначе недолговечные фреймворки агентов является очень популярной. Так что после того, как мы сделали SDK агентов OpenAI, сам Pydantic интегрировал Temporal в свой фреймворк агентов, и Йохан, вы... Я не знаю, о каких мы можем говорить. У нас есть много других в разработке. Это все на сегодня, или вы хотите поговорить о каких-либо из них конкретно? Это все на сегодня, но будет больше. Да, я думаю, у нас есть два или три или четыре, которые сейчас в разработке и которые появятся либо от нас, либо от некоторых других фреймворков агентов. Так что эта идея привнесения надежности в то, что иначе является просто инструментом для доказательства концепции, оказывается довольно мощной. И, наконец, если вы будете так склонны, вот QR-код и URL-адрес. Если вы хотите дать нам обратную связь по этому семинару, мы будем очень признательны. И включите в эту обратную связь. Там есть свободная форма. Включите в эту обратную связь, что бы вы хотели видеть больше. Например: «Это было круто, но не зашло достаточно далеко» или «Вы упомянули это». Я действительно хотел бы увидеть больше о «человеке в цикле». Кстати, если вы зайдете на наш YouTube-канал, вы найдете множество различных презентаций. Так что «человек в цикле», я сделал вебинар об этом около трех недель назад. Мы сделали некоторые модули MCP, вещи MCP, даже продвинутые. Так что мы сделали продвинутый, где мы показали вам, как вы можете использовать Temporal для реализации сервера MCP, который является надежным и поддерживает выборку и сбор информации гораздо более надежным способом, чем это было бы иначе. И с этим у нас осталось около восьми минут. Так что, о, я также упомяну, особенно если вы находитесь в районе залива, но даже если нет, то наша конференция, наша конференция Replay, конференция Temporal, состоится в мае, и она пройдет в Москоне. И так, мы очень хотели бы увидеть вас там. И о, я знаю, этот QR-код здесь предназначался для семинара, который я провел во вторник, но черт возьми, почему бы не использовать его здесь. 75% скидка. Да, 75% скидка на регистрацию на Replay. Так что приглашаю вас прийти туда. Вы найдете меня, вы найдете Йохана, вы найдете еще много нас. И вы можете видеть, что у нас есть всевозможные действительно классные люди, такие как Сэмюэл Ковен, и у нас есть люди из Replet и Nvidia, и многие другие. Так что я оставлю обратную связь там. Итак, у нас осталось несколько минут на вопросы. >> Да. >> Как сохраняется состояние в Temporal? >> Как сохраняется состояние? >> Вы выключаете сервер, он просто теряет всю память обо всех рабочих. >> Да. Хорошо. Так вы говорите о сервере Temporal, который я показал вам, как вы можете запустить его локально. Так что, когда вы запускаете его локально, вы можете поставить переключатель, который говорит: «Эй, сохрани это в, скажем, SQL light или что-то в этом роде». Так что вы можете, есть состояние, которое его поддерживает. Я обычно не запускаю так, потому что я хочу избавиться от вещей в любом случае. Так что Temporal — это открытый исходный код, и у нас много пользователей, которые размещают его самостоятельно. Поскольку это открытый исходный код, мы буквально на таких мероприятиях, как это, всегда встречаем людей. Я встретил кого-то вчера или что-то в этом роде, кто сказал: «О, да, мы используем Temporal». И я говорю, и они просто используют открытый исходный код. Так что это действительно открытый исходный код. И так, у нас есть люди, которые размещают его самостоятельно, и мы поддерживаем реляционные базы данных и Cassandra в качестве бэкэнд-хранилищ в облаке Temporal. Часть причин, по которым люди приходят в облако, заключается в том, что, во-первых, мы запускаем облако в 15 различных регионах Amazon. Я не знаю, четыре, пять, шесть регионов Google. У нас есть многорегиональные пространства имен. Вся эта надежность. И тогда у нас также есть некоторый специальный соус на персистентности, который позволяет нам делать вещи более эффективно. Но у нас есть люди, которые успешно размещают его, используя варианты Cassandra или базы данных. Так что да, есть ли еще вопросы? Да. >> Запуск и остановка агентов. >> Когда я запускаю и останавливаю экземпляр, вы имеете в виду агента? Я имею в виду, как мы его останавливаем, если пользователь хочет его остановить? >> Рабочий процесс, так что >> Рабочий процесс >> да, ну, есть пара разных способов начать рабочий процесс. Вы можете начать рабочий процесс, ожидая, что он будет, вы знаете, синхронным, и он просто заканчивается, и вам придется иметь какой-то способ его убить, но чаще всего вы будете запускать его в асинхронном режиме, и вы получите обратно дескриптор, а затем вы можете делать вещи с этим дескриптором, чтобы остановить рабочие процессы. Но в целом, самое распространенное — это то, что вы определите в своей логике, что означает завершение этого агентного опыта или завершение этого рабочего процесса в той или иной форме. И так вы решите: «О, я закончил сейчас», и вы просто вернетесь. Так что это действительно так же просто, как сделать возврат из него. Это хороший вопрос, поскольку мы говорим об этих асинхронных вещах. Я не говорил об этом в этой сессии, но одна из действительно мощных вещей заключается в том, что эти рабочие процессы могут выполняться часами, минутами, днями, неделями, месяцами, годами, и это очень эффективно. И то, что мы, шаблон, который используют многие наши пользователи, заключается в том, что они используют его, они используют рабочий процесс как своего рода цифрового двойника чего-то другого. Мы также называем это сущностными рабочими процессами. Так, например, у вас может быть рабочий процесс, соответствующий лояльному клиенту, и каждый раз, когда этот лояльный клиент сканирует свой QR-код на кассе, он отправляет сигнал в рабочий процесс, а рабочий процесс иначе не потребляет никаких ресурсов, и он просто всплывает, берет сигнал, обрабатывает то, что ему нужно, и снова уходит. Так что это очень, очень распространенный шаблон — эта идея цифровых рабочих процессов как цифровых двойников какого-либо другого процессора, какой-либо другой сущности. Супер, супер мощно. Многие люди используют это. >> Да. >> Еще один. >> Да. >> Итак, если работа останавливается, и у вас это как бы в этом блочном состоянии, где оно просто сидит, >> есть ли у вас какая-либо интеграция с системами управления инцидентами, которые бы вызывали оповещение, чтобы инженер мог прийти к рабочему? Да. Итак, насколько я знаю, у нас нет таких интеграций, но наши клиенты создают эти интеграции. >> Да. Да. Они абсолютно создают их поверх. Есть ли у нас некоторые из них в облаке, я не уверен, но это не то, что у нас нет, например, нативных коннекторов Slack или подобных вещей. И часть этого, конечно, не обязательно будет вещью Temporal. Например, если вы запускаете своих рабочих на Kubernetes, вы можете настроить конфигурацию Kubernetes так, чтобы при остановке контейнера вы получали оповещения, или когда вы видите что-то в панели управления Kubernetes, где, о боже, мой автоскейлер, и, конечно, вы можете иметь этих рабочих, и вы можете иметь их работающими на Kubernetes с автоскейлерами. Так что большая часть этого или, знаете ли, как бы оркестрация, вероятно, будет проходить через вашу операционную среду. Вы, это на самом деле очень хороший момент, заключается в том, что мы размещаем сервер, но мы не размещаем рабочие нагрузки для вас. Так что вы сами размещаете рабочие нагрузки. Большинству людей это нравится, потому что они хотят полного контроля над этим. Мы подумываем о том, чтобы в некоторых случаях размещать рабочих в будущем, но сейчас этого нет в дорожной карте. Так что да, >> примеры людей, создающих, скажем, голосовых агентов с Temporal или >> примеры людей, создающих голосовых агентов с Temporal. Я не знаю ни одного навскидку. Я >> Я не знаю ни одного развернутого. Люди экспериментируют с этим. Мы экспериментируем с голосовыми агентами. И это, безусловно, то, что имеет смысл. Это одно из мест, где мы ожидаем, что агенты будут развиваться в будущем. >> Да. Да. Вопрос сзади. >> Так, у меня нет Claude в, следите за кулинарной книгой. У меня пока нет примеров для Claude. У меня почти готов Gemini. И да, мы хотим добавить Claude в кулинарную книгу. Мы также с радостью примем PR. Так что, если вы хотите взять этот пример и перенести его на Claude, мы будем рады получить PR и по этому поводу. Так что да, эта кулинарная книга полностью открыта, она находится под лицензией MIT в нашем основном репозитории, нашей основной организации. >> Да. >> Есть ли примеры агентов по извлечению информации из Excel, PDF? >> Примеры агентов по извлечению из Excel или PDF? У меня лично нет. Знаете, одна из других вещей, которую я упомяну, это то, что у нас есть обмен кодом, так что у нас есть кулинарная книга, это наша, и там мы очень тщательно следим за тем, чтобы она демонстрировала лучшие практики, и мы проводим тщательные проверки, потому что мы не хотим вас вводить в заблуждение. У нас также есть обмен кодом, где у нас буквально, я думаю, 20 или 30 или 40 примеров. Возможно, там что-то есть. Я, честно говоря, не уверен. >> Это как GitHub? >> Да, это так. Так что вы найдете обмен кодом на нашем веб-сайте, и все, и я считаю, что все записи в обмене кодом имеют URL-адреса GitHub. Мы не владеем большинством из них, потому что они из сообщества, но они находятся в репозиториях других людей. Так что да, вы найдете это. >> Хорошо. Ну, это было О, есть еще один вопрос? Нет, я просто хочу прокомментировать, что мы несколько раз упоминали, что это будет или что было бы действительно, действительно круто сделать, и, знаете ли, моя команда нанимает людей >> рекламный плакат о найме >> по этим приложениям ИИ Temporal. >> Хорошо. И поскольку он сказал это, я в отделе адвокации разработчиков. Мы тоже ищем адвокатов разработчиков. Так что, если вы подходите под профиль инженера, поговорите с Йоханом. Если вы подходите под профиль адвоката разработчиков, поговорите со мной. Так что, хорошо. Спасибо большое.