Перейти к содержимому
ПереводыAnthropic

Anthropic Engineering: «Building effective agents» и «Writing effective tools for agents» — конспект

Пересказ двух статей инженерного блога Anthropic: пять паттернов workflow и автономный агент — когда что выбирать (2024), и как проектировать инструменты для агентов через прототип, эвал и доработку вместе с самим агентом (2025).

Две статьи из блога Engineering at Anthropic, которые чаще всего советуют прочитать тем, кто начинает делать агентов. Первая отвечает на вопрос «какую архитектуру выбрать», вторая — «как сделать инструменты, которыми агент пользуется правильно». Статьи защищены авторским правом, поэтому здесь конспект своими словами с короткими цитатами; полные тексты — по ссылкам: Building effective agents и Writing effective tools for agents — with agents.

  • Начинайте с самого простого. Часто достаточно одного хорошо настроенного вызова модели с поиском и примерами; агентная система обменивает задержку и деньги на качество, и этот обмен должен окупаться.
  • Workflow и агент — разные вещи. В workflow путь выполнения задан вашим кодом; в агенте модель сама решает, что делать дальше. Пять типовых workflow: цепочка, маршрутизация, параллелизация, оркестратор с исполнителями, оценщик с оптимизатором.
  • Агент — это модель, которая в цикле вызывает инструменты и смотрит на результат. Поэтому качество агента почти целиком определяется качеством инструментов и их описаний — «интерфейса агент — компьютер» (ACI).
  • Инструмент — контракт между детерминированной программой и недетерминированным агентом. Его нельзя проектировать как обычный API для программистов: агент читает ответы токенами, и у него ограничен контекст.
  • Инструменты улучшают через эвал: прототип → реалистичные задачи → прогон агентом → чтение транскриптов → правка (в том числе руками самого агента) → проверка на отложенном наборе.
  • Когда. Первую статью — сразу после урока 8.3.1 «Агентный цикл и ReAct» и перед уроком 8.3.3 «Планирование, память и мультиагентность» (там же раздел «Когда агенты не нужны» — это главная мысль статьи). Вторую — вместе с уроком 8.3.2 «Инструменты и MCP»; её часть про эвалы перекликается с уроком 8.4.2.
  • Код. К первой статье есть три ноутбука в Claude Cookbooks (basic_workflows, evaluator_optimizer, orchestrator_workers); ко второй — рецепт tool_evaluation.
  • Что пропустить. В первой статье список фреймворков (он устарел — авторы позже добавили в начало статьи пометку, что ландшафт инструментов с декабря 2024 года сильно изменился, и ссылку на Claude Managed Agents). Во второй — инструкции по подключению MCP-сервера к Claude Desktop.

Авторы (Эрик Ш. и Барри Чжан) работали с десятками команд, которые делали агентов на LLM, и заметили закономерность: лучше всего получалось не у тех, кто брал сложные фреймворки, а у тех, кто собирал систему из «простых, компонуемых паттернов» (simple, composable patterns). Отсюда весь дальнейший текст: каталог таких паттернов и совет усложнять только тогда, когда усложнение измеримо улучшает результат.

Слово «агент» понимают по-разному: одни — как полностью автономную систему, которая долго работает сама и пользуется множеством инструментов; другие — как заранее расписанный процесс. Anthropic называет всё это агентными системами (agentic systems), но различает два архитектурных типа:

Workflow (рабочий процесс)Агент
Кто решает, что делать дальшеваш код: путь выполнения задан заранеемодель: она сама ведёт процесс и выбирает инструменты
Сильная сторонапредсказуемость, повторяемостьгибкость там, где шагов заранее не знать
Слабая сторонане справится с непредвиденнымдороже, ошибки накапливаются, нужен контроль
Пример из нашего курсаконвейер RAG из урока 8.2.1ReAct-агент из урока 8.3.1

Совет звучит почти парадоксально для статьи об агентах: ищите самое простое решение и, возможно, не делайте агентную систему вовсе. Для многих задач хватает одного вызова модели, улучшенного поиском (RAG) и примерами в промпте. Если сложность всё же нужна, workflow подходят для чётко определённых задач, агенты — когда нужна гибкость и решения модели «в масштабе».

Фреймворки (в статье упомянуты Claude Agent SDK, Strands Agents от AWS, визуальные конструкторы Rivet и Vellum) упрощают старт: берут на себя вызовы модели, разбор инструментов, связывание вызовов. Но они добавляют слои абстракции, за которыми не видно настоящих промптов и ответов, — отлаживать труднее, и возникает соблазн усложнять. Рекомендация: начинать с прямых вызовов API («многие паттерны реализуются в несколько строк кода»), а если берёте фреймворк — понимать, что у него внутри. Неверные представления о том, что «под капотом», авторы называют частым источником ошибок у клиентов. Это ровно принцип «сначала руками, потом фреймворк», которому следует наш курс.

