11.02.2025

Создание эффективных агентов

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

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

Содержание

Что такое агенты?

Термин «агент» может трактоваться по-разному. Одни клиенты называют агентами полностью автономные системы, которые работают самостоятельно в течение длительного времени, используя различные инструменты для решения сложных задач. Другие определяют под этим термином более «жёсткие» схемы, следующие предопределённым сценариям. В Anthropic мы рассматриваем все эти варианты как «агентные системы», но проводим важное архитектурное различие между workflow (рабочим процессом) и агентом:
  • Workflow (рабочий процесс) — это система, в которой LLM и инструменты взаимодействуют по заданным путям в коде.
  • Агент — это система, в которой LLM самостоятельно определяет, как именно использовать инструменты и как структурировать процесс выполнения задачи, сохраняя контроль над ходом работы.

Далее мы подробно рассмотрим оба варианта агентных систем. В приложении 1 («Агенты на практике») мы опишем два направления, где клиенты особенно выиграли от использования подобных систем.

Когда (и когда не) стоит использовать агентов

При разработке приложений с LLM мы рекомендуем выбирать максимально простой путь, усложняя его только при необходимости. Это может означать и полный отказ от «агентной» схемы. Агентные системы обычно повышают затраты и задержку (latency), но зато дают более качественное выполнение задачи. Важно понять, в каком случае эта «наценка» себя оправдывает.

Когда задача становится сложнее, рабочие процессы (workflows) позволяют достичь предсказуемости и стабильности в чётко определённых задачах, а агенты лучше подходят там, где нужна гибкость и «решения, принимаемые моделью» в крупных масштабах. Однако во многих случаях достаточно одной-двух LLM-запросов с Retrieval (поиск информации) и примерами в контексте — без построения большой агентной системы.

Когда и как использовать фреймворки

Сейчас существует много фреймворков для упрощённого создания агентных систем, например:
  • LangGraph (от LangChain)
  • AI Agent (от Amazon Bedrock)
  • Rivet (инструмент с графическим интерфейсом для работы с LLM)
  • Vellum (ещё один GUI-инструмент для сборки и тестирования сложных рабочих процессов)

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

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

Загляните в наш «cookbook» (сборник рецептов), где есть примеры таких реализаций.

Базовые блоки, рабочие процессы и агенты

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

Базовый блок: «Расширенная LLM»

Основой любой агентной системы служит LLM, дополненная возможностями вроде инструментария (tools), Retrieval (поиск данных) и памяти (memory). Современные модели могут активно использовать эти возможности: формировать поисковые запросы, выбирать инструменты и решать, какую информацию стоит запоминать.
Рекомендуется обращать внимание на два ключевых момента:
  1. Адаптируйте возможности под ваш конкретный кейс.
  2. Обеспечьте удобный и хорошо документированный интерфейс для LLM.

Реализовать такие доработки (Retrieval, Tools и т. п.) можно по-разному. Один из вариантов — использовать Model Context Protocol (выпущенный Anthropic), позволяющий легко интегрировать сторонние инструменты с помощью простого клиента.

В дальнейшем будем считать, что каждое обращение к LLM уже имеет «расширенные» возможности.

Workflow: «Цепочка промптов» (Prompt chaining)

Prompt chaining разбивает задачу на ряд шагов, где каждый вызов LLM обрабатывает результат предыдущего. При этом вы можете добавлять программные проверки (gate) на промежуточных шагах, чтобы удостовериться, что процесс идёт по правильному пути.

Когда использовать:

Подходит, если задачу можно легко разбить на чёткие подзадачи. Главная цель — снизить вероятность ошибок (и повысить точность) за счёт упрощения каждого отдельного шага, пусть и ценой дополнительного времени (несколько последовательных запросов).
Примеры
  • Генерация маркетингового текста, а затем его перевод на другой язык.
  • Составление плана документа, проверка соответствия заданным критериям и генерация текста на основе этого плана.

Workflow: «Маршрутизация» (Routing)

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

Когда использовать:

Полезно в сложных задачах, где чётко выделяются разные категории, которые лучше обрабатывать по отдельным веткам, а классификация надёжно работает (будь то LLM-классификация или традиционный алгоритм).
Примеры
  • Разделение пользовательских запросов в службу поддержки на общие вопросы, запросы на возврат денег, технические проблемы и т. п. Каждая категория затем следует своему собственному сценарию, промптам и инструментам.
  • Перенаправление простых/распространённых вопросов на менее дорогие модели (например, Claude 3.5 Haiku), а сложных/редких — на более мощные (Claude 3.5 Sonnet) для оптимизации расходов и скорости.

