使用 Amazon Nova Sonic 构建可扩展语音代理:多代理、工具与会话分段

TL;DR · AI 摘要
AWS 提出基于 Amazon Nova Sonic、Bedrock AgentCore 和 Strands BidiAgent 的三种语音代理架构模式——直接工具调用、子代理即工具、会话分段——可将端到端延迟控制在 500ms 以内,并解决多代理协调与实时音频流管理的工程难题。
核心要点
- AgentCore Gateway 支持 MCP 协议,让 Nova Sonic 直接调用工具,消除中间推理层以降低延迟
- 子代理即工具模式通过 AgentCore Runtime 的微 VM 隔离实现权限与内存边界分离,避免噪声邻居问题
- 会话分段策略按业务阶段拆分代理生命周期,配合持久化内存实现跨会话状态继承
结构提纲
按章节快速跳转。
组织在构建实时语音体验时面临高延迟、多代理协调和实时音频管理三大核心工程难题。
Amazon Nova Sonic 提供端到端语音对话能力,Bedrock AgentCore Runtime 提供无服务器托管与双向 WebSocket 流,Strands BidiAgent 简化流生命周期管理。
Nova Sonic 通过 MCP 协议直接调用工具,无需中间推理层,实现最低延迟的工具集成。
将复杂任务委托给专用子代理,通过微 VM 级隔离确保会话边界安全,避免单点故障扩散。
按业务阶段拆分代理会话,隔离提示词、内存和权限,支持跨会话持久化状态继承。
三种模式在延迟、复杂度和隔离性之间存在权衡,需根据场景组合使用以优化响应速度与可靠性。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- 可扩展语音代理架构
- 核心组件
- Nova Sonic:端到端语音模型
- AgentCore Runtime:无服务器托管+双向流
- Strands BidiAgent:流生命周期管理
- 三大架构模式
- 直接工具调用:MCP 协议,零中间层
- 子代理即工具:微 VM 隔离,权限分离
- 会话分段:阶段拆分,状态持久化
- 关键优化目标
- 延迟:目标 <500ms
- 隔离性:微 VM 级会话边界
- 可维护性:模块化组件复用
金句 / Highlights
值得收藏与分享的关键句。
AgentCore Runtime 提供微 VM 级会话隔离,避免噪声邻居导致的延迟尖峰。
模型与工具之间不存在中间推理层。
现代语音系统越来越多地由工具驱动型代理、作为工具的子代理以及隔离提示词、内存和权限的会话分段策略组成。
可扩展语音代理的设计模式,对于需要快速、自然且可靠语音体验的组织至关重要。许多团队面临高延迟、实时音频管理以及在复杂工作流中协调多个代理等挑战。
本文将介绍如何使用 Amazon Nova Sonic、Amazon Bedrock AgentCore 和 Strands BidiAgent 构建可扩展、可维护的语音代理,高效应对这些挑战,从而带来更灵敏、更智能的客户交互。
我们将探讨三种流行的语音代理架构模式,重点说明其权衡与最小化延迟的最佳实践。
构建模块
在深入架构模式之前,先快速回顾本文示例解决方案中使用的三大关键组件。

Amazon Nova Sonic 是一款基础模型,可为生成式 AI 应用打造自然、类人语音到语音的对话。用户可通过语音实时与 AI 交互,具备理解语调、自然对话流并执行操作的能力。
Amazon Bedrock AgentCore Runtime 是 AI 代理的无服务器托管环境。您将代理打包为容器并部署到 AgentCore Runtime,它会负责扩缩容、会话隔离和计费。对于语音代理,它提供 双向 WebSocket 流 并支持 SigV4 认证、微虚拟机级会话隔离以避免“邻居噪音”延迟峰值、AgentCore Gateway 通过开源 Model Context Protocol (MCP) 实现共享工具托管、跨会话持久化记忆,以及针对语音的指标遥测(如首音频时间)。
Strands Agents 是构建 AI 代理的开源框架。其 BidiAgent 类是 Nova Sonic 与您的应用之间的集成选项之一。它管理双向流生命周期、路由工具调用并处理会话管理,通过模型 SDK 接口简化语音代理应用的开发。
三种集成模式:工具、代理即工具(子代理)和会话分段
现代语音系统不再构建一个“万能”代理,而是越来越多地采用 工具驱动代理、作为工具的子代理 以及 会话分段策略,将提示、记忆和权限隔离。这些模式让团队能够把大型助手拆分为更小、更专业且可复用的组件,同时保持清晰的安全边界。
在运行后续示例之前,请安装 Python 及所需依赖(包括 strands-agents 和 boto3),并确保 IAM 配置具备所需服务的权限。完整示例请参考 GitHub 仓库。
模式 1:AgentCore Gateway – 低延迟的工具选择
工具调用是指语音代理将输入发送到外部函数或服务,由其处理并返回输出。它让代理无需额外推理步骤即可快速、安全地执行任务,如查询数据库或触发服务。
借助 AgentCore Gateway,您可以将现有业务逻辑暴露为 工具——Nova Sonic 在对话期间可直接调用的离散函数。语音模型选择要调用的工具、传递参数、获取结果并朗读出来,模型与工具之间没有中间推理层。