Основа любой агентной системы — модель, у которой есть поиск, инструменты и память. Современные модели сами составляют поисковые запросы, выбирают инструменты и решают, что запомнить. Важно две вещи: подогнать эти возможности под свою задачу и дать модели простой, хорошо документированный интерфейс к ним. Один из способов — протокол MCP (урок 8.3.2). Дальше в статье предполагается, что у каждого вызова модели эти возможности есть.

flowchart LR
subgraph A["1. Цепочка"]
  a1["LLM 1"] --> g{"проверка"} --> a2["LLM 2"] --> a3["LLM 3"]
end
subgraph B["2. Маршрутизация"]
  b0["Классификатор"] --> b1["Промпт А"]
  b0 --> b2["Промпт Б"]
  b0 --> b3["Промпт В"]
end
subgraph C["3. Параллелизация"]
  c1["LLM"] --> cz["Агрегатор"]
  c2["LLM"] --> cz
  c3["LLM"] --> cz
end
Паттерны 1–3: путь задан кодом заранее (наша схема по описаниям в статье)

1. Цепочка промптов (prompt chaining). Задача делится на последовательные шаги; каждый вызов модели получает результат предыдущего. Между шагами можно вставить программную проверку («ворота», gate), которая остановит процесс, если что-то пошло не так. Подходит, когда задача чисто раскладывается на фиксированные подзадачи: каждый вызов решает более простую задачу — платим задержкой, получаем точность. Примеры из статьи: написать рекламный текст, потом перевести его; составить план документа, проверить план по критериям, потом написать документ по плану.

Пример для нашего курса: конспект лекции → проверка «все ли формулы на месте» (код) → 5 вопросов для квиза по конспекту.

2. Маршрутизация (routing). Вход классифицируется и отправляется в специализированную ветку. Так можно писать узкие промпты для каждого типа входа: без маршрутизации оптимизация под один тип запросов портит другие. Подходит, если категории явно различаются и классификацию можно сделать точно — моделью или обычным классификатором. Примеры: разные типы обращений в поддержку (общий вопрос, возврат денег, техническая проблема) — в разные процессы, промпты и инструменты; простые частые вопросы — маленькой дешёвой модели, сложные — большой.

3. Параллелизация (parallelization) в двух вариантах:

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

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

flowchart LR
subgraph D["4. Оркестратор и исполнители"]
  o["Оркестратор"] -->|"подзадачи решает сам"| w1["Исполнитель"]
  o --> w2["Исполнитель"]
  w1 --> s["Синтез"]
  w2 --> s
end
subgraph E["5. Оценщик и оптимизатор"]
  gen["Генератор"] -->|"черновик"| ev["Оценщик"]
  ev -->|"замечания"| gen
  ev -->|"принято"| out["Результат"]
end
Паттерны 4–5: модель влияет на ход работы, но рамка задана кодом

4. Оркестратор и исполнители (orchestrator-workers). Центральная модель сама разбивает задачу, раздаёт подзадачи моделям-исполнителям и сводит их результаты. Внешне похоже на параллелизацию, но разница в гибкости: подзадачи не заданы заранее, их определяет оркестратор по конкретному входу. Подходит, когда подзадачи невозможно предсказать: в программировании число файлов, которые придётся изменить, и характер изменений зависят от задачи. Примеры: продукты для программирования, которые каждый раз меняют много файлов; поиск, где нужно собрать и проанализировать сведения из многих источников (эта идея выросла в исследовательскую систему — см. конспект статьи о ней).

5. Оценщик и оптимизатор (evaluator-optimizer). Один вызов генерирует ответ, другой оценивает и даёт обратную связь — по кругу. Подходит, когда есть ясные критерии оценки и итерации дают измеримую пользу. Два признака: ответ модели заметно улучшается, когда человек формулирует замечания, и модель сама способна дать такие замечания. Это как писатель, который редактирует текст в несколько проходов. Примеры: художественный перевод, где оценщик ловит оттенки, упущенные переводчиком; сложный поиск в несколько раундов, где оценщик решает, нужно ли искать ещё.

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

  1. Получает задачу — командой или в диалоге с человеком.
  2. Когда задача ясна, сам планирует и действует, при необходимости возвращаясь к человеку за сведениями или решением.
  3. На каждом шаге получает «истину от среды» (ground truth from the environment): результаты вызовов инструментов, вывод выполненного кода — и по ним оценивает прогресс.
  4. Может останавливаться на контрольных точках или при препятствиях, чтобы получить обратную связь от человека.
  5. Заканчивает, когда задача решена, — или по условию остановки (например, лимиту итераций), чтобы сохранить контроль.

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