Workflow: «Параллелизм» (Parallelization)

Иногда LLM может одновременно работать над несколькими частями задачи, а затем результаты объединяются программно. Это параллелизация, и у неё есть две основные формы:
  1. Sectioning (Разделение): деление задачи на независимые подзадачи для параллельной обработки.
  2. Voting (Голосование): выполнение одной и той же задачи несколько раз для получения разных вариантов ответа.

Когда использовать:

Подходит, если подзадачи можно обрабатывать одновременно (для ускорения) или если нужно несколько взглядов (итераций) для более надёжного результата. Для сложных задач с несколькими аспектами LLM обычно даёт лучший результат, когда каждый аспект решается отдельным вызовом LLM.
Примеры
Sectioning:
  • Организация «ограждений» (guardrails), когда одна модель обрабатывает запрос, а другая параллельно проверяет его на соответствие политике. Обычно это эффективнее, чем заставлять одну и ту же модель одновременно и отвечать, и проверять.
  • Автоматизированная оценка (eval) качества модели, когда каждый вызов LLM проверяет определённый аспект.

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

Workflow: «Оркестратор-воркеры» (Orchestrator-workers)

В схеме «оркестратор-воркеры» главный LLM динамически разбивает задачу на подзадачи, делегирует их «подчинённым» LLM, а затем объединяет результаты.

Когда использовать:

Подходит для сложных задач, где заранее неясно, какие именно подзадачи потребуются (например, в кодинге количество и характер файлов, которые надо менять, определяется по ходу дела). В отличие от параллелизации, здесь нет заранее определённого набора шагов, а оркестратор сам решает, как именно разбить задачу.
Примеры
  • Системы для написания/редактирования кода, где агент может менять множество файлов по запросу.
  • Поисковые задачи, где нужно собрать и проанализировать информацию из нескольких источников для определения действительно релевантных данных.

Workflow: «Оценщик-оптимизатор» (Evaluator-optimizer)

В схеме «оценщик-оптимизатор» один вызов LLM генерирует ответ, а другой его оценивает и даёт обратную связь. При необходимости процесс повторяется.

Когда использовать:

Когда имеются чёткие критерии оценки, а итеративная доработка приносит реальный прирост качества. Два сигнала, что это может сработать:
  1. Ответы LLM можно заметно улучшить, если человек формулирует обратную связь.
  2. Модель сама способна сформулировать такую обратную связь.

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

Агенты

С развитием LLM в плане понимания сложных входных данных, умения рассуждать и планировать, надёжно пользоваться инструментами и восстанавливаться после ошибок, агенты всё чаще встречаются в продакшне. Работу они начинают либо с команды, либо с «беседы» с человеком. Когда задача понятна, агент планирует и действует автономно, иногда обращаясь к человеку за дополнительными сведениями или подтверждением. При выполнении задач агенту нужны «данные из реального мира» (например, результаты вызова инструмента или выполнения кода) на каждом шаге, чтобы оценивать прогресс. Агент может прерываться для получения обратной связи от человека, например, на заранее определённых контрольных точках или если сталкивается с проблемой. Обычно процесс заканчивается, когда задача выполнена, но часто добавляют и «условия остановки» (например, максимальное число итераций), чтобы обезопаситься от бесконечных циклов.

Хотя агенты способны к решению очень сложных задач, реализовать их можно достаточно просто: по сути, это LLM, которое в цикле использует инструменты на основе возвращаемой информации. Поэтому очень важно продумывать набор инструментов и их документацию. О лучших практиках проектирования инструментов читайте в приложении 2 («Промпт-инжиниринг для инструментов»).

Когда использовать:

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

Но за автономность приходится платить: выше затраты (время, деньги), и ошибки могут накапливаться. Мы рекомендуем тщательно тестировать такие системы в песочнице и использовать надёжные «ограждения» (guardrails).
Примеры
  • Агент для написания кода, решающий задачи из тестового набора SWE-bench, где нужно вносить правки в несколько файлов, ориентируясь только на описание Pull Request.
  • Наша «референсная» реализация «использования компьютера», в которой Claude взаимодействует с компьютером для решения различных задач.

Как комбинировать и настраивать эти паттерны

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

Итоги

Успех в области LLM — это не «самая навороченная система», а «правильная система для конкретных нужд». Начинайте с простых промптов, тщательно оценивайте их качество и переходите к многошаговым агентным системам только тогда, когда более простое решение не справляется.

