使用 AWS Agent Registry 的运行时发现有助于解决代理演示可能掩盖的问题。硬编码的工具在少量场景下运行良好,在几十个时开始退化,超过这个数量就变得难以管理。企业系统暴露了数百个用于定价、支持、订单、库存和客户数据的内部 API。在这些系统中,模型可能花费更多的 token 来消歧工具名称,而不是对用户请求进行推理。每一项新能力都需要修改编排器代码、重新部署,并在本可以按自己节奏发布的团队之间协调发布。
这种模式可能出现在企业软件即服务(SaaS)项目中,团队向代理式消费者暴露大型内部 API 面。随着目录扩展,构建时接线可能成为瓶颈。一种方法是改变编排器访问工具的方式:代理不再将每个工具编译进代理,而是在运行时发现相关工具。
AWS Agent Registry 是一项用于编目和发现 Model Context Protocol (MCP) 服务器、代理和代理技能的托管服务。发布者注册特定于协议的描述符和可搜索的描述。在运行时,编排器可以搜索已批准、可发现的记录,并使用返回的端点和描述符内容来构建客户端。注册表搜索结果不会返回能力的调用凭据或身份验证方案。
本文介绍了重构后的 Python 示例所演示的 Discover → Instantiate → Execute 循环。该代码通过以下方式部署订单管理 MCP 服务器: Amazon Bedrock AgentCore Gateway,这是 Amazon Bedrock AgentCore 的一项功能,两个 agent-to-agent(A2A)代理在 AgentCore runtime上的代理间(A2A)代理、一个注册表和一个编排器。 示例目录 包含部署脚本、编排器、辅助模块和清理脚本。
解决方案概览:发现、实例化、执行
本示例中的编排器代理不具备任何内置的工具或代理知识。
图 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 凭据对请求进行签名。注册表发现提供的是连接元数据,而不是身份验证材料。
执行
系统构建一个仅包含动态发现的工具的临时内部代理。大语言模型(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 服务器。该示例配置了 Cognito JWT 授权用于入站 Gateway 调用,并使用 Gateway 的 AWS Identity and Access Management (IAM) 角色来调用 Lambda 目标。
- Amazon Bedrock AgentCore runtime 托管编排器以及 Pricing 和 Customer Support A2A 代理。运行时调用使用 IAM-authorized Boto3 调用。
- Amazon Bedrock 提供编排器和 A2A 代理使用的基础模型 (FM)。该示例目前通过跨区域模型 ID 配置了 Anthropic Claude Sonnet 模型。参见 Supported models by AWS Region in Amazon Bedrock.
三个演示场景以不同的能力组合来演练发现循环。第一个是仅 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"。协议元数据存储在 mcpServer 或 a2aAgentCard 位于 descriptors 对象中。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 runtime 使用 Boto3/IAM 签名。搜索结果不会返回这些凭证。
- 用目录搜索代替提示填充。借助 Registry 混合搜索,编排器检索一个小型候选集,而不是将完整目录放入模型上下文。搜索质量取决于描述、描述符质量、查询设计和评估。
何时不应使用运行时发现
并非每个工作负载都需要运行时发现。两种模式仍可能更倾向于显式的构建时连接:
- 小型且稳定的目录。如果完整的能力集很小且很少变化,显式的构建时接线可能更简单,并可避免额外的发现请求。
- 固定流水线。当相同的能力总是按固定顺序运行时,将它们实现为确定性流程更直接,并使追踪更聚焦。
结论
运行时从 Registry 发现资产使编排器不再依赖固定目录。针对 AWS Agent Registry,它可以结合语义与关键词的混合搜索来查找已批准的能力(如 2 之类的描述符支持),解析 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 正式发布技术博客文章