跳转到内容
Alibaba Cloud AI Agent Handbook 已开源,汇集50+工程师的一手实践经验点此了解

Agent 管理

Nacos 从 3.1 开始提供 A2A Agent 注册与发现能力。3.3 将 Agent 管理升级为通用的 Agent 资源管理:统一管理 Agent 的身份、目录信息、版本化调用定义和运行端点,并通过 RAD(Remote Agent Discovery)提供搜索、发现和订阅能力。

A2A 仍然是受支持的接入方式。AgentCard 作为 A2A 调用接口的原生描述保留,已有 A2A 应用可继续接入。本文介绍管理和发布流程;应用侧端点注册、发现与订阅的完整示例见 RAD 接入指南。

Nacos 负责告诉应用“Agent 是谁、支持怎样的调用、可用地址在哪里”。实际的消息、任务和流式调用由 Agent 应用及其协议客户端完成。

1. 认识 Agent 资源

1.1. 身份、目录与版本

内容管理什么什么时候修改
Agent名称、展示名称、描述、提供方、业务标签、启用状态和可见范围更新目录信息或治理策略时
Agent 版本一次发布的调用定义,包含 callInterfaces调用协议、原生描述或声明地址发生变化时,创建新版本草稿
调用接口(CallInterface)protocol、protocolVersion、nativeDescriptor 及端点来源顺序随版本一起编辑和发布
运行端点(Runtime Endpoint)Agent 应用当前提供的地址、运行版本和兼容范围应用启动、扩缩容或退出时注册、更新和注销

一个 Agent 由 namespaceId + agentName 唯一标识。不同命名空间可以使用相同名称;同一命名空间内名称不能重复。agentName 创建后不可修改,区分大小写,长度为 1~64 个可打印 ASCII 字符,不能全部为空格。需要中文名称时使用 displayName。

版本号采用 主版本.次版本.修订版本,例如 1.0.0、1.1.0-rc.1,最长 64 个字符,不接受 +build 后缀。已发布的版本内容不可覆盖;调整 Agent 目录描述或业务标签不需要新建定义版本。

Agent 管理面向可调用的 Agent;AgentSpecs 管理面向可分发的规范包,两者分别管理版本和生命周期。

1.2. 调用协议与地址来源

callInterfaces 是有序的调用接口列表,同一版本内 protocol 不能重复。A2A 接口使用 protocol=a2a,其 nativeDescriptor 为 AgentCard。协议中的技能、能力和安全方案保留在原生描述中。

每个调用接口有两类地址来源:

来源适用场景维护方式
DECLARED 声明地址外部提供商、固定网关或稳定访问入口保存于版本定义中;A2A 地址与 AgentCard 的接口声明保持一致
RUNTIME 运行端点应用自动注册、实例扩缩容由发布端应用通过 SDK 注册并维持活性,退出时注销

endpointSourceOrder 指定推荐顺序:["RUNTIME", "DECLARED"] 优先运行端点,["DECLARED", "RUNTIME"] 优先声明地址,必须同时包含两种来源且各出现一次。顺序不代表关闭另一种来源;调用方可在发现时显式过滤来源。

发布定义不会启动 Agent 应用;注册运行端点也不会自动创建或发布定义。使用声明地址时,应由提供方保证地址可达;使用运行端点时,还需检查实例健康和版本兼容性。

2. 接入准备

  • 使用 Nacos 3.3 服务端。升级已有集群时,先完成升级手册中的 A2A 迁移步骤,再使用通用 Agent/RAD 入口。
  • Nacos 3.3 默认开启客户端鉴权。管理账号需要目标 Agent 的管理权限;应用账号需要相应的读取或端点写入权限。按配置访问凭据准备 NACOS_USERNAME、NACOS_PASSWORD;HTTP 示例使用登录后保存的 NACOS_ACCESS_TOKEN。
  • 明确发布者与使用者采用的命名空间。以下示例使用 public。
  • 准备实际运行的 Agent 应用。下文 http://127.0.0.1:9999/a2a 是本地示例地址,部署时应改为使用方能访问的地址。

新建 Agent 在内置可见性策略下默认是 PUBLIC。需要私有发布时,先创建草稿,再通过独立 scope 接口设为 PRIVATE,最后提交发布。scope 作用于整个 Agent;新版本和重试不会重置已有私有设置,创建请求也不直接接受 scope 参数。操作示例见修改资源的 scope。

公开可见不等于免鉴权,也不会赋予调用者写权限,默认值及显式授权规则见可见性插件。Nacos 的登录凭据也不能代替调用 Agent 服务本身所需的凭据。

