Вашим навыкам нужен механизм оценки

Источник: Expo Blog•

Вашим навыкам нужен механизм оценки

Как в Expo проверяют, действительно ли агенты кодирования находят и используют навыки Expo, с помощью тестового инструмента в CI и уроков по усечению каталога.

Это совместный материал с Адитьей Шуклой, Картиком Гуптой и Дэвидом Тинглом из Georgian AI Lab. Мы объединили усилия с ними, чтобы оценить, как агенты программирования находят и используют навыки агента от Expo.

Основные выводы

  • Проверяйте, могут ли агенты находить навыки, а не только то, работают ли навыки при вызове. Прямой вызов не показывает, обнаружит ли агент навык во время обычной работы. Используйте реалистичные промпты задач и изучайте трассировку агента, чтобы увидеть, что он находит.
  • Создайте четкий навык-точку входа, чтобы помочь агентам находить специализированные руководства. В ходе 10 задач по созданию приложений доля агентов, загружающих релевантный навык Expo, выросла с 9% до 55% после того, как мы добавили expo-overview в качестве навыка точки входа.
  • Проектируйте для переполненных каталогов навыков. Когда много навыков делят между собой лимит каталога, описания можно сократить или опустить. Поместите самые важные подсказки в название и первое предложение вашего навыка и протестируйте его в реалистичном каталоге.

В Expo мы объединяем наши навыки агента в один плагин для Claude Code и Codex. Плагин охватывает довольно широкую область: в нем есть навыки для создания нативных интерфейсов, настройки навигации, получения данных, добавления анимаций, работы с модулями Expo и использования наших облачных сервисов. Мы постоянно дорабатываем эти навыки и добавляем лучший возможный контекст, чтобы они могли дополнять то, что агенты программирования уже знают, и помогать им принимать более правильные решения в ходе выполнения задач.

Однако некоторое время у нас не было надежного способа определить, действительно ли эти улучшения помогают. Мы сами пробовали ввести промпт, наблюдали, как агент делает что-то разумное, и радовались результату. Но написание навыков без оценок стало очень напоминать написание кода без тестов. Фраза «это работало с моим промптом» становилась еще одной версией фразы «это работало на моем компьютере».

Эта проблема связана с более широким выводом из опыта Georgian в области оценки: окончательный ответ не может показать нам все, что происходило в процессе. В статье Вашим ИИ-системам необходим цикл оценки Асна Шафик, участница Georgian AI Lab, описывает, как трассировки помогают командам наблюдать за поведением агентов, но для превращения этих наблюдений в нечто измеримое и улучшаемое необходимы оценки. Мы применили эту же идею к нашим навыкам: вместо того чтобы просто проверять, работает ли навык изолированно, нам нужно было протестировать, может ли агент найти правильное сочетание навыков во время рутинных задач по разработке приложений.

В способе тестирования нашей работы также присутствовала предвзятость. Поскольку мы являемся разработчиками и поддерживаем эти навыки, мы уже знали правильные паттерны использования. Если мы хотели протестировать навык Expo UI, мы вызывали /expo-ui в Claude Code или $expo-ui в Codex, а затем смотрели, как агент его использует.

Это показывает нам, является ли навык полезным в правильном направлении после его загрузки, но большинство пользователей не всегда вызывают навык по имени. Они с большей вероятностью опишут то, что им нужно: «Создай todo-приложение для iOS с Expo, чтобы оно выглядело нативным» или «Добавь вкладки и экран настроек в это приложение». Прежде чем какие-либо рекомендации внутри навыка смогут помочь, агент должен сначала распознать, что навык релевантен, и принять решение о его вызове.

У нас не было механизма для измерения многочисленных переменных в этом процессе.

Создание среды оценки

Чтобы решить именно эту проблему, мы разработали среду оценки совместно с нашими коллегами из Georgian. Их предыдущая работа над циклами оценки легла в основу дизайна: 1) определить, какие доказательства будут иметь значение до запуска, 2) зафиксировать траекторию агента для интересующей задачи и 3) сравнить поведение в контролируемых условиях.

