人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载本篇技术指南以 TEN Framework 仓库中的 IMPLEMENTATION.md 为骨架深入剖析nvidia_riva_tts_python扩展的完整实现从类层次、配置模型、gRPC 流式合成调用链到错误处理、测试策略与部署方式。读完本文你将掌握如何将一个 GPU 加速的 NVIDIA Riva TTS 服务以标准 TTS 接口无缝接入 TEN 对话式 AI Agent 图并理解其底层消息流与可观测性设计。扩展概览与组件结构nvidia_riva_tts_python是 TEN Framework 中基于NVIDIA Riva Speech Skills的文本转语音TTS扩展提供高质量、GPU 加速的语音合成能力。它位于仓库 ai_agents/agents/ten_packages/extension/nvidia_riva_tts_python/ 目录下版本号为0.1.1依赖ten_runtime_python0.11与ten_ai_base0.7两个系统包见 manifest.json。扩展的代码结构如下nvidia_riva_tts_python/ ├── extension.py # 主扩展类 NvidiaRivaTTSExtension ├── riva_tts.py # Riva 客户端 NvidiaRivaTTSClient 实现 ├── config.py # 配置模型 NvidiaRivaTTSConfig ├── addon.py # 扩展注册Addon ├── manifest.json # 扩展元数据与接口声明 ├── property.json # 默认属性参数模板 ├── requirements.txt # Python 依赖 ├── pyproject.toml # 打包元数据与依赖声明 ├── README.md # 用户文档 └── tests/ # 测试套件 ├── test_config.py ├── test_extension.py └── test_compliance.py从代码职责划分看四个核心 Python 文件各司其职extension.py定义NvidiaRivaTTSExtension负责生命周期管理、配置加载、请求调度与 TEN 消息收发riva_tts.py定义NvidiaRivaTTSClient封装与 Riva 服务器的 gRPC 通信与流式合成config.py定义NvidiaRivaTTSConfig基于 Pydantic承担参数校验addon.py通过register_addon_as_extension装饰器把扩展注册进 TEN 运行时。类层次与核心职责IMPLEMENTATION.md 中给出的类层次在源码中完全得到印证AsyncTTS2BaseExtension来自 ten_ai_base 的 TTS 基类 └── NvidiaRivaTTSExtension └── 使用 NvidiaRivaTTSClient └── 使用 riva.client.SpeechSynthesisService值得注意的是当前实现继承的是ten_ai_base.tts2中的AsyncTTS2BaseExtension见 extension.py而非旧版AsyncTTSExtension。基类已经提供了send_tts_audio_start、send_tts_audio_data、send_tts_audio_end、send_tts_ttfb_metrics、send_tts_error、finish_request等标准 TTS 消息发送能力扩展只需聚焦于合成本身。NvidiaRivaTTSExtensionextension.pyNvidiaRivaTTSExtension的核心职责包括生命周期管理on_init/on_stop/on_deinit三个异步钩子。其中on_init通过ten_env.get_property_to_json()读取全部属性用NvidiaRivaTTSConfig.model_validate_json()解析配置并实例化NvidiaRivaTTSClient任何异常都会通过send_tts_error上报为ModuleErrorCode.FATAL_ERROR同时附带vendor_info{vendor: nvidia_riva}便于上层定位问题来源音频规格描述synthesize_audio_sample_rate()返回配置的采样率默认 16000 Hzsynthesize_audio_channels()固定返回 1单声道synthesize_audio_sample_width()固定返回 216-bit PCMTTS 请求处理request_tts()接收TTSTextInput驱动整个合成与音频下发流程详见下文合成流程取消支持cancel_tts()记录flush_request_id并调用客户端的cancel()指标统计内部维护request_start_ts、first_chunk_ts、request_total_audio_duration等字段用于计算 TTFB首包时间与整段音频时长随消息上报。vendor()方法返回nvidia_riva作为供应商标识与错误上报中的vendor_info保持一致。NvidiaRivaTTSClientriva_tts.pyNvidiaRivaTTSClient是扩展与 Riva 服务器之间的桥梁仅依赖riva.client与numpy两个外部库。其初始化流程为从配置中读取serverhost:port与use_ssl构造riva.client.Auth(use_ssluse_ssl, uriserver)完成鉴权与连接管理基于 Auth 对象初始化riva.client.SpeechSynthesisService初始化失败时抛出带详细信息的RuntimeError源码 riva_tts.py。Addon 注册addon.pyaddon.py 非常简洁通过register_addon_as_extension(nvidia_riva_tts_python)注册 Addon并在on_create_instance回调中延迟导入NvidiaRivaTTSExtension、创建实例后调用on_create_instance_done交还运行时。这种注册名 包名的约定与 TEN Framework 其他 TTS 扩展如 azure、elevenlabs 等保持一致便于 tman 等工具按名称解析。配置模型与参数详解配置模型NvidiaRivaTTSConfig继承自 PydanticBaseModel除params字典外还包含两个调试字段dump默认false是否开启音频转储dump_path转储文件路径默认指向包目录下的nvidia_riva_tts_in.pcm。真正控制行为的全部参数都放在params字典中validate()方法强制校验三个必填项缺失时抛出带明确提示的ValueError源码 config.py。参数表对应 manifest.json 的 API 声明manifest.json 中通过api.property.properties.params声明了参数的类型契约property.json 提供了带环境变量插值的默认值参数必填类型默认值说明server是stringlocalhost:50051支持${env:NVIDIA_RIVA_SERVER|...}插值Riva 服务器地址格式host:portlanguage_code是stringen-US语言标识如en-US、es-ESvoice_name是stringEnglish-US.Female-1Riva 声学模型/音色标识sample_rate否int6416000输出音频采样率Hzuse_ssl否boolfalse是否对 gRPC 连接启用 SSLproperty.json中server使用了${env:NVIDIA_RIVA_SERVER|localhost:50051}语法意味着部署时可通过环境变量NVIDIA_RIVA_SERVER覆盖服务器地址未设置时回退到localhost:50051。校验逻辑validate()依次检查server缺失或为空 →ValueError(Server address is required for NVIDIA Riva TTS)language_code缺失或为空 →ValueError(Language code is required for NVIDIA Riva TTS)voice_name缺失或为空 →ValueError(Voice name is required for NVIDIA Riva TTS)。测试用例 test_config.py 逐一验证了这三种失败路径并验证sample_rate与use_ssl的默认回退值test_compliance.py 中的test_supported_sample_rates还确认 8000、16000、22050、24000、44100、48000 等常见采样率均可通过校验。完整配置示例{ params: { server: riva-server.example.com:50051, language_code: en-US, voice_name: English-US.Female-1, sample_rate: 22050, use_ssl: true } }常见可用音色具体以 Riva 服务器为准包括English-US.Female-1、English-US.Male-1、English-GB.Female-1、Spanish-US.Female-1等。在 graph 中引用该扩展时将其作为nvidia_riva_tts_python节点并把上述params写入该节点的属性即可。合成流程从文本到 PCM 音频的消息链路IMPLEMENTATION.md 将消息流概括为五步文本输入 → 加载配置 → 流式合成 → PCM 音频输出 → 结束信号。结合源码可以还原更完整的调用链。扩展侧request_tts 驱动流程request_tts()源码 extension.py的逻辑如下幂等去重若request_id等于flush_request_id已被取消或last_end_request_id已结束直接忽略避免重复合成新请求识别current_request_id变化时重置request_total_audio_duration并记录request_start_ts流式消费async for chunk in self.client.synthesize(t.text, t.request_id)逐个消费音频块用_calculate_audio_duration()把字节数换算为毫秒时长公式bytes / (sample_rate × channels × sample_width) × 1000见 extension.py首个音频块到达时发送tts_audio_start消息并对新请求计算并上报TTFB 指标send_tts_ttfb_metrics附带voice_name与language_code作为extra_metadata若该请求已被标记为 flush立即终止循环否则累加音频时长并逐块发送tts_audio_data结束处理当收到text_input_end或触发 flush 时调用_handle_completed_request()发送tts_audio_end携带request_event_interval_ms与request_total_audio_duration_ms指标随后finish_request()收尾并重置状态。被中断的请求以TTSAudioEndReason.INTERRUPTED结束正常结束为REQUEST_END异常路径为ERROR异常兜底任何异常都会记录完整 traceback并通过send_tts_error上报NON_FATAL_ERROR若此时已收到text_input_end且请求处于FINALIZING状态则仍按ERROR原因完成请求保证消息序列完整。客户端侧synthesize 流式合成NvidiaRivaTTSClient.synthesize()源码 riva_tts.py是真正的 Riva 调用点async def synthesize(self, text: str, request_id: str) - AsyncIterator[bytes]:其内部流程为重置_is_cancelled标志服务未初始化时抛出RuntimeError空文本text.strip()为空时仅记录 WARN 日志并直接返回不产出任何音频读取language_code、voice_name、sample_rate后调用流式接口responses self.tts_service.synthesize_online( text, voice_namevoice_name, language_codelanguage_code, sample_rate_hzsample_rate, encodingriva.client.AudioEncoding.LINEAR_PCM, )遍历返回的流式响应每轮先检查取消标志被取消则提前中断再将response.audio通过np.frombuffer(..., dtypenp.int16)转为 int16 数组、再tobytes()还原为字节串后yield出去。这一步虽然看似冗余实则保证了输出严格符合 16-bit 小端 PCM 字节序异常统一包装为RuntimeError(NVIDIA Riva TTS synthesis failed: ...)向上抛出并记录 ERROR 日志。完整消息流1. Text Input → TEN data 消息携带 TTSTextInputtext、request_id、text_input_end 2. Configuration → on_init 阶段从 property.json 加载 voice/language/sample_rate 3. Synthesis → synthesize_online 流式调用 Riva gRPC 接口 4. Audio Output → tts_audio_start → N × tts_audio_dataPCM 字节块 5. Completion → tts_audio_end含 TTFB 与总时长指标→ finish_requestNVIDIA Riva 集成gRPC 与音频格式扩展直接使用官方nvidia-riva-clientPython 包版本锁定为2.25.0见 requirements.txt 与 pyproject.toml依赖关系如下riva.client.Auth负责 gRPC 通道的鉴权与连接管理use_ssl与uri直接透传riva.client.SpeechSynthesisServiceTTS API 封装提供在线流式与离线两种合成方法riva.client.AudioEncoding音频编码枚举本扩展固定使用LINEAR_PCM。Streaming vs Batch实现选择流式合成synthesize_online作为默认路径理由在 IMPLEMENTATION.md 中明确给出更低延迟首个音频块更快到达TTFB 显著缩短实时应用体验更好语音边生成边下发无需等待整段合成完毕内存占用更省无需在内存中缓冲整段音频。批处理模式synthesize在 Riva 客户端中同样可用但本扩展默认不使用——从源码看synthesize_online是唯一被调用的合成入口。音频格式约定编码LINEAR_PCM16-bit 有符号整数采样率可配置默认 16000 Hz扩展侧synthesize_audio_sample_rate()与客户端侧sample_rate_hz保持一致声道数单声道mono字节序小端little-endiannumpy的 int16 转换保证了这一点。这些约定不仅写在文档中也被 test_compliance.py 的test_audio_encoding_linear_pcm、test_audio_format_int16等用例以 mock 方式逐一验证。错误处理与日志策略初始化阶段错误服务器不可达 / 连接失败 → 抛出带连接信息的RuntimeErrorError when initializing NVIDIA Riva TTS: ...在on_init中被捕获并上报FATAL_ERROR鉴权失败 → 由 Riva Auth 抛出的异常同样被包装为RuntimeError依赖缺失 → 模块导入阶段的ImportError。运行阶段错误空文本 → WARN 日志 直接返回不合成、不下发音频合成失败 →RuntimeError携带 Riva 原始错误信息扩展侧上报NON_FATAL_ERROR取消 →_is_cancelled标志触发流中断以INTERRUPTED原因干净收尾并记录日志。日志分级源码中均有对应调用级别场景INFO客户端初始化含 server/SSL 信息、TTS 请求到达文本长度、request_id、取消请求DEBUG合成进度、每个音频块的样本数、取消检测、请求完成WARN空文本输入ERROR初始化失败、合成异常含 traceback、on_init 失败值得一提的设计是所有 Riva 相关日志都带有categoryLOG_CATEGORY_VENDOR而关键路径日志如配置加载带有categoryLOG_CATEGORY_KEY_POINT便于上层日志系统按类别过滤与聚合这是 TEN Framework 面向可观测性的通用约定。测试体系与验证方式扩展自带三个测试文件构成三层验证test_config.py配置模型层。验证合法配置通过校验、三个必填参数缺失时分别抛出对应ValueError、默认值dumpFalse、dump_path含nvidia_riva_tts_in.pcm、sample_rate16000、use_sslFalsetest_extension.py扩展层。验证扩展可初始化、vendor() nvidia_riva、从 JSON 创建配置、采样率获取以及客户端初始化mock Auth 与 SpeechSynthesisService、取消标志、空文本返回空流、正常文本产出字节块test_compliance.pyRiva API 合规层。用 mock 精确断言synthesize_online的调用参数voice_name、language_code、sample_rate_hz、encodingLINEAR_PCM、SpeechSynthesisService以 Auth 实例初始化、SSL 配置透传、int16 音频格式、多块流式响应迭代、空/纯空白文本、以及流中途取消时提前停止。运行测试# 安装测试依赖 pip install pytest pytest-asyncio # 从仓库根目录运行全部测试 pytest ai_agents/agents/ten_packages/extension/nvidia_riva_tts_python/tests/ -v # 带覆盖率统计运行 pytest ai_agents/agents/ten_packages/extension/nvidia_riva_tts_python/tests/ \ --covnvidia_riva_tts_python由于所有 Riva 调用均通过 mock 隔离测试无需真实 Riva 服务器即可执行适合作为 CI 回归用例。部署与实践建议前置条件运行中的 NVIDIA Riva 服务器可通过 NGC 拉取riva_quickstart镜像后执行riva_init.sh/riva_start.sh快速启动应用与 Riva 服务器之间网络可达Python 3.10pyproject.toml声明requires-python 3.10并安装nvidia-riva-client2.25.0与numpy1.21.0。环境变量export NVIDIA_RIVA_SERVERlocalhost:50051该变量会被property.json的${env:NVIDIA_RIVA_SERVER|localhost:50051}语法自动读取作为server参数的默认来源。性能与资源使用参考延迟IMPLEMENTATION.md 给出的参考首包延迟约为 100–200ms实际取决于文本长度与服务器负载、网络距离不同部署环境差异较大应以实测为准流式模式保证音频持续送达资源流式合成下内存占用极小CPU 占用低合成在 Riva 服务器端完成GPU 加速网络侧仅需一条到 Riva 的 gRPC 长连接优化建议实时场景坚持流式模式将 Riva 服务器部署在靠近应用的位置以降低网络延迟客户端连接由扩展统一管理复用避免反复握手按使用场景选择合适采样率如语音通话常用 16000 Hz音乐/高品质场景可用 22050–48000 Hz。未来增强方向IMPLEMENTATION.md 列出的规划方向包括完整 SSML 标签支持、自定义音色克隆、自动语言检测、高频短语缓存、更细粒度的性能指标监控以及 Riva 不可用时的自动降级到备选 TTS。这些方向均属于对现有流式合成链路的增量扩展不会改变本文所述的架构骨架。总结nvidia_riva_tts_python是一个小而完整的 TTS 扩展范例通过AsyncTTS2BaseExtension基类复用 TEN 标准 TTS 消息协议用约两百行核心代码完成了从配置校验、Riva gRPC 流式合成、PCM 音频下发到 TTFB/时长指标上报的完整闭环并以三层测试配置、扩展、API 合规保证了实现的可靠性。对于希望接入自建 GPU TTS 服务的开发者而言它既是开箱即用的扩展也是理解 TEN Framework TTS 扩展开发模式的理想参考实现。赞分享人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载相关推荐TEN Framework 接入 NVIDIA Riva TTSnvidia_riva_tts_python 扩展的配置、原理与实战TEN Framework 接入 NVIDIA Riva TTSnvidia_riva_tts_python 扩展的配置、原理与实战 导读 本文以 TEN F人工智能AI Agent多模态语音AI 应用TEN Framework 中 Groq TTS Python 扩展的集成与实现解析TEN Framework 中 Groq TTS Python 扩展的集成与实现解析 导读 本文以 TEN framework 仓库中的 groq_tts_py人工智能AI Agent多模态语音AI 应用TEN Framework 集成 EZAI 繁中 TTS 扩展ezai_tw_tts_python 配置与实现全解析TEN Framework 集成 EZAI 繁中 TTS 扩展ezai_tw_tts_python 配置与实现全解析 本文档以 ezai_tw_tts_pyt人工智能AI Agent多模态语音AI 应用上一篇终极指南用Python剪映API实现视频批量处理自动化下一篇AzurLaneAutoScript碧蓝航线智能助手完全实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考