newsmode
search
Меню
arrow_back Назад

Your AI Product Needs Evals –

auto_awesomeКраткое саммари

Хамель Хусейн, независимый консультант по AI-продуктам и в прошлом руководитель команды CodeSearchNet (предшественника GitHub CoPilot), утверждает, что почти все неудачные LLM-продукты объединяет одна причина — отсутствие надёжных систем оценки (evals). На примере Lucy, AI-ассистента для риелторов от компании Rechat, он показывает, как систематическая оценка помогает преодолеть плато, когда prompt engineering перестаёт работать и правки превращаются в игру «убей крота». Автор описывает три уровня оценки: Level 1 — быстрые юнит-тесты и ассерты (у Rechat их сотни), Level 2 — человеческая и модельная оценка с логированием трейсов (Rechat использует LangSmith и Metabase), Level 3 — A/B-тестирование для зрелых продуктов. Ключевая мысль: нужно убрать все барьеры на пути к просмотру данных, писать много тестов под свою задачу и не покупать дорогие универсальные инструменты. Хорошая система оценки бесплатно открывает «суперспособности» — fine-tuning, синтез и курирование данных, а также быстрый дебаггинг, поскольку инфраструктура для них во многом совпадает.

Motivation

Мотивация

I started working with language models five years ago when I led the team that created CodeSearchNet, a precursor to GitHub CoPilot. Since then, I’ve seen many successful and unsuccessful approaches to building LLM products. I’ve found that unsuccessful products almost always share a common root cause: a failure to create robust evaluation systems.

Я начал работать с языковыми моделями пять лет назад, когда возглавлял команду, создавшую CodeSearchNet — предшественника GitHub CoPilot. С тех пор я повидал немало удачных и неудачных подходов к созданию LLM-продуктов. Я обнаружил, что у неудачных продуктов почти всегда одна общая первопричина: неспособность построить надёжные системы оценки.

I’m currently an independent consultant who helps companies build domain-specific AI products. I hope companies can save thousands of dollars in consulting fees by reading this post carefully. As much as I love making money, I hate seeing folks make the same mistake repeatedly.

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

This post outlines my thoughts on building evaluation systems for LLMs-powered AI products.

В этой статье изложены мои мысли о построении систем оценки для AI-продуктов на базе LLM.

Iterating Quickly == Success

Быстрая итерация == успех

