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 considered harmful" или, может быть, просто слышал о ней? Я никогда на самом деле ее не читал. Э, но она была обо всем, у нас был этот абстракция в языке программирования 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 функции, что означает, что просто убедитесь, что вы вставляете правильные вещи в контекст, и вы получите лучшие результаты. Владейте своим состоянием и потоком управления и просто делайте это и просто понимайте это, потому что это даст вам гибкость. А затем найдите передовые технологии. Найдите способы делать вещи лучше, чем все остальные, тщательно отбирая то, что вы вставляете в модель, и как вы контролируете то, что выходит. Э, и мои агенты лучше с людьми. Найдите способы позволить агентам сотрудничать с людьми. Э, есть трудные вещи в построении агентов, но вы, вероятно, должны делать их в любом случае, по крайней мере, на данный момент, и вы должны делать большинство из них. Э, я думаю, многие фреймворки пытаются убрать сложные ИИ-части проблемы, чтобы вы могли просто вставить их и использовать. И, э, я думаю, должно быть наоборот. Я думаю, инструменты, которые мы получаем, должны убирать другие сложные части, чтобы мы могли тратить все свое время, сосредоточившись на сложных ИИ-частях, на правильном подборе промптов, на правильном потоке, на правильных токенах. Итак, причина, по которой я здесь, заключается в том, что я веду небольшой бизнес. Э, у нас есть стартап, где мы пытаемся помочь вам сделать многое из того, что мы делаем в открытом доступе, это открытый исходный код, и я считаю, что это действительно важно, и нам нужно работать над этим вместе. Есть некоторые другие вещи, которые трудны, но не так важны и не так интересны. Итак, это то, что мы решаем в Human Layer. Э, работаем над чем-то под названием протокол A2. Приходите ко мне, если хотите поговорить об этом, но это способ добиться консолидации вокруг того, как агенты могут контактировать с людьми. Э, но в основном я просто люблю автоматизировать вещи. Я построил тонны и тонны агентов внутри для своих личных вещей, для поиска квартир, для всех видов внутренних бизнес-задач, которые мы делаем в Human Layer. Э, так что спасибо всем за просмотр. Давайте построим что-нибудь. Увидимся в коридоре. Э, я был бы рад поболтать, если вы хотите обсудить агентов, построение, потоки управления или что-либо из этого. Это 12-факторные агенты. [Аплодисменты]