Проследите один запрос от пользователя до artifact
Отдельные сообщения мы разобрали - теперь соберём из них один сквозной путь и увидим, что в нём легко перепутать. Трасса запроса от пользователя до готового artifact проходит через три разных уровня: продуктовую цель, межагентную задачу и вызовы возможностей. Их состояния живут отдельно, и главная ошибка новичка - смешать историю диалога, идентификатор A2A Task и состояние MCP-запросов в одну кучу.
Разложим тот же сценарий проверки релиза по шагам - кто владелец состояния на каждом и какой факт можно наблюдать снаружи.
Шаг · Контракт · Владелец состояния · Наблюдаемый факт
- 1. Координатор делегирует проверку - A2A Message; A2A client;
messageId, accepted modes - 2. Review Agent принимает работу - A2A Task; A2A server/task store;
submitted, затемworking - 3. Агент ищет возможности - MCP discovery; MCP host/client; Списки tools и resources
- 4. Агент читает доказательства - MCP resource/tool; MCP server; Runbook и release snapshot
- 5. Агент публикует результат - A2A Artifact; A2A task store; Markdown и JSON
- 6. Координатор принимает решение - Продуктовый код; Ваше приложение; Authorization и действие вне протокола
Читать таблицу стоит по колонке "владелец состояния". Координатор владеет продуктовым решением, A2A-сервер - жизненным циклом Task, MCP-host - сессией доступа к возможностям, а MCP-сервер - собственно данными. Ни один из них не должен заглядывать в чужое состояние: координатор не знает про MCP-запросы внутри агента, а MCP-сервер не знает про A2A Task, в рамках которого его вызвали. Именно это разделение и делает систему заменяемой по частям.
Проследить, как одно действие превращается в конкретное сообщение того или иного протокола, помогает инспектор - выберите протокол и действие и посмотрите на получившийся wire-контракт.
Инспектор сообщения
{
"protocol": "MCP",
"operation": "tools/list",
"returns": "Tool[] + ttlMs + cacheScope",
"correlation": "JSON-RPC request id"
}Отсюда важное правило по идентификаторам, о которое спотыкаются даже опытные команды.
Один trace id, разные protocol ids. Прокидывайте общий OpenTelemetry trace context через границы для наблюдаемости, но не заменяйте им JSON-RPC id, MCP request handle, A2A taskId или contextId. У каждого идентификатора своя семантика и свой срок жизни; смешаете их - и корреляция в проде начнёт врать.
Разложить, какой идентификатор для чего, помогает разметчик.
Разведите идентификаторы
trace id (OpenTelemetry). Не путать с: authorization proof.
Теперь, когда мысленная модель собрана, пора перейти от схем к работающему коду - и сделать это на проекте, который можно запустить и проверить прямо сейчас.