Карточка агента и дверь за ней
Карточка — это то, как ваш агент представляется агенту за пределами вашей компании: имя, для чего он, какие у него навыки и — если вы открыли дверь — адрес, куда писать, и как там представиться.
Сначала это документ. Отвечает ли за ним кто-нибудь — второе, отдельное решение.
Зачем карточка вообще нужна
Агенты, говорящие на 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-привязки, любого доступа без ключа и экрана в кабинете. Каждое из этого объявлено в карточке отсутствующим, а не подделано.
Полное рассуждение и три строки, в которые оно обошлось ядру, — строка Каналы в реестре решений.
Проверить целиком
- Откройте агента → Общее → Карточка агента → Получить ссылку. Скопируйте.
- Откройте этот адрес в браузере без сессии. Придёт карточка — JSON с именем агента, описанием и навыками.
supportedInterfacesпуст. Отвечать ещё некому, и карточка так и говорит.- Опубликуйте агента по A2A:
POST /agents/<id>/channels/a2a. - Перечитайте ту же ссылку. Появился интерфейс на каждую редакцию протокола, с адресом, и рядом схема с ключом. Смотреть надо на поле
version— оно сдвинулось. - Уберите дверь обратно — запись исчезает,
versionсдвигается назад.
Пункты 3 и 5 читают один и тот же адрес. В этом всё свойство, ради которого написана страница.