ТЗ: межагентное взаимодействие и обнаружение участников Saga
#1. Цель
Добавить возможность агентам обнаруживать участников совместной работы в рамках текущей Saga и напрямую взаимодействовать с агентами-коллегами.
Реализация должна опираться на существующие механизмы Temporality --- Saga, delegation, Journal и steering. Не создавать отдельную универсальную messaging-подсистему и не унифицировать взаимодействие человека и агента.
#2. Область работ
Добавить инструмент get_collaborators() и инструмент ask_agent() с
поддержкой синхронного и асинхронного режимов.
Существующий ask_human() сохраняется как отдельный механизм HITL. Его
модель форм, валидации, каналов коммуникации и получения ответов не
изменяется.
#Разделение механизмов
Механизм Назначение
get_collaborators() Обнаружение участников текущей Saga
--- людей и агентов
ask_agent() Взаимодействие агента с другим
агентом
#ask_human() Взаимодействие агента с человеком
через HITL
get_collaborators() только предоставляет информацию об участниках. Он
не маршрутизирует сообщения и не заменяет ask_human() или
ask_agent().
#3. get_collaborators()
#Назначение
Возвращать список людей и агентов, участвующих в текущей Saga, чтобы агент мог определить, к кому обратиться.
#Состав результата
Для каждого участника возвращать доступные сведения:
id--- стабильный идентификатор участника;kind--- тип участника:agentилиhuman;role--- роль участника;task--- контекст или назначенная задача;status--- состояние участия/делегации, если применимо;run_id--- идентификатор выполнения для агента, если применимо.
Пример:
{
"collaborators": [
{
"id": "agent:coder-01",
"kind": "agent",
"role": "Coder",
"task": "Implement API",
"status": "running",
"run_id": "run-123"
},
{
"id": "human:analyst-01",
"kind": "human",
"role": "Business Analyst",
"task": "Requirements analysis"
}
]
}
#Правила
- Область видимости --- текущая Saga.
- В список включать участников, реально связанных с работой в этой Saga, а не произвольных агентов или пользователей системы.
- Учитывать вложенные делегации: агент должен видеть участников дочерних и, в пределах разрешённой области видимости, соседних ветвей Saga.
- Не раскрывать сведения, к которым вызывающий агент не имеет доступа.
- Не считать завершённую делегацию автоматически доступной для нового взаимодействия. Возможность обращения к завершённому агенту определяется фактической поддержкой возобновления его run.
- Не возвращать секреты, токены, внутренние credentials и избыточные персональные данные.
#4. ask_agent()
#Назначение
Позволить агенту отправить другому агенту запрос, поручение или структурированные данные без обязательного участия Lead.
Инструмент должен поддерживать два режима:
wait--- дождаться ответа в рамках текущего вызова;async--- зарегистрировать запрос, вернуть управление сразу и доставить ответ отправителю через steering в одном из следующих ходов.
#Предлагаемый интерфейс
ask_agent({
to: "agent:coder-01",
type: "compatibility.check",
payload: {
api_change: "..."
},
mode: "async"
})
Параметры:
Параметр Обязательный Назначение
to Да Идентификатор агента
из доступной области
Saga
type Да Тип запроса/сообщения
payload Да Текстовые или
структурированные
данные
#mode Нет wait или async;
значение по умолчанию
определить при
проектировании
Не ограничивать payload обычным текстом. Предусмотреть передачу
структурированных данных и ссылок на доступные артефакты с соблюдением
существующих правил доступа.
#Синхронный режим (wait)
- Создать запрос и передать его адресату.
- Получатель обрабатывает запрос в рамках своего агентского выполнения.
- Отправитель ожидает ответ.
- Ответ возвращается непосредственно как результат вызова
ask_agent().
Ожидание должно иметь timeout. Истечение timeout не должно приводить к потере уже зарегистрированного запроса.
#Асинхронный режим (async)
- Создать устойчиво идентифицируемый запрос.
- Передать его адресату.
- Вернуть отправителю
request_idи состояниеpending, не ожидая ответа. - Получатель принимает запрос через существующий механизм steering.
- Ответ получателя сохраняется и связывается с исходным запросом.
- Ответ доставляется отправителю через steering и включается во входной контекст следующего хода.
- Отправителю не требуется опрашивать адресата или самостоятельно проверять готовность ответа.
Пример немедленного результата:
{
"request_id": "req-456",
"status": "pending"
}
Пример ответа:
{
"request_id": "req-456",
"status": "completed",
"from": "agent:coder-01",
"payload": {
"compatible": false,
"reason": "The API change breaks backward compatibility."
}
}
#Требования к асинхронному взаимодействию
- Запрос и ответ должны переживать рестарты worker и kernel в пределах гарантий существующей инфраструктуры.
- Каждый запрос должен иметь стабильный
request_id. - Ответ должен однозначно связываться с исходным запросом.
- Поддержать несколько одновременно ожидаемых запросов от одного отправителя.
- Ответы должны поступать независимо, без требования соблюдать порядок отправки.
- Не допускать бесконечного ожидания: предусмотреть timeout, отмену и терминальные ошибки.
- Если адресат завершился, недоступен или не может обработать запрос, отправитель должен получить явный результат, а не зависнуть.
- Повторная доставка после сбоя не должна приводить к неконтролируемому повторному выполнению уже обработанного запроса.
- Входящий запрос не должен автоматически прерывать текущую работу получателя. Он поступает через steering и обрабатывается в соответствии с существующей семантикой steering.
- Не запускать новый run адресата автоматически, если такое поведение отдельно не предусмотрено существующей моделью делегаций.
#5. Внутренняя реализация
Использовать существующие механизмы:
- Saga / delegation --- определение участников и допустимой области взаимодействия;
- Journal --- фиксация отправки, получения и результата запроса в соответствии с существующей моделью событий;
- Steering --- передача входящих запросов получателю и асинхронных ответов отправителю;
- Temporal --- координация ожидания и восстановления там, где это требуется существующей архитектурой.
Запрос должен иметь устойчивую идентичность и сохраняемое состояние. Конкретную схему хранения и механизм восстановления выбрать после изучения текущих реализаций Journal, Saga и steering.
Не вводить отдельный брокер сообщений, самостоятельную mailbox-подсистему, presence, комнаты, подписки и универсальный чат-протокол без доказанной необходимости.
Temporal Signals могут использоваться как внутренний механизм пробуждения workflow, но не должны быть единственным хранилищем запроса или ответа.
#6. Границы доступа и безопасность
- Агент может обращаться только к участникам, видимым ему в текущей Saga и разрешённым политиками доступа.
- Нельзя доверять произвольному
to, переданному моделью: адресат должен проверяться на стороне kernel. - Нельзя обходить ограничения доступа к run, workspace, артефактам и данным через передачу payload.
- Сохранять исходного отправителя и контекст Saga для аудита.
- Не допускать подмены отправителя или ответа другого агента.
- Вложенные делегации не должны автоматически получать права на взаимодействие за пределами унаследованной области доступа.
#7. Тестирование
Добавить unit- и интеграционные тесты.
Сценарий Ожидаемый результат
Вызов get_collaborators() Возвращаются доступные участники
текущей Saga, включая вложенные
делегации
В Saga есть люди и агенты Оба типа присутствуют с корректным
kind
Агент обращается к агенту в режиме Ответ возвращается в текущем вызове
wait
Агент обращается к агенту в режиме Возвращается request_id,
async отправитель продолжает работу
Получатель отвечает позднее Ответ поступает отправителю через steering в следующем ходе
Несколько параллельных запросов Ответы сопоставляются по
request_id
Worker/kernel перезапускается до Запрос и связь с ответом ответа восстанавливаются
Получатель завершился или Отправитель получает явное недоступен терминальное состояние
Повторная доставка запроса Не вызывает неконтролируемого повторного выполнения
Попытка обратиться к чужому агенту Запрос отклоняется проверкой доступа
Получатель занят другой работой Запрос ставится в steering и не прерывает текущий ход
#ask_human() Продолжает работать независимо, без
регрессий HITL
#8. Критерии готовности
- Агент может получить список людей и агентов, участвующих в текущей Saga.
- Агент может адресно обратиться к другому доступному агенту.
- Синхронный запрос возвращает ответ в текущем ходе.
- Асинхронный запрос не блокирует отправителя.
- Асинхронный ответ автоматически поступает отправителю через steering в следующем ходе.
- Запросы и ответы корректно переживают поддерживаемые сценарии рестарта.
- Проверки доступа выполняются kernel-side.
- Существующий
ask_human()и его HITL-возможности не затронуты.
#9. Что не входит в задачу
- Универсальный Agent Messaging / Mailbox как отдельная подсистема.
- Общие чаты, комнаты и presence.
- Broadcast и групповые рассылки.
- Взаимодействие с произвольными агентами вне текущей Saga.
- Автоматическое прерывание выполнения агента входящими запросами.
- Exactly-once execution как гарантия.
- Изменение пользовательского интерфейса HITL.
Итог: реализовать минимальный механизм Human-Agent Collaboration на
уровне Saga: обнаружение участников через get_collaborators() и
межагентное взаимодействие через ask_agent(), используя существующие
delegation, Journal и steering.