📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

What if the harness mattered more than the model? - Aditya Bhargava, Etsy

AI Engineer32:04

Transcription

Всем привет. Меня зовут Адит, произносится как Адит, как налоговая проверка. Эм, и я здесь, чтобы поговорить с вами о том, что если бы обвязка имела большее значение, чем модель? Немного обо мне сначала. Я штатный инженер в Etsy. Я также являюсь руководителем инициативы IC Etsy по агентам коммерции. Я написал "Гроккинг Алгоритмы", иллюстрированную книгу по алгоритмам. А также я публикую иллюстрированные посты на ducktyped.org. Эм, и я хочу поговорить с вами о том, что если бы обвязка имела большее значение, чем модель? Под этим я подразумеваю, что если бы мы должны были уделять больше внимания развитию экспертизы в обвязках? Эм, и мой спорный взгляд здесь заключается в том, что я слышу, как многие люди говорят: "О, модели настолько хороши, что вы можете просто оставить обвязку простой. Просто дайте модели несколько инструментов, и она сделает остальное." И я слышал это так часто, что это уже стало мудростью в индустрии технологий. На что мой ответ: "Да, но это движется в неправильном направлении, потому что это делает нас зависимыми от модных проприетарных моделей, которые нельзя запускать локально. Так что, если бы мы вместо этого поговорили о другом направлении? Что если бы мы сосредоточились на моделях с открытым исходным кодом, которые можно запускать локально? Что если бы мы сосредоточились на создании обвязки, которая настолько хороша, что мы можем получить производительность передовой модели через локальную модель с открытым исходным кодом? Так что, если бы обвязка имела большее значение, чем модель? Что если бы наше внимание должно было быть сосредоточено на обвязке? Эм, насколько важна обвязка? Верно? Это то, что я много исследовал в свободное время. Эм, есть очень интересная статья, которая говорит о Harness Bench, который является бенчмарком для обвязок, чего мы пока не видели много. У нее 106 задач. Она тестирует эти различные модели в различных обвязках. Но суть в том, что она запускает ту же установку. Она проводит ту же оценку, ту же модель, но тестирует различные обвязки. И результаты довольно интересные. Так, оценки варьируются от 52,4% до 76,2%. То есть, разница более чем в 20 пунктов, и изменилась только обвязка. И действительно интересная вещь заключается в том, что для более слабых моделей обвязка имеет большее значение. Если обвязка имеет большее значение, чем модель, это отличная новость. Потому что если модель имеет большее значение, то мы зависим от горстки компаний, которые способны создавать и обучать эти модели. Но если, если хорошая обвязка может компенсировать и заставить более слабую модель работать лучше, то вы можете создавать свои собственные обвязки, и это то, что может сделать любой из нас, и нам не придется зависеть от платных моделей. Так что я потратил много времени и провел много исследований, в частности, над тем, что потребуется для создания действительно хорошей обвязки. И я рано понял, что ни один из существующих инструментов или фреймворков не смог сделать то, что я хотел. И я понял, что на самом деле нужно решение на уровне языка. Так что это мой другой спорный взгляд в этом докладе: я думаю, что создание хорошей обвязки на самом деле требует поддержки на уровне языка. И именно сюда пошли мои исследования за последние 6 месяцев, и я потратил значительную часть этих 6 месяцев на создание нового языка под названием Agency, который является языком для создания агентов. И просто быстро поговорим о терминологии, потому что термины агент и обвязка еще не очень четкие в индустрии. Они не очень хорошо определены. Но в этом докладе я буду использовать их взаимозаменяемо. Но когда я говорю об агенте, я действительно имею в виду обвязку и модель. Так что, если взять, например, Claude code, Claude code — это агент. Он использует Opus, который является моделью, а затем все остальное — это обвязка. Но, знаете, когда мы говорим об Agency, это действительно для создания агентов, но то, что он предоставляет, — это обвязка. Agency очень хорош. Знаете, он еще новый. Создание языка — это большая работа, и ему всего 6 месяцев. Но мне нравится эта цитата Алана Кея: "Простые вещи должны быть простыми, сложные вещи должны быть возможными". И это то, что мне нравится в Agency: я думаю, знаете, когда люди создают агентов, есть много примитивов, много вещей, которые каждый агент должен будет уметь делать, и эти вещи должны быть простыми в реализации. И есть много сложных вещей, которые мы хотим делать с агентами, и эти вещи должны быть возможны в рамках выбранного вами фреймворка, и с Agency это возможно. Итак, теперь у нас есть четкая цель: попытаться создать наилучшую возможную обвязку. И у нас есть отличный инструмент для этого — Agency. Итак, в оставшейся части этого доклада я расскажу о создании кодирующего агента в Agency. И мы увидим, как один и тот же агент развивается на семи разных примерах. Мы увидим ту же модель, ту же задачу, но обвязка будет улучшаться каждый раз, и мы увидим, как обвязка каждый раз улучшает производительность агента. Итак, как я уже сказал, я провел тонну исследований по этому поводу. Мои цели с этим докладом — дать вам основы создания обвязки. Когда мы говорим о создании хорошей обвязки, что это значит? Вы начинаете с нуля, каковы основы? Я расскажу немало о безопасности агентов, потому что, знаете, когда мы говорим о создании агентов, что вы действительно хотите, чтобы они могли делать, — это действовать от нашего имени. Но большая проблема с этим заключается в том, как вы даете агенту возможности, чтобы он мог действовать, но не настолько много возможностей, чтобы он делал что-то небезопасное. Так что, когда мы говорим о качестве и возможностях агента, безопасность агента идет рука об руку с этим. В конце я сделаю введение в некоторые более продвинутые концепции, такие как суб-агенты и самооптимизация. Я думаю, что именно там, знаете, появляются более интересные вещи, и мы действительно начинаем говорить о том, каковы все возможности, знаете, потому что когда вы говорите о создании хорошей обвязки, есть так много вещей для исследования. И поэтому я надеюсь, что вы останетесь со мной до конца, потому что именно там мы переходим к действительно интересным вещам. Итак, это код, который мы попросим нашего кодирующего агента отредактировать. Это код для вычисления медианы упорядоченного списка чисел. И если список имеет нечетную длину, вы просто берете средний элемент. Если список имеет четную длину, вам нужно взять два средних элемента и взять их среднее арифметическое. Но сейчас эта функция этого не делает. Так что в этой функции есть ошибка. Есть тест, который показывает сбой, и мы попросим нашего агента исправить этот код. Так что давайте приступим. Давайте просто погрузимся. Это первый пример. Это уже код Agency. И вы заметите, что Agency очень похож на TypeScript. Он сильно вдохновлен TypeScript с некоторым синтаксисом Python. Так что точка входа — это этот узел main. У меня есть простой промпт. Python-функция median в demo/median.py имеет ошибку. Пожалуйста, исправьте ошибку. И я просто передал этот промпт в функцию LLM. Я получаю результат и печатаю результат. И, конечно, это не сработает, потому что он не может читать или записывать в этот файл. Так что давайте быстро запустим этот пример. Окей. Так, конечно, как и ожидалось, он говорит, что для того, чтобы помочь мне исправить ошибку, мне нужно увидеть существующий код. Так что это просто модель. Очень мало обвязки, и, конечно, она ничего не может сделать. Так что самое очевидное улучшение для любой обвязки — дать ей некоторые инструменты. Так что, быстро, давайте поговорим о том, как работают инструменты в Agency, потому что это очень просто. Я определю функцию. В данном случае, просто для примера, я определю функцию greet, которая приветствует пользователя. А затем я сделаю вызов LLM, который говорит: "Используй мой инструмент greet, чтобы поприветствовать Адита". А затем передам этот инструмент. И каждая функция может автоматически использоваться как инструмент в Agency. Так что больше ничего делать не нужно. Agency создает JSON-схему из этой функции и отправляет ее в вызов LLM. Строка документации здесь будет использоваться как описание инструмента. Так что давайте запустим второй пример. Итак, NPX agency Oops, на самом деле. NPX agency example since actually 01, потому что мы сначала поговорим об инструментах. Итак, привет, Адит? И как мы можем узнать, что он запустил этот инструмент, а затем просто сгенерировал пример, верно? Так что я просто покажу быстро. Agency записывает логи и имеет отличный просмотрщик логов. Так что я просто разверну последний запуск, и вы можете увидеть здесь, что он делает этот вызов инструмента к функции greet с этими параметрами. Инструмент отвечает, возвращая "Привет, Адит", и ассистент просто передает это обратно нам. Итак, это инструменты. Теперь давайте посмотрим на использование инструментов в Agency. Снова, это, знаете, следующий шаг нашего агента, который заключается в том, чтобы дать ему инструменты. Вот пример, где мы даем агенту инструменты для чтения и записи. Опять же, чтение и запись — это просто функции, встроенные в Agency, и поскольку каждая функция может использоваться как инструмент, я могу просто передать это напрямую в LLM. За исключением того, что предоставление агенту возможности читать и записывать произвольные файлы в нашей файловой системе очень небезопасно. Так что по умолчанию Agency не позволит вам это сделать. Agency имеет функцию "человек в контуре", которая потребует некоторого одобрения. Мы нигде ее не предоставляем, поэтому этот код завершится ошибкой и выведет сообщение об ошибке. Так что позвольте мне показать вам, как это выглядит. Отлично. Так, прерывание стандартного чтения не было обработано. Ваше сообщение о прерывании: "Вы уверены, что хотите прочитать этот файл?" Вы можете увидеть имя файла, которое он пытается прочитать, и он, по сути, говорит нам, что мы не одобрили это прерывание. И он дает нам указатель на руководство, верно? Говорит нам, как использовать обработчики. Итак, мы начали просто с модели, попробовали инструменты, и следующий шаг — сделать инструменты безопасными. Так что мы сделаем именно то, что просит это сообщение, и используем обработчик. Итак, теперь вот тот же код, который, знаете, передает эти функции чтения и записи в качестве инструментов. Но теперь он обернут в блок обработчика. И у него есть функция обработчика ниже. Так что теперь, когда эти инструменты вызовут или вызовут прерывание, этот код будет выполнен. Так что он выведет информацию об этом прерывании. Он запросит у пользователя ввод с помощью встроенной функции ввода. И если пользователь одобрит, вызов инструмента будет одобрен. И я знаю, что я говорю "прерывание", и я не совсем определяю, что это значит. И я могу перейти к этому немного позже, но это, по сути, способ приостановить выполнение в какой-то момент. И запросить ввод человека. И поэтому прерывания — это отличная функция в Agency, и все функции в стандартной библиотеке Agency, которые изменяют код или изменяют что-то, или имеют какое-то разрушительное действие, или читают конфиденциальные данные, сначала вызывают прерывание. Итак, вот безопасная версия нашего агента, где инструменты будут вызывать прерывание по умолчанию, и теперь этот код будет спрашивать пользователя: "Вы одобряете?" Давайте запустим этот пример. Окей, вы уверены, что хотите прочитать этот файл? Я просто скажу "да". Вы можете видеть, что он читает. Теперь он пытается записать в этот файл. Так что, знаете, это пример >> [хмыкает] >> нас делает агента безопаснее, запрашивая ввод пользователя. И это лучше, и это безопасно, но это также очень медленно. Так что следующее, что мы хотим сделать, — это сделать агента автономным, сохраняя при этом его безопасность, и это сложная часть, верно? Как вы даете ему достаточно возможностей, чтобы вам не приходилось вручную одобрять каждое действие, не давая ему, не давая ему столько возможностей, чтобы он мог делать что-то разрушительное с вашей файловой системой. Так что Agency имеет действительно классную функцию для решения этой проблемы. Это называется частичное применение функций. >> [прочищает горло] >> Это концепция, заимствованная из функционального программирования. Это очень модный термин для довольно простой концепции. Итак, вот сигнатура инструмента чтения, верно? Принимает имя файла и каталог. И когда вы читаете файл, он будет искать в этом каталоге этот файл. И с частичным применением функций мы берем эту функцию чтения и вызываем для нее partial. И даем ей каталог. И что мы делаем здесь, так это фиксируем аргумент каталога на demo. LLM не сможет изменить этот аргумент. Он даже не будет знать, что этот аргумент существует. Когда мы передаем инструмент чтения теперь, он увидит только один параметр — имя файла. Он передаст имя файла. И он прочитает этот файл из этого каталога. Итак, мы зафиксировали параметр каталога. Теперь агент может читать файлы из этого каталога и записывать файлы только в этот каталог. Частичное применение функций — это отличный способ ограничить возможности вашего агента. Теперь ввод человека не требуется, но он все еще безопасен. Так что давайте посмотрим на это. Итак, снова запустим NPX agency examples. PFA — это частичное применение функций. Итак, здесь он думает, и вы можете видеть, что он прочитал файл. Ему не пришлось просить у нас разрешения. И теперь он сказал, знаете, чтобы исправить эту проблему, он дает нам новый код. Но он не обновляет код. Он спрашивает: "Хотите ли вы, чтобы я обновил файл этой исправленной функцией?" Но он сам этого не сделал. Так что, знаете, эта версия этого агента — лучшая из тех, что мы видели до сих пор, потому что она дает нам правильное решение без какого-либо человеческого вмешательства, но она еще не исправила код. Так что следующий шаг — заставить его фактически исправить код. И вот тут-то и появляется цикл обратной связи. Существует очень популярный шаблон агента под названием React. React означает "reason and act" (рассуждать и действовать). И, по сути, вы просите агента работать в этом цикле. Где вы рассуждаете, действуете, наблюдаете последствия своего действия, а затем решаете, что делать дальше. Так что в данном случае рассуждайте, читайте два файла, действуйте, запускайте тесты, наблюдайте, если тесты не проходят, читайте ошибку, а затем снова рассуждайте. Так что посмотрите на этот сбой теста и подумайте, что вы хотите сделать дальше. И просто делайте это в цикле, пока тесты не пройдут. Так что это очень ключевой шаблон для улучшения агента. И так, давайте теперь посмотрим на того же агента. Единственное, что мы меняем, — это промпт и даем ему возможность запускать эти тесты, и теперь агент должен работать лучше. В данном случае я также буду выводить все вызовы инструментов, чтобы вы могли видеть, что происходит. Ну, может быть, хорошо, подождите. Он всегда там. Вот оно. Окей. Теперь давайте посмотрим на это в действии. Итак, теперь вы можете видеть, что он вызывает инструменты. Он читает эти два файла, как мы сказали. Он запускает тесты. Тесты не проходят. Он записывает в файл. Он снова запускает тест и подтверждает успех. Так что это очень важный этап в разработке обвязки, потому что теперь у нас наконец-то есть агент, который успешно решает задачу, проверяет, что код не работает, изменяет код и проверяет, что код теперь работает. Итак, давайте поговорим о том, как мы улучшили обвязку до сих пор. Итак, мы начали просто с модели, она не могла ничего сделать. Затем мы добавили инструменты, но агент не был безопасен. Затем мы добавили обработчики, которые добавили безопасность, но требовали человеческого вмешательства. Затем мы добавили частичное применение функций, которое было безопасным и быстрым. Затем мы добавили рассуждение, которое дало нам большую уверенность в выводе агента. И, наконец, последний, который мы только что рассмотрели, — это цикл обратной связи, который добавил рассуждение. Так что агент внес изменение и подтвердил, что изменение сработало. Итак, у меня есть еще два примера. В этом мы пойдем немного в другом направлении. И вот здесь мы переходим к некоторым более продвинутым концепциям. Так что это суб-агенты. Все, что мы делали до сих пор, улучшало одну и ту же задачу. Но с суб-агентами мы спрашиваем: "Как заставить агента делать больше?" И позвольте мне быстро показать вам, как выглядит этот код. Окей. Так, эта программа, я начну с того, что покажу вам промпт, который мы ей даем, потому что он немного отличается. Итак, исправьте сбойный тест в test median.py. Затем исследуйте неравенство Йенсена для медиан с помощью агента Wikipedia и объясните его мне в сетевой форме. Итак, вот случай, когда мы фактически просим агента сделать немного больше, верно? И этот интересен тем, что это наш основной агент, но для инструментов мы не даем ему функции чтения и записи. Вместо этого мы даем ему два суб-агента в качестве инструментов. И мне очень нравится этот шаблон в Agency, потому что я видел, как многие фреймворки делают суб-агентов своей собственной концепцией и делают их трудными для понимания. В Agency суб-агент — это просто еще одна функция. И вы просто вызываете ее, используете как инструмент, как и везде. И эта последовательность имеет много преимуществ. Делает его очень простым в написании и понимании. Итак, вот суб-агент кодирующего агента. Тот же, что и раньше. Знаете, есть системное сообщение. Этот суб-агент имеет свой собственный вызов LLM, получает свой собственный набор инструментов. >> [хмыкает] >> Аналогично, у вас есть агент Wikipedia, у которого есть свой собственный инструмент — инструмент поиска. Который является инструментом, встроенным в эту стандартную библиотеку Agency, который позволяет вам искать в Wikipedia. Итак, Agency имеет большую стандартную библиотеку, которая позволяет вам делать всевозможные вещи, включая этот инструмент поиска Wikipedia. Я также использую функцию обратного вызова для вывода информации о вызове инструмента. И теперь давайте посмотрим на этот пример в действии. И это пример, где мы фактически просим агента сделать немного больше. И мы даем ему двух суб-агентов для выполнения его задачи. Итак, здесь вы можете видеть, что он вызывает эти два суб-агента. Он вызывает их параллельно, так что агент Wikipedia выполняет поиск, кодирующий агент изменяет файл, и это исправило ошибку, и теперь вот лимерик. Так что суб-агенты — это круто, потому что они позволяют вам добавлять новые возможности без раздувания контекста. И это хороший шаблон, потому что он позволяет вашему агенту, когда у него есть много различных инструментов в его распоряжении, позволяет вашему агенту делать правильные вещи более последовательно. Часто, когда агенты путаются и терпят неудачу, это потому, что у них слишком много контекстного раздувания, но также и потому, что у них слишком много несвязанных концепций в контексте. И у них слишком много инструментов, которые не связаны. И поэтому им трудно выбрать правильный инструмент для использования. В данном случае мы делаем эту проблему намного чище. Для агента верхнего уровня мы просто говорим: "Выберите суб-агента, которого вы хотите вызвать". А затем у суб-агентов есть эти инструменты, которые как бы сгруппированы таким образом, что имеет смысл. Итак, теперь давайте посмотрим на последний пример, который является самооптимизацией. В Agency встроен оптимизатор Japa. У него есть несколько оптимизаторов, но Japa — очень интересный. И то, как работает функция оптимизации, заключается в том, что вы помечаете любые переменные, которые вы хотите, чтобы оптимизатор оптимизировал. Вы можете просто использовать этот модификатор optimize. А затем вы запускаете оптимизатор и даете ему цель. Так что, знаете, в данном случае вы можете видеть, что два начальных промпта у меня очень простые. Я даю ему почти никакой информации. А затем цель, которую я ему даю, — "Исправить ошибку в median.py, используя TDD". И причина, по которой это такой большой шаг для нашей обвязки, заключается в том, что мы больше не делаем проб и ошибок. Мы больше не просто пробуем что-то, чтобы увидеть, что работает. Вместо этого теперь у нас есть способ систематически измерять и улучшать производительность. Так что я просто собираюсь запустить этот код. Я на самом деле также сброшу. Здесь я изменю этот код. Круто. Так что теперь я не буду показывать полный запуск здесь, потому что оптимизатор занимает время, но вы можете видеть, что сначала он проверяет, какие промпты у него есть, которые ему нужно оптимизировать. Он запустит агента, чтобы установить базовый уровень. Так что базовый показатель составляет 0,2, и он попытается его улучшить. Так что в данном случае я действительно запустил оптимизатор раньше, чтобы я мог показать вам, как выглядит полный запуск. И вот один, где вы можете видеть, что он достиг цели в первой итерации, так что на самом деле это было довольно быстро в данном случае. И вы можете видеть, что он переписал этот промпт. Так что причина, по которой эта самооптимизация так велика, заключается в том, что мы не угадываем и не проверяем. Мы систематически измеряем и улучшаем, что является большим скачком вперед. Итак, это лестница, по которой мы прошли для улучшения обвязки. Знаете, первый шаг был ничем, просто модель не могла даже прочитать файл. Затем мы добавили инструменты, но таким образом, что это было небезопасно и не разрешено в Agency. Далее мы добавили обработчики, которые добавили безопасность, но сделали вещи медленнее, потому что они требовали человеческого вмешательства. Затем мы добавили частичное применение функций, которое было безопасным и быстрым. Затем мы добавили рассуждение, которое дало нам большую уверенность в выводе агента. А затем мы переключились на суб-агентов, добавили больше возможностей, и, наконец, мы сделали самооптимизацию. Так что мы получили измеренное улучшение, а не угадывание и проверку. Так что, знаете, я надеюсь, что это даст вам представление о том, как вы можете создавать обвязки, а затем постепенно улучшать эти обвязки. И я надеюсь, знаете, вы попробуете сделать это и присоединитесь ко мне в этом, знаете, эксперименте, чтобы увидеть, сможем ли мы создать лучшую обвязку. Потому что что, если обвязка имеет большее значение, чем модель. Знаете, что если мы сможем создать достаточно хорошую обвязку, чтобы мы теперь могли начать использовать локальные модели и по-прежнему получать необходимую нам производительность для задач, которые мы хотим выполнять. Так что, какую поддержку на уровне языка предоставляет Agency? Знаете, мы использовали Agency для всех этих примеров. Как это помогло? Простой синтаксис для определения инструментов. Снова, знаете, простые вещи должны быть простыми. Каждому агенту понадобятся инструменты. Давайте сделаем их использование простым. Инструменты для безопасности, очень важные для агентов. Так что прерывания, обработчики, PFA. Истинная пауза и возобновление выполнения. Я не очень много об этом говорил, потому что не хотел делать этот доклад слишком длинным. Но одна из действительно убийственных функций Agency заключается в том, что когда вы вызываете это прерывание, оно фактически приостанавливает выполнение и возвращает управление пользователю. Но таким образом, что вы можете возобновить выполнение позже. И, насколько мне известно, очень немногие языки позволяют вам делать что-то подобное. И поэтому, как правило, большинство фреймворков, которые вы будете использовать, если у них есть функция "человек в контуре", имеют много ограничений. Есть много вещей, которые вам нужно сделать, чтобы обойти это. Agency полностью отличается. Если бы вы захотели, вы могли бы, знаете ли, вызывать прерывания внутри цикла for, внутри вызова инструмента, внутри суб-агента. И это правильно приостановит выполнение, вернется к пользователю, а затем возобновит выполнение в этой точной точке внутри этого суб-агента, внутри этого вызова инструмента, в этой точной точке этого цикла for. Что действительно круто. Вы можете сериализовать выполнение, вы можете вернуться к нему через неделю, и вам не нужно ничего менять во всем коде, который мы рассматривали. Это просто работает, что действительно круто. Он также имеет эти встроенные оптимизаторы, которые отлично подходят, знаете ли, которые помогают вам перейти к более аналитическому, математическому способу выполнения улучшений. Так что, если вы хотите попробовать, пожалуйста, сделайте это. Вы можете установить через PM. Все, что вам нужно, — это пакет и API-ключ, и вы готовы. Основные выводы, знаете ли, агент — это модель плюс обвязка, по крайней мере, для этого доклада. Лучшая обвязка = лучшая производительность, особенно для более слабых моделей. И затем, как построить лучшую обвязку? Дайте ей инструменты, сделайте ее безопасной, сделайте ее автономной, заставьте ее рассуждать, дайте ей суб-агентов и пусть она самооптимизируется. Большое спасибо. Снова, меня зовут Адитья Парих, проверьте agency agencylang.com, а затем, пожалуйста, подпишитесь на меня в Blue Sky, если хотите. Спасибо. Берегите себя.