AgentCore Gateway 将 MCP 服务器托管为托管端点。MCP 是协议,AgentCore Gateway 是 AWS 运行它们的特性。语音代理通过 Gateway ARN 连接。
# Nova Sonic calls tools directly via AgentCore Gateway
model = BidiNovaSonicModel(
model_id="amazon.nova-2-sonic-v1:0",
mcp_gateway_arn=[
"arn:aws:bedrock-agentcore:us-east-1:123456789012:gateway/auth-tools",
"arn:aws:bedrock-agentcore:us-east-1:123456789012:gateway/banking-tools",
"arn:aws:bedrock-agentcore:us-east-1:123456789012:gateway/mortgage-tools",
],
)代码
当用户说“我的账户余额是多少?”时,Nova Sonic:
- 从语音中理解意图。
- 从可用 MCP 工具中选择
get_account_balance。 - 以正确参数调用该工具。
- 朗读结果。
权衡:Nova Sonic 会做出所有决策。如果某个工具调用需要多步验证、条件逻辑或串联多个操作,那么所有推理负担都会落在语音模型的系统提示上。对于简单工具,这没问题;对于复杂工作流,则容易变得脆弱。
模式 2:子代理——通过解耦代理实现额外推理
在子代理(或称代理即工具)模式中,你现有的业务逻辑运行在自治代理中,每个代理都有自己的模型、系统提示、工具和推理能力。语音编排器将整项任务委派给这些子代理,而不是调用单个工具。
从语音代理连接到子代理有多种方式,Agent-to-Agent(A2A)和 Strands 的 Agent-as-Tool 是两种常见做法:
- 本地 agent-as-tool:子代理在进程内运行,使用 Agents as Tools 模式 在 Strands 中被包装成
@tool函数。这是最直接的方式,没有网络跳点,也无需单独部署。代价是子代理与编排器共享同一进程,并随其一起扩展。 - 通过 A2A 协议的远程代理:子代理作为独立的 AgentCore Runtime 上的 A2A 服务器(或远程服务器)部署,并通过网络调用。A2A 是一种开放的代理间通信协议。正如 MCP 将代理连接到工具,A2A 将代理连接到其他代理。正如 AWS 博客 AgentCore Runtime 中的 A2A 协议支持 所述,使用不同框架(Strands、OpenAI、LangGraph、Google ADK)构建的代理可以用通用格式共享上下文和推理,从而实现完全独立的部署和跨框架互操作性。
跨框架互操作性。