Когда агент оправдан: открытые задачи, где число шагов не предсказать и путь не зашить в код; модель будет работать много ходов, и вы должны в какой-то мере доверять её решениям. Цена — более высокие расходы и накопление ошибок, поэтому авторы советуют обширное тестирование в песочнице и защитные ограничения (guardrails). Примеры из практики Anthropic: агент для задач SWE-bench (правки во многих файлах по описанию задачи) и эталонная реализация «computer use», где Claude управляет компьютером.

Паттерны — не предписание, а кубики, из которых собирают систему под задачу. Ключ к успеху, как и с любыми функциями на LLM, — измерять качество и итеративно улучшать; добавлять сложность «только когда она доказуемо улучшает результат».

Три принципа в конце статьи:

  1. Простота устройства агента.
  2. Прозрачность: явно показывать шаги планирования агента.
  3. Тщательно продуманный интерфейс агент — компьютер (ACI): подробная документация инструментов и их тестирование.

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

  • Поддержка клиентов. Разговор естественен, нужны внешние данные (клиент, заказы, база знаний) и действия (возврат денег, обновление заявки), а успех измерим — проблема решена или нет. Некоторые компании даже берут плату только за успешно решённые обращения. (Учебная версия такого агента — в рецепте кукбука и уроке 6 курса Tool use.)
  • Программирование. Решение проверяется автоматическими тестами, агент может итерировать по результатам тестов, задача хорошо структурирована, качество измеряется объективно. Но человеческое ревью всё равно нужно: тесты проверяют функциональность, а не соответствие более широким требованиям системы.

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

Заголовок раздела «Приложение 2. Промпт-инжиниринг инструментов»

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

  • Формат имеет значение, даже если он «косметический». Правку файла можно выразить как diff или как полный новый текст файла; код можно вернуть в markdown или внутри JSON. Для программиста это одно и то же, для модели — нет: чтобы написать diff, нужно заранее знать, сколько строк изменится (это записывается в заголовке фрагмента); код внутри JSON требует экранировать переводы строк и кавычки.
  • Правила выбора формата: дать модели достаточно токенов «подумать», прежде чем она загонит себя в угол; держать формат близким к тому, что модель видела в текстах из интернета; не заставлять её вести точный подсчёт строк или экранировать код.
  • ACI так же важен, как HCI. Сколько сил вкладывают в интерфейсы для людей, столько же стоит вложить в интерфейсы для агентов. Поставьте себя на место модели: очевидно ли по описанию, как пользоваться инструментом? Хорошее описание содержит пример использования, пограничные случаи, требования к формату входа и чёткие границы с соседними инструментами. Пишите его, как хороший docstring для джуниора в команде.
  • Тестируйте, как модель пользуется инструментами, на множестве примеров, и исправляйте найденные ошибки.
  • Защита от ошибок (японский принцип poka-yoke): меняйте аргументы так, чтобы ошибиться было трудно.

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


Часть 2. Writing effective tools for agents — with agents (сентябрь 2025)

Заголовок раздела «Часть 2. Writing effective tools for agents — with agents (сентябрь 2025)»

Обычная функция — контракт между двумя детерминированными системами: getWeather("NYC") каждый раз одинаково узнаёт погоду в Нью-Йорке. Инструмент — контракт между детерминированной системой и недетерминированным агентом. На вопрос «брать ли сегодня зонт?» агент может вызвать погодный инструмент, ответить из общих знаний или сначала уточнить город; иногда он ошибётся или не поймёт, как пользоваться инструментом. Поэтому инструменты и MCP-серверы нужно проектировать для агентов, а не так, как API для других разработчиков. Приятное наблюдение автора (Кен Аидзава): самые «эргономичные» для агентов инструменты оказываются интуитивно понятными и людям.

Процесс: прототип → эвал → доработка вместе с агентом

Заголовок раздела «Процесс: прототип → эвал → доработка вместе с агентом»
flowchart LR
P["Прототип инструментов"] --> T["Задачи для эвала из реальной работы"]
T --> R["Прогон: агент в цикле на каждую задачу"]
R --> A["Анализ: метрики и транскрипты"]
A --> F["Правка инструментов (в т.ч. руками Claude Code)"]
F --> R
F --> H["Проверка на отложенном наборе"]
Цикл улучшения инструментов из статьи (наша схема)

