AWS Agent Registry 如何在运行时发现工具
Discover tools at runtime with AWS Agent Registry
AWS 介绍如何使用 AWS Agent Registry,让智能体编排器在运行时搜索获批的 MCP 服务器和 A2A 智能体,并按请求动态构建客户端与工具集。示例涵盖发现、实例化和执行流程,以及记录审批和独立获取调用凭据的方式;搜索结果提供连接元数据,不包含调用凭据。
示例拆解了运行时发现、实例化与执行的流程,并说明凭据需通过独立可信路径获取,可用于规划工具目录扩展与权限治理。
借助 AWS Agent Registry 进行运行时发现,有助于解决演示中的智能体可能掩盖的问题。硬编码工具在数量少时运行良好,达到几十个时就开始变得难以维护,超过这个数量后则会变得难以管理。企业系统会公开数百个内部 API,用于定价、支持、订单、库存和客户数据。在这些系统中,模型花在区分工具名称上的 token 可能比花在推理用户请求上的还多。每增加一项能力,都需要修改编排器代码、重新部署,并由各团队协调发布,而这些团队更希望按照各自的节奏交付。
这种模式可能出现在各种企业软件即服务(SaaS)项目中:团队向智能体使用方开放大量内部 API。随着目录不断扩展,构建时接线可能会成为瓶颈。一种方法是改变编排器访问工具的方式:不再将每个工具都编译进智能体,而是让智能体在运行时发现相关工具。
AWS Agent Registry 是一项托管服务,用于编目和发现模型上下文协议(MCP)服务器、智能体和智能体技能。发布者可以注册特定于协议的描述符和可搜索的描述。运行时,编排器可以搜索已批准且可发现的记录,并使用返回的端点和描述符内容构建客户端。Registry 搜索结果不会返回能力调用凭证或身份验证方案。
本文将介绍重构后的 Python 示例所演示的“发现 → 实例化 → 执行”循环。该代码通过 Amazon Bedrock AgentCore Gateway(Amazon Bedrock AgentCore 的一项功能)部署订单管理 MCP 服务器、两个运行于 AgentCore runtime 上的智能体间(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 运行时上运行,并查询 AWS Agent Registry。匹配的 MCP 服务器通过 Amazon Bedrock AgentCore Gateway 调用,匹配的 A2A 代理则在 Amazon Bedrock AgentCore 运行时上调用。
该示例采用的参考架构包括 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 身份与访问管理(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 代理名称中。
技术实现
链接的运行时发现示例会部署依赖项、创建并填充 Registry、验证发现功能、部署协调器并运行三个演示。orchestrator_agent.py 包含每次请求的发现循环。utils.py 用于解析 Registry 描述符并创建 MCP 和 A2A 客户端。cleanup.py 用于移除资源。
1. 注册模型
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 描述符包含代理卡片。这些描述符包含连接元数据,但不包含消费者调用该能力时必须提供的凭证。
为 MCP 和 A2A 记录构建符合当前公共 SDK 形状的描述符。
# 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"]2. 审批工作流
当 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",
)3. 发现层
数据平面客户端支持对可发现记录进行关键词与语义混合搜索。最新的方法名称为 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,因为其描述涵盖了这一意图。请将此视为演示结果,而非“目录越大,排名就越好”的普遍结论。
4. 编排器
编排器是一个 Strands agent,部署在 Amazon Bedrock AgentCore runtime 上。它公开 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 运行时调用则通过 boto3 会话签名。
5. 运行三个演示
每个演示都展示了不同形式的发现流程。
演示 1:订单状态(仅 MCP)
一个最终解析为单次 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。
演示 2:定价与折扣(MCP + 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 获取订单项,然后在运行时调用定价智能体进行折扣分析,最后综合生成一条建议。
演示 3:退货与退款(语义匹配)
一个意图并未在任何工具名称中原样出现的请求。
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,
)此演示展示了语义发现的价值。“return refund”这一短语并未出现在 Customer Support Agent 的注册名称中。由于其描述涵盖了这一意图,混合搜索将它排在了较高位置。如果没有 Registry,编排器就需要硬编码哪些代理负责处理退货。
6. 可观测性
在适当情况下,使用 Amazon Bedrock AgentCore Observability 和 Amazon CloudWatch 为发现和调用路径添加监控。实用的信号包括 Registry 搜索成功与失败、所选记录标识符、客户端构建错误、下游调用结果、端到端跟踪关联以及应用程序错误。此示例授予了 Amazon CloudWatch Logs 权限,但不会创建自定义指标或控制面板。生产团队应根据其运营模式定义所需的跟踪、日志和警报。生产部署还应将 Amazon Bedrock Guardrails 作为代理响应的标准控制措施。
受治理的运行时发现为团队带来的优势
建立发现循环后,此前与编排器发布周期耦合的多项能力便可独立运作。
- 解耦发布。各团队可以部署并注册自己的 MCP 服务器、代理和技能。审批策略决定已发布记录何时可供使用者访问。
- 新获批的记录无需修改编排器代码。在此模式中,添加兼容且已获批准的 Registry 记录,无需在编排器中添加针对特定工具的导入项或端点。协议、身份验证设置或编排策略的变更仍可能需要更新代码或配置。
- 受治理的发现。采用手动审批时,只有经过审核并获批的记录才可被发现。IAM 权限可用于区分记录发布者和审批者。
- 身份验证分离。Registry 授权可以使用 IAM 或自定义 JWT。能力调用的身份验证则单独处理:此示例对 Gateway 使用 Cognito OAuth,对 AgentCore 运行时使用 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 正式发布技术博客文章
作者简介
Vibhu Pareek
Vibhu 是 AWS 的高级解决方案架构师。自 2016 年以来,他一直通过架构良好、可重复的模式指导客户采用云技术。凭借在数据库、数据分析和 AI 方面的专长,他热衷于将复杂挑战转化为创新解决方案。工作之余,他喜欢短途徒步,以及羽毛球、足球和游泳等运动。
Shubham Gupta
Shubham 是 AWS 的解决方案架构师,常驻印度班加罗尔,为独立软件供应商(ISV)提供支持。他与工程和领导团队合作,帮助他们在 AWS 上设计、构建和运行产品,从初期架构到投入生产,并深度专注于生成式 AI 和大规模韧性。工作之余,Shubham 是一位徒步爱好者,他将徒步时的同等准备和坚持精神投入到构建经久耐用的系统中。
来源:AWS Machine Learning Blog · aws.amazon.com


