文章展示基于 AWS Agent Registry 的发现、实例化、执行循环,由编排器在运行时通过语义搜索寻找 MCP 服务和 A2A Agent。该方案面向工具数量扩大后,硬编码接入难以维护的问题。
借助 AWS Agent Registry 在运行时发现能力,有助于解决一个在智能体演示中可能被掩盖的问题。工具数量只有几个时,硬编码工具的方式运行良好;达到几十个时,效果开始下降;再多就会变得难以管理。企业系统会提供数百个内部 API,涵盖定价、支持、订单、库存和客户数据。在这些系统中,模型用于区分工具名称的 token,可能比用于推理用户请求的还多。每增加一项新能力,都需要修改编排器代码、重新部署,并协调多个团队同步发布,而这些团队更希望按照自己的节奏交付。
在企业软件即服务(SaaS)项目中,当团队向智能体使用方开放大量内部 API 时,就可能出现这种情况。随着目录规模扩大,构建时接入可能成为瓶颈。一种应对方式是改变编排器访问工具的方式:不再将所有工具编译进智能体,而是让智能体在运行时发现相关工具。
AWS Agent Registry 是一项托管服务,用于编目和发现 Model Context Protocol(MCP)服务器、智能体及智能体技能。发布者注册特定协议的描述符和可搜索的描述。在运行时,编排器可以搜索已获批准、可被发现的记录,并使用返回的端点和描述符内容构建客户端。Registry 搜索结果不会返回调用该能力所需的凭证或身份验证方案。
本文将介绍重构后的 Python 示例所演示的“发现 → 实例化 → 执行”循环。这段代码通过 Amazon Bedrock AgentCore 的一项能力 Amazon Bedrock AgentCore Gateway 部署一个订单管理 MCP 服务器,在 AgentCore runtime 上部署两个 agent-to-agent(A2A)智能体,并部署一个 Registry 和一个编排器。示例目录包含部署脚本、编排器、辅助模块和清理脚本。
本示例中的编排器智能体没有任何关于工具或其他智能体的内置知识。
图 1:不使用 AWS Agent Registry 时(左),端点被硬编码,添加新智能体需要修改代码并重新部署。使用 AWS Agent Registry 时(右),编排器通过语义搜索发现能力,新的集成在注册并获批后即可使用
编排器向 AWS Agent Registry 数据平面发送自然语言查询。搜索响应包含记录标识、名称、描述、记录类型、状态、版本,以及 MCP 服务器元数据或 A2A 智能体卡片等协议描述符。响应不包含调用凭证。应用程序必须通过单独且可信的配置途径获取并应用适当的凭证。
对于返回的每条记录,编排器会根据描述符类型构建客户端。在本示例中,已注册的 MCP 服务器所代表的工具,事先已作为目标添加到 Amazon Bedrock AgentCore Gateway。因此,MCP 描述符指向 Gateway 端点。编排器会单独获取 Cognito OAuth 访问令牌,并在创建 MCPClient 时使用它。A2A 记录包含一张智能体卡片,其中的 URL 指向一个 AgentCore runtime 端点。封装层通过 boto3 数据平面客户端调用该运行时,客户端使用调用方的 AWS 凭证对请求进行签名。Registry 发现机制提供的是连接元数据,而非身份验证材料。
随后,系统构建一个临时内部智能体,仅配备动态发现的工具。大语言模型(LLM)为请求选择合适的一个或多个工具,再将结果整合后返回给用户。本轮交互结束后,内部智能体及其客户端会被销毁。下一个请求会重新搜索,并获得一组新的工具。
图 2:端到端架构。部署在 Amazon Bedrock AgentCore runtime 上的单个编排器查询 AWS Agent Registry。匹配的 MCP 服务器通过 Amazon Bedrock AgentCore Gateway 调用,匹配的 A2A 智能体则在 Amazon Bedrock AgentCore runtime 上调用
示例使用的参考架构包括 AWS Agent Registry、Amazon Bedrock AgentCore Gateway、Amazon Bedrock AgentCore runtime、Amazon Bedrock、Amazon Cognito、AWS Lambda 和 AWS Secrets Manager。
AWS Agent Registry 提供受治理、可搜索的目录,供编排器查询。只有完成所配置审批流程的记录,才会通过支持发现的数据平面提供。
Amazon Bedrock AgentCore Gateway 将订单管理 Lambda 工具作为 MCP 服务器暴露出来。示例为传入 Gateway 的调用配置了 Cognito JWT 授权,并使用 Gateway 的 AWS Identity and Access Management(IAM)角色调用 Lambda 目标。
Amazon Bedrock AgentCore runtime 托管编排器,以及 Pricing 和 Customer Support 这两个 A2A 智能体。运行时调用通过经 IAM 授权的 Boto3 调用完成。
Amazon Bedrock 提供编排器和 A2A 智能体使用的基础模型(FM)。示例目前通过跨区域模型 ID 配置 Anthropic Claude Sonnet 模型。请参阅 Amazon Bedrock 中的“各 AWS 区域支持的模型”。
三个演示场景使用不同的能力组合来检验发现循环。第一个场景仅调用 MCP(查询订单状态)。第二个场景串联 MCP + A2A(定价与折扣)。第三个场景针对含义模糊的用户意图测试纯语义匹配:退货与退款,而匹配到的 A2A 智能体名称中并未出现这些词。
链接中的 runtime-discovery 示例会部署依赖项、创建 Registry 并填充记录、验证发现功能、部署编排器,然后运行三个演示。orchestrator_agent.py 包含每个请求的发现循环。utils.py 解析 Registry 描述符,并创建 MCP 和 A2A 客户端。cleanup.py 用于删除资源。
Registry 记录包含可搜索的描述,以及特定协议的描述符。示例使用 Agent Registry 控制平面客户端执行 Registry 和记录的生命周期操作,使用 Agent Registry 数据平面客户端进行运行时发现。
创建采用手动审批和 IAM 授权的 Registry。
registry_client = session.client("agent-registry-control")
dp_client = session.client("agent-registry")
reg = registry_client.create_registry(
name="OrderManagementRegistry",
description=(
"Registry for Order Management & Customer Service — "
"agent discovers tools and agents via semantic search"
),
approvalConfiguration={"autoApprovalRules": []},
)
REGISTRY_ARN = reg["registryArn"]
REGISTRY_ID = REGISTRY_ARN.split("/")[-1]
创建记录时,recordType 字段是必填项。在本示例中,MCP 服务器使用 recordType="MCP",基于 A2A 的智能体使用 recordType="AGENT"。协议元数据存储在 descriptors 对象的 mcpServer 或 a2aAgentCard 下。MCP 描述符包含服务器元数据和工具定义。A2A 描述符包含智能体卡片。这些描述符包含连接元数据,但不包含使用方调用该能力时必须提供的凭证。
按照当前公开 SDK 的描述符结构构建 MCP 和 A2A 记录。
# MCP descriptor
mcp_descriptors = {
"mcpServer": {
"data": json.dumps(server_metadata),
"dataSchemaVersion": "2025-12-11",
"additionalData": {
"tools": {
"data": json.dumps({"tools": tool_schemas}),
"dataSchemaVersion": "2025-06-18",
}
},
}
}
# A2A descriptor
a2a_descriptors = {
"a2aAgentCard": {
"data": json.dumps(agent_card),
"dataSchemaVersion": "0.3",
}
}
描述应使用面向用户的语言,明确区分该能力与其他相近记录。描述符内容提供特定协议所需的服务器、工具或智能体卡片数据。应使用有代表性的查询来评估搜索质量。本文并不假设目录规模扩大就会自动改善排序效果。
按照当前控制平面的结构创建 Registry 记录。
descriptors = (
mcp_descriptors
if cfg["protocol"] == "MCP"
else a2a_descriptors
)
response = registry_client.create_registry_record(
registryId=REGISTRY_ID,
name=name,
description=cfg["description"],
recordType=cfg["protocol"],
descriptors=descriptors,
recordVersion="1.0",
)
record_id = response["recordId"]
当 autoApproval 设置为 false 时,新记录必须从 DRAFT 转为 PENDING_APPROVAL,再转为 APPROVED。提交和状态更新操作均通过 IAM 授权,因此可以分离发布者与审批者的权限。支持发现的 Registry 数据平面只会返回已获批准的记录。
分两步完成审批状态转换。
record = registry_client.get_registry_record(
registryId=REGISTRY_ID,
recordId=record_id,
)
if record["status"] == "DRAFT":
registry_client.submit_registry_record_for_approval(
registryId=REGISTRY_ID,
recordId=record_id,
)
registry_client.update_registry_record_status(
registryId=REGISTRY_ID,
recordId=record_id,
status="APPROVED",
statusReason="Approved",
)
数据平面客户端支持对可发现记录进行关键词与语义混合搜索。最新的方法名为 search_discoverable_registry_records。结果包含标准化的记录字段和可发现能力的描述符,但不包含能力调用所需的凭证。
跨协议搜索已获批准且可发现的记录。
response = dp_client.search_discoverable_registry_records(
registryIds=[REGISTRY_ARN],
searchQuery=query,
maxResults=3,
)
records = response.get("registryRecords", [])
在示例场景中,退货退款查询会检索到 Customer Support Agent,因为它的描述涵盖了这一意图。应将其视为演示结果,而不能据此笼统地认为,只要目录规模扩大,排名效果就会改善。
编排器是一个部署在 Amazon Bedrock AgentCore runtime 上的 Strands 智能体。它提供 discover_and_execute,用于搜索 Registry、解析每个返回的描述符、创建对应的 MCP 或 A2A 客户端,并仅使用发现的这些能力构建一个请求级内部智能体。
图 3:编排器处理每个请求的流程。外层智能体将用户请求转换为 Registry 搜索。内部智能体根据搜索结果组装,并在本轮交互结束时销毁。
discover_and_execute 的核心逻辑可以放在一个代码块中:
编排器的发现、实例化与执行循环。
@tool
def discover_and_execute(request: str) -> str:
records = dp_client.search_discoverable_registry_records(
registryIds=[REGISTRY_ARN],
searchQuery=request,
maxResults=5,
).get("registryRecords", [])
# Registry returns descriptors, not invocation credentials.
oauth_token = fetch_oauth_token_from_config()
mcp_clients, a2a_tools = [], []
for record in records:
metadata = parse_server_metadata(record)
if metadata["protocol"] == "MCP":
mcp_clients.append(
create_mcp_client_from_metadata(metadata, oauth_token)
)
elif metadata["protocol"] == "A2A":
a2a_tools.append(
create_a2a_tool_from_metadata(metadata, session, REGION)
)
return run_request_scoped_agent(request, mcp_clients, a2a_tools)
model = BedrockModel(model_id=MODEL_ID, region_name=REGION)
started_clients = []
try:
mcp_tools = []
for c in mcp_clients:
c.start()
started_clients.append(c)
mcp_tools.extend(c.list_tools_sync())
##agent compiled in realtime within agent
sub_agent = Agent(
model=model,
tools=mcp_tools + a2a_tools,
system_prompt=(
"You are an Order Management & Customer Service assistant. "
"Use the RIGHT tool for each request:\\n"
"- Order lookups, status, cancellations, address changes: use MCP tools\\n"
"- Pricing, discounts, promo codes: use the pricing_agent tool\\n"
"- Returns, refunds, complaints, escalations: use the customer_support_agent tool\\n"
"Always use the most specific tool for the task."
),
)
return str(sub_agent(request))
finally:
for c in started_clients:
try:
c.stop()
except Exception:
pass
该示例通过发出多个搜索查询来提高订单管理领域的召回率,对记录去重,并在请求结束后关闭 MCP 客户端。这种查询扇出是该示例特有的编排选择,并非 Registry 的要求。身份验证仍然独立于发现流程:Gateway 的 OAuth 令牌从 Cognito 配置和 Secrets Manager 中获取,而 A2A runtime 调用则通过 boto3 会话进行签名。
每个演示都会展示发现循环的一种不同形式。
一个最终通过单次 MCP 工具调用完成的请求。
result = invoke_orchestrator(
"What is the current status and tracking info for order 123?",
agentcore_client, orchestrator_arn,
)
Registry 返回订单管理 MCP 服务器。编排器通过 Gateway 调用 get_order_status,LLM 整合生成便于人类阅读的回复,随后内部智能体终止。本轮交互不涉及 A2A。
一个最终通过跨协议调用链完成的请求。
result = invoke_orchestrator(
"Order 123 has 2x Widget Pro at $99.98. What discount tiers or "
"promo codes can reduce the price?",
agentcore_client, orchestrator_arn,
)
Registry 返回订单管理 MCP 服务器和定价 A2A 智能体:一个自然语言查询,涉及两种协议。LLM 先调用 get_order_status 获取订单明细,再调用 runtime 上的定价智能体进行折扣分析,最后整合成一条建议。
一个意图未直接出现在任何工具名称中的请求。
result = invoke_orchestrator(
"I want to return order 789 (Premium Headphones, delivered "
"March 10). Am I eligible for a return and what is the refund "
"amount?",
agentcore_client, orchestrator_arn,
)
这个演示展示了语义发现的价值。Customer Support Agent 的注册名称中并没有出现“return refund”这一短语。混合搜索之所以将其排在靠前位置,是因为它的描述涵盖了这一意图。如果没有 Registry,编排器就需要通过硬编码来确定由哪个智能体处理退货。
根据需要,使用 Amazon Bedrock AgentCore Observability 和 Amazon CloudWatch 对发现与调用路径进行监测。值得关注的信号包括 Registry 搜索的成功与失败、选中记录的标识符、客户端构建错误、下游调用结果、端到端追踪关联,以及应用程序错误。该示例授予了 Amazon CloudWatch Logs 权限,但没有创建自定义指标或仪表板。生产团队应根据自身的运维模式,定义所需的追踪、日志和告警。生产部署还应将 Amazon Bedrock Guardrails 作为智能体回复的标准管控措施。
建立发现循环后,此前与编排器发布绑定的几项能力便可以独立运作。
解耦发布。 团队可以部署和注册自己的 MCP 服务器、智能体及技能。审批策略决定已发布的记录何时可供使用方访问。
新增获批记录无需修改编排器代码。 在这种模式下,添加兼容且已获批准的 Registry 记录,无需在编排器中添加特定工具的导入语句或端点。协议、身份验证配置或编排策略的变化,仍可能需要更新代码或配置。
受治理的发现。 采用人工审批时,只有经过审核并获批的记录才会变得可发现。IAM 权限可以将记录发布者与审批者分离。
独立的身份验证。 Registry 授权可以使用 IAM 或自定义 JWT。能力调用的身份验证则独立处理:该示例为 Gateway 使用 Cognito OAuth,为 AgentCore runtime 使用 Boto3/IAM 签名。搜索结果不会返回这些凭证。
搜索目录,而非将整个目录塞入提示词。 借助 Registry 混合搜索,编排器只需检索一小组候选项,无需将整个目录放入模型上下文。搜索质量取决于描述内容、描述符质量、查询设计和评估。
并非每种工作负载都需要运行时发现。以下两种模式仍可能更适合在构建时显式配置连接关系:
规模小且稳定的目录。 如果完整的能力集合规模较小,而且很少变化,在构建时显式配置连接关系可能更简单,还能避免额外的发现请求。
固定流水线。 当同一组能力始终按固定顺序运行时,将其实现为确定性流程会更直接,也能让追踪更聚焦。
在运行时从 Registry 发现资产,可以降低编排器对固定目录的依赖。借助 AWS Agent Registry,它可以通过语义与关键词混合搜索查找已获批准的能力,解析 MCP 或 A2A 描述符,并实例化请求级客户端。治理决定哪些内容可以被发现。对于 Registry 和每项被调用的能力,身份验证仍然是需要明确处理的事项。
AWS Agent Registry 现已正式发布,其能力不止于这个单账户示例:
组织范围内的发现和跨账户共享可以通过受支持的 AWS Organizations 及共享机制,让经过治理的记录可供其他账户访问。
自动能力同步可以从 URL 获取内容并填充受支持的描述符。同步请求中的凭证提供程序配置用于获取描述符内容,不会作为调用身份验证信息返回给运行时使用方。
审批工作流可以利用 Registry 状态 API 和 IAM 权限,将 CI 检查、安全审查或人工审批接入 DRAFT → PENDING_APPROVAL → APPROVED 生命周期。
标签、AWS CloudFormation 支持和基础设施即代码模式可以让 Registry 的部署与治理流程可重复执行。评估时,应针对组织自身的目录验证搜索相关性和调用行为。
运行这个运行时发现示例,然后注册一个你自己的兼容 MCP 服务器或智能体。确认其描述符、审批状态、身份验证路径和搜索行为符合你的生产环境要求。
AWS Agent Registry 正式发布公告
AWS Agent Registry 文档
Amazon Bedrock AgentCore 控制台(Registry)
AWS Agent Registry 正式发布技术博客文章