Like software engineering, success with AI hinges on how fast you can iterate. You must have processes and tools for:

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

  • Evaluating quality (ex: tests).
  • Debugging issues (ex: logging & inspecting data).
  • Changing the behavior or the system (prompt eng, fine-tuning, writing code)
  • Оценивать качество (например, тесты). Отлаживать проблемы (например, логирование и инспекция данных). Менять поведение или саму систему (prompt engineering, дообучение, написание кода).

    Many people focus exclusively on #3 above, which prevents them from improving their LLM products beyond a demo.1 Doing all three activities well creates a virtuous cycle differentiating great from mediocre AI products (see the diagram below for a visualization of this cycle).

    Многие сосредотачиваются исключительно на пункте №3 выше, что не даёт им вывести свои LLM-продукты дальше уровня демо.1 Хорошее выполнение всех трёх активностей создаёт благотворный цикл, отличающий отличные AI-продукты от посредственных (визуализацию этого цикла см. на схеме ниже).

    If you streamline your evaluation process, all other activities become easy. This is very similar to how tests in software engineering pay massive dividends in the long term despite requiring up-front investment.

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

    To ground this post in a real-world situation, I’ll walk through a case study in which we built a system for rapid improvement. I’ll primarily focus on evaluation as that is the most critical component.

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

    Case Study: Lucy, A Real Estate AI Assistant

    Кейс: Lucy, AI-ассистент для недвижимости

    Rechat is a SaaS application that allows real estate professionals to perform various tasks, such as managing contracts, searching for listings, building creative assets, managing appointments, and more. The thesis of Rechat is that you can do everything in one place rather than having to context switch between many different tools.

    Rechat — это SaaS-приложение, позволяющее специалистам по недвижимости выполнять самые разные задачи: управлять контрактами, искать листинги, создавать креативные материалы, управлять встречами и многое другое. Идея Rechat в том, что всё можно делать в одном месте, а не переключаться между множеством разных инструментов.

    Rechat’s AI assistant, Lucy, is a canonical AI product: a conversational interface that obviates the need to click, type, and navigate the software. During Lucy’s beginning stages, rapid progress was made with prompt engineering. However, as Lucy’s surface area expanded, the performance of the AI plateaued. Symptoms of this were:

    AI-ассистент Rechat по имени Lucy — это образцовый AI-продукт: диалоговый интерфейс, избавляющий от необходимости кликать, печатать и перемещаться по программе. На ранних этапах развития Lucy быстрый прогресс достигался за счёт prompt engineering. Однако по мере расширения охвата Lucy производительность AI вышла на плато. Симптомами этого были:

  • Addressing one failure mode led to the emergence of others, resembling a game of whack-a-mole.
  • There was limited visibility into the AI system’s effectiveness across tasks beyond vibe checks.
  • Prompts expanded into long and unwieldy forms, attempting to cover numerous edge cases and examples.
  • Устранение одного режима отказа приводило к появлению других — это напоминало игру «убей крота». Видимость эффективности AI-системы по разным задачам была ограничена и сводилась к проверкам «на ощущение». Промпты разрастались в длинные и громоздкие конструкции, пытаясь охватить многочисленные крайние случаи и примеры.

    Problem: How To Systematically Improve The AI?

    Проблема: как систематически улучшать AI?

    To break through this plateau, we created a systematic approach to improving Lucy centered on evaluation. Our approach is illustrated by the diagram below.

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

    This diagram is a best-faith effort to illustrate my mental model for improving AI systems. In reality, the process is non-linear and can take on many different forms that may or may not look like this diagram.

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

    I discuss the various components of this system in the context of evaluation below.

    Различные компоненты этой системы я разбираю ниже в контексте оценки.

    The Types Of Evaluation

    Типы оценки

    Rigorous and systematic evaluation is the most important part of the whole system. That is why “Eval and Curation” is highlighted in yellow at the center of the diagram. You should spend most of your time making your evaluation more robust and streamlined.

    Строгая и систематическая оценка — важнейшая часть всей системы. Именно поэтому блок «Eval and Curation» выделен жёлтым в центре схемы. Бо́льшую часть времени вам следует тратить на то, чтобы сделать вашу оценку более надёжной и отлаженной.

    There are three levels of evaluation to consider:

    Стоит рассмотреть три уровня оценки:

  • Level 1: Unit Tests
  • Level 2: Model & Human Eval (this includes debugging)
  • Level 3: A/B testing
  • Level 1: Юнит-тесты. Level 2: Модельная и человеческая оценка (включая отладку). Level 3: A/B-тестирование.

    The cost of Level 3 > Level 2 > Level 1. This dictates the cadence and manner you execute them. For example, I often run Level 1 evals on every code change, Level 2 on a set cadence and Level 3 only after significant product changes. It’s also helpful to conquer a good portion of your Level 1 tests before you move into model-based tests, as they require more work and time to execute.

    Стоимость Level 3 > Level 2 > Level 1. Это определяет частоту и способ их выполнения. Например, Level 1 я часто запускаю при каждом изменении кода, Level 2 — с заданной периодичностью, а Level 3 — только после значимых изменений в продукте. Также полезно покрыть значительную часть тестов Level 1, прежде чем переходить к тестам на базе моделей, поскольку последние требуют больше работы и времени на выполнение.

    There isn’t a strict formula as to when to introduce each level of testing. You want to balance getting user feedback quickly, managing user perception, and the goals of your AI product. This isn’t too dissimilar from the balancing act you must do for products more generally.

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

    Level 1: Unit Tests

    Level 1: Юнит-тесты

    Unit tests for LLMs are assertions (like you would write in pytest). Unlike typical unit tests, you want to organize these assertions for use in places beyond unit tests, such as data cleaning and automatic retries (using the assertion error to course-correct) during model inference. The important part is that these assertions should run fast and cheaply as you develop your application so that you can run them every time your code changes. If you have trouble thinking of assertions, you should critically examine your traces and failure modes. Also, do not shy away from using an LLM to help you brainstorm assertions!

    Юнит-тесты для LLM — это ассерты (вроде тех, что вы писали бы в pytest). В отличие от обычных юнит-тестов, эти ассерты стоит организовать так, чтобы их можно было использовать не только в юнит-тестах, но и, например, при очистке данных и автоматических повторах (используя ошибку ассерта для коррекции) во время инференса модели. Важно, чтобы эти ассерты выполнялись быстро и дёшево по ходу разработки приложения, чтобы вы могли запускать их при каждом изменении кода. Если вам трудно придумывать ассерты, критически изучите ваши трейсы и режимы отказа. И не стесняйтесь использовать LLM, чтобы помочь себе с мозговым штурмом ассертов!

    Step 1: Write Scoped Tests

    Шаг 1: Пишите тесты с ограниченной областью

    The most effective way to think about unit tests is to break down the scope of your LLM into features and scenarios. For example, one feature of Lucy is the ability to find real estate listings, which we can break down into scenarios like so:

    Эффективнее всего думать о юнит-тестах, разбивая область действия вашей LLM на функции (features) и сценарии. Например, одна из функций Lucy — способность находить листинги недвижимости, которую мы можем разбить на сценарии так:

    Feature: Listing Finder

    Функция: Поиск листингов (Listing Finder)

    This feature to be tested is a function call that responds to a user request to find a real estate listing. For example, “Please find listings with more than 3 bedrooms less than $2M in San Jose, CA”

    Тестируемая функция — это вызов функции, отвечающий на запрос пользователя найти листинг недвижимости. Например: «Найди, пожалуйста, листинги с более чем 3 спальнями дешевле $2M в Сан-Хосе, Калифорния».

    The LLM converts this into a query that gets run against the CRM. The assertion then verifies that the expected number of results is returned. In our test suite, we have three user inputs that trigger each of the scenarios below, which then execute corresponding assertions (this is an oversimplified example for illustrative purposes):

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


    There are also generic tests that aren’t specific to any one feature. For example, here is the code for one such generic test that ensures the UUID is not mentioned in the output:

    Есть также общие тесты, не привязанные к какой-то конкретной функции. Например, вот код одного такого общего теста, который проверяет, что UUID не упоминается в выводе:

    const noExposedUUID = message => { // Remove all text within double curly braces const sanitizedComment = message.comment.replace(/\{\{.*?\}\}/g, '') // Search for exposed UUIDs const regexp = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/ig const matches = Array.from(sanitizedComment.matchAll(regexp)) expect(matches.length, 'Exposed UUIDs').to.equal(0, 'Exposed UUIDs found') }

    const noExposedUUID = message => { // Remove all text within double curly braces const sanitizedComment = message.comment.replace(/\{\{.*?\}\}/g, '') // Search for exposed UUIDs const regexp = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/ig const matches = Array.from(sanitizedComment.matchAll(regexp)) expect(matches.length, 'Exposed UUIDs').to.equal(0, 'Exposed UUIDs found') }

    CRM results returned to the LLM contain fields that shouldn’t be surfaced to the user; such as the UUID associated with an entry. Our LLM prompt tells the LLM to not include UUIDs. We use a simple regex to assert that the LLM response doesn’t include UUIDs.

    Результаты из CRM, возвращаемые в LLM, содержат поля, которые не должны показываться пользователю, — например, UUID, связанный с записью. Наш промпт для LLM указывает модели не включать UUID. Мы используем простой regex, чтобы убедиться (ассертом), что ответ LLM не содержит UUID.

    Rechat has hundreds of these unit tests. We continuously update them based on new failures we observe in the data as users challenge the AI or the product evolves. These unit tests are crucial to getting feedback quickly when iterating on your AI system (prompt engineering, improving RAG, etc.). Many people eventually outgrow their unit tests and move on to other levels of evaluation as their product matures, but it is essential not to skip this step!

    У Rechat сотни таких юнит-тестов. Мы постоянно обновляем их на основе новых отказов, которые наблюдаем в данных, когда пользователи бросают вызов AI или когда продукт развивается. Эти юнит-тесты крайне важны для быстрого получения обратной связи при итерациях над вашей AI-системой (prompt engineering, улучшение RAG и т. д.). Многие со временем перерастают свои юнит-тесты и переходят к другим уровням оценки по мере зрелости продукта, но крайне важно не пропускать этот шаг!

    Step 2: Create Test Cases

    Шаг 2: Создавайте тест-кейсы

    To test these assertions, you must generate test cases or inputs that will trigger all scenarios you wish to test. I often utilize an LLM to generate these inputs synthetically; for example, here is one such prompt Rechat uses to generate synthetic inputs for a feature that creates and retrieves contacts:

    Чтобы протестировать эти ассерты, нужно сгенерировать тест-кейсы или входные данные, которые запустят все сценарии, которые вы хотите проверить. Я часто использую LLM для синтетической генерации таких входных данных; например, вот один из промптов, который Rechat использует для генерации синтетических входов для функции, создающей и извлекающей контакты:

    Write 50 different instructions that a real estate agent can give to his assistant to create contacts on his CRM. The contact details can include name, phone, email, partner name, birthday, tags, company, address and job. For each of the instructions, you need to generate a second instruction which can be used to look up the created contact. . The results should be a JSON code block with only one string as the instruction like the following: [ ["Create a contact for John (johndoe@apple.com)", "What's the email address of John Smith?"] ]

    Write 50 different instructions that a real estate agent can give to his assistant to create contacts on his CRM. The contact details can include name, phone, email, partner name, birthday, tags, company, address and job. For each of the instructions, you need to generate a second instruction which can be used to look up the created contact. . The results should be a JSON code block with only one string as the instruction like the following: [ ["Create a contact for John (johndoe@apple.com)", "What's the email address of John Smith?"] ]

    Using the above prompt, we generate test cases like below:

    Используя приведённый выше промпт, мы генерируем тест-кейсы вроде следующих:

    [ [ 'Create a contact for John Smith (johndoe@apple.com) with phone number 123-456-7890 and address 123 Apple St.', 'What\'s the email address of John Smith?' ], [ 'Add Emily Johnson with phone 987-654-3210, email emilyj@email.com, and company ABC Inc.', 'What\'s the phone number for Emily Johnson?' ], [ 'Create a contact for Tom Williams with birthday 10/20/1985, company XYZ Ltd, and job title Manager.', 'What\'s Tom Williams\' job title?' ], [ 'Add a contact for Susan Brown with partner name James Brown, and email susanb@email.com.', 'What\'s the partner name of Susan Brown?' ], ]

    [ [ 'Create a contact for John Smith (johndoe@apple.com) with phone number 123-456-7890 and address 123 Apple St.', 'What\'s the email address of John Smith?' ], [ 'Add Emily Johnson with phone 987-654-3210, email emilyj@email.com, and company ABC Inc.', 'What\'s the phone number for Emily Johnson?' ], [ 'Create a contact for Tom Williams with birthday 10/20/1985, company XYZ Ltd, and job title Manager.', 'What\'s Tom Williams\' job title?' ], [ 'Add a contact for Susan Brown with partner name James Brown, and email susanb@email.com.', 'What\'s the partner name of Susan Brown?' ], ]

    For each of these test cases, we execute the first user input to create the contact. We then execute the second query to fetch that contact. If the CRM doesn’t return exactly 1 result then we know there was a problem either creating or fetching the contact. We can also run generic assertions like the one to verify UUIDs are not in the response. You must constantly update these tests as you observe data through human evaluation and debugging. The key is to make these as challenging as possible while representing users’ interactions with the system.

    Для каждого из этих тест-кейсов мы выполняем первый пользовательский ввод, чтобы создать контакт. Затем выполняем второй запрос, чтобы извлечь этот контакт. Если CRM возвращает не ровно 1 результат, мы знаем, что возникла проблема либо при создании, либо при извлечении контакта. Мы также можем запускать общие ассерты — например, тот, что проверяет отсутствие UUID в ответе. Эти тесты нужно постоянно обновлять по мере того, как вы наблюдаете данные через человеческую оценку и отладку. Главное — делать их как можно более сложными, при этом отражающими взаимодействие пользователей с системой.

    You don’t need to wait for production data to test your system. You can make educated guesses about how users will use your product and generate synthetic data. You can also let a small set of users use your product and let their usage refine your synthetic data generation strategy. One signal you are writing good tests and assertions is when the model struggles to pass them - these failure modes become problems you can solve with techniques like fine-tuning later on.

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

    On a related note, unlike traditional unit tests, you don’t necessarily need a 100% pass rate. Your pass rate is a product decision, depending on the failures you are willing to tolerate.

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

    Step 3: Run & Track Your Tests Regularly

    Шаг 3: Регулярно запускайте и отслеживайте тесты

    There are many ways to orchestrate Level 1 tests. Rechat has been leveraging CI infrastructure (e.g., GitHub Actions, GitLab Pipelines, etc.) to execute these tests. However, the tooling for this part of the workflow is nascent and evolving rapidly.

    Есть много способов оркестрировать тесты Level 1. Rechat использует CI-инфраструктуру (например, GitHub Actions, GitLab Pipelines и т. д.) для выполнения этих тестов. Однако инструментарий для этой части рабочего процесса ещё незрел и быстро развивается.

    My advice is to orchestrate tests that involve the least friction in your tech stack. In addition to tracking tests, you need to track the results of your tests over time so you can see if you are making progress. If you use CI, you should collect metrics along with versions of your tests/prompts outside your CI system for easy analysis and tracking.

    Мой совет — оркестрируйте тесты с наименьшим трением в вашем технологическом стеке. Помимо запуска тестов, нужно отслеживать их результаты во времени, чтобы видеть, есть ли прогресс. Если вы используете CI, стоит собирать метрики вместе с версиями ваших тестов/промптов за пределами CI-системы — для удобного анализа и отслеживания.

    I recommend starting simple and leveraging your existing analytics system to visualize your test results. For example, Rechat uses Metabase to track their LLM test results over time. Below is a screenshot of a dashboard Rechat built with Metabase:

    Я рекомендую начинать просто и использовать вашу существующую аналитическую систему для визуализации результатов тестов. Например, Rechat использует Metabase для отслеживания результатов своих LLM-тестов во времени. Ниже — скриншот дашборда, который Rechat построил с помощью Metabase:

    This screenshot shows the prevalence of a particular error (shown in yellow) in Lucy before (left) vs after (right) we addressed it.

    Этот скриншот показывает распространённость определённой ошибки (показана жёлтым) в Lucy до (слева) и после (справа) того, как мы её устранили.

    Level 2: Human & Model Eval

    Level 2: Человеческая и модельная оценка

    After you have built a solid foundation of Level 1 tests, you can move on to other forms of validation that cannot be tested by assertions alone. A prerequisite to performing human and model-based eval is to log your traces.

    После того как вы выстроили прочный фундамент из тестов Level 1, можно переходить к другим формам валидации, которые невозможно протестировать одними лишь ассертами. Обязательное условие для проведения человеческой и модельной оценки — логирование ваших трейсов.

    Logging Traces

    Логирование трейсов

    A trace is a concept that has been around for a while in software engineering and is a log of a sequence of events such as user sessions or a request flow through a distributed system. In other words, tracing is a logical grouping of logs. In the context of LLMs, traces often refer to conversations you have with a LLM. For example, a user message, followed by an AI response, followed by another user message, would be an example of a trace.

    Трейс — это концепция, давно существующая в разработке ПО; это лог последовательности событий, таких как пользовательские сессии или поток запроса через распределённую систему. Иными словами, трассировка — это логическая группировка логов. В контексте LLM трейсы часто означают разговоры, которые вы ведёте с LLM. Например, сообщение пользователя, за которым следует ответ AI, за которым следует ещё одно сообщение пользователя, — это пример трейса.

    There are a growing number of solutions for logging LLM traces.2 Rechat uses LangSmith, which logs traces and allows you to view them in a human-readable way with an interactive playground to iterate on prompts. Sometimes, logging your traces requires you to instrument your code. In this case, Rechat was using LangChain which automatically logs trace events to LangSmith for you. Here is a screenshot of what this looks like:

    Решений для логирования трейсов LLM становится всё больше.2 Rechat использует LangSmith, который логирует трейсы и позволяет просматривать их в удобочитаемом виде с интерактивной площадкой (playground) для итераций над промптами. Иногда для логирования трейсов нужно инструментировать ваш код. В данном случае Rechat использовал LangChain, который автоматически логирует события трейса в LangSmith за вас. Вот скриншот того, как это выглядит:

    I like LangSmith - it doesn’t require that you use LangChain and is intuitive and easy to use. Searching, filtering, and reading traces are essential features for whatever solution you pick. I’ve found that some tools do not implement these basic functions correctly!

    Мне нравится LangSmith — он не требует использования LangChain, интуитивно понятен и прост в использовании. Поиск, фильтрация и чтение трейсов — это важнейшие функции для любого решения, которое вы выберете. Я обнаружил, что некоторые инструменты реализуют эти базовые функции некорректно!

    Looking At Your Traces

    Просмотр ваших трейсов

    You must remove all friction from the process of looking at data. This means rendering your traces in domain-specific ways. I’ve often found that it’s better to build my own data viewing & labeling tool so I can gather all the information I need onto one screen. In Lucy’s case, we needed to look at many sources of information (trace log, the CRM, etc) to understand what the AI did. This is precisely the type of friction that needs to be eliminated. In Rechat’s case, this meant adding information like:

    Вы должны устранить любое трение в процессе просмотра данных. Это означает рендеринг ваших трейсов в специфичном для предметной области виде. Я часто обнаруживал, что лучше построить собственный инструмент просмотра и разметки данных, чтобы собрать всю нужную информацию на одном экране. В случае Lucy нам нужно было смотреть на множество источников информации (лог трейса, CRM и т. д.), чтобы понять, что сделал AI. Это как раз тот тип трения, который нужно устранять. В случае Rechat это означало добавление такой информации, как:

  • What tool (feature) & scenario was being evaluated.
  • Whether the trace resulted from a synthetic input or a real user input.
  • Filters to navigate between different tools and scenario combinations.
  • Links to the CRM and trace logging system for the current record.
  • Какой инструмент (функция) и сценарий оценивались. Возник ли трейс из синтетического ввода или из реального пользовательского ввода. Фильтры для навигации между разными комбинациями инструментов и сценариев. Ссылки на CRM и систему логирования трейсов для текущей записи.

    I’ve built different variations of this tool for each problem I’ve worked on. Sometimes, I even need to embed another application to see what the user interaction looks like. Below is a screenshot of the tool we built to evaluate Rechat’s traces:

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

    Another design choice specific to Lucy is that we noticed that many failures involved small mistakes in the final output of the LLM (format, content, etc). We decided to make the final output editable by a human so that we could curate & fix data for fine-tuning.

    Ещё одно проектное решение, специфичное для Lucy: мы заметили, что многие отказы связаны с мелкими ошибками в финальном выводе LLM (формат, содержание и т. д.). Мы решили сделать финальный вывод редактируемым человеком, чтобы можно было курировать и исправлять данные для дообучения.

    These tools can be built with lightweight front-end frameworks like Gradio, Streamlit, Panel, or Shiny in less than a day. The tool shown above was built with Shiny for Python. Furthermore, there are tools like Lilac which uses AI to search and filter data semantically, which is incredibly handy for finding a set of similar data points while debugging an issue.

    Такие инструменты можно построить с помощью лёгких фронтенд-фреймворков вроде Gradio, Streamlit, Panel или Shiny менее чем за день. Показанный выше инструмент был построен на Shiny для Python. Кроме того, есть инструменты вроде Lilac, который использует AI для семантического поиска и фильтрации данных, что невероятно удобно для нахождения набора похожих точек данных при отладке проблемы.

    I often start by labeling examples as good or bad. I’ve found that assigning scores or more granular ratings is more onerous to manage than binary ratings. There are advanced techniques you can use to make human evaluation more efficient or accurate (e.g., active learning, consensus voting, etc.), but I recommend starting with something simple. Finally, like unit tests, you should organize and analyze your human-eval results to assess if you are progressing over time.

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

    As discussed later, these labeled examples measure the quality of your system, validate automated evaluation, and curate high-quality synthetic data for fine-tuning.

    Как будет рассказано далее, эти размеченные примеры измеряют качество вашей системы, валидируют автоматизированную оценку и курируют качественные синтетические данные для дообучения.

    How much data should you look at?

    Сколько данных нужно просматривать?

    I often get asked how much data to examine. When starting, you should examine as much data as possible. I usually read traces generated from ALL test cases and user-generated traces at a minimum. You can never stop looking at data—no free lunch exists. However, you can sample your data more over time, lessening the burden. 3

    Меня часто спрашивают, сколько данных изучать. На старте следует изучать как можно больше данных. Я обычно читаю трейсы, сгенерированные из ВСЕХ тест-кейсов, и как минимум трейсы, сгенерированные пользователями. Вы никогда не сможете перестать смотреть на данные — бесплатного обеда не бывает. Однако со временем можно сэмплировать данные сильнее, снижая нагрузку.3

    Automated Evaluation w/ LLMs

    Автоматизированная оценка с помощью LLM

    Many vendors want to sell you tools that claim to eliminate the need for a human to look at the data. Having humans periodically evaluate at least a sample of traces is a good idea. I often find that “correctness” is somewhat subjective, and you must align the model with a human.

    Многие вендоры хотят продать вам инструменты, которые якобы устраняют необходимость в том, чтобы человек смотрел на данные. Хорошая идея — чтобы люди периодически оценивали хотя бы выборку трейсов. Я часто обнаруживаю, что «корректность» довольно субъективна, и вам нужно выравнивать модель с человеком.

    You should track the correlation between model-based and human evaluation to decide how much you can rely on automatic evaluation. Furthermore, by collecting critiques from labelers explaining why they are making a decision, you can iterate on the evaluator model to align it with humans through prompt engineering or fine-tuning. However, I tend to favor prompt engineering for evaluator model alignment.

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

    I love using low-tech solutions like Excel to iterate on aligning model-based eval with humans. For example, I sent my colleague Phillip the following spreadsheet every few days to grade for a different use-case involving a natural language query generator. This spreadsheet would contain the following information:

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

  • model response: this is the prediction made by the LLM.
  • model critique: this is a critique written by a (usually more powerful) LLM about your original LLM’s prediction.
  • model outcome: this is a binary label the critique model assigns to the model response as being “good” or “bad.”
  • model response: это предсказание, сделанное LLM. model critique: это критика, написанная (обычно более мощной) LLM о предсказании вашей исходной LLM. model outcome: это бинарная метка, которую критикующая модель присваивает model response как «хорошо» или «плохо».

    Phillip then fills out his version of the same information - meaning his critique, outcome, and desired response for 25-50 examples at a time (these are the columns prefixed with “phillip_” below):

    Затем Phillip заполняет свою версию той же информации — то есть свою критику, исход и желаемый ответ для 25–50 примеров за раз (это столбцы с префиксом «phillip_» ниже):

    This information allowed me to iterate on the prompt of the critique model to make it sufficiently aligned with Phillip over time. This is also easy to track in a low-tech way in a spreadsheet:

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

    This is a screenshot of a spreadsheet where we recorded our attempts to align model-based eval with a human evaluator.

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

    General tips on model-based eval:

    Общие советы по модельной оценке:

  • Use the most powerful model you can afford. It often takes advanced reasoning capabilities to critique something well. You can often get away with a slower, more powerful model for critiquing outputs relative to what you use in production.
  • Model-based evaluation is a meta-problem within your larger problem. You must maintain a mini-evaluation system to track its quality. I have sometimes fine-tuned a model at this stage (but I try not to).
  • After bringing the model-based evaluator in line with the human, you must continue doing periodic exercises to monitor the model and human agreement.
  • Используйте самую мощную модель, которую можете себе позволить. Чтобы хорошо что-то критиковать, часто требуются продвинутые способности к рассуждению. Для критики выводов нередко можно обойтись более медленной, но более мощной моделью по сравнению с той, что вы используете в продакшене. Модельная оценка — это мета-задача внутри вашей более крупной задачи. Вам нужно поддерживать мини-систему оценки, чтобы отслеживать её качество. На этом этапе я иногда дообучал модель (но стараюсь этого не делать). После того как вы привели модельный оценщик в соответствие с человеком, нужно продолжать периодически выполнять упражнения по мониторингу согласия модели и человека.

    In this example, we used agreement between the model and human evaluator because our dataset was roughly balanced (about 50% of instances were failures). However, using raw agreement is generally not recommended and can be misleading when classes are imbalanced. Instead, you should typically measure precision and recall separately to get a more accurate picture of your judge’s alignment.

    В этом примере мы использовали согласие между моделью и человеческим оценщиком, потому что наш датасет был примерно сбалансирован (около 50% случаев были отказами). Однако использование сырого согласия в целом не рекомендуется и может вводить в заблуждение при несбалансированных классах. Вместо этого обычно следует измерять precision и recall по отдельности, чтобы получить более точную картину выравнивания вашего судьи.

    My favorite aspect about creating a good evaluator model is that its critiques can be used to curate high-quality synthetic data, which I will touch upon later.

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

    Level 3: A/B Testing

    Level 3: A/B-тестирование

    Finally, it is always good to perform A/B tests to ensure your AI product is driving user behaviors or outcomes you desire. A/B testing for LLMs compared to other types of products isn’t too different. If you want to learn more about A/B testing, I recommend reading the Eppo blog (which was created by colleagues I used to work with who are rock stars in A/B testing).

    Наконец, всегда полезно проводить A/B-тесты, чтобы убедиться, что ваш AI-продукт стимулирует желаемое поведение или результаты пользователей. A/B-тестирование для LLM не сильно отличается от других типов продуктов. Если вы хотите узнать больше об A/B-тестировании, я рекомендую читать блог Eppo (который создали коллеги, с которыми я раньше работал и которые являются звёздами A/B-тестирования).

    It’s okay to put this stage off until you are sufficiently ready and convinced that your AI product is suitable for showing to real users. This level of evaluation is usually only appropriate for more mature products.

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

    Evaluating RAG

    Оценка RAG

    Aside from evaluating your system as a whole, you can evaluate sub-components of your AI, like RAG. Evaluating RAG is beyond the scope of this post, but you can learn more about this subject in a post by Jason Liu.

    Помимо оценки системы в целом, вы можете оценивать отдельные подкомпоненты вашего AI, такие как RAG. Оценка RAG выходит за рамки этой статьи, но узнать больше об этом можно в статье Jason Liu.

    Eval Systems Unlock Superpowers For Free

    Системы оценки бесплатно открывают суперспособности

    In addition to iterating fast, eval systems unlock the ability to fine-tune and debug, which can take your AI product to the next level.

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

    Fine-Tuning

    Дообучение

    Rechat resolved many failure modes through fine-tuning that were not possible with prompt engineering alone. Fine-tuning is best for learning syntax, style, and rules, whereas techniques like RAG supply the model with context or up-to-date facts.

    Rechat устранил множество режимов отказа через дообучение, что было невозможно одним лишь prompt engineering. Дообучение лучше всего подходит для усвоения синтаксиса, стиля и правил, тогда как такие техники, как RAG, снабжают модель контекстом или актуальными фактами.

    99% of the labor involved with fine-tuning is assembling high-quality data that covers your AI product’s surface area. However, if you have a solid evaluation system like Rechat’s, you already have a robust data generation and curation engine! I will expand more on the process of fine-tuning in a future post.4

    99% труда, связанного с дообучением, — это сборка качественных данных, покрывающих область действия вашего AI-продукта. Однако если у вас есть надёжная система оценки, как у Rechat, то у вас уже есть мощный движок генерации и курирования данных! Подробнее о процессе дообучения я расскажу в будущей статье.4

    Data Synthesis & Curation

    Синтез и курирование данных

    To illustrate why data curation and synthesis come nearly for free once you have an evaluation system, consider the case where you want to create additional fine-tuning data for the listing finder mentioned earlier. First, you can use LLMs to generate synthetic data with a prompt like this:

    Чтобы проиллюстрировать, почему курирование и синтез данных достаются почти бесплатно, как только у вас есть система оценки, рассмотрим случай, когда вы хотите создать дополнительные данные для дообучения упомянутого ранее поиска листингов (listing finder). Сначала вы можете использовать LLM для генерации синтетических данных с промптом вроде этого:

    Imagine if Zillow was able to parse natural language. Come up with 50 different ways users would be able to search listings there. Use real names for cities and neighborhoods. You can use the following parameters: <omitted for confidentiality> Output should be a JSON code block array. Example: [ "Homes under $500k in New York" ]

    Imagine if Zillow was able to parse natural language. Come up with 50 different ways users would be able to search listings there. Use real names for cities and neighborhoods. You can use the following parameters: Output should be a JSON code block array. Example: [ "Homes under $500k in New York" ]

    This is almost identical to the exercise for producing test cases! You can then use your Level 1 & Level 2 tests to filter out undesirable data that fails assertions or that the critique model thinks are wrong. You can also use your existing human evaluation tools to look at traces to curate traces for a fine-tuning dataset.

    Это почти идентично упражнению по созданию тест-кейсов! Затем вы можете использовать ваши тесты Level 1 и Level 2, чтобы отфильтровать нежелательные данные, которые не проходят ассерты или которые критикующая модель считает неверными. Вы также можете использовать ваши существующие инструменты человеческой оценки, чтобы просматривать трейсы и курировать их для датасета дообучения.

    Debugging

    Отладка

    When you get a complaint or see an error related to your AI product, you should be able to debug this quickly. If you have a robust evaluation system, you already have:

    Когда вы получаете жалобу или видите ошибку, связанную с вашим AI-продуктом, вы должны уметь быстро её отладить. Если у вас есть надёжная система оценки, у вас уже есть:

  • A database of traces that you can search and filter.
  • A set of mechanisms (assertions, tests, etc) that can help you flag errors and bad behaviors.
  • Log searching & navigation tools that can help you find the root cause of the error. For example, the error could be RAG, a bug in the code, or a model performing poorly.
  • The ability to make changes in response to the error and quickly test its efficacy.
  • База трейсов, по которой можно искать и фильтровать. Набор механизмов (ассерты, тесты и т. д.), которые помогают помечать ошибки и нежелательное поведение. Инструменты поиска и навигации по логам, помогающие найти первопричину ошибки. Например, причиной может быть RAG, баг в коде или плохо работающая модель. Возможность вносить изменения в ответ на ошибку и быстро тестировать их эффективность.

    In short, there is an incredibly large overlap between the infrastructure needed for evaluation and that for debugging.

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

    Conclusion

    Заключение

    Evaluation systems create a flywheel that allows you to iterate very quickly. It’s almost always where people get stuck when building AI products. I hope this post gives you an intuition on how to go about building your evaluation systems. Some key takeaways to keep in mind:

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

  • Remove ALL friction from looking at data.
  • Keep it simple. Don’t buy fancy LLM tools. Use what you have first.
  • You are doing it wrong if you aren’t looking at lots of data.
  • Don’t rely on generic evaluation frameworks to measure the quality of your AI. Instead, create an evaluation system specific to your problem.
  • Write lots of tests and frequently update them.
  • LLMs can be used to unblock the creation of an eval system. Examples include using a LLM to:
    • Generate test cases and write assertions
    • Generate synthetic data
    • Critique and label data etc.
  • Re-use your eval infrastructure for debugging and fine-tuning.
  • Устраните ВСЁ трение при просмотре данных. Сохраняйте простоту. Не покупайте навороченные LLM-инструменты. Сначала используйте то, что у вас уже есть. Если вы не смотрите на множество данных, вы делаете что-то неправильно. Не полагайтесь на универсальные фреймворки оценки для измерения качества вашего AI. Вместо этого создайте систему оценки, специфичную для вашей задачи. Пишите много тестов и часто их обновляйте. LLM можно использовать, чтобы разблокировать создание системы оценки. Примеры использования LLM: генерация тест-кейсов и написание ассертов; генерация синтетических данных; критика и разметка данных и т. д. Переиспользуйте вашу инфраструктуру оценки для отладки и дообучения.

    I’d love to hear from you if you found this post helpful or have any questions. My email is hamel@parlance-labs.com.

    Я был бы рад услышать от вас, если эта статья оказалась полезной или если у вас есть вопросы. Моя почта: hamel@parlance-labs.com.

    This article is an adaptation of this conversation I had with Emil Sedgh and Hugo Browne-Anderson on the Vanishing Gradients podcast. Thanks to Jeremy Howard, Eugene Yan, Shreya Shankar, Jeremy Lewi, and Joseph Gleasure for reviewing this article.

    Эта статья — адаптация этого разговора, который у меня состоялся с Emil Sedgh и Hugo Browne-Anderson в подкасте Vanishing Gradients. Спасибо Jeremy Howard, Eugene Yan, Shreya Shankar, Jeremy Lewi и Joseph Gleasure за рецензирование этой статьи.

    Footnotes

    Сноски

  • This is not to suggest that people are lazy. Many don’t know how to set up eval systems and skip these steps.↩︎

  • Some examples include arize, human loop, openllmetry and honeyhive.↩︎

  • A reasonable heuristic is to keep reading logs until you feel like you aren’t learning anything new.↩︎

  • If you cannot wait, I’ll be teaching this course on fine-tuning soon.↩︎

  • Это не означает, что люди ленивы. Многие просто не знают, как настроить системы оценки, и пропускают эти шаги.↩︎ В качестве примеров можно назвать arize, human loop, openllmetry и honeyhive.↩︎ Разумная эвристика — продолжать читать логи, пока не почувствуете, что больше не узнаёте ничего нового.↩︎ Если вам не терпится, я скоро буду преподавать этот курс по дообучению.↩︎