Как делать synthetic eval datasets для agentic workflows?
Краткий тезис
Создание синтетических датасетов для оценки агентных воркфлоу — это процесс генерации искусственных диалогов, которые имитируют реальное взаимодействие пользователя с агентом. Основные этапы включают task decomposition (разбиение задачи]] на подзадачи), state space exploration (обход возможных состояний агента), LLM generation (генерацию запросов и ожидаемых траекторий), self-consistency (мажоритарное голосование между несколькими LLM) и human validation (экспертную проверку небольшой части данных). Такой подход позволяет получить покрытие сценариев, которое сложно собрать вручную, и автоматизировать тестирование агентов без дорогого продакшн-трафика.
1. Зачем нужны синтетические датасеты для agentic workflows
Обычный RAG-пайплайн (retrieval + generation) оценивается статическими парами вопрос–ответ. В agentic workflow (агентном пайплайне) ответ зависит от последовательности действий, вызовов инструментов и промежуточных состояний. Поэтому для eval-датасета требуется не просто вопрос и правильный ответ, а ожидаемая траектория (trajectory|expected trajectory): набор шагов, которые агент должен выполнить, с учётом возможных ветвлений.
Проблемы ручного сбора
- Огромное количество сценариев (особенно для мульти-шаговых агентов).
- Сложность моделирования краевых случаев (отказы инструментов, частичные ошибки).
- Субъективность асессоров при выборе «правильной» траектории.
Synthetic generation (generation|синтетическая генерация) решает эти задачи, используя LLM как «криэйтора» данных.
2. Task Decomposition (декомпозиция задачи)
Первый этап — разбить сложную задачу, которую должен решать агент, на более простые подзадачи. Например, для агента поддержки клиентов глобальная задача «обработка жалобы» декомпозируется на:
- идентификация проблемы;
- поиск решения в базе знаний;
- предложение компенсации или эскалация;
- завершение диалога.
Как это делается
- Вручную пишется иерархия задач]] (task tree) — эксперт задаёт основные классы сценариев.
- LLM достраивает подзадачи, используя prompt engineering (например, «Сгенерируй 10 типовых инцидентов для поддержки. Для каждого опиши шаги решения»).
- Результат — список task templates (шаблонов задач) с переменными (например, «сумма ущерба», «тип продукта»).
Каждый шаблон в дальнейшем превращается в полноценный eval-пример.
3. State Space Exploration (обход пространства состояний)
Агентный воркфлоу — это конечный автомат. State space exploration — это систематический перебор всех возможных состояний и переходов между ними.
Пример: агент может попросить уточнение → пользователь может дать данные или отказаться. Если отказ — агент может повторить запрос, эскалировать или завершить диалог. Каждая ветка даёт разный eval-пример.
Подходы
- Breadth-first traversal (обход в ширину) — генерируем все варианты ответов на каждом шаге.
- Monte Carlo sampling — случайно выбираем ветки, чтобы покрыть наиболее вероятные пути.
- Coverage-driven generation — используем эвристики (например, если есть условие «если пользователь выбрал А, то шаг 2; иначе шаг 3»), генерируем по одному примеру на каждое условие.
Результат — набор состояний-транзакций (state–action–next state). Каждый такой набор становится частью eval-примера.
4. LLM Generation (генерация запросов и ожидаемых траекторий)
Из шаблонов и состояний LLM генерирует human-like запросы (то, что напишет пользователь) и expected траектории (правильные действия агента).
Пример промпта
Задача: обработать жалобу на задержку доставки.
Подзадачи: 1) запросить номер заказа, 2) проверить статус, 3) предложить компенсацию.
Сгенерируй диалог, где пользователь:
- сначала даёт неполную информацию,
- потом после уточнения даёт номер заказа,
- агент проверяет и предлагает возврат 10%.
Ожидаемая траектория:
1. Агент: ask_order_number
2. Пользователь: says_no_number
3. Агент: reask_order_number
4. Пользователь: gives_order_number
5. Агент: check_status(order_number) → delayed
6. Агент: propose_refund(10%)
7. Пользователь: accept
8. Агент: close_ticket
Важно, чтобы траектория была детерминированной (для простоты валидации) или содержала несколько альтернатив (для более гибкой оценки).
5. Self-Consistency (самосогласованность)
Одна LLM может генерировать шум. Self-consistency — метод, когда несколько (3–5) различных LLM (или один LLM с разными temperature) генерируют траектории для одного и того же запроса. Затем голосованием (majority vote) выбирается наиболее часто встречающаяся траектория.
Реализация
- Параллельно вызываем API (GPT-4, Claude, Llama 3 и т.д.).
- Для каждого шага траектории считаем, какое действие выбрано большинством.
- Если согласованность низкая (менее 2 из 3), такой пример отбрасывается или отправляется на человеческую проверку.
Преимущества
- Уменьшает влияние bias одной модели.
- Позволяет автоматически отфильтровать нелогичные траектории.
Недостаток дороговизна (умножение на количество LLM). Можно использовать только для небольшого пула примеров (например, 500–1000).
6. Human Validation (человеческая валидация)
Даже при самосогласованности остаются ошибки. Рекомендуется human validation для 10% сгенерированных примеров (случайная стратифицированная выборка по типам сценариев).
Критерии для асессора
- Реалистичность запроса.
- Полнота траектории (нет ли лишних или пропущенных шагов).
- Соответствие бизнес-логике.
- Отсутствие токсичности или нелогичных действий.
Выявленные ошибки исправляются, и эти примеры возвращаются в датасет как golden answers (эталонные ответы). Затем на них можно дообучать генерацию траекторий для остальных примеров.
7. Пример: агент поддержки (сценарии)
Разберём три типовых сценария для демонстрации.
| Сценарий | Запрос пользователя | Ожидаемая траектория |
|---|---|---|
| Уточнение (inquiry) | «Где мой заказ? Уже прошло 5 дней.» | 1. ask_order_number<br>2. user_gives_number<br>3. check_status → delivered<br>4. answer: «Заказ доставлен вчера»<br>5. close |
| Компенсация (refund) | «Доставка опоздала на неделю, хочу возврат.» | 1. ask_order_number<br>2. check_status → delayed<br>3. check_refund_policy → eligible<br>4. propose_refund(50%)<br>5. user_accept<br>6. process_refund<br>7. close |
| Эскалация человеку (escalation) | «Я уже 10 раз звонил, ничего не делаете!» | 1. check_history → multiple_tickets<br>2. apologize<br>3. propose_callback<br>4. user_accept<br>5. escalate_to_human<br>6. set_callback_time<br>7. close |
Для каждого сценария в датасете должны быть варианты с ошибками агента (например, агент предложил компенсацию, хотя политика не позволяет). Эти «негативные» примеры используются для оценки робастности.
8. Инструменты и фреймворки
Существуют готовые инструменты для упрощения пайплайна:
- [Вики/LangSmith|LangSmith(Вики/TLS|https://smith.Вики/agent|langchain.com/) — позволяет создавать Вики/датасеты|датасеты из трассировок реального агента, а также генерировать синтетические с помощью
Вики/LangSmith|LangSmith.Вики/generation|generate. - [Вики/RAGAS|RAGAS(Вики/TLS|https://github.com/explodinggradients/ragas) — расширенная версия умеет оценивать агентные рабочие процессы, включая Вики/API call|инструментальные вызовы (Вики/action|tool calls).
- [Вики/Agent-Eval|Agent-Eval(Вики/TLS|https://github.com/microsoft/agent-eval) (Microsoft) — фреймворк для генерации eval-кейсов на основе спецификации агента.
- Собственный скрипт на Python с библиотеками instructor (для структурированного вывода) и pydantic для валидации траекторий.
Пример кода генерации одного примера:
from openai import OpenAI
from pydantic import BaseModel
class Step(BaseModel):
action: str
agent_response: str
class Trajectory(BaseModel):
user_query: str
steps: list[Step]
client = OpenAI()
prompt = """Сгенерируй запрос пользователя и ожидаемую траекторию для агента поддержки.
Сценарий: компенсация за задержку.
Правила: агент может предложить компенсацию 10-50%.
"""
response = client.beta.chat.completions.parse(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
response_format=Trajectory
)
example = response.choices[0].message.parsed
9. Проблемы и ограничения
- Bias генерации LLM склонна генерировать «идеальные» траектории, не покрывая ошибки (например, когда агент неправильно интерпретирует запрос). Нужно специально просить негативные сценарии.
- Стоимость вызов нескольких LLM для self-consistency умножает затраты. Для сокращения можно использовать один LLM с разными системными сообщениями.
- Сложность валидации человеку тяжело проверять длинные траектории. Рекомендуется разбивать на атомарные шаги.
- Неоднозначность ожидаемого поведения для одного и того же запроса может быть несколько правильных путей. Решение — генерировать set of acceptable trajectories (набор допустимых траекторий) и оценивать вхождение фактической в этот набор.
Пет-проект для закрепления
Задача Создать синтетический eval-датасет для агента, который бронирует встречи (Google Calendar API).
Инструменты
Шаги:
- Декомпозиция выделите 4 задачи — new_booking, reschedule, cancel, check_availability.
- State space: определите возможные состояния: user_requests, agent_asks_time, user_provides_time, agent_confirms, user_approves, agent_booked, agent_fails.
- Генерация используйте LLM (например, GPT-4) для генерации 50 примеров (по 10–15 на каждую задачу с разными ветками).
- Self-consistency для каждого запроса сгенерируйте 3 траектории разными моделями (или с разными temperature) и выберите мажоритарную.
- Human validation: попросите коллегу проверить 5 случайных примеров.
- Сборка датасета сохраните в JSON с полями:
query,trajectory_steps(список dict с action и context),expected_final_state.
Ожидаемый результат JSON-файл с ~40 проверенными примерами. На них можно прогнать вашего агента и посчитать метрики (accuracy траектории, точность выбора следующего шага).
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 870 | Проектирование agentic RAG |
| 871 | Оценка качества агентов (offline/online) |
| 872 | Мониторинг агентов в production |
| 873 | Паттерны агентов (ReAct, Plan-and-Execute) |
| 876 | Human-in-the-loop для agentic workflows |
| 877 | Оптимизация tool calls |
Навигация
- Предыдущий: 874
- Следующий: 876
- Индекс: 00. Индекс разборов