Проблема: как узнать, что умеет чужой агент?

Представь: в сети живут десятки агентов-сервисов. Ты хочешь собрать пайплайн — нужен агент, который умеет искать в вебе. Но как ты узнаешь, что вон тот сервис по адресу research.example.com — именно исследователь, а не бухгалтер? Какой у него эндпоинт? Он вообще принимает текст или только файлы? Нужен ли токен?

Спрашивать вживую нельзя — агент это не человек. Нужен машиночитаемый способ самоописания: стандартный документ, который любой клиент прочитает и поймёт без предварительной договорённости. В вебе эту роль играют OpenAPI-спеки и robots.txt; в A2A — Agent Card.

ℹ️ Agent Card = резюме + контракт + адрес

Одна визитка отвечает сразу на три вопроса клиента: «Кто ты и что умеешь?» (резюме — name, description, skills), «Как с тобой говорить?» (контракт — url, capabilities, форматы), «Как войти?» (доступ — authentication). Прочитал карточку — знаешь всё, чтобы отправить задачу.

Где лежит и как её находят

Ключевая идея — предсказуемый адрес. Agent Card публикуется по well-known пути, как robots.txt у сайтов. Клиенту достаточно знать домен агента — путь до карточки стандартный:

домен агента:  https://research.example.com
                        │
                        ▼  клиент делает GET по стандартному пути
https://research.example.com/.well-known/agent.json
                        │
                        ▼
              ┌─────────────────────┐
              │   Agent Card (JSON) │  ← кто, skills, url, auth
              └─────────────────────┘
                        │
                        ▼  теперь клиент знает, как слать задачу

Три способа, как клиент вообще узнаёт про агента:

  • Прямой адрес — знаешь домен, читаешь /.well-known/agent.json. Простейший случай.
  • Каталог / реестр (registry) — сервис-«жёлтые страницы», где перечислены агенты и их карточки. Клиент ищет по навыкам («кто умеет web_research?») и получает список карточек.
  • Передача в общении — один агент по ходу работы сообщает другому URL карточки третьего агента (динамическое расширение сети).
✅ Почему well-known путь — это важно

Стандартный адрес превращает обнаружение в соглашение без договорённости: не нужно заранее обмениваться эндпоинтами. Как браузер всегда знает, где искать favicon.ico, так A2A-клиент всегда знает, где визитка. Это делает агентов по-настоящему обнаружимыми.

Анатомия Agent Card

Разберём, из каких блоков состоит визитка и зачем каждый. Условно поля делятся на четыре группы: идентификация, подключение, возможности и навыки.

100%
колёсико — масштаб  ·  зажать и тянуть — перемещение
Agent Card /.well-known/agent.json ① Идентификация name · description · version · provider кто это и чем занимается ② Подключение url · authentication (schemes) куда слать задачу и как войти ③ Возможности capabilities · defaultInputModes/OutputModes streaming, форматы (текст/файлы/данные) ④ Навыки (skills[]) id · name · description · tags · examples что конкретно умеет — по этому выбирают клиент читает и решает, подходит ли агент агент-сервер публикует карточку, реализует навыки

Полная карточка выглядит так (набор и имена полей зависят от версии спецификации — здесь показан характерный вид):

agent.json — Agent Card исследовательского агента
json
{
  "name": "Research Agent",
  "description": "Ищет информацию в вебе и делает структурированную выжимку",
  "version": "1.2.0",
  "provider": { "organization": "DataTalks", "url": "https://datatalks.ru" },

  "url": "https://research.example.com/a2a",
  "authentication": { "schemes": ["bearer"] },

  "capabilities": {
    "streaming": true,
    "pushNotifications": false
  },
  "defaultInputModes":  ["text/plain"],
  "defaultOutputModes": ["text/plain", "application/json"],

  "skills": [
    {
      "id": "web_research",
      "name": "Web research",
      "description": "Поиск по теме и выжимка ключевых фактов с источниками",
      "tags": ["search", "summarization"],
      "examples": ["Собери факты про рынок EV в 2025", "Что нового в A2A?"]
    }
  ]
}

Ключевые поля и зачем они

Пройдёмся по полям, на которые клиент реально смотрит при выборе:

ПолеЧто описываетЗачем клиенту
name / descriptionКто агент и чем занимаетсяБыстрый отсев: подходит ли вообще
urlЭндпоинт A2A-сервисаКуда слать message/send
authenticationСхемы доступа (bearer, apiKey…)Как получить/передать токен
capabilitiesВозможности: streaming, pushМожно ли стримить прогресс долгой задачи
defaultInput/OutputModesФорматы вход/выход (MIME)Примет ли текст/файлы; что вернёт
skills[]Конкретные навыки с id, tags, examplesГлавное поле выбора — что именно умеет

Skills — сердце карточки. Именно по ним клиент (или оркестратор) решает, кому отдать задачу. Хорошее описание навыка содержит id (машинный ключ), человекочитаемые name/description, tags для поиска и examples — примеры запросов, которые агент обрабатывает. Examples особенно важны: по ним и человек, и LLM-роутер быстро поймут, о чём навык.

✅ Agent Card ≈ tool schema, но для целого агента

Вспомни JSON Schema для tool calling (модуль 02): там ты описываешь функцию, чтобы LLM понял, когда её вызвать. Agent Card — то же самое, но уровнем выше: описываешь целый агент, чтобы другой агент понял, когда делегировать ему задачу. Skills в карточке играют роль «инструментов», доступных оркестратору.

Как клиент выбирает агента

Обнаружение — половина дела; вторая — выбор. Когда карточек несколько (из реестра), клиент/оркестратор сопоставляет задачу с навыками. Часто это делает сама LLM: ей дают список Agent Card, и она выбирает подходящего — ровно как выбирает инструмент по tool schema.

