Skip to content

Свой внешний агент ​

Что нужно реализовать, чтобы собственный сервис заработал в EVA как внешний агент.

Что вообще требуется ​

Агент это обычный веб-сервис, который отвечает на несколько запросов по протоколу EACP. Платформа не запускает его, не следит за его процессом и не планирует его работу. Агент работает сам, а платформа только управляет им и собирает его события.

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

Шаг 1. Обязательный минимум ​

ОбработчикЧто вернуть
GET /manifestОписание себя: версия протокола, сведения об агенте, список возможностей
GET /health/readyГотовность
GET /statusЖивое состояние: чем занят, сколько задач активно и в очереди

В описании обязательно указать версию протокола, начинающуюся с 1., иначе платформа откажется подключаться.

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

Шаг 2. Авторизация ​

Платформа передаёт при каждом обращении заголовок с токеном, который администратор ввёл при подключении.

Authorization: Bearer <ваш service token>

Ваша задача проверять этот токен и отвечать 401 при неверном и 403 при недостатке прав.

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

Шаг 3. Адрес ​

Соблюдайте требования к адресу, иначе платформа его не примет.

ПравилоПодробности
СхемаТолько http или https
Данные для входа в адресеНельзя
Параметры запроса и якорьНельзя

Принято оканчивать базовый адрес на /agent-api/v1.

Шаг 4. Настройки, если они у вас есть ​

Не описывайте свои поля в платформе. Вместо этого отдайте их схему, и платформа нарисует форму сама.

ОбработчикЧто делает
GET /settings/schemaСхема настроек в формате JSON Schema
GET /settingsТекущие значения
PATCH /settingsПрименить изменения
GET /settings/historyИстория изменений, постранично

Смысл такого подхода

Платформа сознательно не знает полей конкретного агента. Благодаря этому добавление нового агента с любыми настройками не требует правок EVA.

Шаг 5. Поток событий ​

Это то, ради чего платформа держит с вами постоянную связь.

ОбработчикЧто делает
GET /eventsПостраничная история, начиная с указанного номера
GET /events/streamПоток, начиная с указанного номера

Требования к событиям:

Номер должен монотонно возрастать. Платформа хранит номер последнего прочитанного события и продолжает с него. Так события не теряются при обрыве связи и не удваиваются.

У каждого события должен быть свой идентификатор. Платформа проверяет уникальность и по номеру, и по идентификатору.

Маскирование персональных данных обязательно

Каждое событие обязано быть помечено как прошедшее маскирование. Событие без такой пометки платформа отклонит с ошибкой и не запишет.

Ответственность за само маскирование лежит на вас. Платформа только проверяет наличие пометки и не даёт немаскированным данным попасть в свою базу.

События несут только изменения. Поэтому если вы объявляете проекцию спорных случаев, платформа один раз выполнит полную загрузку текущего состояния, а дальше будет применять изменения из потока.

Шаг 6. Команды, если нужны ​

ОбработчикЧто делает
POST /commandsПринять команду, вернуть код 202 и идентификатор операции
GET /operations/{operationId}Отдать состояние операции

Список возможных команд объявляйте в описании себя. Платформа его не задаёт.

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

Шаг 7. Спорные случаи, если работа требует человека ​

Когда агент не может решить сам, отложите случай и отдайте его платформе. Оператор разберёт его и вернёт вам решение.

ОбработчикЧто делает
GET /attention-casesОчередь случаев
GET /attention-cases/{id}Один случай
GET /attention-cases/{id}/source-fileИсходный файл
POST /attention-cases/{id}/correctionsПрименить исправление полей
POST /attention-cases/{id}/select-...Применить выбор кандидата
POST /attention-cases/{id}/resumeПродолжить обработку
POST /attention-cases/{id}/resolveЗавершить вручную
POST /attention-cases/{id}/replacement-documentПринять замену файла

Каждое изменяющее обращение приходит с четырьмя вещами, и все четыре нужно учитывать:

Что приходитЧто с этим делать
Ожидаемая версияСравнить со своей. Не совпало, значит случай уже изменился, отклоните
Кто выполняетЗаписать в свой аудит
ПричинаОбязательна, записать в аудит
Ключ идемпотентностиНе применять то же действие дважды

Шаг 8. Свои разделы в интерфейсе, если нужны ​

Расширение протокола версии 1.1 позволяет объявить свои экраны, и платформа нарисует их сама, без правок EVA.

ОбработчикЧто делает
GET /ui/manifestОписание разделов
GET /ui/views/{viewId}/dataДанные раздела
GET /ui/views/{viewId}/records/{recordId}Одна запись
POST /ui/views/{viewId}/actions/{actionId}Выполнить объявленное действие
GET /ui/views/{viewId}/exportВыгрузка раздела файлом

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

ТребованиеПодробности
Размер описанияНе больше 512 КБ
Условный запросПоддержите метку и ответ «не изменилось», платформа кэширует описание
Идентификаторы, а не адресаОбъявляйте идентификаторы разделов. Путь платформа соберёт сама
Права на действияУказывайте требуемое право у каждого действия, платформа его проверит

Адреса платформе передавать нельзя

Это принципиальное правило. Агент не даёт платформе готовых адресов для обращения: она собирает их сама из идентификатора раздела. Так агент не может заставить платформу обратиться в произвольное место.

Про строгость разбора

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

Встроенные страницы через iframe объявить можно, но по умолчанию они выключены. Платформа покажет оператору пояснение вместо содержимого.

Шаг 9. Модель от платформы, если она вам нужна ​

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

ОбработчикЧто делает
GET /llm-bindingОтдать текущую привязку
PUT /llm-bindingПринять привязку от платформы
DELETE /llm-bindingУдалить привязку

Расход при этом попадёт в общий учёт платформы и будет отнесён на вашего агента.

Шаг 10. Формат ошибок ​

Отвечайте по стандарту описания проблем:

json
{
  "type": "urn:eva:error:unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid token",
  "code": "UNAUTHORIZED",
  "request_id": "0f3c..."
}

Проверка перед подключением ​

Что проверитьКак
Версия протоколаНачинается с 1.
АдресСоответствует требованиям, оканчивается на /agent-api/v1
ТокенПроверяется, неверный даёт 401
Описание себяОтдаётся и содержит раздел возможностей
ГотовностьОтдаётся
События помечены как замаскированныеИначе платформа их отклонит
Ключи идемпотентности учитываютсяПовтор не выполняется дважды

После подключения администратор нажимает проверку соединения. Платформа запросит описание и готовность и покажет результат.

Отладка ​

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

Полное описание вызовов на странице Контракт EACP.

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