3. 创建与发布 Agent

3.1. 通过控制台管理

  1. 在 AI 管理中心进入 Agent 管理,选择目标命名空间,点击 创建 Agent。
  2. 已有 AgentCard 时,选择 从已知协议导入,粘贴完整的 A2A AgentCard,检查导入预览中的名称、版本和接口地址。也可以选择 全新创建,填写目录信息、首个版本和调用协议。
  3. 保存后得到草稿。检查版本内容、端点来源顺序和可见范围,再执行 提交审核。
  4. 未配置审核流程时,提交后直接上线;已配置审核流程时,等待审核完成,通过后执行 发布。
  5. 在版本详情和运行时端点区域检查定义及地址,再从使用方验证发现和实际调用。

更新时,编辑元数据用于调整 Agent 的目录信息;编辑草稿用于修改未发布的调用定义。修改已发布内容,应使用 基于此版本创建草稿并指定新版本号。

3.2. 通过 HTTP 创建草稿

管理集成使用 /nacos/v3/admin/ai/agents 下的接口。以下示例创建名为 route-planner 的 Agent 及 1.0.0 草稿。先将调用定义保存到 agent-call-interfaces.json:

[
{
"protocol": "a2a",
"protocolVersion": "0.3.0",
"descriptorMediaType": "application/json",
"nativeDescriptor": {
"protocolVersion": "0.3.0",
"name": "route-planner",
"description": "Plan a route between two locations.",
"url": "http://127.0.0.1:9999/a2a",
"preferredTransport": "JSONRPC",
"version": "1.0.0",
"capabilities": {"streaming": false},
"defaultInputModes": ["text"],
"defaultOutputModes": ["text"],
"skills": [
{
"id": "plan-route",
"name": "Route planning",
"description": "Plan a route between two locations.",
"tags": ["routing"]
}
]
},
"endpointSourceOrder": ["RUNTIME", "DECLARED"],
"endpointSets": [
{
"source": "DECLARED",
"endpoints": [
{"uri": "http://127.0.0.1:9999/a2a", "transport": "JSONRPC"}
]
}
]
}
]

这是 A2A 0.3.0 描述示例。使用其他 A2A 版本时,应提交该版本的完整 AgentCard,并保持名称、版本与外层 Agent 定义一致。直接填写通用 HTTP 表单时,应同时保持 AgentCard 地址与 DECLARED 端点一致;控制台的 A2A 导入入口会完成相应转换。

在文件所在目录运行以下 Bash 命令:

Terminal window
curl -sS -X POST 'http://127.0.0.1:8848/nacos/v3/admin/ai/agents/draft' \
-H "accessToken: ${NACOS_ACCESS_TOKEN}" \
--data-urlencode 'namespaceId=public' \
--data-urlencode 'agentName=route-planner' \
--data-urlencode 'version=1.0.0' \
--data-urlencode 'description=Plan a route between two locations.' \
--data-urlencode 'tags=["routing"]' \
--data-urlencode 'callInterfaces@agent-call-interfaces.json'

callInterfaces、tags 等复杂字段是表单中的 JSON 字符串,不是整个 HTTP 请求的 JSON body。创建成功仍为 draft,此时不能通过普通运行时发现使用该版本。

3.3. 提交并检查发布结果

提交草稿:

Terminal window
curl -sS -X POST 'http://127.0.0.1:8848/nacos/v3/admin/ai/agents/submit' \
-H "accessToken: ${NACOS_ACCESS_TOKEN}" \
--data-urlencode 'namespaceId=public' \
--data-urlencode 'agentName=route-planner' \
--data-urlencode 'version=1.0.0'

检查响应及版本状态;有审核流程时,可通过控制台查看结果,也可以读取精确版本:

Terminal window
curl -sS -G 'http://127.0.0.1:8848/nacos/v3/admin/ai/agents/version' \
-H "accessToken: ${NACOS_ACCESS_TOKEN}" \
--data-urlencode 'namespaceId=public' \
--data-urlencode 'agentName=route-planner' \
--data-urlencode 'version=1.0.0'

只有处于 reviewed 且审核通过时,才执行下面的发布操作;已是 online 则直接进入发现验证。审核未通过时,先查看原因,再重新编辑或重新提交。

Terminal window
curl -sS -X POST 'http://127.0.0.1:8848/nacos/v3/admin/ai/agents/publish' \
-H "accessToken: ${NACOS_ACCESS_TOKEN}" \
--data-urlencode 'namespaceId=public' \
--data-urlencode 'agentName=route-planner' \
--data-urlencode 'version=1.0.0'

