Skip to content

常见协议 ​

一次 Agent 任务的运行离不开对 LLM 等多个环节的 API交互,由此产生了非常多的 Agent 相关的协议,它们沿着 Agent 能力扩张逐步形成。

模型最初只接收一段文本,随后开始理解多轮消息和工具调用;工具越来越多后,需要统一的能力接入协议;任务变长、参与者增多后,又出现状态化模型接口、Agent 间协议和客户端协议。

1. 协议演进时间线 ​

1.1 从文本生成到 Agent 系统 ​

阶段代表协议主要变化通信双方
早期文本生成Completions API输入 prompt,返回续写文本应用与 LLM
2023 年起OpenAI Chat Completions用角色消息表达对话,逐步加入 Function CallingAgent 框架与 LLM
2023—2024 年Anthropic Messages用 Messages 和 Content Blocks 表达文本、图片与工具调用Agent 框架与 LLM
2024 年末MCP(Model Context Protocol)统一工具、资源和提示的发现与调用Agent Host 与能力服务
2025 年OpenAI Responses用类型化 Items 统一消息、推理、工具和多轮状态Agent 框架与 OpenAI 平台
2025 年A2A(Agent2Agent Protocol)用 Agent Card、Task 和 Artifact 支持跨 Agent 协作Agent 与 Agent
2025 年后Agent Client Protocol 等将 Agent 任务、事件和权限交互接入 IDE 与客户端客户端与 Agent 框架

这条时间线包含三种不同层次:

  • LLM 请求与响应协议:Chat Completions、Responses、Anthropic Messages,决定 Context 如何送入模型以及模型动作如何返回。
  • 能力接入协议:MCP,决定 Host 如何发现并调用外部工具、资源和提示。
  • Agent 通信协议:A2A、Agent Client Protocol 等,决定任务如何跨 Agent 或客户端流转。

同一项任务可以使用多种协议。协议名称相似时,先判断通信双方,再判断传递的是消息、工具调用还是任务。

2. OpenAI Chat Completions:以消息为中心 ​

2.1 从 prompt 到 messages 消息 ​

早期 Completions API 的核心输入是一段 prompt。应用要把系统规则、用户问题和历史对话拼成字符串,模型无法从协议结构中准确区分这些内容的来源。

Chat Completions 将输入改为 messages 数组。每条消息带有角色,这使得 Agent 框架可以分别表达系统规则、用户输入、模型历史和工具结果。因此,这种结构很快就成为了兼容 OpenAI 接口的模型服务所采用的基础形态。

该协议中常见角色包括:

角色内容来源作用
developer / system应用开发者定义行为、约束、任务规则和输出要求
user用户提交目标、问题和补充信息
assistant模型保存历史回答或工具调用请求
toolAgent 框架执行工具后产生把真实观察结果回填给模型

模型 API 不会自动知道本地文件、工具执行结果或未提交的历史。Agent 框架必须在请求中提供当前决策需要的 Context。

2.2 请求与响应结构 ​

Chat Completions 使用 POST /v1/chat/completions,通过 Bearer API Key 认证。一个最小请求由模型和消息列表组成:

json
{
  "model": "model-id",
  "messages": [
    {
      "role": "developer",
      "content": "你是产品研究助手,结论必须注明依据。"
    },
    {
      "role": "user",
      "content": "整理三款同类产品的核心差异。"
    }
  ]
}

响应以 choices 表示候选结果,每个 choice 包含模型消息和结束原因:

json
{
  "id": "chatcmpl_123",
  "object": "chat.completion",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "我需要先获取三款产品的最新资料。"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 128,
    "completion_tokens": 24,
    "total_tokens": 152
  }
}

其中,Agent 框架主要关注 choices[0].message、finish_reason 和 usage 这些字段,用于核心流程的设计。finish_reason 可以表示自然结束、长度限制、工具调用或内容策略等情况,具体枚举取决于模型和接口版本。

2.3 Function Calling 的完整闭环 ​

工具定义位于请求顶层 tools,它不属于 messages。每个函数包含名称、说明和 JSON Schema 参数:

json
{
  "model": "model-id",
  "messages": [
    {"role": "user", "content": "搜索产品 A 的定价方案。"}
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "search_web",
        "description": "搜索公开网页并返回标题、URL 和摘要。",
        "parameters": {
          "type": "object",
          "properties": {
            "query": {"type": "string"}
          },
          "required": ["query"],
          "additionalProperties": false
        },
        "strict": true
      }
    }
  ]
}

当模型需要工具时,会在 assistant 消息中返回 tool_calls 来发起工具调用。其中 arguments 通常是 JSON 字符串,Agent 框架需要解析和校验:

json
{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": null,
        "tool_calls": [
          {
            "id": "call_search_01",
            "type": "function",
            "function": {
              "name": "search_web",
              "arguments": "{\"query\":\"产品 A 官方定价\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ]
}

模型只提出候选动作。Agent 框架校验权限与参数、执行工具后,使用 role: tool 和 tool_call_id 回填结果:

json
{
  "model": "model-id",
  "messages": [
    {"role": "user", "content": "搜索产品 A 的定价方案。"},
    {
      "role": "assistant",
      "tool_calls": [
        {
          "id": "call_search_01",
          "type": "function",
          "function": {
            "name": "search_web",
            "arguments": "{\"query\":\"产品 A 官方定价\"}"
          }
        }
      ]
    },
    {
      "role": "tool",
      "tool_call_id": "call_search_01",
      "content": "{\"title\":\"Pricing\",\"url\":\"https://example.com/pricing\"}"
    }
  ]
}

第二次模型调用才能基于工具结果形成回答。若模型仍可继续调用工具,请求还要携带与上一轮一致的 tools 定义。并行工具调用会产生多个 call ID,每个结果都要与原调用准确关联。

这里要区分“模型提出动作”和“工具真正执行”两个环节。自定义函数工具通常由 Agent 框架接住并分发:

例如,模型返回 read_file(path="docs/plan.md") 时,模型本身没有读取用户磁盘;Agent 框架会在允许的工作区内调用本地函数,再把文件内容作为 tool 消息回传。query_order(order_id="A-1024") 则可能由框架调用企业订单 HTTP API;search_notes(keyword="向量数据库") 可以继续转发给 MCP Client,由 notes MCP Server 执行。

平台托管工具的路径不同。以 OpenAI Responses 的 web_search 为例,Agent 框架只需在请求中声明工具,搜索、网页抓取和部分工具循环由远端模型平台完成,客户端收到的是 web_search_call、引用及最终文本,应用无需实现一个本地 search_web()。

2.4 多轮状态与流式响应 ​

Chat Completions 的多轮状态通常由 Agent 应用自身维护。Agent 框架保存历史消息,并在下一轮请求中重放仍然需要的部分。历史过长时可以做摘要、裁剪或检索,但工具调用消息与对应结果必须成对保留,否则模型会看到不完整的动作轨迹。

启用 stream: true 后,接口通过 SSE 返回增量 chunk。文本通常位于 choices[].delta.content,工具参数也可能分片到达。客户端需要累计 delta,直到接收到结束信号,再解析完整参数或提交最终文本。

这种协议适合已有消息式架构、兼容接口和简单生成场景。复杂 Agent 仍然需要应用自己维护工具循环、历史状态与流事件类型。

3. Anthropic Messages:以 Content Blocks 表达内容 ​

3.1 顶层结构 ​

Anthropic Messages API 同样使用多轮消息,但系统指令、消息内容和工具事件的组织方式不同:

  • system 位于请求顶层,不作为 messages 中的 system 角色。
  • messages 主要使用 user 和 assistant 角色。
  • content 可以是字符串,也可以是由文本、图片、工具调用和工具结果组成的 Content Blocks。
  • max_tokens 是请求中的显式输出上限。
  • 工具参数 schema 使用 input_schema。

Messages API 使用 POST /v1/messages。请求通常携带 x-api-key、anthropic-version 和 content-type,其中版本请求头决定采用的协议版本。

json
{
  "model": "model-id",
  "max_tokens": 1024,
  "system": "你是产品研究助手,结论必须注明依据。",
  "messages": [
    {
      "role": "user",
      "content": "搜索产品 A 的定价方案。"
    }
  ],
  "tools": [
    {
      "name": "search_web",
      "description": "搜索公开网页并返回标题、URL 和摘要。",
      "input_schema": {
        "type": "object",
        "properties": {
          "query": {"type": "string"}
        },
        "required": ["query"]
      }
    }
  ]
}

3.2 tool_use 与 tool_result ​

模型调用工具时,响应的 content 中出现 tool_use block:

json
{
  "id": "msg_123",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "我先查询官方定价页面。"
    },
    {
      "type": "tool_use",
      "id": "toolu_search_01",
      "name": "search_web",
      "input": {
        "query": "产品 A 官方定价"
      }
    }
  ],
  "stop_reason": "tool_use",
  "usage": {
    "input_tokens": 180,
    "output_tokens": 48
  }
}

Agent 框架执行后,把 tool_result block 放在下一条 user 消息中,并通过 tool_use_id 关联原调用:

json
{
  "model": "model-id",
  "max_tokens": 1024,
  "messages": [
    {"role": "user", "content": "搜索产品 A 的定价方案。"},
    {
      "role": "assistant",
      "content": [
        {
          "type": "tool_use",
          "id": "toolu_search_01",
          "name": "search_web",
          "input": {"query": "产品 A 官方定价"}
        }
      ]
    },
    {
      "role": "user",
      "content": [
        {
          "type": "tool_result",
          "tool_use_id": "toolu_search_01",
          "content": "{\"title\":\"Pricing\",\"url\":\"https://example.com/pricing\"}"
        }
      ]
    }
  ]
}

Content Blocks 让一条消息可以同时携带解释文本和工具动作。Agent 框架处理响应时应遍历所有 blocks,不能假设 content 只有一段文本。

3.3 状态、停止原因与流式事件 ​

Messages API 的对话历史由调用方提供。Agent 框架需要保存 user/assistant 轮次、tool_use 与 tool_result,再构造下一次请求。

stop_reason 表示本轮停止原因,例如自然结束、达到 token 上限、需要工具或遇到停止序列。流式模式使用类型化 SSE 事件,包括消息开始、内容块开始、内容增量、内容块结束和消息结束。客户端应按照事件类型组装文本、工具输入或其他 block。

3.4 Chat Completions 与 Anthropic Messages ​

语义OpenAI Chat CompletionsAnthropic Messages
系统规则developer / system 消息顶层 system
历史消息messagesmessages
主要角色developer/system、user、assistant、tooluser、assistant
内容结构message content 与 tool_callscontent 中的类型化 blocks
工具 schematools[].function.parameterstools[].input_schema
工具调用assistant.tool_calls[]tool_use block
工具结果role: tool + tool_call_iduser 消息中的 tool_result + tool_use_id
结束原因finish_reasonstop_reason
流式处理choices[].delta类型化 message/content block 事件

两种协议表达的核心语义接近:规则、历史、工具定义、模型动作、工具观察和结束状态。适配层可以把它们转换成 Agent 框架内部统一的 message、tool_call、tool_result 和 usage 事件。

4. MCP:工具生态开始标准化 ​

4.1 MCP 标准化 ​

Function Calling 规定模型如何表达工具调用,却没有规定工具服务如何安装、连接、发现能力和传输结果。每个 Agent 框架仍需为文件系统、数据库和业务平台编写专用适配器。

2024 年末出现的 Model Context Protocol(MCP) 将 Agent Host 与外部能力服务之间的通信标准化。一个 MCP Server 可以被多个兼容 Host 复用,工具提供方无需分别适配每种模型协议。

4.2 Host、Client 与 Server ​

角色所处位置职责
HostIDE、桌面助手或 Agent 应用管理模型、用户会话、权限、Context 和多个 MCP 连接
ClientHost 内部与一个 Server 建立连接并交换协议消息
Server本地进程或远程服务声明能力,访问真实数据源或业务系统

模型通常不直接连接 MCP Server。Host 通过 Client 发现能力,把当前可用的 MCP Tool 映射成模型能够理解的工具定义。模型生成调用后,Agent 框架再将参数发送给 MCP Server。

4.3 数据层、生命周期与 JSON-RPC ​

MCP 包含数据层和传输层。数据层基于 JSON-RPC 2.0,定义初始化、能力协商、请求、响应和通知。传输层负责在本地进程或网络服务之间承载这些消息。

连接建立后通常经历以下过程:

  1. Client 发送 initialize,声明协议版本、客户端信息和能力。
  2. Server 返回协商后的版本、服务端信息和能力。
  3. Client 发送 initialized 通知,初始化完成。
  4. Client 根据能力调用 tools/list、resources/list 或 prompts/list。
  5. Host 选择适合当前任务的能力提供给模型。
  6. 模型产生动作后,Client 使用 tools/call 或资源方法与 Server 交互。

带 id 的 JSON-RPC 请求需要对应响应;通知不带 id。Host 应校验响应 ID、协议版本和 Server 声明的能力,不能假设所有 Server 都支持同一组方法。

4.4 Tools、Resources 与 Prompts ​

能力表达内容常见方法示例
Tool可执行且可能失败的动作tools/list、tools/call搜索笔记、查询数据库、创建工单
Resource通过 URI 定位的上下文resources/list、resources/read文件、文档、配置、数据库记录
Prompt可复用的消息模板prompts/list、prompts/get代码审查模板、报告整理模板

Tool 通过名称、描述和 inputSchema 声明参数。Resource 适合浏览和读取内容。Prompt 适合向用户或 Host 提供领域任务入口。Server 还可以通过通知报告能力或资源变化。

MCP Tool 与模型工具之间需要适配。MCP Server 返回的是 MCP 自己的工具描述,模型 API 接收的则是 OpenAI tools[].function 或 Anthropic tools[].input_schema;Agent 框架负责转换两种 schema,并把模型返回的 tool call 重新映射为 MCP tools/call。下图只保留这条核心数据链路:

4.5 MCP 的传输层:stdio 与 Streamable HTTP ​

MCP 数据层定义了初始化、能力发现和工具调用等 JSON-RPC 消息,传输层负责把这些消息送到 Server。当前规范主要提供两种传输方式:本地进程使用 stdio,远程服务使用 Streamable HTTP。两者承载的是同一套 MCP 消息,差异在于连接位置、进程生命周期和网络治理方式。

传输连接形态适用场景主要风险
stdioHost 启动本地 Server,通过 stdin/stdout 通信文件系统、Git、本地 CLI进程权限、工作目录、stdout 被日志污染
Streamable HTTPClient 连接远程 HTTP 服务企业 API、共享知识库、云端工具身份认证、租户隔离、限流、网络中断

stdio Server 应把协议消息写入 stdout,把普通日志写入 stderr。远程 Server 要在服务端执行身份认证和授权,Host 隐藏某个工具只能减少模型看到的能力,无法替代服务端权限检查。

早期远程传输使用 HTTP + SSE。新实现应使用当前规范中的 Streamable HTTP,并在初始化阶段确认协议版本。

当 MCP Server 很多时,把全部工具 schema 放进每轮请求会消耗 Context,也会降低工具选择准确率。Agent 框架可以先暴露能力索引,再根据任务按需加载完整工具定义;Skill 负责按需加载任务知识、模板或脚本,MCP 负责能力连接与发现,两者分工不同。

4.6 实现一个最小 MCP Server ​

4.6.1 能力设计 ​

下面的内存笔记 Server 同时暴露 Tool、Resource 和 Prompt:

能力名称作用
Toolsearch_notes按关键词搜索笔记
Resourcenote://{note_id}读取指定笔记
Promptsummarize_note生成笔记整理任务模板

4.6.2 FastMCP 示例 ​

python
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("notes")

notes = {
    "vector-db": "向量数据库保存 embedding,并支持相似度检索。",
    "rag": "RAG 先检索资料,再把相关片段交给模型生成回答。",
}


@mcp.tool()
def search_notes(keyword: str) -> list[dict]:
    """按关键词搜索可访问的笔记。"""
    return [
        {"id": note_id, "preview": text[:80]}
        for note_id, text in notes.items()
        if keyword in text
    ]


@mcp.resource("note://{note_id}")
def read_note(note_id: str) -> str:
    """读取一篇笔记。"""
    return notes.get(note_id, "")


@mcp.prompt()
def summarize_note(note_id: str) -> str:
    """生成笔记整理任务。"""
    return f"读取 note://{note_id},整理核心概念、适用场景和限制。"


if __name__ == "__main__":
    mcp.run(transport="stdio")

Host 初始化连接并发现 search_notes 后,可以发送:

json
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "search_notes",
    "arguments": {
      "keyword": "向量数据库"
    }
  }
}