Strands Agents 内建支持两种协议:MCP 用于工具访问,A2A 用于代理间通信。动手实践可参考社区指南 Agent Collaboration: Strands Agents, MCP, and the Agent2Agent Protocol。
以下是本地 agent-as-tool 方式,每个子代理都是一个 @tool,包装了一个完整的 Strands Agent:
# sub_agents.py — 使用 Agents-as-Tools 模式将子代理定义为 Strands 工具
from strands import Agent, tool
from strands.models import BedrockModel
# 每个子代理都是一个完整的 Strands Agent,被包装成 @tool
# BidiAgent 编排器通过 Nova Sonic 的工具调用使用它们
@tool
def authenticate_customer(account_id: str, date_of_birth: str) -> str:
"""使用账户 ID 和出生日期验证客户身份。
处理完整的验证流程,包括身份检查和重试逻辑。
返回验证状态和令牌。"""
auth_agent = Agent(
model=BedrockModel(model_id="amazon.nova-lite-v1:0"),
system_prompt="""你是身份验证代理。使用提供的账户 ID 和出生日期验证客户身份。
调用 verify_identity 检查凭据。用 1-2 句话返回清晰的验证状态。""",
tools=[verify_identity, check_account_exists], # 子代理自己的工具
)
result = auth_agent(f"验证账户 {account_id},出生日期:{date_of_birth}")
return str(result)
@tool
def handle_banking_inquiry(query: str, auth_token: str) -> str:
"""处理银行业务查询——余额、交易、转账。
验证权限并以对话方式总结结果。"""
banking_agent = Agent(
model=BedrockModel(model_id="amazon.nova-lite-v1:0"),
system_prompt="""你是银行业务代理。使用提供的工具回答客户查询。
用 2-3 句自然语言总结结果。不要返回原始 JSON。""",
tools=[get_account_balance, get_recent_transactions, transfer_funds],
)
result = banking_agent(query)
return str(result)
@tool
def handle_mortgage_inquiry(query: str) -> str:
"""处理抵押贷款查询——利率、计算、资格、申请状态。
自行进行计算和推理。"""
mortgage_agent = Agent(
model=BedrockModel(model_id="amazon.nova-lite-v1:0"),
system_prompt="""你是抵押贷款专家。帮助查询利率、付款计算和资格评估。
回答要简洁、对话式——将被朗读出来。""",
tools=[get_mortgage_rates, calculate_payment, check_eligibility],
)
result = mortgage_agent(query)
return str(result)代码
语音编排器随后使用 BidiAgent 并调用这些子代理工具:
# voice_orchestrator.py — 使用子代理作为工具的 BidiAgent
from strands.experimental.bidi.agent import BidiAgent
from strands.experimental.bidi.models.nova_sonic import BidiNovaSonicModel
from sub_agents import authenticate_customer, handle_banking_inquiry, handle_mortgage_inquiry
model = BidiNovaSonicModel(
region="us-east-1",
model_id="amazon.nova-2-sonic-v1:0",
provider_config={"audio": {"voice": "tiffany", "input_sample_rate": 16000, "output_sample_rate": 16000}},
)
agent = BidiAgent(
model=model,
tools=[authenticate_customer, handle_banking_inquiry, handle_mortgage_inquiry],
system_prompt="""You are a banking voice assistant. Route customer requests to the
appropriate specialist. Always authenticate before accessing account data.
Keep your own responses brief — the sub-agents handle the details.""",
)
await agent.run(inputs=[ws_input], outputs=[ws_output])代码
子代理自己完成思考。Nova Sonic 无需编排每一步,只需委派并播报结果。
权衡: 每次调用子代理都会增加延迟:子代理自身的模型推理加上其工具调用。在语音对话中,这意味着子代理推理时会出现更长的静默。AWS 关于多代理语音助手的博客建议,先用 Amazon Nova 2 Lite 等更小、更高效的模型作为子代理,在仍能高效处理专业任务的前提下降低延迟。
Amazon Nova 2 Sonic 支持异步工具调用,因此工具在后台运行时可保持对话自然进行。它能持续接收输入、并行运行多个工具,并在用户中途变更请求时优雅适应,最终只聚焦仍相关的结果。
模式 3:会话分段实现超低延迟
第三种值得考虑的方法并不完全对应 MCP 或子代理模式,而是专为语音场景设计,把延迟放在首位。
与其委派外部工具或子代理,你将对话拆分为逻辑阶段,每个阶段拥有独立的 Nova Sonic 会话、系统提示和工具集。当对话从一个阶段过渡到下一阶段(例如从身份验证到账户查询)时,你关闭当前会话,并在同一 WebSocket 连接内开启新的会话,附带不同的提示和工具。每个子语音代理可以使用自己的 MCP 网关、工具,甚至子代理——区别在于它以聚焦的提示和最小化的工具面运行,从而降低推理开销和延迟。