Прототип. Заранее трудно угадать, какие инструменты агенту будут удобны, — нужно попробовать. Быстро соберите прототип; если пишете его с помощью Claude Code, дайте агенту документацию используемых библиотек (многие сайты документации публикуют её в «плоском» виде для LLM — файлы llms.txt). Оберните инструменты в локальный MCP-сервер и подключите к агенту или передавайте их прямо в вызовы API. Пощупайте сами, соберите отзывы пользователей.

Задачи для эвала. Сгенерируйте много задач, основанных на реальном использовании и реалистичных данных, а не на игрушечной «песочнице». Хорошая задача может требовать нескольких — даже десятков — вызовов инструментов. Контраст из статьи (в пересказе):

Сильная задачаСлабая задача
Назначь встречу с Джейн на следующей неделе по проекту Acme, приложи заметки с прошлого планирования и забронируй переговорнуюНазначь встречу с jane@acme.corp на следующей неделе
Клиент 9182 говорит, что с него трижды списали деньги за одну покупку: найди записи в логах и проверь, не пострадал ли кто-то ещёНайди в логах платежей purchase_complete и customer_id=9182
Клиентка подала заявку на отказ от подписки: выясни почему, какое удерживающее предложение подойдёт и какие есть рискиНайди заявку на отказ клиента 45892

Слабые задачи по сути диктуют агенту, какой инструмент вызвать с какими аргументами, — они не проверяют, понимает ли он инструменты. У каждой задачи должен быть проверяемый ответ или результат; проверка может быть простым сравнением строк или LLM-судьёй, но не должна быть слишком строгой (отбраковывать верные ответы из-за формата, пунктуации или другой формулировки). Можно указать и ожидаемые инструменты, но осторожно: правильных путей бывает несколько, и подгонять эвал под одну стратегию не стоит.

Прогон. Программно, прямыми вызовами API, простым агентным циклом (while: вызов модели ↔ вызов инструмента) — по циклу на задачу. В системном промпте агентов-испытуемых попросите выводить не только структурированный ответ (для проверки), но и рассуждения и отзыв — причём до вызовов инструментов: это запускает рассуждение по шагам и повышает «эффективный интеллект» модели. У Claude для этого есть режим размышлений между вызовами инструментов (interleaved thinking). Кроме итоговой точности собирайте: время вызовов и задач, число вызовов, расход токенов, ошибки инструментов.

Анализ. Агенты — хорошие помощники в поиске проблем: противоречивые описания, неэффективные реализации, запутанные схемы. Но важнее часто то, о чём агент промолчал: модели не всегда «говорят, что думают» (автор ссылается на исследование интерпретируемости Anthropic — см. конспект «On the Biology of a Large Language Model»). Читайте сырые транскрипты, включая вызовы и ответы инструментов. Метрики подсказывают диагноз: много повторных вызовов — пересмотрите пагинацию и лимиты; много ошибок с неверными параметрами — улучшите описания и примеры. Реальный случай: при запуске инструмента веб-поиска Claude без нужды дописывал «2025» к поисковому запросу и ухудшал результаты — исправили описанием инструмента.

Доработка вместе с агентом. Склейте транскрипты прогонов и отдайте их Claude Code: он хорошо анализирует транскрипты и переписывает много инструментов разом, сохраняя согласованность описаний и реализаций. По словам автора, бо́льшая часть советов статьи получена именно так — многократной оптимизацией внутренних инструментов Anthropic (Slack, Asana и др.) с помощью Claude Code. Чтобы не переобучиться на «тренировочных» задачах, результат проверяли на отложенном наборе (held-out test set) — и даже инструменты, написанные экспертами вручную, удавалось улучшить.

1. Выбирайте, какие инструменты делать (и какие не делать). Больше инструментов — не значит лучше. Частая ошибка — просто обернуть каждый метод существующего API. У агента другие «возможности восприятия»: контекст ограничен, а память компьютера дешёвая. Если инструмент list_contacts вернёт всю адресную книгу, агент будет читать её токен за токеном — как человек, листающий справочник с первой страницы. Лучше search_contacts или сразу message_contact. Инструмент может объединять несколько операций:

ВместоЛучше
list_users, list_events, create_eventschedule_event — сам находит свободное время и создаёт встречу
read_logssearch_logs — возвращает только нужные строки с контекстом вокруг
get_customer_by_id, list_transactions, list_notesget_customer_context — собирает всё свежее и важное о клиенте сразу

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