На высоком уровне среда оценки принимает требования к продукту в качестве задачи, запускает по ней агента программирования и оценивает как процесс (траекторию агента и использование навыков), так и продукт (созданное мобильное приложение).

Определение того, что нужно измерять

Среда оценивает агента программирования с помощью задач, взятых из набора данных сценариев, которые, как мы выяснили, репрезентативно отражают то, как реальные пользователи создают продукты с помощью Expo. Сценарий может представлять собой сквозную задачу, например создание полноценного мобильного приложения за один запуск, или более детальную, например отладку постоянно падающей сборки для разработчиков или добавление функции в существующее приложение.

Любая надежная оценка строится на основе надежного набора проверок. Вместо того чтобы выводить эти проверки постфактум из траектории агента, каждый сценарий в нашем наборе данных аннотирован следующим образом:

  • какие навыки, по нашему мнению, агент сочтет полезными при выполнении данной задачи;
  • какие признаки следует искать, если выполняются рекомендации из навыков;
  • какие примитивные функции предполагает сквозная задача, которые наш агентский оценщик должен протестировать (QA).

Эти проверки дают нам три разных уровня доказательств:

  • Срабатывание навыка: загрузил ли агент навыки, имеющие отношение к задаче?
  • Усвоение навыка: видим ли мы свидетельства того, что агент следовал полученным рекомендациям?
  • Поведение приложения: собирается ли результирующее приложение и выполняет ли оно действия, описанные в PRD задачи?

Эти вопросы связаны между собой, но каждый из них проливает свет на отдельный аспект поведения агента, который мы наблюдали.

Навык не может повлиять на агента, если он никогда не загружается, поэтому необходимо измерять срабатывание навыка. Однако навык может быть загружен и проигнорирован, поэтому измерение признаков усвоения также имеет значение.

Агент также может создать работающую функцию на основе существующих знаний, вообще не обращаясь к навыку, который мы надеялись он использовать. Это абсолютно нормально! На самом деле, крайне важно не наказывать агента за правильное выполнение задачи, даже если он не прибегает к проверенным знаниям Expo. Более того, это сигнал о том, что навык мог быть поглощен растущими возможностями передовых моделей. Создание этих элементов в виде отдельных уровней оценки облегчило понимание того, в чем именно агенту программирования можно помочь больше всего.

Запуск агента программирования с вашей задачей

На первой итерации мы тестируем агентов программирования на более амбициозных сквозных сценариях: мы начинаем с документа требований к продукту (PRD), который фиксирует высокоуровневый промпт пользователя о желании создать конкретное мобильное приложение. Затем наша среда оценки развертывает агента программирования с этой задачей и записывает его траекторию в процессе создания, включая вызываемые им навыки. Как только агент завершает генерацию, среда упаковывает артефакты сборки в архив для передачи на следующие этапы.

Оценка как процесса, так и продукта

Затем среда запускает две параллельные задачи оценки, которые отвечают на ортогональные вопросы:

Статическая оценка: набор детальных детерминированных проверок, которые измеряют качество сборки созданного приложения, были ли вызваны какие-либо навыки за время траектории агента и попали ли рекомендации из этих навыков в созданный исходный код.

Оценка приложения: агентский оценщик, который может собрать и запустить мобильное приложение, созданное агентом программирования, а затем управлять приложением так, как это сделал бы пользователь, для проверки основных функциональных примитивов.

Рисунок 1. Среда оценки начинается с требований к продукту и ожидаемого поведения, передает задачу агенту кодирования и сохраняет созданное приложение и трассировку агента в качестве артефакта. Затем она раздельно оценивает срабатывание навыков, свидетельства применения навыков в дереве исходного кода и поведение приложения на iOS.

Запуск среды оценки в CI

