013: Агент/Делегат
- Требует:
- Дополняется:
Это правило, которое позволяет выполнять задачу в отдельной, «чистой» комнате. Когда в Вызове появляется свойство _delegate, система понимает, что нужно запустить Действие или новый Запрос в изолированном пространстве. При этом свойство _scopes работает как пропуск, давая контролируемый доступ к информации из родительского окружения.
Делегирование — это способ решения важной проблемы: как сделать так, чтобы агенты могли расти и собираться из разных частей, как конструктор. Это мощный инструмент, который позволяет запускать Инструменты в «песочнице» — отдельном, безопасном месте. Так информация из разных задач не смешивается, и одни и те же инструменты можно использовать снова и снова. Когда мы передаём (делегируем) Вызов внешнему исполнителю (делегату) — будь то другой Запрос или Действие в подзапросе — система может строить сложное поведение агента из независимых, готовых блоков.
Реализация через Действие
По своей сути, делегирование — это не какое-то новое правило, а просто умное применение уже существующей системы Действий. Запуск делегата выполняет особое Действие, которое можно назвать «универсальным обработчиком». Система автоматически использует его для любого Вызова, в котором находит свойство _delegate.
Это Действие-делегат получает три стандартных аргумента:
call: Полный объект вызова, включая все параметры для подзапроса.tool: Схема инструмента, из которой действие читает свойство_delegate, чтобы понять, что именно нужно запустить.context: Набор сообщений из родительского окружения, которые будут переданы в подзапрос.
Логика этого действия проста: оно берёт эти три аргумента, собирает из них новый, изолированный Запрос и отправляет его в работу. Это изящное решение показывает, насколько мощными являются основные правила системы: структура Действия настолько надёжна, что даже сложные механики, как делегирование, можно построить на её основе, не придумывая новых правил.
Проблема: Громоздкие инструменты и «смешение контекста»
Когда агент становится умнее и получает больше возможностей, хранить все его Инструменты в одном большом «ящике» становится неудобно и неэффективно.
- Слишком большие схемы: У языковых моделей (LLM) есть предел того, сколько информации они могут обработать за раз. Если сложить много сложных Инструментов вместе, модель может запутаться и не сможет правильно выбрать нужный вариант.
- Смешение контекста: Когда все Инструменты находятся в одной «комнате», языковую модель может сбить с толку лишняя информация. В итоге она может выбрать не тот Инструмент или неправильно его настроить.
- Сложно использовать повторно: Инструмент, созданный для одного агента, нельзя просто так взять и отдать другому. Придётся тащить за собой всю его «комнату» с настройками.
Делегирование решает эти проблемы, вводя Изоляцию через Делегирование — способ передать Вызов на выполнение в отдельное, изолированное место.
Как вызвать делегата
Чтобы поручить выполнение задачи делегату, нужно в схеме Инструмента добавить свойство _delegate. Это свойство — как записка для системы, которая говорит: «Эту команду нужно выполнять не здесь, а передать внешнему исполнителю».
Свойство _delegate — это просто текст (string), и его можно использовать двумя способами:
-
Сохранённый, многоразовый Запрос — это самая распространённая форма Идеи. Механизм Делегирования — это основной способ объединять такие Идеи в более сложные системы. Подробности см. в 101: Концепция/Идея.
Указать на сохранённый Запрос: В тексте можно написать путь или интернет-адрес файла (JSON), который описывает отдельный Запрос. Представь, что это подробная инструкция для другой команды. Так один Инструмент может поручить свою работу совершенно другой, независимой инструкции.
-
Создать анонимного делегата: Если написать специальное слово
'anonymous', то будет создан «анонимный» делегат. Это полезно, когда нужно быстро создать чистое, изолированное место для выполнения Вызова Инструмента, не создавая для этого отдельного файла с инструкциями. Система автоматически создаст для этого Вызова новую, пустую «комнату».
Выполнение в изолированном пространстве
Делегат предоставляет «чистую комнату» для выполнения задачи. Вместо того чтобы работать в общем и шумном пространстве родительского агента, Вызов обрабатывается в новом, отдельном сеансе. Контекст для этого подзапроса не наследуется автоматически, а создаётся с нуля.
Именно здесь ключевую роль играет Ограниченный контекст. Свойство _scopes в схеме Инструмента работает как мост, который точно указывает, какие части информации из родительского контекста нужно «импортировать» в рабочее пространство делегата. Это даёт родительскому агенту полный контроль над тем, что видит делегат, предотвращая «смешение контекста» и обеспечивая полную независимость.
Работа с большими схемами
Делегирование также помогает, когда у Инструмента очень большой или сложный результат работы. Вместо того чтобы описывать этот огромный результат (схему _output) в главном запросе и занимать место, можно определить Инструмент только с параметрами для ввода и указателем _delegate.
Языковая модель сможет спланировать Вызов, зная только, что нужно подать на вход, а сложный результат будет создан уже внутри изолированного подзапроса делегата. Это позволяет агенту планировать последовательность сложных действий, не видя перед собой сразу все гигантские инструкции для каждого шага. Модель просто доверяет, что делегат сделает свою работу правильно и вернёт нужный результат, который потом можно будет использовать.
Стратегии обработки делегатов
Инструмент становится Делегатом, как только в его схеме появляется свойство _delegate. Это сигнал, что Вызов нужно передать дальше. Ключевой вопрос: когда это происходит? Система поддерживает две стратегии, позволяя выбирать между строгой безопасностью и гибкостью.
1. Обработка во время выполнения (по умолчанию)
Самый гибкий подход, используемый по умолчанию, — это обработка делегата во время выполнения, уже после того, как агент сгенерировал Вызов.
Этот метод открывает удивительную возможность, которой нет в обычном программировании: языковая модель работает как умный «переходник». Агент может создать Вызов с параметрами, которые не совсем совпадают с тем, что ожидает делегат в своей схеме input. Во время выполнения система собирает вместе контекст делегата и данные от вызывающего, а языковая модель внутри подзапроса сама пытается понять, как их сопоставить.
Это огромное преимущество. Делегаты могут меняться и развиваться независимо друг от друга. Даже если делегат изменит свои правила приёма данных, вызывающие его агенты не сломаются сразу. Языковая модель попытается адаптировать старый формат Вызова к новой схеме input, создавая устойчивость и слабую связанность, которые уникальны для этой архитектуры.
Процесс выглядит так:
- Агент генерирует Вызов для модульного Инструмента.
- Исполнитель видит свойство
_delegateи запускает процесс делегирования. - Сборка контекста: Исполнитель загружает файл с описанием делегата (если он не анонимный) и собирает его базовый контекст. Затем, используя
_scopes, он добавляет туда нужную информацию от родителя. - Сопоставление ввода: Параметры из Вызова упаковываются в Сообщение Ввода и добавляются в контекст. Именно здесь включается способность языковой модели быть «переходником»: она будет использовать эти входные данные для выполнения логики делегата, даже если их схемы не совпадают идеально.
- Выполнение: Создаётся новый, изолированный Запрос с объединённым контекстом. Результат возвращается как итог первоначального Вызова.
2. Предварительная обработка (опционально)
В ситуациях, где нужны более строгие гарантии, делегата можно обработать заранее, ещё до того, как первоначальный Запрос будет отправлен агенту.
В этом режиме система заранее загружает описание Запроса делегата и объединяет его схему input со схемой параметров Инструмента. Это позволяет языковой модели агента с самого начала видеть точные требования делегата, гарантируя, что созданный Вызов будет идеально правильным и безопасным. Важно, что при таком объединении можно включить и схему _output делегата, создавая строгий контракт на ожидаемый результат.
Этот подход даёт такую же надёжность, как в традиционных API, где и входные, и выходные данные известны и проверяются. Он жертвует гибкостью обработки во время выполнения и лучше всего подходит для критически важных, чётко определённых задач, где гибкость не нужна.
Пример: Гибкое сопоставление данных во время выполнения
Этот пример показывает, как работает концепция «LLM как переходник». Делегат успешно выполняется, даже если Вызов от агента не полностью совпадает с его схемой входных данных. Это поведение по умолчанию, при обработке во время выполнения.
Что видит вызывающий агент
Агенту-оркестратору нужно отправить сообщение. Он знает об Инструменте sendMessage, который делегирует задачу внешнему агенту по URL-адресу. Основываясь на своей информации, он создаёт Вызов с параметрами userId и text, не зная, что именно нужно самому делегату.
// ВЫЗОВ, СОЗДАННЫЙ ОРКЕСТРАТОРОМ
{
"_tool": "sendMessage",
"_delegate": "http://example.com/agents/speaker_EN",
"userId": "u_123",
"text": "Hello, world!"
}
Что видит делегат и итоговый контекст
Делегат speaker_EN — это отдельное описание Запроса. Во время выполнения система упаковывает параметры от вызывающего агента в свойство input внутри Сообщения Ввода. Но самое важное: она также включает собственную схему делегата, которая не совпадает с предоставленным input. Теперь задача языковой модели делегата — устранить этот смысловой разрыв. Она сама догадается, что userId — это recipientId, а text — это messageBody. Это не программная замена, а смысловое сопоставление, которое происходит внутри модели.
// ИТОГОВЫЙ КОНТЕКСТ ДЛЯ ПОДЗАПРОСА
[
{
"type": "system",
"message": "You are an expert in messaging in English."
},
{
"type": 'input",
// Это необработанные данные от вызывающего агента.
"input": {
"userId": "u_123",
"text": "Hello, world!"
},
// А это формат, который ожидает сам делегат
"schema": {
"type": "object",
"properties": {
"recipientId": { "type": "string" },
"messageBody": { "type": "string" }
}
}
}
]
Пример: Создатели музыки
Делегаты позволяют создавать мощные комбинации, так как описания Запросов могут работать как самостоятельные сервисы, которыми управляют другие агенты. Это создаёт понятную и гибкую иерархию: агенты высокого уровня могут заниматься общей организацией (оркестрацией), передавая узкоспециализированные задачи многоразовым делегатам низкого уровня.
Представим процесс с двумя специалистами-делегатами: Композитором и Саунд-дизайнером.
-
Саунд-дизайнер— это эксперт низкого уровня. Это самостоятельное описание Запроса, которое знает всё о физике звука и умеет управлять синтезаторами для создания конкретных аудиофайлов. -
Композитор— специалист среднего уровня. Его главная задача — создать песню. Он использует свои собственные инструменты, чтобы придумать мелодию и структуру композиции. Чтобы воплотить свою идею в жизнь, он делает Вызовы к делегатуСаунд-дизайнеру, чтобы тот синтезировал нужные звуки.
Такая двухуровневая иерархия — обычное дело. Но настоящая сила делегатов — в их динамическом, гибком объединении для решения конкретной задачи.
Такая схема позволяет гибко управлять процессом. Высокоуровневый Продюсер может поручить задачу Композитору, который, в свою очередь, использует Саунд-дизайнера. Однако Продюсер также может обратиться к Саунд-дизайнеру напрямую для выполнения определённых задач, минуя Композитора.
Теперь представим высокоуровневого агента-Продюсера. Цель Продюсера — создать готовую музыкальную запись. В зависимости от задачи Продюсер может по-разному управлять своими делегатами:
-
Иерархическая оркестрация: Чтобы создать песню,
Продюсерможет сделать один-единственный Вызов к делегатуКомпозитору.Продюсердаёт общие указания («Мне нужна грустная баллада»), аКомпозиторвыполняет всю свою внутреннюю работу, включая собственные вложенные Вызовы кСаунд-дизайнеру. В этом случаеПродюсерудаже не нужно знать о существованииСаунд-дизайнера. -
Параллельная оркестрация: Если
Продюсерудля записи нужны ещё и звуковые эффекты (например, шаги или шум дождя), он может делать Вызовы напрямую кСаунд-дизайнерудля этих задач, параллельно с Вызовом кКомпозитору.
Это показывает главный принцип: комбинация инструментов не задана жёстко. Продюсер может либо рассматривать Композитора как «чёрный ящик», либо напрямую взаимодействовать с его составными частями (Саунд-дизайнером), в зависимости от того, что требуется в данный момент. Такая гибкость позволяет объединять один и тот же набор экспертов-делегатов в разных комбинациях, создавая очень гибкую и развивающуюся систему.
От Делегирования к Ограниченным контекстам
Делегирование создаёт изолированное пространство для работы, но чтобы оно было полезным, делегату нужен способ получать информацию от своего родителя. Свойство _scopes как раз и служит этим мостом между контекстами. То, как именно работает этот мост, подробно описано в правилах Ограниченного контекста.