Skip to content

Карточка агента и дверь за ней

Карточка — это то, как ваш агент представляется агенту за пределами вашей компании: имя, для чего он, какие у него навыки и — если вы открыли дверь — адрес, куда писать, и как там представиться.

Сначала это документ. Отвечает ли за ним кто-нибудь — второе, отдельное решение.

Зачем карточка вообще нужна

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

Что написано в карточке и откуда берётся

в карточкеоткуда
имя, описаниесобственная строка агента
навыки с описанияминавыки, которыми пользуется этот агент
что умеетпотоковая выдача — да, пока дверь открыта (AGNT2-355); исходящих уведомлений нет; одна карточка
version — отпечатоквсё перечисленное выше, свёрнутое в строку
адрес для вызоваживая дверь A2A — и его нет, когда двери нет
как представитьсята же дверь: ключ в заголовке — или ничего

Ни одно из этого — не поле, которое кто-то заполняет «для карточки». Второй текст — это текст, который через неделю разойдётся с первым. Следствие людей удивляет, и оно правильное: дайте агенту новый навык — и карточка изменится под ссылкой, которую вы раздали вчера. Карточка описывает агента сейчас, а отпечаток — то, по чему другая сторона заметит это одним сравнением, не вычитывая документ.

Ссылка

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

Получить ссылку выдаёт её. Четыре вещи про неё:

  • Её показывают один раз. Копии нигде не остаётся. Потеряли — отзывайте и выдавайте новую.
  • Пока живёт одна, вторую не выдадут. Старый адрес у кого-то на руках. Отозвать, потом выдать — два решения, в том порядке, в котором вы их на самом деле имеете в виду.
  • Отзыв действует со следующего чтения, без периода отсрочки.
  • Отозванная ссылка не стирается. Когда адрес попал не к тому человеку, кто-то должен иметь возможность увидеть, что он существовал и когда его читали в последний раз, — строка переживает отзыв вместе с обоими фактами. Это в базе, а не на экране: после отзыва панель снова предлагает «Получить ссылку» и о прежней не говорит ничего, потому что читает только живую.

Адрес выглядит так, и это всё, что нужно читателю:

https://<адрес вашего api>/agent-cards/acd.<публичная половина>.<секретная половина>

Все отказы — один и тот же отказ

Шесть причин — выдуманный адрес, неверный секрет, отозванная ссылка, выключенный агент, заархивированный и удалённый — отвечают одинаково. Ответ не подтверждает, что такой агент когда-либо был. Это сделано нарочно и измерено: ответ на удалённого агента целиком сравнивается с ответом на адрес, который никогда не выдавали.

Карточка с мёртвым адресом хуже, чем никакой

Адрес в карточке означает «пишите сюда, и вам ответят». Поэтому адрес появляется только тогда, когда есть кому отвечать, и исчезает, когда отвечать перестают. Читатель, не нашедший ни одного вызываемого интерфейса, на этом останавливается — карточку можно прочесть, но не написать, — и это честное утверждение. Оно лучше, чем отправить чужого агента в тишину и позволить решить, что сломаны мы.

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

Открыть дверь — A2A

Опубликовать агента по A2A — то же по смыслу действие, что и поставить его на сайт: одна привязка, та же строка аудита, та же отмена. Сегодня это вызов api, а не экран — POST /agents/:id/channels/a2a, — и адрес появляется в карточке в тот момент, когда вызов удался.

Что дальше делает партнёр:

GET  <ссылка на карточку>          → адрес, в supportedInterfaces
POST /a2a/v1/agents/<id агента>    → { "jsonrpc": "2.0", "method": "message/send", … }
     X-Embed-Key: emk.<публичная>.<секретная>
     ← задача, завершённая, с ответом
POST … { "method": "tasks/get", … }
     ← та же задача, завтра

Обе редакции протокола отвечают по этому одному адресу, и редакцию выбирает имя метода — ни заголовка, ни настройки. message/send и tasks/get — это 0.3; SendMessage и GetTask — это 1.0.

Четыре опасных вопроса про открытую наружу ручку

Чей это ход?владельца агента, в команде агента, через ту же проверку членства, что и у участника. Партнёр никогда не становится субъектом.
Что ему можно?ничего сверх ответа. Ни воркера, ни сети, ни расписания — и на привязке A2A нет ручки, которая всё это открывает.
Что он запишет?свой собственный разговор. В долговременные заметки агента ничего: чужой абзац не должен въехать в следующий ход владельца.
Куда это ляжет?один разговор на партнёра на агента, рядом с разговорами посетителей сайта и никогда внутри разговора владельца.

У партнёра есть имя, и в этом весь смысл

Кредом служит тот же embed-ключ, который участник выдаёт стороне, с которой команда договорилась разговаривать. Его публичная половина — это личность партнёра везде, где это важно: на неё завязан разговор, лимит потока принадлежит только ему, и расход подписан его именем.

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

Ответ приходит по частям, а работа остаётся за дверью

С AGNT2-355 тот же адрес отвечает и на message/stream (SendStreamingMessage в 1.0): клиент партнёра получает задачу в момент её появления, затем ответ кусок за куском по мере того, как агент его пишет, затем итоговый статус — через Server-Sent Events, в том порядке, в каком агент это произвёл. Карточка так и говорит: capabilities.streaming равно true ровно пока дверь открыта.

Что партнёр видит из РАБОТЫ — рассуждения агента и инструменты, за которые он берётся, — решает владелец, и по умолчанию это закрыто: поток партнёра несёт ответ и ничего больше, пока владелец не откроет видимость на привязке A2A (PUT /agents/:id/channels/a2a/access). Открыто — рассуждения и каждый шаг инструмента приходят отдельными пометками рядом с ответом, никогда внутри него и никогда с выводом инструмента. Это единственное из четырёх прав, которое можно открыть партнёрам; руки, память и расписание остаются закрытыми.

Чего нет — заявлено, а не построено наполовину

Исходящих уведомлений на адрес партнёра, переподключения к уже идущему потоку, отмены задачи, расширенной карточки за аутентификацией, gRPC-привязки, любого доступа без ключа и экрана в кабинете. Каждое из этого объявлено в карточке отсутствующим, а не подделано.

Полное рассуждение и три строки, в которые оно обошлось ядру, — строка Каналы в реестре решений.

Проверить целиком

  1. Откройте агента → ОбщееКарточка агентаПолучить ссылку. Скопируйте.
  2. Откройте этот адрес в браузере без сессии. Придёт карточка — JSON с именем агента, описанием и навыками.
  3. supportedInterfaces пуст. Отвечать ещё некому, и карточка так и говорит.
  4. Опубликуйте агента по A2A: POST /agents/<id>/channels/a2a.
  5. Перечитайте ту же ссылку. Появился интерфейс на каждую редакцию протокола, с адресом, и рядом схема с ключом. Смотреть надо на поле version — оно сдвинулось.
  6. Уберите дверь обратно — запись исчезает, version сдвигается назад.

Пункты 3 и 5 читают один и тот же адрес. В этом всё свойство, ради которого написана страница.