Сама среда оценки запускается на базе рабочих процессов CICD в Expo, и мы подключаем ее к репозиторию Expo Skills, где Expo разрабатывает и поддерживает свой плагин. На сегодняшний день в любой момент, когда кто-то в Expo выпускает новый навык или обновляет существующие, он может запустить оценку прямо из пулл-реквеста, добавив метку eval. Затем среда просто запускает выбранные сценарии для версии плагина Expo в ветке main и версии в пулл-реквесте, а в конечном итоге выводит результаты этой оценки прямо в PR.

Теперь это все прочнее входит в цикл разработки в Expo: авторы навыков владеют своими задачами и проверками истинности (ground truth) и поддерживают их точно так же, как модульные тесты, поэтому сам плагин разрабатывается как код: внесите изменения, запустите их на наборе сценариев и изучите результаты, прежде чем принимать решение о дальнейших шагах.

Чем это нам помогло?

Одной из первых вещей, которые показали нам трассировки создания, было то, что ожидаемые навыки Expo практически никогда не загружались так, как нам хотелось бы.

Это было полезно, поскольку приложения все еще могли выглядеть внешне успешными. Агент уже обладал достаточными знаниями об Expo и React Native для создания кода, поэтому простой просмотр финального результата или сканирование нескольких файлов не обязательно раскрыли бы тот факт, что наш плагин никак не помог процессу. Трассировка сделала это очевидным.

У нас было несколько идей о том, почему это могло происходить.

  • Агент мог уже чувствовать уверенность в том, что сможет выполнить задачу, и поэтому никогда не искал дополнительных инструкций.
  • Описания в шапке (frontmatter) навыка могли неадекватно описывать ситуации, в которых должен использоваться каждый навык.
  • По мере роста плагина количество доступных навыков могло само по себе затруднять навигацию по коллекции.

Раньше мы могли спорить об этих可能性, обновлять описание и пробовать несколько промптов вручную. Теперь у нас появился механизм для их тестирования.

Мы начали с самого очевидного вмешательства — улучшения названий и описаний отдельных навыков. Описание — это то, что видит агент, когда решает, актуален ли навык, поэтому это казалось естественным началом. Эти изменения помогли нам прояснить назначение каждого навыка, но они не продвинули нас достаточно далеко.

Это привело нас обратно к третьей гипотезе, которая на самом деле была подозрением, вынашиваемым нами уже некоторое время…

Предоставление агенту точки входа в навыки Expo

Экосистема Expo охватывает множество областей: React Native, сам SDK Expo, Expo Router, модули Expo, нативные элементы пользовательского интерфейса и, конечно же, наши облачные сервисы. Вместе они предлагают невероятно мощный набор возможностей для разработки, развертывания и мониторинга приложений. Наличие специализированных навыков для каждого из них позволяет нам предоставлять подробные инструкции, не загружая всю экосистему Expo в контекст агента каждый раз. Но это также означает, что агенту приходится выбирать из более чем двадцати возможных навыков для начала работы.

Нам нужна была единая точка входа: та, которая могла бы помочь агенту войти в коллекцию, а затем ориентироваться в ней.

Результатом стал expo-overview: навык точки входа и маршрутизатор для всех задач Expo и EAS. Его описание определяет его как отправную точка для любого запроса, связанного с Expo, EAS или задачей React Native. Внутри навыка карта связывает общие цели с более узконаправленными навыками, содержащими соответствующие руководства. Он также управляет небольшим набором правил настройки, применимых ко всему плагину, таким как определение версии Expo SDK и установка пакетов с помощью npx expo install. Недавно Sentry и Convex пришли к аналогичному паттерну для своих собственных плагинов навыков: по сути, дать агенту четкое место для начала работы, а затем направить его к более специализированным инструкциям.

Этот обзорный навык не отменяет того факта, что агенту по-прежнему приходится просматривать более 20 навыков; скорее, он решает наблюдаемую нами проблему: часто агент просто вообще не вызывал никакой навык Expo.