Server 返回搜索结果后,Agent 框架将结果转换成模型协议对应的工具结果。模型若要阅读全文,Agent 框架再调用 resources/read 获取 note://vector-db。

真实服务还需要补充认证授权、输入限制、分页、超时、错误类型、版本管理和审计日志。协议统一接口,工具的正确性仍由 Server 实现和 Agent 框架的执行策略共同保证。

5. OpenAI Responses:从 Messages 走向 Items ​

5.1 为什么出现 Responses API ​

Chat Completions 以 message 为核心,工具调用、推理、文本和多轮状态需要应用组织。随着 Agent 开始使用网页搜索、文件搜索、代码执行、计算机操作和远程 MCP,单一 message 对象越来越难表达不同类型的动作。

2025 年推出的 Responses API 使用类型化 Items 作为基本单元。message、reasoning、function_call 和 function_call_output 都是独立 Item。接口还可以使用平台托管工具,并通过 previous_response_id 或 Conversations 管理多轮关系。

OpenAI 当前仍支持 Chat Completions,同时建议新项目优先使用 Responses API。

5.2 请求与输出结构 ​

Responses 使用 POST /v1/responses。请求通过 instructions 和 input 组织内容,简单输入可以是一段字符串,复杂输入可以是 Item 数组:

json
{
  "model": "model-id",
  "instructions": "你是产品研究助手,结论必须注明依据。",
  "input": "整理三款同类产品的核心差异。"
}

