如何将LINE Bot语音合成迁移到Gemini 3.1原生TTS?2026年台湾中文配置与避坑
AIAI Summary (BLUF)
本文介绍如何将LINE Bot的语音合成功能升级至Google Gemini 3.1 Flash原生TTS,涵盖代码演进、需避免的关键异步等待错误,以及针对台湾中文的本地化配置调整与避坑指南。
Background (背景)
在之前的实践环节中,我们使用了 Gemini 3.1 Flash Live 实现了语音识别,并借助 Gemini 2.5 Live API谷歌Gemini的实时API,基于WebSocket,支持语音交互但复杂度高。 的“旁路”方法,勉强实现了文本转语音(TTS)功能。
然而在 2026 年 4 月,Google 正式发布了 Gemini 3.1 Flash TTS。这是一个专为音频输出设计的原生模型,不再需要 Live WebSocket全双工通信协议,允许服务器主动推送数据,常用于实时应用。,可以通过标准的 generate_content 流程直接输出高质量音频。
作为开发者,您自然希望立即跟进更优雅、更原生的解决方案。本文将分享如何将 LINE Bot基于LINE聊天平台的机器人,可通过API实现自动回复、语音播报等功能。 的语音总结功能升级到 Gemini 3.1 Native TTS,并揭示过程中遇到的“异步之坑”。
Technical Upgrade: From Live API to Native TTS (技术升级:从 Live API 到原生 TTS)
之前的阅读功能是使用 Gemini 2.5 Live API 模拟的。虽然可用,但存在几个不足:
Gemini 3.1 Flash TTS谷歌推出的原生文本转语音模型,可通过标准generate_content接口直接输出高质量音频,无需WebSocket。 的出现改变了这一切:
| 维度 (Aspect) | Gemini 2.5 Live API | Gemini 3.1 Flash TTS |
|---|---|---|
| 复杂度 (Complexity) | 需要管理 WebSocket 连接生命周期 (Requires managing WebSocket connection lifecycle) | 使用熟悉的 generate_content_stream 接口 (Uses familiar generate_content_stream interface) |
| 模型限制 (Model limitations) | 必须使用特定 native-audio 模型,主要支持 us-central1 (Must use specific native-audio model, primarily us-central1) |
模型名为 gemini-3.1-flash-tts-preview,全局可用 (Model name gemini-3.1-flash-tts-preview, globally available) |
| 返回格式 (Return format) | 固定 16kHz 采样率 (Fixed 16kHz sample rate) | 动态参数,MIME 类型自动检测,通常提升至 24kHz (Dynamic parameters, auto-detected from MIME type, typically 24kHz) |
The table above is self-contained; no further translation is needed as each cell already includes bilingual content.
Core Code Evolution — tools/tts_tool.py (核心代码演进)
新的实现更加简洁,关键在于 response_modalities=["audio"] 设置:
async def text_to_speech(text: str) -> tuple[bytes, int]:
client = genai.Client(api_key=GOOGLE_AI_API_KEY, http_options={"api_version": "v1beta"})
contents = [
types.Content(
role="user",
parts=[
# Add localization instructions to make the tone more natural
types.Part.from_text(text=f"Please use Traditional Chinese with Taiwanese vocabulary, and read the following summary in a friendly and natural tone. ## Transcript:\n{text}"),
],
),
]
config = types.GenerateContentConfig(
response_modalities=["audio"],
speech_config=types.SpeechConfig(
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(voice_name="Zephyr")
)
),
)
pcm_chunks = []
sample_rate = 24000 # Default value
try:
# ⚠️ This is the big pit that almost made me stay up all night fixing it
response_stream = await client.aio.models.generate_content_stream(
model="gemini-3.1-flash-tts-preview",
contents=contents,
config=config,
)
async for chunk in response_stream:
if chunk.parts:
for part in chunk.parts:
if part.inline_data:
pcm_chunks.append(part.inline_data.data)
# Get the sampling rate dynamically from the MIME type (e.g. audio/L16;rate=24000)
if part.inline_data.mime_type:
sample_rate = parse_rate(part.inline_data.mime_type)
except Exception as e:
logger.error(f"TTS Error: {e}")
raise
pcm_bytes = b"".join(pcm_chunks)
duration_ms = int(len(pcm_bytes) / (sample_rate * 2) * 1000)
# Subsequently, it is also converted to m4a via ffmpeg and sent to LINE...
上述代码展示了核心逻辑:使用 client.aio.models.generate_content_stream 并以 "audio" 作为响应模态,配合 SpeechConfig 指定语音参数(如 Zephyr 音色)。关键改进包括动态采样率提取和区域化提示。
The Pitfall: The Missing await (陷阱:缺失的 await)
本次升级遇到了一个非常微妙的 TypeError,在远程部署后持续出现:
TypeError: 'async for' requires an object with __aiter__ method, got coroutine
❌ Incorrect Writing (错误写法)
当我按照示例编写时,直觉上认为可以直接对方法进行 async for:
# This is wrong!
async for chunk in client.aio.models.generate_content_stream(...):
pass
✅ Correct Solution (正确解法)
在 Google GenAI Python SDK 的异步版本中,generate_content_stream 本身是一个 async 函数,它会返回一个迭代器。因此你必须先 await 获取该迭代器,然后再对其执行 async for。
# Correct approach: two steps
response_stream = await client.aio.models.generate_content_stream(...)
async for chunk in response_stream:
pass
这个细节在普通的同步代码或某些旧版 SDK 中可能不存在,但在处理 3.1 Flash TTS 的异步流时,这正是能否成功运行的关键。
Localization Adjustment: Making the Bot Speak "Taiwanese" (区域化调整:让机器人说“台湾腔”)
虽然摘要本身已是繁体中文,但 TTS 模型在朗读时偶尔会带有非本土的腔调或词汇。我们通过提示工程解决了这个问题:
"Please use Taiwanese vocabulary in Traditional Chinese, and read it in a friendly and natural tone..."
加入这行指令后,Gemini 输出的音频在语调、断句上更贴近台湾用户的使用习惯,大大提升了“听摘要”的亲和力。
Summary: Changes Brought by Native TTS (总结:原生 TTS 带来的变化)
从 Live API 迁移到原生 TTS 后:
这次经验也提醒我,即使看似成熟的 SDK,在处理 async 模式时也应仔细检查返回值类型。
如果你也希望让 LINE Bot 开口说话,Gemini 3.1 Flash TTS 绝对是目前的最佳选择。
完整代码已更新至 GitHub,下次见!
常见问题(FAQ)
为什么需要从Live API升级到Gemini 3.1原生TTS?
Live API需要管理WebSocket连接生命周期,模型受限且采样率固定为16kHz。原生TTS使用标准generate_content_streamGoogle GenAI SDK中的异步流式生成方法,用于逐步获取模型输出。接口,支持动态采样率(24kHz),连接更稳定,代码量减少约30%。
Gemini 3.1 Flash TTS的模型名称和核心配置是什么?
使用异步版本SDK时最常见的错误是什么?如何解决?
版权与免责声明:本文仅用于信息分享与交流,不构成任何形式的法律、投资、医疗或其他专业建议,也不构成对任何结果的承诺或保证。
文中提及的商标、品牌、Logo、产品名称及相关图片/素材,其权利归各自合法权利人所有。本站内容可能基于公开资料整理,亦可能使用 AI 辅助生成或润色;我们尽力确保准确与合规,但不保证完整性、时效性与适用性,请读者自行甄别并以官方信息为准。
若本文内容或素材涉嫌侵权、隐私不当或存在错误,请相关权利人/当事人联系本站,我们将及时核实并采取删除、修正或下架等处理措施。也请勿在评论或联系信息中提交身份证号、手机号、住址等个人敏感信息。