Discovery → выбор → отправка (концептуально, Python)
python
import httpx

# 1. DISCOVERY — читаем визитку по well-known пути
card = httpx.get("https://research.example.com/.well-known/agent.json").json()

# 2. ПРОВЕРКА пригодности — есть ли нужный навык и формат
def fits(card, need_tag: str) -> bool:
    skills_ok = any(need_tag in s.get("tags", []) for s in card["skills"])
    text_ok   = "text/plain" in card.get("defaultInputModes", [])
    return skills_ok and text_ok

assert fits(card, "search")

# 3. АУТЕНТИФИКАЦИЯ по объявленной схеме
assert "bearer" in card["authentication"]["schemes"]
headers = {"Authorization": f"Bearer {TOKEN}"}

# 4. ОТПРАВКА задачи на объявленный url (метод message/send из прошлого урока)
resp = httpx.post(card["url"], headers=headers, json={
    "jsonrpc": "2.0", "id": 1, "method": "message/send",
    "params": {"message": {"role": "user",
        "parts": [{"kind": "text", "text": "Собери факты про рынок EV 2025"}]}}
})

Заметь: весь код опирается только на поля карточки — skills, defaultInputModes, authentication, url. Клиент ничего не знает о внутренностях агента и не должен. Карточка — единственный контракт.

Как писать хорошую карточку

  • Честность важнее маркетинга. Описывай то, что агент реально умеет. Завышенные skills → клиенты шлют задачи, которые агент проваливает.
  • Гранулярные skills. Один навык = одна понятная способность. Лучше три чётких навыка, чем один «умею всё».
  • Заполняй examples и tags. По ним агента находят в реестре и выбирают LLM-роутеры. Пустые examples = агент невидим для умного выбора.
  • Версионируй. version позволяет клиентам отслеживать изменения контракта.
  • Не раскрывай лишнего. Карточка публична — не клади в description секреты, внутренние URL или детали реализации.
⚠️ Точные имена полей зависят от версии

A2A развивается: набор и написание полей (например, форматы модальностей, структура authentication, наличие расширенной/аутентифицированной карточки) могут отличаться между версиями спецификации. Держи в голове структуру — идентификация, подключение, возможности, навыки, — а точные ключи сверяй с официальной схемой своей версии.

Типичные ошибки

❌ Ошибка 1: карточка не по well-known пути

Если положить agent.json по произвольному адресу, клиенты его не найдут автоматически. Смысл well-known — предсказуемость. Публикуй по /.well-known/agent.json.

❌ Ошибка 2: пустые или размытые skills

«Умный ассистент, помогаю со всем» — бесполезно для выбора. Ни человек, ни LLM-роутер не поймут, когда тебя звать. Конкретные навыки с examples — обязательны.

❌ Ошибка 3: секреты в публичной карточке

Agent Card доступна всем, кто знает домен. Токены, внутренние эндпоинты, детали инфраструктуры в ней — утечка. Только контракт, ничего чувствительного.

❌ Ошибка 4: карточка врёт о возможностях

Объявил streaming: true, но не поддерживаешь — клиент рассчитывает на прогресс и ломается. Карточка — контракт: что объявлено, то должно работать.

Шпаргалка

Agent Card — всё в одном месте
text
ЧТО: JSON-визитка агента в A2A — резюме + API-контракт + точка входа
ГДЕ: /.well-known/agent.json  (предсказуемый well-known путь, как robots.txt)

ОБНАРУЖЕНИЕ:
  прямой адрес (знаю домен) · реестр/каталог (поиск по навыкам) · передача в общении

4 ГРУППЫ ПОЛЕЙ:
  ① идентификация — name, description, version, provider  (кто и чем занят)
  ② подключение   — url, authentication.schemes           (куда слать + как войти)
  ③ возможности   — capabilities (streaming/push), defaultInput/OutputModes
  ④ навыки        — skills[]: id, name, description, tags, examples  ← ГЛАВНОЕ

ВЫБОР: клиент/LLM сопоставляет задачу ↔ skills (как выбор tool по schema)
  код опирается ТОЛЬКО на поля карточки — внутренности агента скрыты

ХОРОШАЯ КАРТОЧКА:
  честная · гранулярные skills · заполненные examples/tags · версионирование
  без секретов (карточка публична)

ГРАБЛИ:
  • не по well-known пути → не найдут
  • размытые/пустые skills → невидим для выбора
  • секреты в публичной карточке → утечка
  • объявил capability, но не реализовал → клиент ломается

СВЯЗЬ: Agent Card ≈ tool schema, но для ЦЕЛОГО агента (модуль 02: JSON Schema)

Практическое задание

Задание: спроектируй Agent Card

  1. Напиши Agent Card для агента-переводчика: name, description, version, url, authentication, capabilities, defaultInput/OutputModes, минимум два skills с id, tags и examples.
  2. Объясни, по какому пути его опубликуешь и почему именно там.
  3. Представь реестр из трёх карточек (переводчик, исследователь, аналитик). Опиши, как LLM-роутер выберет агента под задачу «переведи и суммаризируй статью». Сколько агентов и в каком порядке?
  4. Найди в своей карточке потенциальные утечки: есть ли что-то, что не должно быть публичным?
  5. Сравни поле skills с JSON Schema инструмента из модуля 02. Что общего, в чём разница уровней?
  6. Со звёздочкой: подними локальный A2A-сервер (SDK/пример), открой его /.well-known/agent.json в браузере, разбери реальные поля и сверь со спецификацией своей версии.

Что дальше

Agent Card говорит, что агент умеет. Но внутри агент сам может подключать инструменты и данные — и здесь в мультиагентную картину входит MCP. Следующий урок — как MCP работает в мультиагентных системах и как уживается с A2A.