AI Agents · บทเรียน

การแปลงข้อความเป็นเสียงพูดในคำตอบของตัวแทน

OpenAI TTS, ElevenLabs และ Google TTS API ในไปป์ไลน์ตัวแทน

บทเรียน 2 จาก 413 ขั้นตอน

การแปลงข้อความเป็นเสียงพูดในคำตอบของตัวแทน เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การแปลงเสียงพูดเป็นข้อความด้วย Whisper และ Deepgram
  2. การแปลงข้อความเป็นเสียงพูดในคำตอบของตัวแทน
  3. การสร้างลูปสนทนาด้วยเสียง
  4. การปรับเวลาแฝงให้เหมาะที่สุดสำหรับตัวแทนเสียง
← กลับไปที่ AI Agents