Почему так могло происходить? Задача разработки приложений уже наделяет агента длинным списком решений, которые нужно принять в отношении архитектуры, зависимостей, навигации, состояния и реализации. Если ему также приходится выбирать из более чем двадцати навыков посреди всего остального, он может просто продолжить работу с тем, что уже знает, и никогда не обратиться ни к одному из них. Это предположение, но цель состоит в том, чтобы просто минимизировать энергию активации для обращения к навыку.

Рисунок 2. Точка входа минимизирует трение при первом переходе, увеличивая вероятность того, что агент обратится к нужному навыку.

Что показала среда оценки?

Мы добавили метку eval к пулл-реквесту, добавляющему этот новый навык, и позволили нашей среде оценки запустить те же три сценария приложения для существующего плагина и предлагаемого изменения. Первым обнадеживающим сигналом было то, что агент проговорил:

«Я начну с загрузки навыка expo-overview, так как эта задача связана с созданием приложения Expo/React Native...»

В другом сценарии агент объяснил то же решение еще более прямолинейно:

«Я начну с загрузки навыка Expo overview, так как он должен запускаться первыми для любой задачи Expo/EAS».

Это было то поведение, которого мы пытались добиться. Пользователь не упоминал expo-overview или какие-либо последующие навыки в запросе. Агент распознал более широкую задачу Expo, выбрал точку входа, а затем использовал информацию о маршрутизации внутри нее, чтобы решить, что еще загрузить.

Затем трассировки показали следующие навыки, загруженные по порядку для трех PRD из нашего набора данных:

  • Notes: expo-overview → expo-project-structure
  • Hot Chocolate: expo-overview → expo-project-structure → expo-router
  • Wiki Reader: expo-overview → expo-project-structure → expo-router → expo-ui

Обзорный навык загружался первым во всех трех запусках. Затем каждый запуск продолжался из обзорного навыка по меньшей мере в один соответствующий последующий навык. Как только агент преодолевает этот первый порог загрузки хотя бы одного навыка Expo, он, судя по всему, с гораздо большей вероятностью принимает решение второго порядка, чем тогда, когда все возможные навыки конкурировали за выбор одновременно.

С 10% сеансов агента, загружающих навык, до более чем 50%

Чтобы проверить, распространяется ли этот многообещающий первоначальный результат из PR на более широкий круг задач, мы повторно запустили Claude Code с sonnet-5-high, на этот раз для 10 PRD новых мобильных приложений. Пользовательский промпт упоминал Expo, но никогда не называл конкретный навык. Мы сравнили плагин до и после добавления expo-overview и выполнили по три запуска для каждого варианта, чтобы сгладить стохастичность в траектории агента.

В базовых запусках без expo-overview только около 10% сеансов агента принимали решение загрузить какой-либо навык Expo. С expo-overview этот показатель подскочил до 55% всех сеансов агента, загружающих 1 или более последующих навыков.

† Нисходящий навык (downstream skill) — это любой навык, не являющийся expo-overview. В базовом варианте, где expo-overview отсутствует, это просто любой навык Expo.

‡ Успешное применение (uptake) — это свидетельство наличия желаемых паттернов в созданном исходном коде, которые можно проверить статически.

Каждая сессия кандидата загрузила expo-overview. Это подтвердило нашу цель — предоставить агенту надежную точку входа для задачи, связанной с Expo. Что еще важнее, 55% сессий продолжили работу хотя бы с одним более специализированным навыком, по сравнению с лишь 9% базовых сессий, в которых навык загружался напрямую.

Показатель Relevant Skill Recall (полнота релевантных навыков) дает более строгую версию того же вопроса. Внутри датасета мы также определяем сопоставление подмножества навыков Expo, релевантных для каждого PRD. Это навыки, которые обеспечили бы полезные рекомендации для соответствующей задачи и которые, как мы ожидаем, агент должен вызвать. Этот показатель Relevant Skill Recall вырос с 2% до 18%, но остался неполным: даже после добавления expo-overview агент часто вызывал лишь подмножество релевантных навыков для большинства задач.

