Agent-to-Agent (A2A) 协议是一种开放的消息传递标准,可让自主 AI 代理在不同的系统之间进行通信和协调任务。
在 CX Agent Studio 中,A2A 协议工具可让您的代理应用将任务委托给外部远程代理,或让外部应用和编排器使用标准化消息传递来调用您的 CX Agent Studio 代理。
A2A 的运作方式
CX Agent Studio 中的 A2A protocol 采用委托模型运行。
委托模型
在委托模型中,发起方 CX Agent Studio 智能体充当主要编排器,并保留对整个会话的总体控制权:
- 会话所有权:主要代理维护用户对话会话。 当需要执行专业子任务时,主智能体会将远程智能体作为工具进行调用。
- 控制流:远程代理处理请求并返回结构化响应数据。控制权会立即返回到主代理,该代理会为最终用户总结或整合结果。
- 上下文转移:主代理仅传输委托任务所需的参数和对话上下文。
基于文本的通信
A2A protocol 中的所有智能体间通信都是基于文本的:
- 如果最终用户通过语音渠道(例如电话或 WebRTC)与主要代理互动,则语音会先转换为文本。
- 主代理在 HTTP 请求载荷中将文本转写内容和参数发送到远程子代理。
- 原始音频流和嵌入内容不会通过 A2A 网络接口传输。
结算
如果主会话和远程会话都在 CX Agent Studio 中,并且位于同一项目中,则您只需支付 1 个会话的费用。
否则,对于跨多个项目或第三方系统的主会话和远程会话,系统会向您收取 2 个会话的费用。
身份验证和访问控制
身份验证要求取决于通信方向和目标服务。
| 方向 | 目标目的地 | 身份验证机制 | 所需 IAM 角色 | 说明 |
|---|---|---|---|---|
| 入站(CX Agent Studio 外部) | CX Agent Studio 智能体应用 | OAuth 2.0 访问令牌 | roles/ces.client |
外部调用者调用 CX Agent Studio 入站端点时需要此角色。 |
| 出站(从 CX Agent Studio 到 CX Agent Studio) | 其他项目中的 CX Agent Studio 智能体 | 服务代理 | roles/ces.client |
授予给目标项目上调用项目的服务代理。 |
| 出站(从 CX Agent Studio 到 Cloud Run) | Cloud Run 服务 | 服务代理 ID 令牌 | roles/run.invoker |
授予给 Cloud Run 服务上调用项目的服务代理。 |
| 出站(从 CX Agent Studio 到 Vertex AI) | Vertex AI Agent Engine | 服务代理 OAuth | roles/aiplatform.user |
授予给目标项目上调用项目的服务代理。 |
| 出站(从 CX Agent Studio 到第三方) | 外部端点(例如 ServiceNow 或 Salesforce) | API 密钥或 OAuth | 使用 Secret Manager 进行管理 | 在工具执行期间注入的存储凭据。 |
服务代理身份
CX Agent Studio 的出站请求使用 CX Agent Studio 服务代理:
service-PROJECT_NUMBER@gcp-sa-ces.
将 PROJECT_NUMBER 替换为您的 Google Cloud 项目编号。
入站身份验证
当外部应用、自定义代理或编排器调用 CX Agent Studio 时,必须在 Authorization 标头中传递有效的 Google 颁发的 OAuth 2.0 访问令牌:
测试:为您的有效账号生成临时访问令牌:
gcloud auth print-access-token程序化客户端:使用应用默认凭证 (ADC):
gcloud auth application-default print-access-token生产环境:使用具有
roles/ces.client(Customer Engagement Suite Client) 角色的专用 Google 服务账号。
前提条件
在配置 A2A 协议工具之前:
在您的项目中启用 Gemini Enterprise for Customer Experience API (
ces.googleapis.com):gcloud services enable ces.googleapis.com --project=PROJECT_ID确保已向调用方主账号或服务账号授予
Customer Engagement Suite Client角色 (roles/ces.client)。
配置 A2A Protocol 工具
如需将主代理连接到外部远程代理,请执行以下操作:
- 打开 CX Agent Studio 控制台。
- 选择您的项目,然后打开代理应用。
- 在代理构建器中,点击工具图标。
- 点击 +(添加)按钮以创建新工具。
- 选择 A2A Protocol 工具卡片。
- 使用 界面表单或 JSON 编辑器配置代理卡片。
- 在 URL 字段中,输入远程代理的基础端点网址(例如
https://ces.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/apps/APP_ID或您的 Cloud Run 服务网址)。 请勿将/message:send附加到网址;CX Agent Studio 会在运行时自动附加/message:send。 - 为端点选择合适的身份验证类型。
- 点击创建。
智能体卡片示例
以下 JSON 示例定义了远程天气智能体的智能体卡片:
{
"name": "weather_agent",
"description": "Agent capable of querying weather conditions and local time for given locations.",
"version": "0.1.0",
"supportedInterfaces": [
{
"url": "https://ces.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/apps/APP_ID",
"protocolBinding": "HTTP+JSON",
"protocolVersion": "1.0"
}
],
"skills": [
{
"id": "get_weather",
"name": "get_weather",
"description": "Retrieves weather conditions for a specified location.",
"tags": [
"weather",
"forecast"
],
"examples": [],
"inputModes": [],
"outputModes": []
},
{
"id": "get_current_time",
"name": "get_current_time",
"description": "Retrieves current local time for a specified city or timezone.",
"tags": [
"time",
"clock"
],
"examples": [],
"inputModes": [],
"outputModes": []
}
]
}
添加路线说明
指示主代理何时委托给 A2A 工具。 例如:
If the user asks for weather information or local time, use {@TOOL: weather_agent}.
Pass the city or location specified by the user.
If the tool returns an error, inform the user that weather details are temporarily unavailable.
入站消息传递
外部系统可以使用入站 A2A 消息传递端点直接向 CX Agent Studio 代理应用发送消息。
入站端点网址
向以下端点发送 HTTP POST 请求:
https://ces.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/apps/APP_ID/message:send
替换以下内容:
PROJECT_ID:您的 Google Cloud 项目 ID。LOCATION:托管代理应用的区域(例如us-central1)。APP_ID:CX Agent Studio 代理应用的唯一标识符。
请求载荷架构
用于发送入站消息的 JSON 载荷结构:
{
"message": {
"messageId": "msg-MY_UNIQUE_MESSAGE_UUID",
"role": "ROLE_USER",
"content": [
{
"text": "Hello! I would like help checking my account balance."
}
],
"metadata": {
"gecx_a2a_agent_context": "MY_SERIALIZED_AGENT_CONTEXT_STRING"
}
}
}
使用 curl 的请求示例
您可以使用 curl 测试入站消息传递:
curl -X POST \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "X-Goog-User-Project: PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{
"message": {
"messageId": "msg-'"$(uuidgen)"'",
"role": "ROLE_USER",
"content": [
{
"text": "Hello!"
}
]
}
}' \
"https://ces.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/apps/APP_ID/message:send"
上下文和状态管理
A2A protocol 使用 AgentContext 消息来管理代理之间的变量和会话状态。上下文通过 SendMessageRequest 的元数据中的 gecx_a2a_agent_context 键传入。
变量映射
委托任务时,您可以在主代理和远程代理之间映射变量:
- 出站映射:
RemoteAgentTool.input_variable_mapping计算发送给远程代理的AgentContext.variables。 - 入站映射:当远程代理做出响应时,更新主代理的变量。
RemoteAgentTool.output_variable_mapping
对于入站请求(从外部客户端到 CX Agent Studio),应用会反序列化 gecx_a2a_agent_context 元数据,并将 AgentContext.variables 直接写入当前会话。在响应客户端时,更新后的变量会写回 AgentContext.variables。
会话结束
主代理会监控 AgentContext.session_metadata.closed 以确定远程会话何时结束:
- 出站请求始终将
closed设置为false。 如果远程代理的响应将closed设置为true,则 A2A 连接会终止。 - 对于返回到客户端的入站响应,如果会话已结束,CX Agent Studio 应用会将
closed设置为true。
有状态模式
使用 CXAS 应用的远程会话始终是有状态的。主 CXAS 会话和远程 CXAS 会话将共享同一会话 ID,远程会话将保留主代理和远程代理之间的对话历史记录。
对于与第三方系统进行的远程会话,远程会话默认情况下将是无状态的,远程代理将从主代理接收每条消息,并将其视为新会话(即新情境 ID)。
您可以启用 RemoteAgentTool.stateful_agent 字段,以自动缓存并重用远程代理返回的第一个上下文 ID。
在远程代理响应 AgentContext.session_metadata.closed == true 之前,此缓存的上下文 ID 将用于会话的剩余时间。如果会话已关闭,系统会重置缓存,并在下次工具调用时缓存新的上下文 ID。
部署远程子代理
您可以在 Google Cloud 服务上部署自定义远程代理,以充当 CX Agent Studio 的子代理。
部署到 Cloud Run
如需在 Cloud Run 上托管使用智能体开发套件 (ADK) 构建的智能体,请执行以下操作:
在智能体项目目录中创建
Dockerfile:FROM python:3.11-slim WORKDIR /app COPY pyproject.toml requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir "google-adk[a2a]==1.32.0" "a2a-sdk[all]==0.3.26" COPY . . ENV PORT=8080 ENV PYTHONUNBUFFERED=1 EXPOSE 8080 CMD ["python", "-m", "app.a2a_rest_server"]将容器部署到 Cloud Run:
gcloud run deploy my-adk-agent \ --project=PROJECT_ID \ --region=us-central1 \ --source=. \ --memory=4Gi \ --no-cpu-throttling向调用项目的 CX Agent Studio 服务代理授予 Cloud Run 服务的
roles/run.invoker角色。按照配置 A2A 协议工具中的步骤将 Cloud Run 服务网址附加到 CX Agent Studio。
部署到 Vertex AI Agent Engine
如需将 ADK 代理部署到 Vertex AI Agent Engine,请执行以下操作:
在
requirements.txt中定义依赖项:a2a-sdk==0.3.26 google-adk[a2a]>=1.15.0,<2.0.0使用 Vertex AI SDK 部署引擎:
import os import sys from google.protobuf import json_format import vertexai from vertexai.agent_engines import _agent_engines sys.path.append("./") from app.agent_runtime_app import agent_runtime client = vertexai.Client(project="PROJECT_ID", location="us-central1") ops = agent_runtime.register_operations() class_methods_proto = _agent_engines._generate_class_methods_spec_or_raise( agent_engine=agent_runtime, operations=ops ) class_methods_list = [ json_format.MessageToDict(cm, preserving_proto_field_name=True) for cm in class_methods_proto ] agent_config = { "entrypoint_module": "app.agent_runtime_app", "entrypoint_object": "agent_runtime", "source_packages": ["app", "requirements.txt"], "requirements_file": "requirements.txt", "class_methods": class_methods_list, "agent_framework": "google-adk", "env_vars": { "GOOGLE_CLOUD_LOCATION": "us-central1", }, "min_instances": 1, "max_instances": 10, "resource_limits": {"cpu": "4", "memory": "8Gi"}, } engine = client.agent_engines.create(config=agent_config) print(f"Deployed Engine Resource Name: {engine.api_resource.name}")向调用项目的 CX Agent Studio 服务代理授予目标项目的
roles/aiplatform.user角色。按照配置 A2A Protocol 工具中的步骤将 Agent Engine 端点附加到 CX Agent Studio。
连接到第三方端点
CX Agent Studio 可以将任务委托给外部第三方端点,例如 ServiceNow 或 Salesforce。
在控制台中配置该工具时:
- 按照配置 A2A 协议工具中的步骤操作。
- 选择第三方端点所需的身份验证方法(例如 API 密钥或 OAuth)。
- 使用 Secret Manager 安全地存储凭据。
A2A 协议工具与“智能体即工具”的比较
CX Agent Studio 提供了多种方法来协调多智能体工作流。
| 功能 | 将智能体作为工具 | A2A Protocol 工具 |
|---|---|---|
| 范围 | 应用内(同一 CX Agent Studio 应用中的智能体)。 | 应用间(外部代理、远程服务或第三方平台)。 |
| 通信 | 直接在内存中 / 内部执行。 | 使用 A2A 消息传递标准发出网络 HTTP 请求。 |
| 使用场景 | 在不移交会话的情况下重复使用内部子代理。 | 调用 Cloud Run、Vertex AI 或外部 API 上的自定义 ADK 代理。 |
| 协议 | 平台内部工具执行。 | 通过 REST 实现标准化 A2A JSON 载荷。 |
LLM 工具执行
在后台,A2A protocol 调用通过标准 LLM 工具调用运行:
- 当 A2A 工具分配给代理时,工具说明和技能定义会作为函数声明提供给模型。
- 当模型决定委托子任务时,会生成函数调用事件。
- CX Agent Studio 运行时会拦截函数调用,将参数转换为 A2A HTTP 请求,并将其发送到配置的远程端点。
- 远程代理返回的回答会传递回模型,以继续生成对话回答。
如需详细了解如何将代理封装为可调用的工具,请参阅 GitHub 上的 ADK AgentTool 实现。