При построении агентов мы следуем трём основным принципам:
  1. Сохраняйте простоту дизайна.
  2. Делайте процесс прозрачным: явно показывайте ход рассуждений агента.
  3. Внимательно продумывайте «интерфейс агент-компьютер» (ACI), уделяя время документации и тестированию инструментов.

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

Благодарности

Статью написали Эрик Шлунц (Erik Schluntz) и Барри Чжан (Barry Zhang). В ней отражён наш опыт по созданию агентов в Anthropic и ценные идеи, которыми поделились наши клиенты. Мы очень благодарны всем, кто помогал нам в этой работе.

Приложение 1: Агенты на практике

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

A. Служба поддержки клиентов

В службе поддержки сочетаются привычные чат-формы и инструменты для выполнения действий. Это органично подходит для более «открытых» агентов, так как:
  • Общение с пользователем само по себе носит диалоговый характер, при этом часто нужны внешние данные и действия;
  • Можно подключать инструменты, чтобы просматривать клиентские данные, историю заказов, статьи из базы знаний;
  • Действия (например, возврат средств или обновление тикета) можно выполнять программно;
  • Результат хорошо измеряется по тому, решена ли проблема.

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

B. Агенты для написания кода

Сфера разработки ПО особенно выиграла от LLM — от дополнения кода до полностью автономного решения задач. Агентам в этой области помогают:
  • Возможность проверить решения автоматическими тестами;
  • Итеративный процесс корректировок на основе результатов тестов;
  • Чёткие границы и структуры задач;
  • Объективные метрики качества.

В нашем собственном прототипе агенты успешно решают реальные GitHub-issues из бенчмарка SWE-bench, используя только описание PR. Автоматические тесты помогают гарантировать корректность функционала, но перед слиянием кода обязательно нужна проверка человеком, чтобы убедиться, что решение вписывается в общий контекст и требования проекта.

Приложение 2: Промпт-инжиниринг для инструментов

Вне зависимости от того, какую агентную систему вы строите, инструменты (tools) наверняка станут её важной частью. С их помощью Claude (или другая LLM) может взаимодействовать с внешними сервисами и API, передавая при этом чётко заданную структуру и определения в рамках нашего API. Если Claude решит вызвать инструмент, он добавит «tool use block» в ответе API. Стоит вложить столько же сил в продумывание инструментария, сколько в основные промпты. Ниже кратко описано, как к этому подойти.

Зачастую одно и то же действие можно реализовать по-разному. Например, редактирование файла можно описывать через формат diff или же предложить модели переписать весь файл целиком. Код может возвращаться внутри Markdown или внутри JSON. С точки зрения классического программирования это неважно — мы можем потом как угодно преобразовать результат. Но для LLM разница существенна. Например, делать diff сложнее, так как придётся указывать правильное число изменяемых строк перед самим кодом. А при написании кода внутри JSON нужны дополнительные экранирования.

Рекомендации:
1. Давайте модели достаточно «места на размышление» (токенов), чтобы она не «загоняла себя в угол».
2. Старайтесь использовать знакомые модели форматы, как в текстах из интернета.
3. Избегайте сложных «служебных» требований к формату (например, точного подсчёта строк в diff или экранирования каждого символа).

Подумайте о том, сколько усилий мы обычно вкладываем в создание удобных человеко-машинных интерфейсов (HCI). Стоит быть столь же внимательными при проектировании интерфейса «агент-компьютер» (ACI). Несколько идей:
• Представьте себя на месте модели. Ясно ли из описания, как использовать этот инструмент? Или нужно поломать голову? Если второе — модель тоже будет ошибаться. Хорошая спецификация содержит примеры, крайние случаи, информацию о форматах входа и чёткие различия от других инструментов.
• Переименуйте параметры и дополните описания так, чтобы всё было максимально очевидно. Представьте, что пишете docstring для младшего разработчика. Важно, когда много инструментов или они похожи.
• Обязательно тестируйте использование ваших инструментов. Гоняйте разные примеры, смотрите, какие ошибки модель делает, и дорабатывайте.
• Внедряйте «poka-yoke» (защиту от дурака).Меняйте аргументы и формат так, чтобы модель сложнее делала ошибки.

Во время работы над нашим агентом для SWE-bench мы больше всего времени потратили именно на тонкую настройку инструментов, а не на общий промпт. Например, мы столкнулись с ситуацией, когда модель делала ошибки, используя относительные пути после смены директории. Решение — запретить относительные пути и требовать абсолютные. Модель тут же перестала ошибаться.
Читайте также