Анализ этого показателя для отдельных навыков дал нам больше интуитивного понимания:

Навыки, которые загружались чаще всего, были связаны с ранними, конкретными решениями, такими как создание структуры кодовой базы (expo-project-structure) или настройка маршрутов страниц (expo-router).

В одном PRD агент загрузил обзорный навык и перешел к действию: «(Позвольте мне) проверить навык project-structure для получения рекомендаций по созданию структуры». В другой задаче, насыщенной навигацией, он установил связь еще прямее: «Теперь давайте перенесем его на использование Expo Router (нужно для навигации по вкладкам) и проверим навык router на предмет шагов настройки». Оба примера представляли собой задачи, к которым агент приступил сразу после ознакомления с обзорным навыком, и поэтому он часто читал и соответствующий навык тоже.

Упущения оказались не менее интригующими: в одном случае агент загрузил expo-overview и expo-router, затем объявил, что будет строить основной слой данных, реализовал выборку RSS и Atom и протестировал реальные фиды, и все это ни разу не загрузив expo-data-fetching (возможно, самый релевантный навык для этой задачи), предпочитая опираться на врожденные знания. В другом примере агент загрузил expo-ui для элементов управления, но не загрузил expo-native-ui, хотя expo-overview рекомендует использовать их вместе. Сгенерированный код использовал Dimensions.get() и SafeAreaView от React Native — два паттерна, от которых его отговорило бы пропущенное руководство по Native UI.

Судя по этим случаям, агент вызывает релевантные навыки гораздо чаще в начале задачи, сразу после чтения Обзора. По мере продвижения по остальной части работы он с меньшей вероятностью вызывает релевантные навыки, предпочитая работать с другими источниками информации.

Одно из возможных объяснений заключается в том, что, хотя expo-overview является де-факто точкой входа, он не совсем воспринимается как общий маршрутизатор, к которому агент должен неоднократно возвращаться на протяжении всей задачи.

Это был первоначальный сигнал на основе горстки точек данных, и предстоит проделать еще много работы, чтобы более надежно направлять агентов к мудрости релевантных навыков. Но теперь мы могли видеть четкую разницу в поведении, на которое пытались повлиять. Это была та обратная связь, которой нам не хватало.

Подводные камни слишком большого количества навыков? Усечение!

Наши первые эксперименты проводились в Claude Code, но этот результат также заставил нас задуматься о том, как навыки представлены в других агентах кодинга. Мы заглянули «под капот» открытого Codex CLI, чтобы понять интерфейс, где происходит обнаружение навыков.

Сразу после системного промпта идет раздел Каталога навыков (Skill Catalog), содержащий имя каждого доступного навыка, его описание и путь к файлу. В Codex этот каталог имеет фиксированную общую длину, которую должны делить между собой все навыки, доступные агенту. Для проверяемой нами версии этот лимит был установлен ровно в 2% от контекстного окна, или 5440 токенов из 272k в целом.

Мы также долгое время задавались вопросом о влиянии скученности навыков: что происходит, когда навыки из нашего плагина конкурируют с другими навыками, не относящимися к Expo?

С помощью ряда контролируемых тестов мы выяснили, что когда полный каталог навыков превышал лимит в 5,4 тыс. токенов, Codex начинал с укорачивания описаний навыков, сохраняя только их начало. При еще большем количестве навыков описания исчезали полностью, оставляя только названия навыков. В конце концов это приводило к тому, что из каталога удалялись целиком целые навыки!

Мы наблюдали это в одной тестовой среде со 175 установленными навыками, включая 24 из плагина Expo. При контекстном окне в 272k мы обнаружили, что все навыки Expo были перечислены, но видны были только первые 60 или около того символов каждого описания.