响应顶层包含状态、用量和 output。output 是类型化 Item 数组,不能假设其中每一项都是文本消息:

json
{
  "id": "resp_123",
  "object": "response",
  "status": "completed",
  "output": [
    {
      "type": "message",
      "id": "msg_123",
      "role": "assistant",
      "status": "completed",
      "content": [
        {
          "type": "output_text",
          "text": "以下是三款产品的核心差异。",
          "annotations": []
        }
      ]
    }
  ],
  "usage": {
    "input_tokens": 96,
    "output_tokens": 32,
    "total_tokens": 128
  }
}

SDK 常提供 response.output_text 聚合文本。需要处理工具、推理或多模态内容时,应遍历 output 并根据 type 分派。

5.3 Function Calling 的 Item 闭环 ​

Responses 中函数定义采用扁平结构:

json
{
  "model": "model-id",
  "input": "搜索产品 A 的定价方案。",
  "tools": [
    {
      "type": "function",
      "name": "search_web",
      "description": "搜索公开网页并返回标题、URL 和摘要。",
      "parameters": {
        "type": "object",
        "properties": {
          "query": {"type": "string"}
        },
        "required": ["query"],
        "additionalProperties": false
      },
      "strict": true
    }
  ]
}

模型动作以 function_call Item 返回:

