تحويل النص إلى كلام في استجابات الوكيل
واجهات OpenAI TTS وElevenLabs وGoogle TTS API في مسارات الوكلاء
تحويل النص إلى كلام في استجابات الوكيل درس مجاني في AI Agents على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Agents، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Agents 4 دروس في المجموع.
لماذا تحتاج الوكلاء إلى TTS
الوكيل الصوتي الذي يستمع فقط ويردّ بالنص ليس وكيلًا صوتيًا حقيقيًا. يحوّل تحويل النص إلى كلام (TTS) ردود الوكيل النصية إلى صوت منطوق، وبذلك تكتمل دورة الصوت بأكملها.
هناك واجهتا برمجة تطبيقات رائدتان: OpenAI TTS (سريع، منخفض التكلفة، ويوفر 6 أصوات) وElevenLabs (أصوات فائقة الواقعية، وبث مباشر، واستنساخ الصوت).
أساسيات OpenAI TTS
تحوّل واجهة TTS في OpenAI النص إلى كلام خلال ثوانٍ. وتوفر ستة أصوات مدمجة: 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البث باستخدام OpenAI TTS
لتقليل زمن الاستجابة المُدرَك، ابثّ الصوت أثناء توليده بدلًا من انتظار اكتمال الملف. يستطيع المتصل بدء تشغيل الصوت بينما لا يزال توليد بقية الصوت مستمرًا.
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: تحويل نص عالي الجودة إلى كلام
ينتج 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تحويل النص إلى كلام بالبث عبر 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')تحويل النص إلى كلام جملةً جملةً للبث
بالنسبة إلى استجابات LLM الطويلة، قسّم النص إلى جمل، ثم حوّلها إلى كلام وشغّلها واحدة تلو الأخرى. سيسمع المستخدم الجملة الأولى خلال نحو 500ms بينما لا يزال توليد بقية النص مستمرًا.
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اختبار المعرفة
ما الفائدة الأساسية من استخدام تحويل النص إلى كلام جملةً جملةً في الوكيل الصوتي؟
مراجعة: تحويل النص إلى كلام في استجابات الوكيل
يوفر OpenAI TTS (tts-1 وtts-1-hd) 6 أصوات مع توليد سريع ودعم للبث، مما يجعله مناسبًا لمعظم الوكلاء الصوتيين. ويوفر ElevenLabs أصواتًا واقعية عالية الجودة، مع eleven_turbo_v2 للبث منخفض زمن الاستجابة.
شغّل الصوت باستخدام sounddevice (بسيط) أو pygame (قابل للمقاطعة). خزّن العبارات الشائعة مؤقتًا لإلغاء تكاليف استدعاءات API المتكررة. استخدم التوليد جملةً جملةً للاستجابات الطويلة لتقليل زمن الاستجابة المُدرَك. ويضمن التخزين المؤقت لـ TTS باستخدام تجزئات MD5 تقديم النص المتطابق من ذاكرة التخزين المؤقت دائمًا.
الأسئلة الشائعة
هل درس «تحويل النص إلى كلام في استجابات الوكيل» مجاني؟
نعم — نص درس «تحويل النص إلى كلام في استجابات الوكيل» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Agents، انتقل إلى CoddyKit PRO. تتضمن دورة AI Agents 4 دروس في المجموع.
ماذا ستتعلم في «تحويل النص إلى كلام في استجابات الوكيل»؟
واجهات OpenAI TTS وElevenLabs وGoogle TTS API في مسارات الوكلاء تتمرن على AI Agents مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ AI Agents؟
لا تُشترط خبرة سابقة. AI Agents على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «تحويل النص إلى كلام في استجابات الوكيل»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس AI Agents هذا؟
نعم. كل درس في AI Agents يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تحويل الكلام إلى نص باستخدام Whisper وDeepgram
- تحويل النص إلى كلام في استجابات الوكيل
- بناء حلقة محادثة صوتية
- تحسين زمن الاستجابة للوكلاء الصوتيين