Таким образом, по мере роста каталога доступных навыков агент выбирает из большего числа вариантов, получая при этом потенциально меньше информации о каждом из них. Самое название и вводные слова навыка уже могут иметь значение.

Кратко (TL;DR): если слишком много навыков борются за одни и те же 2% вашего контекстного окна, некоторые из их описаний (или даже сами навыки!) могут быть обрезаны! Убедитесь, что ваши устойчивы к этому!

Это также выявило скрытое допущение в нашей настройке: наш тестовый инструмент развертывает агента кодинга в чистой среде только с установленным плагином Expo, без какой-либо конкуренции с навыками от других поставщиков. Такая изоляция полезна при сравнении двух версий плагина, поскольку она устраняет несвязанные источники вариативности. Но это не обязательно то, как пользователи запускают агентов кодинга. У реального пользователя может быть установлено множество плагинов, и все они борются за один и тот же бюджет каталога и за внимание агента.

По сути, навыки необходимо оценивать в тех условиях, в которых мы ожидаем их обнаружения.

Изолированный каталог может подсказать нам, читаем ли навык сам по себе. Он не может сказать нам, остается ли этот навык видимым и отличным от других внутри переполненного каталога. Наш первоначальный эксперимент измерял первый случай. Но усечение, которое мы наблюдали в более репрезентативной локальной обстановке, предполагает, что второе, вероятно, тоже заслуживает собственного условия оценки!

Чему мы научились

Первый урок заключался в том, что группа полезных по отдельности навыков не обязательно объединяется в столь же эффективный плагин. Как только он вырастает больше чем до нескольких навыков, любому плагину, скорее всего, потребуется та или иная форма оркестрации информации. Агент должен понимать не только то, что говорит каждый навык, но и то, как навыки соотносятся друг с другом и с чего ему следует начать.

Второй урок заключался в том, что нам нужно было оценить то, как пользователи на самом деле взаимодействуют с плагином. Прямой вызов по-прежнему полезен, когда мы разрабатываем содержимое одного навыка, но он не может подсказать нам, обнаружит ли агент этот навык при обычном запросе. Начав с широких требований к продукту и читая полученные трассы, мы смогли напрямую наблюдать проблему выбора.

Это также включало оценку обстановки, в которой пользователи действительно взаимодействуют с плагином: когда множество других навыков также могут бороться за внимание, эффекты вашего дизайна могут выглядеть иначе. Поэтому окружение является не менее важной частью ваших оценок.

Третий урок заключался в том, что измерения процесса могут подсказать нам что-то полезное еще до того, как мы получим идеальный сквозной результат. Мы продолжаем улучшать проверки использования в тестовом окружении и App Evaluator, потому что в конечном итоге нас волнует, приводит ли руководство к созданию лучшего приложения. Но срабатывание — это необходимый первый шаг. Если навык никогда не попадает в контекст агента, качество содержащихся в нем инструкций не имеет значения для этого запуска.

Именно поэтому подключение тестового окружения к CI оказалось для нас важным. Мы не хотим, чтобы оценка навыков была разовым экспериментом, который мы проводим, когда уже ожидаем положительного результата. Мы хотим, чтобы это стало частью процесса разработки плагина: внести изменения, запустить реалистичные задачи, изучить трассировки и артефакты и использовать полученные знания для выбора следующего шага.

expo-overview стал первым полезным примером такого цикла. Тестовое окружение показало нам, что агенты не находят наши навыки. Мы изменили архитектуру коллекции, вместо того чтобы продолжать настраивать каждый навык по отдельности. Следующий запуск показал, что агент рассуждает о новой точке входа так, как мы и задумывали, и загружает больше последующих инструкций.

Это дало нам первый наглядный пример работы процесса: наблюдать, где агенты испытывают трудности, вносить точечные изменения и измерять, меняется ли их поведение.

Предстоит сделать еще многое. Но теперь у он нас есть механизм оценки. Он нужен и вам.

О чём эта статья