3.4. 后续版本与代码式发布

一个 Agent 最多有一个编辑中版本和一个审核中版本。后续版本可直接提供新的 callInterfaces,也可用 basedOnVersion 复制已有精确版本,两者不能同时提供。复制后,先在草稿中调整协议描述的版本、地址等内容,再提交。

通过 SDK 发布时,注意两类接口的区别:

  • 旧 A2A 发布接口 releaseAgentCard:首个版本直接上线并成为最新版本(latest),即使 setAsLatest=false。后续新版本也会直接上线;setAsLatest=true 时设为最新版本,false 时保留原来的最新版本。
  • 新 RAD 发布接口 publishAgent:首个版本自动尝试发布,不受 autoSubmit 的值影响。后续新版本或已有草稿,autoSubmit=false 时保存为草稿,true 时自动提交发布。

这里的“首个版本”指该 Agent 还没有任何版本;已有草稿也算已有版本。新接口的自动发布会遵循已配置的审核流程,可能需要等待审核。调用后检查返回的 AgentVersionDetail.getStatus(),确认是否已为 online。

**3.3 SDK 兼容说明:**使用 3.3 SDK 的 releaseAgentCard 连接支持 RAD 的服务端时,SDK 会自动使用新的发布流程,无需手动选择。此时 setAsLatest 的作用与 autoSubmit 相同:后续版本设为 false 时保存草稿,设为 true 时提交发布。该方法没有返回值,可通过控制台确认发布状态。

新接口可以更新草稿;已提交审核、已上线或已下线的版本保持不变。如需修改这些版本,请创建新版本。发布超时后,先检查版本是否已经保存或上线,再决定是否重试。

详细状态及操作规则见 AI 资源生命周期。标准发布或重新上线会把 latest 指向本次版本;下线当前 latest 后会选择其余在线版本中版本号最大的一个。latest 由服务端维护,不能通过自定义标签覆盖。

4. 发现和使用 Agent

4.1. 搜索、发现与订阅

能力用途主要结果
Search按名称子串、业务标签、调用协议寻找 Agent可见且已启用的在线 Agent 目录与版本信息
Discover按名称、版本或标签获取调用定义和端点callInterfaces[].endpointSets[].endpoints[]
Watch订阅同一发现条件的变化初始完整快照,以及后续变化或不可用事件

Search 的 agentNameContains 区分大小写;tagsAll 要求全部精确匹配;protocolsAny 要求至少一个在线版本包含任一指定协议。它们是 Agent 目录筛选条件,不能等同于对 AgentCard 内任意 skills 或描述执行语义搜索。Search 命中也不保证存在健康端点。

只查询目录后,应继续 Discover 获取调用地址,再由 A2A 等协议客户端调用。接入示例、过滤条件和订阅清理见 RAD 接入指南。

4.2. 明确版本选择

选择方式定义版本运行端点兼容范围
不传 version 和 label当前 latest兼容任一当前在线版本的运行端点
显式 label=latest当前 latest仅兼容该版本的运行端点
指定 version 或其他 label对应的精确在线版本仅兼容该版本的运行端点

version 与 label 不能同时使用。需要严格跟随最新定义的应用应显式设置 label=latest;固定版本或灰度标签时,也应检查目标版本已上线。过滤条件只裁剪所选定义的接口与地址,不会自动改选另一个版本。

5. A2A 接入与兼容

5.1. AgentCard 与通用 Agent 的关系

A2A AgentCard 保存为 protocol=a2a 调用接口的 nativeDescriptor。Card 的 name 和 version 对应 Agent 名称和版本,接口 URL 对应声明地址。既有 A2A API 仍用于发布、查询和订阅 Card;通用 RAD API 返回包含原生 Card 和端点集合的发现结果。

  • 已有 A2A 应用:可以继续使用 releaseAgentCard、getAgentCard 和 subscribeAgentCard 等接口。3.3 SDK 会自动适配服务端,无需手动选择 RAD。发布行为的变化见第 3.4 节。
  • 新应用:直接使用 searchAgents、discoverAgent、subscribeAgent 和 registerAgentEndpoints 等 RAD 接口,服务端需支持 RAD。完整示例见 RAD 接入指南。

同一个 SDK 实例为同一 Agent 注册 A2A 地址时,选择旧 A2A 或新 RAD 的一组注册、注销接口配套使用,避免混用。Nacos 的访问账号与 Agent 服务自身的调用凭据分别配置。

