การแปลงข้อความเป็นเสียงพูดในคำตอบของตัวแทน
OpenAI TTS, ElevenLabs และ Google TTS API ในไปป์ไลน์ตัวแทน
การแปลงข้อความเป็นเสียงพูดในคำตอบของตัวแทน เป็นบทเรียน AI Agents ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Agents และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน
เหตุผลที่เอเจนต์ต้องใช้ TTS
เอเจนต์เสียงที่รับฟังได้อย่างเดียวแต่ตอบกลับเป็นข้อความไม่ใช่เอเจนต์เสียงอย่างแท้จริง การแปลงข้อความเป็นเสียง (TTS) จะแปลงคำตอบที่เป็นข้อความของเอเจนต์ให้เป็นเสียงพูด ทำให้กระบวนการทำงานด้วยเสียงครบวงจร
API ชั้นนำมีสองรายการ ได้แก่ OpenAI TTS (รวดเร็ว ราคาประหยัด และมีเสียงให้เลือก 6 แบบ) และ ElevenLabs (เสียงสมจริงมาก รองรับการสตรีมและการโคลนเสียง)
พื้นฐาน OpenAI TTS
API TTS ของ OpenAI แปลงข้อความเป็นเสียงพูดได้ภายในไม่กี่วินาที มีเสียงในตัว 6 แบบ ได้แก่ alloy, echo, fable, onyx, nova และ shimmer รองรับรูปแบบเสียงเอาต์พุต MP3, opus, AAC และ FLAC
import openai
import os
client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
def text_to_speech(text, voice='alloy', output_path='response.mp3'):
response = client.audio.speech.create(
model='tts-1', # tts-1 (fast) or tts-1-hd (higher quality)
voice=voice, # alloy, echo, fable, onyx, nova, shimmer
input=text,
response_format='mp3' # mp3, opus, aac, flac
)
with open(output_path, 'wb') as f:
f.write(response.content)
print(f'Audio saved to: {output_path}')
return output_path
# Available voices:
# alloy - neutral, balanced
# echo - warm, conversational
# fable - expressive
# onyx - deep, authoritative
# nova - friendly, upbeat
# shimmer - soft, clearการสตรีม TTS ด้วย OpenAI
หากต้องการลดความหน่วงที่ผู้ใช้รับรู้ ให้สตรีมเสียงทันทีที่สร้างแทนการรอไฟล์ทั้งหมด ผู้โทรสามารถเริ่มเล่นเสียงได้ขณะที่ส่วนที่เหลือยังคงกำลังสังเคราะห์
import openai
import os
client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
def stream_tts_to_file(text, output_path, voice='nova'):
with client.audio.speech.with_streaming_response.create(
model='tts-1',
voice=voice,
input=text
) as response:
response.stream_to_file(output_path)
return output_path
def stream_tts_to_bytes(text, voice='nova'):
audio_chunks = []
with client.audio.speech.with_streaming_response.create(
model='tts-1',
voice=voice,
input=text
) as response:
for chunk in response.iter_bytes(chunk_size=4096):
audio_chunks.append(chunk)
return b''.join(audio_chunks)ElevenLabs SDK: TTS คุณภาพสูง
ElevenLabs สร้างเสียงที่สมจริงที่สุดเท่าที่มีอยู่ รองรับการโคลนเสียง การควบคุมน้ำเสียงเชิงอารมณ์ และการสตรีม
ติดตั้งด้วย pip install elevenlabs
from elevenlabs import ElevenLabs, VoiceSettings
import os
client = ElevenLabs(api_key=os.getenv('ELEVENLABS_API_KEY'))
def elevenlabs_tts(text, voice_id='pNInz6obpgDQGcFmaJgB', output_path='response.mp3'):
# Common voice IDs:
# Rachel: 21m00Tcm4TlvDq8ikWAM
# Adam: pNInz6obpgDQGcFmaJgB
# Bella: EXAVITQu4vr4xnSDxMaL
audio = client.generate(
text=text,
voice=voice_id,
model='eleven_multilingual_v2', # supports 29 languages
voice_settings=VoiceSettings(
stability=0.5, # 0.0-1.0: lower = more expressive
similarity_boost=0.8, # 0.0-1.0: higher = closer to original voice
style=0.3 # 0.0-1.0: style exaggeration
)
)
with open(output_path, 'wb') as f:
for chunk in audio:
f.write(chunk)
return output_pathการสตรีม TTS ด้วย ElevenLabs
ElevenLabs รองรับการสตรีม โดยรับชิ้นส่วนเสียงได้ก่อนที่ข้อความทั้งหมดจะสังเคราะห์เสร็จ วิธีนี้สำคัญอย่างยิ่งสำหรับเอเจนต์เสียงที่ความหน่วงมีผลต่อประสบการณ์ใช้งาน
from elevenlabs import ElevenLabs
import os
client = ElevenLabs(api_key=os.getenv('ELEVENLABS_API_KEY'))
def streaming_tts(text, voice_id='pNInz6obpgDQGcFmaJgB'):
audio_stream = client.generate(
text=text,
voice=voice_id,
model='eleven_turbo_v2', # fastest model, optimized for streaming
stream=True
)
return audio_stream # yields audio chunks as they are generated
def stream_to_file(text, output_path, voice_id='pNInz6obpgDQGcFmaJgB'):
stream = streaming_tts(text, voice_id)
with open(output_path, 'wb') as f:
for chunk in stream:
if chunk:
f.write(chunk)
print(f'Streaming TTS complete: {output_path}')การเล่นเสียงด้วย sounddevice
หลังจากสร้างเสียง TTS แล้ว ให้เล่นเสียงบนอุปกรณ์ภายในเครื่อง sounddevice ร่วมกับ soundfile เป็นตัวเลือกข้ามแพลตฟอร์มที่ง่ายที่สุดสำหรับเอเจนต์ที่ทำงานบนเครื่องภายในเครื่อง
ติดตั้งด้วย pip install sounddevice soundfile
import sounddevice as sd
import soundfile as sf
import numpy as np
import tempfile
import os
def play_audio_file(audio_path):
data, sample_rate = sf.read(audio_path)
sd.play(data, sample_rate)
sd.wait() # block until playback finishes
def play_mp3_bytes(audio_bytes):
# Write to temp file then play (soundfile needs a file)
with tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) as f:
f.write(audio_bytes)
tmp_path = f.name
try:
play_audio_file(tmp_path)
finally:
os.unlink(tmp_path)
def say(text, voice='nova'):
audio_bytes = stream_tts_to_bytes(text, voice=voice)
play_mp3_bytes(audio_bytes)
# Usage
say('Hello! How can I help you today?')การเล่นเสียงด้วย pygame
pygame ให้การควบคุมที่มากกว่า คุณสามารถตรวจสอบว่าเสียงยังเล่นอยู่หรือไม่ หยุดเสียงก่อนจบ และเล่นเสียงหลายรายการได้ จึงมีประโยชน์สำหรับการจัดการการขัดจังหวะในเอเจนต์เสียง
ติดตั้งด้วย pip install pygame
import pygame
import io
import tempfile
import os
pygame.mixer.init(frequency=44100, size=-16, channels=1, buffer=512)
def play_audio_pygame(audio_bytes):
with tempfile.NamedTemporaryFile(suffix='.mp3', delete=False) as f:
f.write(audio_bytes)
tmp_path = f.name
try:
pygame.mixer.music.load(tmp_path)
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
pygame.time.wait(50) # check every 50ms
finally:
pygame.mixer.music.stop()
os.unlink(tmp_path)
def stop_audio():
if pygame.mixer.music.get_busy():
pygame.mixer.music.stop()
print('Audio stopped (interrupt)')การแคชคำตอบ TTS
วลีทั่วไป เช่น คำทักทาย ข้อความแสดงข้อผิดพลาด และข้อความแจ้งเมนู มักถูกสังเคราะห์ซ้ำหลายครั้ง ให้แคชไฟล์เสียงเหล่านี้เพื่อจ่ายค่าการสังเคราะห์เพียงครั้งเดียวต่อวลี
import hashlib
import os
TTS_CACHE_DIR = '/tmp/tts_cache'
os.makedirs(TTS_CACHE_DIR, exist_ok=True)
def cached_tts(text, voice='nova'):
cache_key = hashlib.md5(f'{voice}:{text}'.encode()).hexdigest()
cache_path = os.path.join(TTS_CACHE_DIR, f'{cache_key}.mp3')
if os.path.exists(cache_path):
print('TTS cache hit')
return cache_path
# Generate and save
audio_bytes = stream_tts_to_bytes(text, voice=voice)
with open(cache_path, 'wb') as f:
f.write(audio_bytes)
print(f'TTS cached: {cache_path}')
return cache_path
# Pre-warm cache for common phrases on startup
COMMON_PHRASES = [
'Hello! How can I help you today?',
'I did not catch that. Could you repeat?',
'Let me look that up for you.',
'Thank you, goodbye!'
]
def prewarm_tts_cache():
for phrase in COMMON_PHRASES:
cached_tts(phrase)
print(f'Pre-warmed {len(COMMON_PHRASES)} phrases')TTS ทีละประโยคสำหรับการสตรีม
สำหรับคำตอบยาวจาก LLM ให้แบ่งข้อความเป็นประโยค แล้วสังเคราะห์และเล่นทีละประโยค ผู้ใช้จะได้ยินประโยคแรกภายในประมาณ 500 มิลลิวินาที ขณะที่ส่วนที่เหลือยังคงกำลังถูกสร้าง
import re
def split_into_sentences(text):
sentences = re.split(r'(?<=[.!?])\s+', text.strip())
return [s.strip() for s in sentences if s.strip()]
def stream_response_as_voice(llm_response_text, voice='nova'):
sentences = split_into_sentences(llm_response_text)
print(f'Speaking {len(sentences)} sentences')
for i, sentence in enumerate(sentences):
if not sentence:
continue
print(f'Speaking ({i+1}/{len(sentences)}): {sentence[:60]}')
cache_path = cached_tts(sentence, voice=voice)
play_audio_file(cache_path)
# Example
response = 'The weather today is sunny and 22 degrees. Perfect for outdoor activities. Bring sunscreen if you plan to be outside for more than an hour.'
stream_response_as_voice(response)การเลือกเสียงและโมเดล
เลือกเสียงให้เข้ากับบุคลิกของเอเจนต์ เสียงทุ้มกว่า เช่น onyx และ echo เหมาะกับเอเจนต์ที่เป็นทางการหรือมืออาชีพ ส่วนเสียงที่อบอุ่นกว่า เช่น nova และ shimmer เหมาะกับผู้ช่วยที่เป็นมิตร
VOICE_PROFILES = {
'assistant': {'service': 'openai', 'voice': 'nova', 'model': 'tts-1'},
'professional': {'service': 'openai', 'voice': 'onyx', 'model': 'tts-1-hd'},
'narrator': {'service': 'openai', 'voice': 'fable', 'model': 'tts-1-hd'},
'premium': {'service': 'elevenlabs', 'voice_id': '21m00Tcm4TlvDq8ikWAM', 'model': 'eleven_multilingual_v2'}
}
def speak(text, persona='assistant'):
profile = VOICE_PROFILES.get(persona, VOICE_PROFILES['assistant'])
if profile['service'] == 'openai':
audio_bytes = stream_tts_to_bytes(text, voice=profile['voice'])
play_mp3_bytes(audio_bytes)
elif profile['service'] == 'elevenlabs':
output_path = elevenlabs_tts(text, voice_id=profile['voice_id'])
play_audio_file(output_path)
speak('Your meeting has been rescheduled.', persona='professional')การปรับอัตราเร็วและระดับเสียงพูด
บริบทที่แตกต่างกันต้องใช้ลักษณะการพูดที่แตกต่างกัน การแจ้งเตือนควรพูดเร็วขึ้นเล็กน้อย ส่วนการเล่าเรื่องควรช้าลงและแสดงอารมณ์มากขึ้น ให้ประมวลผลเสียง TTS ภายหลังเพื่อปรับความเร็วโดยไม่เปลี่ยนระดับเสียง
from pydub import AudioSegment
from pydub.effects import speedup
import os
def adjust_speech_speed(audio_path, speed_factor=1.0, output_path=None):
if speed_factor == 1.0:
return audio_path
audio = AudioSegment.from_file(audio_path)
if speed_factor > 1.0:
# Speed up without changing pitch
audio = speedup(audio, playback_speed=speed_factor)
else:
# Slow down: overlay with silence (simple method)
# For production: use ffmpeg with atempo filter
slow_factor = 1.0 / speed_factor
audio = audio._spawn(
audio.raw_data,
overrides={'frame_rate': int(audio.frame_rate / slow_factor)}
).set_frame_rate(audio.frame_rate)
if output_path is None:
base = os.path.splitext(audio_path)[0]
output_path = f'{base}_speed{speed_factor}.mp3'
audio.export(output_path, format='mp3')
return output_path
# Usage
path = text_to_speech('Your meeting starts in 5 minutes.')
fast_path = adjust_speech_speed(path, speed_factor=1.2) # 20% faster for alertsตรวจสอบความเข้าใจ
ประโยชน์หลักของการสังเคราะห์ TTS ทีละประโยคในเอเจนต์เสียงคืออะไร
สรุปทบทวน: การแปลงข้อความเป็นเสียงในคำตอบของเอเจนต์
OpenAI TTS (tts-1, tts-1-hd) มีเสียง 6 แบบ สังเคราะห์ได้รวดเร็ว และรองรับการสตรีม จึงเหมาะกับเอเจนต์เสียงส่วนใหญ่ ElevenLabs ให้เสียงที่สมจริงและมีคุณภาพสูงกว่า โดย eleven_turbo_v2 เหมาะสำหรับการสตรีมที่มีความหน่วงต่ำ
เล่นเสียงด้วย sounddevice (เรียบง่าย) หรือ pygame (รองรับการขัดจังหวะ) แคชวลีทั่วไปเพื่อลดค่าใช้จ่าย API ที่เกิดซ้ำ ใช้การสังเคราะห์ทีละประโยคสำหรับคำตอบยาวเพื่อลดความหน่วงที่ผู้ใช้รับรู้ การแคช TTS ด้วยแฮช MD5 ช่วยให้ข้อความเดียวกันถูกเรียกจากแคชเสมอ
เรียนรู้ AI Agents ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 60
- บทเรียน
- 239
คำถามที่พบบ่อย
บทเรียน “การแปลงข้อความเป็นเสียงพูดในคำตอบของตัวแทน” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การแปลงข้อความเป็นเสียงพูดในคำตอบของตัวแทน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Agents ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Agents มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การแปลงข้อความเป็นเสียงพูดในคำตอบของตัวแทน”
OpenAI TTS, ElevenLabs และ Google TTS API ในไปป์ไลน์ตัวแทน คุณปฏิบัติ AI Agents ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Agents หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Agents บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การแปลงข้อความเป็นเสียงพูดในคำตอบของตัวแทน” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Agents นี้ได้ไหม
ได้ บทเรียน AI Agents ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การแปลงเสียงพูดเป็นข้อความด้วย Whisper และ Deepgram
- การแปลงข้อความเป็นเสียงพูดในคำตอบของตัวแทน
- การสร้างลูปสนทนาด้วยเสียง
- การปรับเวลาแฝงให้เหมาะที่สุดสำหรับตัวแทนเสียง