设想一个银行语音助手有三个对话阶段:身份验证、账户管理、房贷咨询。与其加载一个包含所有工具的庞大系统提示,不如把每个阶段作为专注的 Nova Sonic 会话运行:
# 阶段 1:身份验证
auth_session = BidiNovaSonicModel(
model_id="amazon.nova-2-sonic-v1:0",
mcp_gateway_arn=["arn:...gateway/auth-tools"], # 仅身份验证工具
)
auth_agent = BidiAgent(
model=auth_session,
tools=[],
system_prompt="""你是身份验证助手。
收集用户的账户 ID 和出生日期。
调用 verify_identity 完成验证。
验证通过后说“您已准备就绪”并结束。""",
)
# 运行直至身份验证完成
await auth_agent.run(inputs=[ws_input], outputs=[ws_output])
# 阶段 2:账户管理(新会话、新提示、新工具)
banking_session = BidiNovaSonicModel(
model_id="amazon.nova-2-sonic-v1:0",
mcp_gateway_arn=["arn:...gateway/banking-tools"], # 仅银行工具
)
banking_agent = BidiAgent(
model=banking_session,
tools=[],
system_prompt="""你是银行助手。用户已通过身份验证。
协助查询余额、交易和转账。
回答保持一两句话。""",
)
await banking_agent.run(inputs=[ws_input], outputs=[ws_output])代码
每个阶段都获得一个干净的 Nova Sonic 会话,具备:
- 聚焦的系统提示:更短、更具体,减少模型困惑空间。
- 仅相关工具:通过 MCP 网关、本地工具或两者结合。模型无需在 15 个工具中挑选,只需关注 3 个。
- 可选的子代理:需要深度推理的阶段可在内部使用模式 2,而简单阶段仅保留工具。
- 前一阶段的会话上下文可作为聊天记录传入新会话,确保整体对话连贯。
工具、子代理和会话分段模式对比
因素|工具|子代理(代理即工具)|会话分段 延迟 | 低 | 较高(子代理推理) | 最低(会话切换时产生延迟) 每轮工具集 | 加载的工具 | 子代理的工具 | 仅阶段相关工具 系统提示 | 一条大提示 | 编排器 + 子代理提示 | 小型、阶段特定提示 推理深度 | 仅语音模型 | 语音模型 + 子代理 | 每阶段仅语音模型 复用现有代理 | 高(同一 MCP 工具) | 最高(同一子代理) | 中等(每阶段组合工具/子代理) 对话连贯性 | 无缝 | 无缝 | 阶段间需交接逻辑
语音代理延迟最佳实践
构建语音代理时,延迟比文本代理更为关键。以下实用技巧可保持快速响应:
子代理先用小模型。 语音编排器使用 Nova Sonic 进行对话,但子代理无需大模型。先用 Amazon Nova 2 Lite 或 Nova 2 Micro,它们快速、成本低,且能胜任大多数专业任务。若质量需要,可再升级特定子代理至更大模型,但默认选小模型。
为有状态的子代理设计缓存。 每次调用都访问数据库或 API 的无状态子代理会每次都增加延迟。相反,应设计子代理在会话内缓存来自数据源(API、AWS Lambda 函数、数据库)的结果。如果银行子代理已经获取过一次账户详情,就应该将该数据保存在内存中,后续关于余额、交易、摘要的问题都从缓存中返回,而不是反复调用后端。
在身份验证后预取数据。 这对联络中心场景尤其有价值。客户完成身份验证后,你已经知道他们是谁。不要等到他们提问才开始拉取数据。立即在后台获取账户余额、近期交易、待处理提醒和房贷状态。当客户问“我的余额是多少?”时,答案已经在内存里。
并行化独立的工具调用。 如果用户问“给我账户概览”,不要依次调用 get_checking_balance、get_savings_balance、get_credit_card_balance。使用并发执行,让三个调用同时进行。Strands 原生支持这一点。代理的工具执行器默认并行运行独立调用。
使用填充语掩盖工具延迟。 当工具调用或子代理委托不可避免时,指示语音模型在等待时说一句简短的填充语:“让我为您查一下……”或“稍等,我正在查找……”这样对话就不会陷入沉默,而是保持活跃。
最小化每会话的工具数量。 随着可用工具数量增加,工具选择会变慢。如果你的代理有 15 个工具,但典型对话只用到 3 到 4 个,考虑使用会话分段模式,在每个阶段只加载相关工具。
清理
完成示例测试后,记得清理你创建的资源以避免不必要的费用。按照仓库说明停止服务并删除任何已部署的基础设施。
结论
将文本聊天机器人迁移到语音助手并不是简单的封装工作。交互模型在响应设计、延迟预算到轮流发言行为上都完全不同。但借助结构良好的多代理架构和 Amazon Bedrock AgentCore,业务逻辑层保持不变。
你已经构建的子代理是最大的资产。复用它们。
关于在 AgentCore Runtime 上部署 Strands BidiAgent 语音助手并使用 WebSocket 流式传输的完整示例,请参见 AgentCore 双向流式示例。
后续步骤
接下来,你可以扩展示例以适应自己的用例,集成业务工具,优化语音交互提示,并在真实场景中测试代理,为生产部署做准备。要了解更多关于 AWS 语音代理的信息,请访问:
- Amazon Nova 2 Sonic 服务卡片
- Amazon Bedrock AgentCore Runtime 双向流式传输
- Strands BidiAgent
- Amazon Bedrock AgentCore 双向流式示例代码
- * *