5.2. 自定义 A2A 应用

3.3 Java SDK 可通过以下入口保留 AgentCard 的使用方式;agentCard 应是应用提供的完整 Card:

import com.alibaba.nacos.api.ai.AiFactory;
import com.alibaba.nacos.api.ai.AiService;
import com.alibaba.nacos.api.ai.AgentService;
import com.alibaba.nacos.api.ai.model.a2a.AgentCard;
import java.util.Properties;
Properties properties = new Properties();
properties.setProperty("serverAddr", "127.0.0.1:8848");
properties.setProperty("namespace", "public");
properties.setProperty("username", System.getenv("NACOS_USERNAME"));
properties.setProperty("password", System.getenv("NACOS_PASSWORD"));
AiService aiService = AiFactory.createAiService(properties);
AgentService agentService = aiService.agent();
try {
// Publish the application's complete AgentCard. See section 3.4 for version behavior.
agentService.releaseAgentCard(agentCard, "SERVICE", false);
} finally {
aiService.shutdown();
}

上述片段仅发布应用提供的完整 Card。通过管理端确认版本已 online 后,再由运行端注册端点、消费端查询或订阅;示例见 Java SDK 使用手册。运行端保留 SDK 实例,退出时用同一实例注销端点并关闭。

使用旧 subscribeAgentCard 接口订阅时,如果 AgentCard 被删除或暂时查不到,SDK 默认会触发保护:不会向监听器传入 null 或空 Card,也不会发送删除通知。

通过 HTTP 集成旧 A2A 管理接口时,可将完整 AgentCard 保存为 agent-card.json 后导入:

Terminal window
curl -sS -X POST 'http://127.0.0.1:8848/nacos/v3/admin/ai/a2a' \
-H "accessToken: ${NACOS_ACCESS_TOKEN}" \
--data-urlencode 'namespaceId=public' \
--data-urlencode 'agentCard@agent-card.json'

这里提交的是 Card 本身,不能使用第 3 节的 callInterfaces 数组文件。此入口属于上述旧 A2A 兼容路径;需要草稿审核的管理集成应使用通用 Agent 管理入口。

5.3. 发布通过Spring AI Alibaba开发的Agent

以下保留 Spring AI Alibaba 1.0.0.4 的接入示例,适合已使用该版本的应用;不同框架版本的依赖与配置应按其版本说明和 A2A 指南核对。升级 Nacos 服务端不等于自动升级框架所依赖的 Nacos Client,发布行为仍以实际 Client 版本及其选择的接入方式为准。

5.3.1. 引入依赖

<!-- Spring AI Alibaba版本 1.0.0.4 -->
<properties>
<spring.ai.alibaba.version>1.0.0.4</spring.ai.alibaba.version>
</properties>
<dependencies>
<!-- 引入A2A Server starter -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-a2a-server</artifactId>
<version>${spring.ai.alibaba.version}</version>
</dependency>
<!-- 引入A2A Nacos 注册中心 -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-a2a-registry</artifactId>
<version>${spring.ai.alibaba.version}</version>
</dependency>
<!-- 引入A2A 百炼大模型客户端,可以用其他的spring ai大模型客户端代替,如openai -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
<version>${spring.ai.alibaba.version}</version>
</dependency>
</dependencies>

5.3.2. 构建Agent

通过Spring AI Alibaba中定义的Agentic API快速定义及构建Agent运行逻辑,如下代码,创建了一个直接访问大模型Agent:

@Configuration
public class RootAgentConfiguration {
@Bean
@Primary
public BaseAgent rootAgent(ChatModel chatModel) throws GraphStateException {
return ReactAgent.builder().name("{your_agent_name}").description("{your_agent_description}").model(chatModel)
.instruction("{your_agent_system_prompt}").build();
}
}

5.3.3. Agent 自动注册的参数配置