2. Пространства имён (namespacing). Агент может получить десятки MCP-серверов и сотни инструментов, в том числе чужих. Общие префиксы по сервису и ресурсу (asana_search, jira_search, asana_projects_search, asana_users_search) помогают выбрать нужный. Префикс или суффикс — выбор, заметно влияющий на результаты эвала, и разный для разных моделей; решайте по своим эвалам.

3. Возвращайте осмысленный контекст. Только информацию с высоким «сигналом»: name, image_url, file_type полезнее, чем uuid, 256px_image_url, mime_type. Агенты гораздо лучше работают с понятными названиями, чем с загадочными идентификаторами: замена случайных буквенно-цифровых UUID на осмысленные имена (или даже на простую нумерацию с нуля) заметно повышает точность Claude в задачах поиска и снижает число выдумок. Если идентификаторы всё же нужны для следующих вызовов, дайте параметр response_format со значениями "concise" и "detailed": в примере со Slack краткий ответ (только текст сообщений, без thread_ts, channel_id, user_id) занимает примерно треть токенов подробного (72 токена против 206). Формат ответа (XML, JSON, Markdown) тоже влияет на качество, и универсального ответа нет — модели лучше работают с форматами, похожими на их обучающие данные.

4. Экономьте токены. Для ответов, которые могут быть большими, — пагинация, выбор диапазона, фильтры, обрезка с разумными значениями по умолчанию. В Claude Code ответы инструментов по умолчанию ограничены 25 000 токенов. Если обрезаете — подскажите агенту, что делать (например, искать узко несколько раз вместо одного широкого поиска). Ошибки тоже «промпт-инжинирьте»: вместо непонятного кода ошибки или трассировки стека — конкретное, выполнимое указание, что исправить, с примером правильного входа.

5. Промпт-инжиниринг описаний. Описания и схемы загружаются в контекст агента, поэтому сильнее всего влияют на его поведение. Описывайте инструмент, как новому сотруднику: проговорите то, что обычно подразумеваете (особые форматы запросов, узкие термины, связи между ресурсами). Называйте параметры однозначно: не user, а user_id. Ожидаемые входы и выходы задавайте строгими моделями данных. Даже маленькие правки описаний дают большой эффект: по словам автора, Claude 3.5 Sonnet вышел на лучший на тот момент результат в SWE-bench Verified после точных уточнений описаний инструментов. Для MCP-серверов полезны аннотации инструментов (tool annotations) — они сообщают, какие инструменты обращаются к внешнему миру или делают необратимые изменения.

Хорошие инструменты, по формулировке автора, «намеренно и чётко определены, разумно расходуют контекст агента, сочетаются в разных workflow и позволяют агенту интуитивно решать реальные задачи». Механизмы взаимодействия агентов с миром будут меняться (протокол MCP, сами модели), но системный подход через эвалы позволит инструментам развиваться вместе с агентами.

  1. Откройте ноутбук basic_workflows и запустите цепочку, параллелизацию и маршрутизацию на локальной модели через claude_local.py («Подготовка»). Для какой из ваших задач (например, разбор конспекта лекции) подошёл бы каждый паттерн?
  2. Возьмите агента из практики урока 8.3.1 и перепишите один инструмент по принципам второй статьи: осмысленные имена вместо id, response_format, полезное сообщение об ошибке. Сравните число шагов до ответа на 10 задачах до и после.
  3. Составьте 5 «сильных» и 5 «слабых» задач для эвала своего инструмента по образцу таблицы выше. Почему слабые задачи завышают оценку?
  4. Пройдите по чат-боту из курса Tool use и найдите три нарушения принципов второй статьи (подсказка: get_user с key/value, ответ строкой str(tool_result), отмена заказа без проверки).
ENRU
agentic systemагентная система
workflowрабочий процесс (путь задан кодом)
augmented LLM«дополненная» LLM (с поиском, инструментами, памятью)
prompt chaining / gateцепочка промптов / контрольная проверка («ворота»)
routingмаршрутизация
parallelization: sectioning / votingпараллелизация: секционирование / голосование
orchestrator-workersоркестратор и исполнители
evaluator-optimizerоценщик и оптимизатор
ground truth from the environment«истина от среды» — результат действия
agent-computer interface (ACI)интерфейс агент — компьютер
poka-yokeзащита от ошибок (дурака)
namespacingпространства имён (общие префиксы)
held-out test setотложенный тестовый набор
interleaved thinkingразмышления между вызовами инструментов