json
{
  "type": "function_call",
  "id": "fc_123",
  "call_id": "call_search_01",
  "name": "search_web",
  "arguments": "{\"query\":\"产品 A 官方定价\"}",
  "status": "completed"
}

Agent 框架执行函数后,提交 function_call_output Item,并使用相同 call_id 建立关联:

json
{
  "model": "model-id",
  "previous_response_id": "resp_123",
  "input": [
    {
      "type": "function_call_output",
      "call_id": "call_search_01",
      "output": "{\"title\":\"Pricing\",\"url\":\"https://example.com/pricing\"}"
    }
  ]
}

使用 previous_response_id 可以引用上一轮 Response。若应用选择手动管理状态,则需要把相关 Items 按原顺序放入后续 input。调用链中的 reasoning、function call 和 function output 都可能影响下一步,不能只保留最终文本。

5.4 内置工具、状态与流事件 ​

Responses API 可以在请求中声明平台托管的网页搜索、文件搜索、代码执行、计算机操作、图像生成和远程 MCP 等工具。部分工具循环可以在一次 API 请求内部完成;自定义函数仍需要应用接收调用、执行并回填结果。

多轮状态有三种常见方式:

  • 使用 previous_response_id 串联相邻 Response。
  • 使用 Conversations 保存长期会话中的 Items。
  • 设置 store: false 并由应用完整管理输入历史,适合有特定数据保留要求的场景。

