Transcription
[Музыка] Кто здесь строит агентов? Поднимите руку, кто построил 10+ агентов? Кто-нибудь здесь построил около сотни агентов? Хорошо, у нас есть несколько. Отлично. Мне нравится. Итак, я думаю, многие из нас прошли этот путь создания агентов. И то, что случилось со мной, знаете, я решил, что хочу построить агента. Мы выяснили, что мы хотим, чтобы он делал. Мы хотим двигаться быстро. Мы разработчики, поэтому мы используем библиотеки. Мы не пишем все с нуля. И вы доводите это до 70-80%. Этого достаточно, чтобы вызвать восторг у генерального директора и добавить еще шесть человек в вашу команду. Но затем вы понимаете, что 70-80% недостаточно хорошо. И что, если вы хотите пройти этот порог качества в 70-80%, вы находитесь на семи уровнях в стеке вызовов, пытаясь реверс-инжинирингом понять, как создается этот промпт, или как передаются эти инструменты? Откуда все это берется? И если вы такой же, как я, вы в конечном итоге просто выбрасываете все и начинаете с нуля. Или вы можете даже обнаружить, что это не та проблема, для которой подходят агенты. Я помню, один из первых агентов, который я пытался построить, был агент DevOps. Я сказал: «Вот мой make-файл. Вы можете запускать make-команды. Соберите проект». Не смог разобраться. Сделал все не в том порядке. Я думаю: «Круто, давайте исправим промпт». И в течение следующих двух часов я добавлял все больше и больше деталей о том, что это было, и о каждом шаге, и о точном порядке, пока не дошел до точки, где я сказал: «Это точный порядок выполнения шагов сборки». Это было классное упражнение, но в конце я подумал: «Знаете, я мог бы написать bash-скрипт, чтобы сделать это примерно за 90 секунд». Не каждая проблема требует агента. И поэтому я прошел этот путь. Я думаю, многие из вас прошли похожие пути. И то, что произошло, это я пошел и поговорил, пытаясь помочь людям создавать лучшие, более надежные агенты. Я поговорил с более чем 100 основателями, строителями, инженерами. И я начал замечать закономерности. Одна из них заключалась в том, что большинство производственных агентов не были такими уж агентными. Они были в основном просто программным обеспечением, но были эти основные вещи, которые делали многие люди. Были эти закономерности, которые делали их приложения на основе LLM действительно, действительно хорошими. И ни один из них не делал своего рода переписывание с нуля. Скорее, они брали эти небольшие модульные концепции, у которых не было названий и определений, и применяли их к своему существующему коду. И что действительно здорово в этом, так это то, что я не думаю, что вам нужен опыт в области ИИ, чтобы сделать это. Это основы программной инженерии. Ну, наверное, не основы, но так же, как Heroku нужно было определить, что значит строить в облаке, мы даже не называли это облачными нативными тогда, но так строились приложения, которые могли работать в облаке 10 лет назад. Я решил собрать то, что, по моему мнению, будет 12 факторами ИИ-агентов. Из всего, что я видел, работая в этой области. Итак, мы создали этот репозиторий на GitHub. Вы можете пойти и прочитать его. Оказывается, многие другие люди согласились и почувствовали то же самое. Итак, мы были на главной странице Hacker News весь день, 200 тысяч просмотров в социальных сетях. Я просто выложу это и без комментариев. И для контекста, мы получили около 4000 звезд за месяц-два. Есть 14 активных контрибьюторов. Очень легко прочитать это и услышать разговор и сказать: «О, мы здесь, это разговор против фреймворков». Я не собираюсь критиковать фреймворки. Я бы думал об этом скорее как о списке желаний, списке запросов на функции: как мы можем заставить фреймворки служить потребностям действительно хороших строителей, которым нужна высокая надежность и которые хотят по-прежнему двигаться быстро. Итак, что я здесь делаю? Я хочу, чтобы вы забыли все, что знаете об агентах, и переосмыслили с первых принципов, как мы можем применить все, что мы узнали из программной инженерии, к практике создания действительно надежных агентов. Итак, мы немного изменим порядок. Если вы хотите все 12 факторов по порядку, это 30-минутный доклад, поэтому мы объединим некоторые вещи. В конце будет QR-код. Вы можете изучить его в свободное время. Фактор один, самые волшебные вещи, которые могут делать LLM. Это не имеет никакого отношения к циклам, операторам switch, коду, инструментам или чему-либо еще. Это превращение предложения вроде этого в JSON, который выглядит так. Даже неважно, что вы делаете с этим JSON. Для этого существуют другие факторы. Но если вы это делаете, это одна часть, которую вы можете интегрировать в свое приложение уже сегодня. Фактор четыре. Это ведет прямо к... Кто-нибудь читал эту статью «go to» считается вредным или, может быть, просто слышал о ней? Я никогда ее не читал. Но она была о том, что у нас было это абстракция в языке программирования C и многих других языках программирования того времени, которая говорила, что эта штука «go to» делает код ужасным. Это неправильная абстракция. Никто не должен ее использовать. Я собираюсь рискнуть и сказать, что использование инструментов вредно. И я ставлю это в кавычки, потому что я не говорю о предоставлении агенту доступа к миру. Очевидно, это супер круто. Но я думаю, что все усложняет идея о том, что использование инструментов — это какая-то волшебная вещь, где некая эфирная инопланетная сущность взаимодействует со своей средой, потому что происходит то, что наш LLM выдает JSON. Мы передадим это некоторому детерминированному коду, который что-то сделает, а затем, возможно, мы вернем это. Но опять же, это другие факторы. Так что, если у вас есть такие структуры, и вы можете заставить LLM выдать что-то, что их генерирует, тогда вы можете передать это в цикл, как этот, или в оператор switch, как этот. Нет ничего особенного в инструментах. Это просто JSON и код. Это фактор четыре. Фактор восемь, и мы объединим здесь пару. Владение вашим потоком управления. И я хочу сделать шаг назад и поговорить о том, как мы сюда попали. Мы давно пишем DAG в программном обеспечении. Если вы писали оператор if, вы писали направленный граф. Код — это граф. Вы также можете быть знакомы с оркестрацией DAG. Кто-нибудь использовал что-то вроде Airflow или Prefect или что-то подобное? Так что эта концепция разбиения на узлы дает вам определенные гарантии надежности. Но то, что должны были делать агенты, и я думаю, многие люди об этом говорят, и я думаю, в некоторых случаях это реализовано, это то, что вам не нужно писать DAG. Вы просто говорите LLM: «Вот цель», и LLM найдет путь туда. И мы моделируем это как очень простой цикл. Знаете, LLM определяет следующий шаг. Вы наращиваете некоторое контекстное окно, пока LLM не скажет: «Эй, мы закончили». Итак, как это выглядит на практике, вы получаете событие. Вы передаете его в свой промпт. Он говорит, что вы хотите вызвать API, и вы получаете результат. Поместите это в контекстное окно. Передайте все обратно в промпт. Это самый наивный простой способ создания агентов. И LLM вызовет несколько шагов, а затем в конечном итоге скажет: «Круто, мы выполнили все задачи из исходного события, которое, возможно, было сообщением пользователя с просьбой что-то сделать. Возможно, это сбой». Но затем мы получаем окончательный ответ. И наш материализованный DAG — это просто эти три шага по порядку. Оказывается, это не очень хорошо работает. Особенно при работе с более длинными рабочими процессами. В основном это длинные контекстные окна. Есть и другие причины, которые можно поднять. И люди говорят: «О, даже кто-нибудь вставлял два миллиона токенов в Gemini раньше и пытался посмотреть, что произойдет?» Вы можете это сделать. Вы получите ответ. API вернет вам что-то. Но я не думаю, что кто-то будет спорить с вами, что вы всегда будете получать более точные, лучшие, более надежные результаты, контролируя и ограничивая количество токенов, которые вы помещаете в это контекстное окно. Так что это не совсем работает, но мы будем использовать это как абстракцию для построения. Что такое агент на самом деле? У вас есть ваш промпт, который дает инструкции о том, как выбрать следующий шаг. У вас есть оператор switch, который берет любой JSON, выданный моделью, и делает с ним что-то. У вас есть способ построения контекстного окна. И у вас есть цикл, который определяет, когда, где, как и почему вы выходите. И если вы владеете своим потоком управления, вы можете делать забавные вещи, такие как break, switch, summarize, LLM — судья и все такое. И это ведет прямо к тому, как мы управляем состоянием выполнения и бизнес-состоянием наших агентов. Многие инструменты предоставляют вам такие вещи, как текущий шаг, следующий шаг, количество попыток, все эти оркестраторы DAG, они все имеют такие концепции. Но у вас также есть ваше бизнес-состояние. Какие сообщения были отправлены? Какие данные мы показываем пользователю? Какие вещи мы ждем одобрения? И мы хотим иметь возможность запускать, приостанавливать, возобновлять эти вещи, как мы делаем для любых стандартных API. Это все просто программное обеспечение. И поэтому, если вы можете поместить своего агента за REST API или MCP-сервер и управлять этим циклом таким образом, чтобы обычный запрос поступал, и мы загружаем это контекстное окно в LLM. Мы позволим нашему агенту вызывать долгосрочные инструменты. Таким образом, мы можем прервать рабочий процесс, сериализовать это контекстное окно прямо в базу данных, потому что мы владеем контекстным окном. Мы вернемся к этому. И затем, когда мы запустим рабочий процесс, в конечном итоге он вернется с этим идентификатором состояния и результатом. Мы используем идентификатор состояния, чтобы загрузить состояние обратно из базы данных, а затем мы можем добавить результат к программе и отправить его обратно в LLM. Агент даже не знает, что произошло в фоновом режиме. Агенты — это просто программное обеспечение, так давайте писать программное обеспечение. И создание действительно хороших требует большой гибкости. И поэтому вы действительно хотите владеть внутренним циклом того, как все это собирается вместе. Это унификация. Это пауза и возобновление. Фактор два, я думаю, большинство людей находят его первым: вы действительно хотите владеть своими промптами. Есть хорошие абстракции, которые, если вы не хотите тратить много времени на написание промпта вручную, вы можете вставить что-то, и вы получите действительно хороший набор примитивов и действительно хороший промпт. Например, это сделает вас потрясающим промптом, который вам пришлось бы посещать школу промптов три месяца, чтобы создать такой хороший промпт, но в конечном итоге, если вы хотите пройти какой-то порог качества, вы будете писать каждый токен вручную. Потому что LLM — это чистые функции фокуса, и единственное, что определяет надежность вашего агента, — это насколько хорошие токены вы можете получить, а единственное, что определяет токены, которые вы получаете, помимо переобучения собственной модели и чего-то подобного, — это быть очень осторожным с тем, какие токены вы вводите. Я не знаю, что лучше. Я не знаю, как вы хотите построить свой промпт, но я знаю, что чем больше вещей вы можете попробовать, чем больше настроек вы можете протестировать и чем больше вещей вы можете оценить, тем вероятнее вы найдете что-то действительно хорошее. Владея своими промптами, вы также хотите владеть тем, как вы строите свое контекстное окно. Так что вы можете использовать стандартный формат сообщений OpenAI или в данный момент, когда вы говорите LLM выбрать следующий шаг, ваша единственная задача — сказать ему, что произошло до сих пор. Вы можете поместить всю эту информацию, как угодно, в одно сообщение пользователя и спросить: «Эй, что происходит дальше?» или поместить ее в системное сообщение. Таким образом, вы можете моделировать свое состояние события, свою модель потока, как угодно, и сериализовать ее, как угодно. И некоторые из трассировок, которые мы используем в некоторых агентах, которые мы строим внутри компании, я расскажу об этом через секунду, могут выглядеть так. Но если вы не смотрите на каждый токен и если вы не оптимизируете плотность и ясность того, как вы передаете информацию LLM, вы можете упустить возможности и качество. Так что LLM — это чистые функции, токены на входе, токены на выходе, и все, что делает агентов хорошими, — это контекстное инжиниринг. Так что у вас есть ваш промпт, у вас есть ваша память, у вас есть ваш RAG, у вас есть ваша история. Все это просто о том, как получить правильные токены в модель. Так что она дает нам действительно хороший ответ и решает проблему пользователя. Решает мою проблему в основном. Я не знаю, что лучше, но я знаю, что вы хотите попробовать все. Итак, давайте владеть построением вашего контекста. Это немного спорно. Поэтому это отдельный фактор. И способ сделать его хорошим — интегрировать его с другими факторами. Но вы могли бы, когда модель ошибается и вызывает API неправильно или вызывает API, который не работает, вы могли бы взять вызов инструмента, который она сделала, и получить связанную с ним ошибку, поместить это в контекстное окно и заставить ее попробовать снова. Кто-нибудь когда-нибудь имел плохой опыт с этим? Видели, как эта штука просто раскручивается, сходит с ума, теряет контекст и просто застревает? Вот почему вам нужно владеть своим контекстным окном. Не просто слепо добавляйте вещи. Если у вас есть ошибки, а затем вы получаете допустимый вызов инструмента, очистите все ожидающие ошибки. Суммируйте их. Не помещайте весь стек-трейс в ваш контекст. Подумайте, что вы хотите сказать модели, чтобы получить лучшие результаты. Контакт с людьми с помощью инструментов. Это немного тонко. Но я видел, что это просто то, что я видел в дикой природе. Почти все избегают этого очень важного выбора в самом начале вывода, когда вы решаете между вызовом инструмента и сообщением человеку. Если вы можете перенести этот акцент на токен естественного языка, вы можете дать модели разные способы. Вы можете сказать: «Я закончил», или «Мне нужно уточнение», или «Мне нужно поговорить с менеджером», или что угодно, и два, вы переносите намерение на генерацию первого токена и выборку на что-то, что является естественным языком, который модель понимает. Так что ваши трассировки могут выглядеть так, если вы здесь привлекаете человеческий ввод. Это позволяет вам создавать агентов с автоматическим циклом. Я не буду об этом говорить. Если вы зайдете на сайт, там есть ссылка на этот пост. Я много об этом писал. Я не знаю, что лучше, но вам, вероятно, стоит попробовать все. Это контакт с людьми с помощью инструментов. Идет прямо вместе с запуском вещей откуда угодно и встречей с пользователями там, где они находятся. Люди не хотят иметь семь открытых вкладок с разными агентами в стиле ChatGPT. Просто позвольте людям писать по электронной почте с агентами, которых вы строите. Позвольте им общаться в Slack с агентами, которых вы строите. Discord, SMS, что угодно. Мы видим, что это набирает обороты повсюду. И у вас должны быть маленькие сфокусированные агенты. Итак, мы говорили об этой структуре и почему она не очень хорошо работает. Итак, что работает? Вещи, которые люди делают и которые работают очень хорошо, — это микроагенты. Так что у вас все еще есть в основном детерминированный DAG, и у вас есть эти очень маленькие циклы агентов с примерно 3-10 шагами. Мы делаем это в Human Layer. У нас есть бот, который управляет нашими развертываниями. Большая часть нашего конвейера развертывания — это детерминированный код CI/CD. Но когда мы доходим до точки, когда GitHub PR объединен и тесты проходят в разработке, прошу прощения, мы отправляем его в модель. Мы говорим: «Разверни эту штуку». Он говорит: «Круто, я разверну фронтенд». И затем вы можете отправить это человеку. Человек говорит: «На самом деле нет, сначала сделай бэкенд». Это превращение естественного языка в JSON. Это следующий шаг в нашем рабочем процессе. Предлагается бэкенд, он утверждается, развертывается, затем агент знает: «Хорошо, мне нужно вернуться и развернуть фронтенд». Как только все это сделано и успешно, мы возвращаемся к детерминированному коду. Итак, теперь мы запустим сквозные тесты против прода. Если это сделано, иначе мы передаем его обратно в маленький агент отката, который внутри очень похож. Я не буду вдаваться в подробности, но вот как это работает в нашем канале Slack. Да, 100 инструментов, 20 шагов, легко. Управляемый контекст, четкие обязанности. Многие люди говорят: «Что, если LLM будут становиться умнее? Что, если я смогу вставить два миллиона токенов, и он сможет это сделать?» И я думаю, мы очень увидим что-то вроде этого, где вы начинаете с в основном детерминированного рабочего процесса и начинаете посыпать LLM в ваш код, в ваш бэкенд, в вашу логику. Со временем LLM смогут выполнять более крупные, более сложные задачи, пока весь этот конечный API или конвейер или что-то еще не будет управляться агентом. Это здорово. Но вам все равно нужно знать, как проектировать эти вещи, чтобы получить лучшее качество. Это кто-то из Notebook LM, и это, по сути, их взгляд, и я думаю, они сделали это хорошо: найдите что-то, что находится на границе того, что модель может надежно делать, например, то, что она не всегда может сделать правильно, и если вы сможете добиться того, чтобы это делалось правильно, потому что вы спроектировали надежность в свою систему, тогда вы создадите что-то волшебное, и вы создадите что-то лучшее, чем то, что строят все остальные. Так что это маленькие сфокусированные агенты. Здесь есть мем о stateless reducers. Полагаю, кто-то действительно написал мне в Твиттере: это не reducer, это transducer, потому что есть несколько шагов. Но в основном агенты должны быть stateless. Вы должны владеть состоянием, управлять им, как хотите. Так что мы все еще ищем правильные абстракции. Есть пара постов в блогах, которые я ссылаю в статье. Фреймворки против библиотек. Есть очень старая статья с Ruby Comp о том, хотим ли мы дублирования или пытаемся разобраться в этих абстракциях? Если вы хотите создать 12-факторного агента, мы работаем над чем-то под названием create 12-factor agent, потому что я считаю, что агентам нужен не bootstrap. Вам не нужна обертка вокруг внутренней вещи. Вам нужно что-то больше похожее на shad CN, которое как бы разворачивается, а затем я буду владеть им, и я буду владеть кодом, и меня это устраивает. Итак, в итоге, агенты — это программное обеспечение. Вы все можете писать программное обеспечение. Кто-нибудь когда-нибудь писал оператор switch? Цикл while. Да. Хорошо. Так что мы можем делать эти вещи. LLM — это stateless функции, что означает, что просто убедитесь, что вы помещаете правильные вещи в контекст, и вы получите лучшие результаты. Владейте своим состоянием и потоком управления и просто делайте это и просто понимайте это, потому что это даст вам гибкость. И затем найдите передовые технологии. Найдите способы делать вещи лучше, чем все остальные, тщательно подбирая то, что вы помещаете в модель, и как вы контролируете то, что выходит. И мои агенты лучше работают с людьми. Найдите способы позволить агентам сотрудничать с людьми. Есть сложные вещи в создании агентов, но вам, вероятно, стоит делать их в любом случае, по крайней мере, сейчас, и вам стоит делать большинство из них. Я думаю, многие фреймворки пытаются убрать сложные ИИ-части проблемы, чтобы вы могли просто вставить их и использовать. И я думаю, должно быть наоборот. Я думаю, инструменты, которые мы получаем, должны убирать другие сложные части, чтобы мы могли тратить все свое время, сосредоточившись на сложных ИИ-частях, на правильном подборе промптов, на правильном потоке, на правильных токенах. Так что причина, по которой я здесь, заключается в том, что я действительно управляю малым бизнесом. У нас есть стартап, где мы пытаемся помочь вам сделать многое из того, что мы делаем в открытом доступе, это open source, и я считаю, что это действительно важно, и нам нужно работать над этим вместе. Есть некоторые другие вещи, которые сложны, но не так важны и не так интересны. Вот что мы решаем в Human Layer. Работаем над чем-то под названием протокол A2. Подойдите ко мне, если хотите поговорить об этом, но это способ добиться консолидации вокруг того, как агенты могут контактировать с людьми. Но в основном я просто люблю автоматизировать вещи. Я построил тонны и тонны агентов внутри для своих личных дел, для поиска квартир, для всех видов внутренних бизнес-дел, которые мы делаем в Human Layer. Так что спасибо всем за просмотр. Давайте построим что-нибудь. Увидимся на треке в коридоре. Я буду рад поболтать, если вы хотите обсудить агентов, создание, поток управления или что-либо из этого. Это 12-факторные агенты. [Аплодисменты]