Skip to content

Внешние агенты ​

Как устроена работа платформы с внешними агентами: состав, модель данных, синхронизация событий, объявляемые агентом разделы и выдача модели.

Роль платформы ​

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

Это отдельная сущность, не связанная с таблицей агентов чата

Существующая таблица агентов чата не изменяется и в этой возможности не участвует. Связей между ними нет: ни внешнего ключа, ни общих полей. Совпадает только слово «агент».

Общая схема ​

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

Состав ​

СоставляющаяГдеНазначение
Клиент протоколаapps/api/src/integrations/managed-agents/eacp-client.tsВсе обращения к агенту, проверка адреса, разбор ошибок
Служба агентовapps/api/src/services/managed-agents-service.tsРеестр, шифрование токена, команды, запись событий
Синхронизация событийapps/api/src/services/managed-agent-event-sync.tsПостоянное чтение потока событий всех включённых агентов
Служба выдачи моделиapps/api/src/services/managed-agent-llm-service.tsСлужебная учётная запись, ключ, привязка модели
Адреса управленияapps/api/src/routes/managed-agents.ts30 адресов управления агентами
Адреса ручного разбораapps/api/src/routes/attention.ts11 адресов работы со спорными случаями
Контрактcontracts/eacp/Описание протокола с зафиксированными хешами файлов

Модель данных ​

Реестр агентов ​

managed_agents

ПолеНазначение
nameОтображаемое имя
base_urlАдрес управляющего API, уникален
auth_typeСпособ авторизации, всегда bearer
encrypted_tokenТокен агента, шифрование AES-256-GCM
enabledИдёт ли синхронизация событий
agent_type, instance_id, agent_version, protocol_versionВзято из описания, которое присылает агент
manifest_jsonПоследнее полученное описание целиком
statusЧерновик, готов, деградация, отключён, ошибка
last_ready_at, last_checked_at, last_errorРезультат последней проверки

Журнал событий ​

managed_agent_events это неизменяемый локальный журнал: номер события, идентификатор, источник, тип, серьёзность, время, предмет, идентификатор связи, данные и обязательная пометка о маскировании.

managed_agent_event_cursors хранит по каждому агенту номер последнего прочитанного события. Это позиция чтения потока.

Защита от повторов держится на двух уникальных ограничениях: на паре агент плюс номер события и отдельно на идентификаторе события.

Команды ​

managed_agent_commands это аудит: ключ идемпотентности, тип команды, кто послал, переданные данные, идентификатор операции у агента, состояние и текст ошибки.

Ручной разбор ​

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

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

eva_attention_audit_events отдельный журнал событий разбора.

managed_agent_attention_sync_states позиция чтения и результат последней синхронизации спорных случаев.

Объявляемые агентом разделы ​

managed_agent_ui_manifests кэш описания разделов: версия расширения, ревизия, метка для условного запроса, само описание, признак пригодности, текст ошибки разбора и список ухудшений.

managed_agent_ui_actions аудит нажатых кнопок в объявленных разделах.

Что именно пишется в аудит нажатий

Записываются раздел, действие, затронутые записи, кто нажал, имена переданных полей, ожидаемая версия, причина, состояние и краткая сводка ответа. Значения полей не записываются: это сделано ради персональных данных.

Выдача модели ​

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

Изменения существующих таблиц ​

Это самое важное для понимания последствий.

ИзменениеЗачем
У пользователей появилось поле вида учётной записи, по умолчанию «человек»Служебная учётная запись агента помечается как машинная. Она авторизуется только по ключу и никогда не входит по паролю
В журнале расхода ссылка на чат стала необязательнойОбращения агента к модели происходят вне любого чата
В журнале расхода появилась ссылка на агентаРасход относится на агента, а не на чат

Вид записи расхода для таких обращений отличается от обычного обращения через шлюз.

Синхронизация событий ​

Это фоновый набор обработчиков внутри процесса API.

СвойствоЗначение
Проверка списка агентовКаждые 15 секунд
Задержки при обрыве1, 2, 5, 10, 30 секунд, счётчик сбрасывается после успешного события
Что читаетсяПоток событий агента, начиная с сохранённого номера
Первичная загрузкаОдин раз на обработчик, если агент объявляет проекцию спорных случаев, потому что события несут только изменения
Пропуск агентаТолько если агент прямо объявил, что потока событий у него нет

Таймер не удерживает процесс: при остановке платформы он не мешает завершению.

Немаскированные события отклоняются

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

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

Объявляемые агентом разделы ​

Платформа не знает заранее, какие экраны нужны конкретному агенту. Агент присылает описание своих разделов, а платформа рисует их сама.

Как складывается состав разделов ​

РазделУсловие появления
ОбзорБезусловно
ЗаданияБезусловно
Объявленные агентомСтолько, сколько объявил, в заданном им порядке
НастройкиАгент отдаёт схему настроек и не объявил своей формы настроек
Реестр операцийАгент объявил такую возможность и не объявил своего раздела с этим именем
Ручной разборТо же правило
ЖурналАгент ведёт историю событий

Общих разделов только два

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

Порядок платформенных закреплён: обзор первым, задания вторыми, журнал последним.

Поддерживаемые виды разделов: таблица, карточка записи, форма, показатели, лента событий, произвольные данные, встроенная страница.

Внутри карточки записи бывают панели: произвольные данные, лента, файлы, пары ключ и значение, размеченный текст.

ОграничениеЗначение
Предел размера описания512 КБ, задан в коде
Кэш описанияСрок жизни задаётся переменной, по умолчанию 30 секунд
Условный запросПоддерживается по метке, повторный запрос без изменений возвращает признак «не изменилось»
Разбор описанияНе строгая проверка, а нормализация с ухудшением: неизвестный вид раздела превращается в произвольные данные, лишние поля отбрасываются

Важное решение по безопасности

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

Выдача модели агенту ​

Платформа создаёт для агента служебную учётную запись, ключ API и привязывает модель. Агенту сообщается адрес OpenAI-совместимого шлюза платформы.

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

Ключ можно перевыпустить, привязку проверить или удалить.

Права ​

ОбъектДействия
Внешние агентыЧтение, Администрирование
Ручная обработка агентовДевять независимых действий вместо обычного набора

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

Такое разделение позволяет выдать право на действие, не выдавая права видеть персональные данные.

Расхождение в текущей версии

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

Переменные окружения ​

ПеременнаяПо умолчаниюНазначение
EACP_TIMEOUT_MS15000Таймаут обычного обращения к агенту
EACP_EXPORT_TIMEOUT_MS120000Таймаут выгрузки
MANAGED_AGENT_UI_MANIFEST_TTL_SECONDS30Срок жизни кэша описания разделов
MANAGED_AGENT_UI_EXPORT_MAX_BYTES33554432Предел размера выгрузки
MANAGED_AGENT_UI_EMBED_ENABLEDfalseРазрешение встроенных страниц агента
MANAGED_AGENT_LLM_GATEWAY_URLАдрес платформы плюс /v1Адрес шлюза для агента

Настроек в базе эта возможность не добавляет: строк общих настроек платформы не появляется.

Документация платформы EVA