引用前一条 Response 会简化状态传递,但历史输入仍会计入模型输入。instructions 只描述当前请求应使用的高层规则,构建多轮调用时要明确哪些指令需要再次提供。

流式模式返回类型化 SSE 事件,例如 response.created、response.output_text.delta、函数参数增量、response.completed 和 error。客户端可以按事件类型更新文本、工具状态和任务状态。

5.5 三种 LLM 协议的核心区别 ​

维度Chat CompletionsAnthropic MessagesOpenAI Responses
基本单位MessageMessage + Content BlockItem
规则入口developer/system 消息顶层 systeminstructions 或输入消息
输入历史messagesmessagesinput Items、previous_response_id 或 Conversation
文本输出choices[].message.contentcontent[type=text]output[type=message],SDK 可用 output_text
自定义函数tool_callstool_usefunction_call Item
函数结果tool 消息tool_result blockfunction_call_output Item
平台内置工具能力较少,循环多由应用管理取决于平台能力原生支持多类托管工具与远程 MCP
状态管理应用重放消息应用重放消息支持应用重放,也支持 Response/Conversation 串联
流式形态choices[].deltacontent block 类型事件response 类型事件
适用场景兼容接口、消息式应用、现有系统Claude 应用与 block 式内容处理新建 OpenAI Agent、内置工具和复杂事件流

迁移时不能只替换 URL。应用还要调整输入结构、输出遍历、函数 schema、函数结果关联、状态策略、Structured Outputs 字段和流式事件处理。

6. A2A(Agent2Agent Protocol):Agent 开始跨系统协作 ​

6.1 工具调用与任务委派的差异 ​

工具调用通常是一次边界清晰的动作:Agent 框架提交参数,等待结果或错误。Agent 任务可能包含多轮推理、内部工具调用、补充输入、进度事件和多个产物。

2025 年推出的 A2A(Agent2Agent Protocol) 面向跨 Agent、跨框架和跨组织协作。调用方关注对方能做什么、任务进展到哪里、需要补充什么以及交付了哪些 Artifact,无需了解下游 Agent 的内部执行轨迹。

6.2 核心对象 ​

对象作用
Agent Card描述 Agent 的身份、地址、能力、输入输出模式和认证要求
Task表达可持续运行、查询状态和恢复的工作
Message用户、调用方和 Agent 之间交换的内容
PartMessage 或 Artifact 中的文本、文件或结构化数据单元
ArtifactAgent 生成的报告、代码补丁、数据文件等交付物

Agent Card 解决能力发现。调用方选择 Agent 后创建 Task,使用任务 ID 关联后续消息、状态和产物。

6.3 任务生命周期 ​

长任务需要表达已提交、处理中、需要输入、完成、失败和取消等状态。具体状态名称以采用的规范版本为准。

下游 Agent 缺少资料时,可以进入 input-required 一类状态,由调用方补充信息后继续。任务完成后返回 Artifact;失败时返回错误与可恢复信息。流式事件或状态订阅让调用方持续获得进展。

6.4 MCP 与 A2A ​

