Клиент — это роль, а не жанр программы
Спецификация называет вторую сторону клиентом и определяет её по функции: клиент владеет средой, показывает интерфейс пользователю и распоряжается доступом к ресурсам. Канонический случай — редактор кода: Zed, JetBrains, Neovim, Emacs, Visual Studio Code.
Но перечень реализаций показывает, что роль шире жанра: клиентами выступают терминальные интерфейсы, настольные и веб-приложения, мобильные клиенты, вычислительные блокноты — и мессенджеры, от Slack и Telegram до Matrix. Общее у всех одно: есть рабочая директория, есть человек рядом и есть право сказать «нет». Всё остальное — оформление.
Это и делает протокол интересным за пределами разработки: он описывает не «как встроить агента в IDE», а как отделить агента от поверхности, через которую с ним работают (Agent Harness — та же граница со стороны обвязки).
Ловушка именования: клиент здесь и клиент в MCP — противоположные концы
Слово «клиент» в этих двух протоколах значит разное, и путаница дорогая:
| Кто клиент | Кто сервер / вторая сторона | Направление | |
|---|---|---|---|
| MCP | сам агент | серверы инструментов и данных | агент тянется наружу за возможностями |
| ACP | редактор или другая поверхность | агент, запущенный подпроцессом | поверхность впускает агента к себе |
Протоколы при этом не конкурируют, а стыкуются: агент, подключённый к редактору по ACP, может одновременно быть MCP-клиентом для своих инструментов. Один отвечает на вопрос «что агент умеет», другой — «где он работает и кто его пускает».
Инверсия владения средой
Обычный кодовый агент читает и пишет файлы сам, а команды запускает в своём процессе. По ACP он этого не делает: файловые и терминальные операции — методы клиента, которые агент вызывает.
fs/read_text_file,fs/write_text_file— чтение и запись, с параметрами сессии, пути и (для чтения) диапазона строк;terminal/create,terminal/output,terminal/wait_for_exit,terminal/kill,terminal/release— жизненный цикл команды;session/request_permission— запрос разрешения до чувствительной операции;elicitation/create— запрос структурированных данных у пользователя.
Спецификация называет две причины прямо, и обе практические: так агент получает доступ к несохранённому состоянию редактора — буферам, которых на диске ещё нет, — и так клиент отслеживает правки, сделанные во время работы агента.
Следствие важнее обеих причин: граница безопасности возникает из устройства, а не из дисциплины. Клиент опосредует все внешние операции, поэтому подтверждение перед действием — не вежливость агента, которую он может забыть, а место, через которое действие физически проходит (Tool Gateway — та же идея как самостоятельный паттерн, Human in the Loop — что делать в этой точке).
Набор методов: кто кого вызывает
| Направление | Что |
|---|---|
| клиент → агент | initialize (согласование версии и возможностей), authenticate, session/new, session/load (необязательное восстановление сессии), session/prompt, session/set_mode, logout |
| клиент → агент, уведомление | session/cancel — прервать обработку |
| агент → клиент | fs/*, terminal/*, session/request_permission, elicitation/create |
| агент → клиент, уведомление | session/update — куски сообщений, статусы вызовов инструментов, план, смена режима |
Два места стоит отметить отдельно. initialize согласует не только версию, но и возможности: внутри одной версии протокола стороны договариваются, какие необязательные части поддержаны, — то есть совместимость определяется парой «версия плюс возможности», а не номером сборки библиотеки. И session/update несёт план агента наравне с текстом: план здесь элемент протокола, а не абзац внутри ответа (Plan and Execute).
Цена переносимости: общее подмножество
У кросс-провайдерного протокола обвязки есть системная цена — он сходится к пересечению возможностей поставщиков, и то, что есть только у одного, через него не выражается (Agent Harness).
Наблюдаемый пример: мета-обвязка omnigent гоняет чужие кодовые агенты по ACP, и у части из них собственный вход в аккаунт держит их же командная строка. Выбор модели через ACP не проходит — и правильная реакция здесь оказалась не «тихо проигнорировать флаг», а отказать явно: --model отвергается с объяснением, вместо того чтобы молча запустить модель по умолчанию аккаунта. Пример стоит запомнить как образец поведения на границе абстракции: невыразимое требование — это отказ, а не подстановка (Unknown Not A Value).
Чем этот слой отличается от AG-UI
Вопрос возникает закономерно: оба протокола — про то, как агент разговаривает с чем-то, что показывают человеку, у обоих потоковые обновления и остановка ради подтверждения. В случае «чат с агентом» они и выглядят одинаково. Различие тем не менее резкое, и проходит оно по тому, что вторая сторона даёт агенту.
| ACP | AG UI Protocol | |
|---|---|---|
| что даёт вторая сторона | среду: файлы, терминал, права | показ и ввод: отрисовку событий и ответы человека |
| кто кого запускает | клиент запускает агента подпроцессом | агент работает сам по себе, где угодно |
| транспорт | JSON-RPC через стандартный ввод-вывод — одна машина | любой сетевой: SSE, веб-сокеты, вебхуки |
| что течёт | двусторонние вызовы методов с ответами | преимущественно поток событий |
| время жизни | привязано к процессу агента | сессия и прогон, переживающие соединение |
Проверка, к какому слою относится своя граница, одна: получает ли агент через неё возможности, которых у него иначе нет? Да — это граница среды, и вопросы к ней про права и изоляцию. Нет, только показ и ввод — граница интерфейса, и вопросы к ней про плотность подачи и про то, где живёт ожидание человека.
Граница между слоями не священная: одна программа может говорить обоими сразу — вниз по ACP с локальным кодовым агентом, вверх по AG-UI с браузером. Так и устроен редактор с веб-интерфейсом.
Не путать с Agent Communication Protocol
Аббревиатура ACP занята дважды, и оба значения про агентов:
- Agent Client Protocol — этот, «поверхность ↔ кодовый агент», Apache-2.0, стабильная версия протокола
1; - Agent Communication Protocol — из линии BeeAI/IBM, про обмен между агентами; в академическом сравнении протоколов управления он идёт в одном ряду с MCP, A2A, ANP и ERC-8004 (Agent2Agent Protocol).
Разводить их надо по вопросу: первый отвечает «кто пускает агента в среду», второй — «как агенты разговаривают друг с другом».
Связано с
- Agent Harness — тот же разрез со стороны обвязки: поверхности, поток событий, цена кросс-провайдерной абстракции
- MCP — соседний слой и противоположная роль слова «клиент»
- Agent2Agent Protocol — слой «агент ↔ агент» и однофамилец этой аббревиатуры
- AG UI Protocol — слой «агент ↔ приложение пользователя»; ACP про среду, AG-UI про интерфейс
- Human in the Loop — что происходит в точке
session/request_permission - Tool Gateway — граница, на которой намерение становится побочным эффектом; здесь она встроена в протокол
- Agent Execution Platform — где эта граница живёт, когда поверхность своя