server:
port: 9999
spring:
application:
name: a2a-server-example
ai:
# 配置大模型的参数,如API-KEY,模型名称等
dashscope:
api-key: ${BAILIAN_API_KEY}
base-url: https://dashscope.aliyuncs.com/compatible-mode
chat:
options:
model: qwen-plus-latest
alibaba:
a2a:
# 配置Nacos的地址和用户名密码
nacos:
server-addr: ${NACOS_ADDRESS:localhost:8848}
username: ${NACOS_USERNAME:nacos}
password: ${NACOS_PASSWORD}
# 配置A2A server的额外信息,如版本号,agentCard中的Skills等
server:
version: 1.0.1
card:
# 配置Agent(AgentCard)的URL,若当前版本无可用端点,会使用此 URL
url: http://localhost:9999/a2a
skills:
- id: nacos-question-answer
name: Nacos Question Answer
description: Answer questions about Nacos.
tags:
- Nacos
examples:
- What is Nacos?
icon-url: https://img.alicdn.com/imgextra/i4/O1CN01rW3vAB1FDWKSOiFf0_!!6000000000453-2-tps-204-40.png
documentation-url: https://nacos.io
provider:
organization: Alibaba
url: https://www.alibaba.com

5.3.4. 启动A2A Server Agent

随后启动 A2A Server(如 mvn spring-boot:run),并在 Nacos 控制台检查 Agent 的版本状态和端点。若实际使用的 Client 发布后进入审核流程,需完成审核发布后再验证调用。

5.4. 通过Spring AI Alibaba查询/订阅/调用 Agent

5.4.1. 引入依赖

<!-- Spring AI Alibaba版本 1.0.0.4 -->
<properties>
<spring.ai.alibaba.version>1.0.0.4</spring.ai.alibaba.version>
</properties>
<dependencies>
<!-- 引入A2A Client starter -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-a2a-client</artifactId>
<version>${spring.ai.alibaba.version}</version>
</dependency>
<!-- 引入A2A Nacos 注册中心 -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-a2a-registry</artifactId>
<version>${spring.ai.alibaba.version}</version>
</dependency>
</dependencies>

5.4.2. 构建A2A Agent Client

通过Spring AI Alibaba中定义的Agentic API快速构建A2A的Agent Client

@Configuration
public class RootAgentConfiguration {
@Bean
public BaseAgent rootAgent(AgentCardProvider agentCardProvider) throws GraphStateException {
return A2aRemoteAgent.builder()
// 传入自动构建的Nacos AgentCard Provider
.agentCardProvider(agentCardProvider)
// 设置需要的Agent的名称,Nacos AgentCard Provider会根据此名称自动订阅AgentCard和Agent的可访问端点
.name("{remote_agent_name}").description("{remote_agent_description}").build();
}
}

5.4.3. Agent 自动发现的参数配置

spring:
application:
name: a2a-client-example
ai:
alibaba:
a2a:
nacos:
# 开启从Nacos中自动发现Agent
discovery:
enabled: true
server-addr: ${NACOS_ADDRESS:localhost:8848}
username: ${NACOS_USERNAME:nacos}
password: ${NACOS_PASSWORD}

5.4.4. 调用A2A Agent Client

在运行时,获取构建好的A2A Agent Client进行调用,Agent会自动的订阅Nacos中的AgentCard及Agent的服务端点,同时选择可用的端点进行调用,如:

@RestController
@RequestMapping("/")
public class TestController {
private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(TestController.class);
private final BaseAgent rootAgent;
public TestController(BaseAgent rootAgent) {
this.rootAgent = rootAgent;
}
@GetMapping("stream")
public Flux<String> stream(@RequestParam("question") String question)
throws GraphStateException, GraphRunnerException {
return rootAgent.stream(Map.of("messages", List.of(new UserMessage(question)))).mapNotNull(output -> {
LOGGER.debug("stream agent invoke : `{}`", output.toString());
if (output.isSTART() || output.isEND()) {
return null;
}
if (output instanceof StreamingOutput) {
return ((StreamingOutput) output).chunk();
}
return null;
}).publishOn(Schedulers.parallel());
}
}

6. 常见问题

现象检查与处理
控制台已有 Agent,应用仍发现不到确认命名空间、资源启用状态、版本是否 online,以及调用账号的权限与可见范围
刚发布后 Search 未命中,但精确 Discover 正常搜索索引同步可能尚未完成,稍后重试;不要立即重复创建资源
发现结果没有地址检查协议/来源过滤、声明地址、运行端点注册情况,以及注册的兼容范围是否包含目标在线版本
返回了 healthy=false 的运行端点Discover 会保留不健康端点供调用方判断;调用前应选择健康地址并应用相应选址策略
下线版本后仍看到应用实例版本下线只影响定义的发现可用性;应用仍需注销自己注册的运行端点
发布后实际调用失败检查 Agent 服务是否已启动、网络可达、调用协议匹配,以及业务服务自身的鉴权配置
升级期间通用 Agent/RAD 请求被拒绝先完成升级手册中的 A2A 迁移与验证,再切换使用新入口