维度MCPA2A
交互对象Tool、Resource、PromptAgent、Task、Message、Artifact
粒度一次能力调用或资源读取可能持续多轮的任务
发现内容Server 提供的具体能力Agent 的专业能力和交互方式
状态以请求响应和通知为主强调任务生命周期和产物

Supervisor 可以通过 A2A 委派代码审查任务,审查 Agent 再通过 MCP 读取仓库、查询工单和运行测试。

7. Agent Client Protocol:Agent 进入 IDE 与桌面端 ​

7.1 客户端需要哪些事件 ​

IDE、终端和桌面应用需要展示完整任务过程,包括:

  • 创建、恢复和取消会话。
  • 接收流式文本、计划与执行进度。
  • 展示工具开始、工具完成和终端输出。
  • 请求用户确认文件写入、命令或外部操作。
  • 展示文件 diff、诊断结果和最终产物。

Agent Client Protocol 将这些交互组织为客户端与 Agent 框架之间的标准消息。客户端负责展示和收集用户输入,Agent 框架负责模型调用、工具调度、状态管理和执行控制。规范源码和实现可参阅 Agent Client Protocol GitHub 仓库。

7.2 与模型流式协议的区别 ​

模型 API 的流事件描述一次模型调用,例如文本 token 或函数参数增量;客户端协议描述完整 Agent 任务,其中可能包含多次模型调用、多个工具和用户确认。

Agent 框架通常会把底层模型事件转换成更稳定的任务事件。产品可以扩展 trace_id、耗时、风险等级和结果摘要,但应明确区分标准字段与应用字段。

7.3 ACP 的名称歧义 ​

ACP 可能指 Agent Client Protocol,也可能指 Agent Communication Protocol。前者连接客户端与 Agent 框架,后者通常描述 Agent 间消息和任务交换。不同项目使用相同缩写不代表协议兼容,接入时应核对全称、规范版本、维护组织和 SDK。

8. 如何选择协议 ​

8.1 先看通信双方 ​

需求选择方向关键判断
调用 OpenAI 模型并兼容现有消息系统Chat Completions是否依赖 messages、choices 和现有兼容网关
新建 OpenAI Agent 或使用内置工具Responses是否需要 Items、托管工具、状态串联和类型化事件
调用 ClaudeAnthropic Messages是否正确处理 system、Content Blocks 和 tool_use/tool_result
接入工具与数据源MCP是否需要跨 Host 复用、能力发现和统一连接
跨 Agent 委派任务A2A是否需要能力发现、长任务状态和 Artifact
连接 IDE 或桌面客户端Agent Client Protocol 或产品协议是否需要会话、事件、权限与文件变更
同一进程内模块调用Agent 框架内部接口是否存在真正的跨进程或互操作需求

8.2 Agent 框架的统一事件模型 ​

支持多种协议时,Agent 框架不宜让业务逻辑直接依赖供应商字段。可以先转换为内部事件:

text
user_message
assistant_message
tool_call(id, name, arguments)
tool_result(id, content, is_error)
state_update
artifact
usage
final

协议适配器负责外部 JSON 与内部事件之间的转换。这样可以替换模型供应商、把 MCP Tool 映射到多个模型接口,并用统一 trace 串起客户端、模型、工具和下游 Agent。

8.3 安全与可靠性 ​

  1. 身份传递:区分用户、Agent 框架、工具服务和下游 Agent,记录每次调用代表谁执行。
  2. 最小权限:模型只看到当前任务需要的能力,Server 对每次读取和写入独立授权。
  3. 参数校验:模型产生的 JSON 仍是不可信输入,Agent 框架要校验 schema、路径、范围和副作用。
  4. 工具描述污染:第三方工具名称、描述和返回内容都可能包含诱导指令,接入和升级时需要审查。
  5. 上下文隔离:跨 Server 或跨 Agent 只传递完成任务所需的信息,执行脱敏与租户隔离。
  6. 状态完整性:工具调用与结果必须通过 call ID 配对,任务事件要有顺序和可恢复状态。
  7. 审计链路:使用 trace ID 串联客户端事件、模型请求、MCP 调用和 A2A Task。

参考资料 ​