Главная / Статьи

Оценка агентов и навыков на практике: траектории, оценщики, параметры pass^k и инструменты

Как оценивать агентов и навыки: наборы триггеров и выполнения, порядок силы оценщика, точность и воспроизводимость, pass@k против pass^k, небольшой инструментарий на Python и выбор утилит.

Издатель: REACTAPP.TOP11 мин чтения2573 слов

Источники: Evals: A Crash Course for Agents and Skills

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

Ментальная модель

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

Оценивайте оба аспекта:

  • Результат: удовлетворяет ли готовый продукт поставленной задаче?
  • Траектория: выбирал ли агент правильные навыки и инструменты, избегал ли опасных действий и работал ли эффективно?

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

Уровни оценки

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

  • Выбор навыка. Был ли выбран правильный навык? Оцените точность, полноту и количество ложных срабатываний.
  • Соблюдение инструкций навыка. Соблюдались ли на самом деле инструкции навыка, включая необходимые шаги и запрещённые действия?
  • Использование инструментов. Правильно ли вызывались инструменты, с правильными аргументами, в разумном порядке и без ненужных вызовов?
  • Результат выполнения задачи. Работает ли полученный результат? На эти вопросы отвечают тесты, проверки схемы и поведенческие утверждения.
  • Качество. Является ли результат устойчивым и соответствующим требованиям? Решает это шкала оценки или рецензент.
  • Безопасность. Соблюдались ли ограничения в отношении конфиденциальной информации, разрушительных операций и внедрения команд?
  • Эффективность. Сколько ресурсов — токенов, времени задержки, вызовов и попыток — потребовалось для достижения результата?
  • Для навыка нужны два набора критериев

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

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

    - prompt: "Patch the vulnerable npm dependencies"
      expected_skill: cve-remediation
    - prompt: "Review authentication input validation"
      forbidden_skill: cve-remediation
    

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

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

    Как выглядит хороший пример

    Предпочитайте реалистичные снимки хранилищ данных вместо изолированных тривиальных примеров. Хороший пример является самодостаточным и может быть проверен машиной:

    {
      "id": "fix-null-condition",
      "prompt": "Fix saving rules with a null condition",
      "fixture": "repos/null-condition",
      "setup": ["npm install"],
      "checks": [
        "npm test -- null-condition.test.js",
        "git diff --check"
      ],
      "rubric": [
        "Fixes the root cause",
        "Preserves existing behavior",
        "Adds a regression test",
        "Avoids unrelated changes"
      ],
      "forbidden": [
        "deleting existing tests",
        "hard-coded fixture-specific output"
      ]
    }
    

    Инструменты оценки: используйте самый мощный из имеющихся

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

    1. точные утверждения
    2. компиляция и модульные или интеграционные тесты
    3. проверка схемы или дерева синтаксиса
    4. проверка поведения через браузер или API
    5. статический анализ траектории
    6. LLM, оценивающий результат по критериям
    7. человеческий аудит

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

    Показатели, которые стоит отслеживать

    • Доля успешных случаев — это процент запусков, прошедших все критические проверки.
    • Pass@k — это вероятность того, что хотя бы одна из k попыток окажется успешной.
    • Pass^k — это вероятность того, что все k попыток окажутся успешными, что является наиболее точным показателем надежности.
    • Точность и воспроизводимость маршрутизации описывают качество выбора стратегии.
    • Уровень регрессии учитывает случаи, когда ранее задачи проходили успешно, но теперь терпят неудачу.
    • Стоимость выполнения одной успешной задачи, медианное и крайнее время отклика, количество вызовов инструментов, частота повторных попыток и частота необходимости вмешательства человека также должны отображаться на панели управления.

    Для производственных агентов стабильная надежность обычно важнее впечатляющих результатов в идеальных условиях.

    Создание набора данных

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

    Затем разделите их на три набора:

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

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

    Рабочий цикл

    Рассматривайте это как тест-ориентированное разработчество для поведения агентов:

    1. Зафиксируйте реальный сбой.
    2. Преобразуйте его в воспроизводимый пример теста.
    3. Запишите оценку до того, как взаимодействовать с навыком или агентом.
    4. Проведите несколько базовых тестов.
    5. Внесите одну целенаправленную изменение.
    6. Повторно запустите тестирование по целевому случаю вместе со всем набором тестов на регрессию.
    7. Сравните качество, надежность, задержку и стоимость.
    8. Оставьте изменение только в том случае, если улучшится общее соотношение показателей.

    Частые ошибки

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

    Показатели маршрутизации в конкретных терминах

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

    • Истинно положительный результат (TP): активация была необходима и действительно произошла.
    • Ложно положительный результат (FP): активация не должна была произойти, но произошла — ложная активация.
    • Ложно отрицательный результат (FN): активация должна была произойти, но не произошла.
    • Истинно отрицательный результат (TN): активация не должна была произойти, и действительно не произошла.

    Точность показывает, с какой частотой активация была правильной: TP делено на (TP + FP). Если навык активировался десять раз, и восемь из них были правильными, то точность составляет 80%. Высокая точность означает мало ложных активаций.

    Показатель воспроизводимости показывает, сколько из запросов, требовавших определенного навыка, было действительно обработано: TP делено на (TP + FN). Если десять запросов требовали этого навыка, а было обработано семь, то показатель воспроизводимости составляет 70%.

    Ложное срабатывание — это просто ложноположительный результат. Примером может служить запрос «Upgrade React dependencies», который ошибочно запускает процедуру проверки безопасности. Множество ложных срабатываний означает низкую точность.

    Матрица путаницы учитывает всё. При значениях TP = 8, FN = 2, FP = 3 и TN = 7 запросы, которые должны были вызвать реакцию, делятся на 8 и 2, а запросы, которые не должны были её вызвать, — на 3 и 7. Точность составляет 8 / 11, примерно 72,7%, а показатель воспроизводимости — 8 / 10, то есть 80%. Высокая точность означает, что навык редко активируется по ошибке. Высокая воспроизводимость означает, что он редко упускает релевантные запросы. Широко сформулированные условия срабатывания обычно повышают показатель воспроизводимости, но снижают точность.

    С чего начать

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

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

    Минимальная структура, которую можно скопировать

    Достаточно теории. Небольшой скрипт на чистом Python с использованием только стандартной библиотеки может оценить как процесс маршрутизации навыка, так и результат выполнения задачи агентом. Состоящий примерно из 70 строк кода демонстрирует все вышеупомянутые элементы: примеры данных, многоуровневые системы оценки, повторные запуски и показатели надежности.

    Структура папок:

    evals/
      cases/
        skills/security-review.trigger.json
        agents/fix-null-condition.json
      graders.py
      metrics.py
      runner.py
      run.py        # CLI entry1. Case files. A skill trigger case is just positives and negatives. An agent case is a prompt plus graders and a run count.
    

    В файле случая триггера перечисляется имя навыка вместе с указаниями о том, что должно и чего не должно его активировать:

    // cases/skills/security-review.trigger.json
    {
      "skill": "security-review",
      "positives": [
        "Audit this endpoint for SQL injection",
        "Check the login flow for auth bypasses",
        "Is this file-upload handler safe?"
      ],
      "negatives": [
        "Upgrade React dependencies",
        "Rename this variable across the repo",
        "Add a loading spinner to the form"
      ]
    }
    

    В досье агента указываются идентификатор, задание, необходимые элементы и проверки, которые следует применить:

    // cases/agents/fix-null-condition.json
    {
      "id": "fix-null-condition",
      "prompt": "Fix saving rules with a null condition",
      "fixture": "fixtures/null-condition",
      "setup": ["npm ci"],
      "runs": 5,
      "graders": [
        { "type": "shell", "cmd": "npm test -- null-condition", "critical": true },
        { "type": "shell", "cmd": "git diff --check" },
        { "type": "forbidden", "pattern": "it\\.skip|xit\\(", "message": "must not disable tests" }
      ]
    }
    

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

    # graders.py
    import re, subprocess
    def shell(step, ctx):
        r = subprocess.run(step["cmd"], cwd=ctx.workdir, shell=True,
                           capture_output=True, text=True)
        ok = r.returncode == 0
        return {"pass": ok, "score": 1 if ok else 0, "detail": r.stdout[-400:]}
    def forbidden(step, ctx):
        bad = re.search(step["pattern"], ctx.diff) is not None
        return {"pass": not bad, "score": 0 if bad else 1,
                "detail": step["message"] if bad else ""}
    def judge(step, ctx):
        v = ctx.llm.rate(step["rubric"], ctx.artifact)  # 0..1, blinded
        return {"pass": v >= step.get("threshold", 0.7), "score": v}
    GRADERS = {"shell": shell, "forbidden": forbidden, "judge": judge}3. Metrics. Success rate, pass@k, pass^k, and the routing confusion matrix — exactly the numbers from earlier.
    

    Модуль метрик преобразует списки результатов выполнения в числа:

    # metrics.py
    def success_rate(rs):
        return sum(1 for r in rs if r["pass"]) / len(rs)
    def pass_at_k(rs):
        return 1 if any(r["pass"] for r in rs) else 0
    def pass_hat_k(rs):
        return 1 if all(r["pass"] for r in rs) else 0
    def routing(positives, negatives, fired):
        tp = sum(1 for p in positives if fired(p))
        fp = sum(1 for n in negatives if fired(n))
        fn = len(positives) - tp
        tn = len(negatives) - fp
        return {"tp": tp, "fp": fp, "fn": fn, "tn": tn,
                "precision": tp / (tp + fp or 1),
                "recall": tp / (tp + fn or 1)}4. The runner. One function per suite. The agent runner repeats each case so pass^k is meaningful; the skill runner just asks the router which skills fire.
    

    Запускающий процесс загружает кейсы, вызывает оценщиков, повторяет каждый запуск и выводит метрики:

    # runner.py
    import json
    from graders import GRADERS
    from metrics import success_rate, pass_at_k, pass_hat_k, routing
    def run_agent_case(agent, path):
        c = json.load(open(path))
        runs = []
        for _ in range(c.get("runs", 3)):
            ctx = agent.run(c["prompt"], fixture=c["fixture"], setup=c["setup"])
            ok = True
            for step in c["graders"]:
                g = GRADERS[step["type"]](step, ctx)
                if step.get("critical") and not g["pass"]:
                    ok = False
            runs.append({"pass": ok})
        return {"id": c["id"], "success": success_rate(runs),
                "pass_at_k": pass_at_k(runs), "pass_hat_k": pass_hat_k(runs)}
    def run_skill_trigger(router, path):
        c = json.load(open(path))
        fired = lambda prompt: c["skill"] in router.route(prompt)
        return {"skill": c["skill"], **routing(c["positives"], c["negatives"], fired)}5. Run it. The CLI just dispatches on the case type and prints the metrics.
    

    При его запуске получается вывод следующего вида:

    $ python run.py cases/agents/fix-null-condition.json
    fix-null-condition   success=0.80   pass@5=1.00   pass^5=0.20
    $ python run.py cases/skills/security-review.trigger.json
    security-review      precision=0.86  recall=1.00   (tp=6 fp=1 fn=0 tn=5)
    

    Читайте эти строки так, как рекомендуется вся данная методология. Агент выполняет четыре запуска из пяти, поэтому параметр pass@5 кажется идеальным, однако значение pass^5 в 0,20 указывает на то, что он пока ненадежен. Этот инструмент обрабатывает каждый подлинный запрос с точностью воспроизведения 1,0, но один раз сработал там, где не следовало, при точности 0,86, так что есть один ложный сигнал, который необходимо устранить.

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

    Используйте готовые фреймворки, когда это возможно

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

    Общие принципы формулировки запросов и оценки LLM

    OpenAI Evals — это первоначальная платформа в стиле реестра, предусматривающая определение тестов в формате YAML с использованием инструментов оценки на Python для любых моделей; она подходит для проверки результатов вывода и классификации. promptfoo основан на настройках, отображает промпты для моделей в виде матрицы плечом к плечу, включает проверки типа contains, регулярных выражений, JSON-схемы и критериев оценки LLM, а также имеет режим красной команды, что делает его хорошим стартом для определения навыков и выявления регрессий в промптах. DeepEval функционирует как pytest для LLM, предоставляя показатели точности, релевантности и галлюцинаций, а также пользовательские критерии оценки G-Eval, и легко интегрируется в процессы CI. Ragas ориентирован специально на пайплайны RAG, оценивая точность и воспроизводимость контекста, точность ответов и их релевантность. Функция оценки LLM в MLflow позволяет отслеживать и сравнивать результаты, если MLflow уже используется.

    Отслеживание, наборы данных и платформы для оценки

    LangSmith предлагает наборы данных, инструменты для отслеживания траекторий и функции оценки, которые полезны, когда необходимо изучить весь ход выполнения вместо просто результата. Langfuse — это программное обеспечение с открытым исходным кодом, позволяющее размещать его на собственном сервере и работающее с любыми моделями; он включает инструменты для отслеживания, оценки и работы с наборами данных для мониторинга в производственных условиях. Braintrust рассматривает процессы оценки как часть системы непрерывной интеграции, предоставляя функции оценки, наборы данных с версионированием и возможность сравнения результатов экспериментов. Arize Phoenix основан на технологии OpenTelemetry для отслеживания и включает шаблоны оценки, удобные для выявления регрессий в реальном трафике. Inspect от Британского института безопасности ИИ — это тщательно спроектированная платформа для решения задач и оценки, которая активно используется для серьезных оценок агентов и уровня безопасности.

    Критерии оценки агентов

    SWE-bench и SWE-bench Verified являются стандартом для определения того, может ли агент решить реальную проблему в GitHub, причем в качестве критерия оценки используются собственные тесты репозитория. AgentBench, WebArena, GAIA и τ-bench предоставляют внешние критерии для оценки использования инструментов, выполнения веб-задач и работы многоэтапных агентов. Фреймворки вроде AutoGen и LangGraph предоставляют механизмы тестирования для проверки вызовов инструментов и промежуточных шагов.

    Выбор

    • Для работы с промптами и маршрутизацией навыков promptfoo — самый быстрый способ настройки и добавления проверок.
    • Для метрик, ориентированных на код и используемых в CI, рассмотрите DeepEval или Braintrust.
    • Для оценки динамики работы многоэтапных агентов обратите внимание на LangSmith, Langfuse или Inspect.
    • Для технологии RAG добавьте Ragas.
    • Для реального тестирования кодирующих агентов используйте SWE-bench Verified.

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