Voice Assistant với ElevenLabs + Claude — Trợ lý giọng nói
Điểm nổi bật
Nhấn để đến mục tương ứng
- 1 Để áp dụng kiến trúc voice assistant hiệu quả, bạn cần nắm rõ: Microphone --Deepgram STT--> Text Text --Claude LLM --> Response text Text --ElevenLabs --> Audio Audio --> Speaker — đây là bước quan trọng giúp tối ưu quy trình làm việc với AI trong thực tế.
- 2 Về elevenlabs tts — text thành giọng nói, thực tế cho thấy ElevenLabs cung cấp nhiều giọng nói pre-built và API để generate audio: """Liệt kê tất cả voices có sẵn.""" voices_response eleven.voices.get_all voices for voice in voices_response.voices: voices.append "id": voice.voice_id, "name": voice.name, "category": voice.category, "labels": voice.labels return voices text, voice_id"21m00Tcm4T — đây là con dao hai lưỡi nếu không hiểu rõ giới hạn và điều kiện áp dụng của nó.
- 3 Kết quả đo lường từ streaming tts cho low latency: Để giảm latency, stream audio ngay khi Claude bắt đầu generate text: as sd as np voice_id"21m00Tcm4TlvDq8ikWAM": """Stream TTS và play ngay khi có audio.""" audio_stream eleven.generate texttext, voicevoice_id, model"eleven_multilingual_v2", streamTrue # Collect chunks và play audio_chunks — các chỉ số cụ thể này giúp bạn đánh giá chính xác hiệu quả trước khi đầu tư nguồn lực.
- 4 Bước thực hành then chốt trong streaming claude + tts pipeline: Kỹ thuật nâng cao: stream response từ Claude và feed từng câu vào TTS để minimize perceived latency: conversation_historyNone, voice_id"21m00Tcm4TlvDq8ikWAM": """ Stream response từ Claude, feed câu hoàn chỉnh vào TTS ngay lập tức — nắm vững điều này giúp bạn triển khai nhanh hơn và giảm thiểu lỗi thường gặp.
- 5 Góc nhìn thực tế về complete voice assistant loop: as sd as np sample_rate16000: """Record audio từ microphone.""" printf"Recording durations... Speak now" audio sd.rec intduration * sample_rate, sampleratesample_rate, channels1, dtypenp.int16 sd.wait return audio.tobytes async language"vi": """STT từ raw audio bytes.""" payload — hiệu quả phụ thuộc nhiều vào cách triển khai và ngữ cảnh sử dụng cụ thể.
Voice assistant hoàn chỉnh cần ba thành phần: STT (Speech-to-Text — nghe người dùng), LLM (xử lý và trả lời), và TTS (Text-to-Speech — nói lại). Bài này xây dựng pipeline kết hợp Deepgram STT + Claude + ElevenLabs TTS — tạo voice assistant chất lượng cao với giọng nói tự nhiên.
ElevenLabs là TTS service hàng đầu với giọng nói cực kỳ tự nhiên, hỗ trợ tiếng Việt, và cho phép clone giọng nói tùy chỉnh.
Kiến trúc Voice Assistant
Microphone --[Deepgram STT]--> Text
Text --[Claude LLM] --> Response text
Text --[ElevenLabs] --> Audio
Audio --> Speaker
Cài đặt
pip install anthropic deepgram-sdk elevenlabs pyaudio sounddevice numpy
import os
import asyncio
import anthropic
from elevenlabs.client import ElevenLabs
from elevenlabs import VoiceSettings
from deepgram import DeepgramClient, PrerecordedOptions
claude = anthropic.Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
eleven = ElevenLabs(api_key=os.environ.get("ELEVENLABS_API_KEY"))
deepgram = DeepgramClient(api_key=os.environ.get("DEEPGRAM_API_KEY"))
print("Voice assistant components initialized")
ElevenLabs TTS — Text thành giọng nói
ElevenLabs cung cấp nhiều giọng nói pre-built và API để generate audio:
def list_available_voices():
"""Liệt kê tất cả voices có sẵn."""
voices_response = eleven.voices.get_all()
voices = []
for voice in voices_response.voices:
voices.append({
"id": voice.voice_id,
"name": voice.name,
"category": voice.category,
"labels": voice.labels
})
return voices
def text_to_speech(
text,
voice_id="21m00Tcm4TlvDq8ikWAM", # Rachel - tự nhiên, rõ ràng
model_id="eleven_multilingual_v2", # Hỗ trợ tiếng Việt
output_path=None
):
"""
Chuyển text thành audio với ElevenLabs.
Args:
text: Nội dung cần đọc
voice_id: ID của voice (lấy từ list_available_voices)
model_id: Model TTS (multilingual_v2 cho tiếng Việt)
output_path: Lưu file nếu cần, None để stream
Returns:
Audio bytes hoặc path đến file
"""
audio = eleven.generate(
text=text,
voice=voice_id,
model=model_id,
voice_settings=VoiceSettings(
stability=0.5, # 0-1, cao = ổn định hơn
similarity_boost=0.8, # 0-1, cao = giống voice hơn
style=0.0, # Style exaggeration
use_speaker_boost=True # Tăng chất lượng
)
)
audio_bytes = b"".join(audio)
if output_path:
with open(output_path, "wb") as f:
f.write(audio_bytes)
return output_path
return audio_bytes
# Test TTS
audio_data = text_to_speech(
"Xin chào! Tôi là trợ lý AI của bạn. Tôi có thể giúp gì cho bạn?",
output_path="greeting.mp3"
)
print(f"Generated audio: {len(audio_data)} bytes")
Streaming TTS cho low latency
Để giảm latency, stream audio ngay khi Claude bắt đầu generate text:
import sounddevice as sd
import numpy as np
import io
from pydub import AudioSegment
def stream_tts(text, voice_id="21m00Tcm4TlvDq8ikWAM"):
"""Stream TTS và play ngay khi có audio."""
audio_stream = eleven.generate(
text=text,
voice=voice_id,
model="eleven_multilingual_v2",
stream=True
)
# Collect chunks và play
audio_chunks = []
for chunk in audio_stream:
if chunk:
audio_chunks.append(chunk)
# Convert và play
audio_bytes = b"".join(audio_chunks)
audio = AudioSegment.from_mp3(io.BytesIO(audio_bytes))
# Convert to numpy array cho sounddevice
samples = np.array(audio.get_array_of_samples(), dtype=np.float32)
samples = samples / (2**15) # Normalize to [-1, 1]
sd.play(samples, audio.frame_rate)
sd.wait() # Chờ finish
Streaming Claude + TTS Pipeline
Kỹ thuật nâng cao: stream response từ Claude và feed từng câu vào TTS để minimize perceived latency:
import re
def stream_claude_to_tts(user_message, conversation_history=None, voice_id="21m00Tcm4TlvDq8ikWAM"):
"""
Stream response từ Claude, feed câu hoàn chỉnh vào TTS ngay lập tức.
Giảm latency từ 3-5s xuống còn ~1s perceived.
"""
messages = conversation_history or []
messages.append({"role": "user", "content": user_message})
full_response = ""
sentence_buffer = ""
tts_tasks = []
# Stream Claude response
with claude.messages.stream(
model="claude-haiku-4-5", # Haiku nhanh nhất
max_tokens=1024,
system="""Bạn là voice assistant thông minh. Trả lời ngắn gọn, tự nhiên,
phù hợp khi đọc to. Không dùng bullet points, markdown, hay code blocks.
Tối đa 2-3 câu mỗi lần trả lời.""",
messages=messages
) as stream:
for text in stream.text_stream:
full_response += text
sentence_buffer += text
# Detect câu hoàn chỉnh (kết thúc bằng . ! ? hoặc ...)
sentences = re.split(r'(?<=[.!?])s+', sentence_buffer)
if len(sentences) > 1:
# Có ít nhất 1 câu hoàn chỉnh
complete_sentence = sentences[0].strip()
sentence_buffer = " ".join(sentences[1:])
if complete_sentence:
print(f"[TTS] {complete_sentence}")
# Generate TTS cho câu này (trong production: async)
audio = text_to_speech(complete_sentence, voice_id)
tts_tasks.append(audio)
# Xử lý phần còn lại
if sentence_buffer.strip():
audio = text_to_speech(sentence_buffer.strip(), voice_id)
tts_tasks.append(audio)
# Play tất cả audio chunks theo thứ tự
for audio_chunk in tts_tasks:
play_audio(audio_chunk)
return full_response, messages
def play_audio(audio_bytes):
"""Play audio bytes."""
import io
from pydub import AudioSegment, playback
audio = AudioSegment.from_mp3(io.BytesIO(audio_bytes))
playback.play(audio)
Complete Voice Assistant Loop
import sounddevice as sd
import numpy as np
def record_audio(duration=5, sample_rate=16000):
"""Record audio từ microphone."""
print(f"Recording {duration}s... (Speak now)")
audio = sd.rec(
int(duration * sample_rate),
samplerate=sample_rate,
channels=1,
dtype=np.int16
)
sd.wait()
return audio.tobytes()
async def stt_from_bytes(audio_bytes, language="vi"):
"""STT từ raw audio bytes."""
payload = {"buffer": audio_bytes}
options = PrerecordedOptions(
model="nova-2",
language=language,
punctuate=True,
smart_format=True
)
response = await deepgram.listen.asyncprerecorded.v("1").transcribe_file(
payload, options
)
return response.results.channels[0].alternatives[0].transcript
def voice_assistant():
"""Main voice assistant loop."""
conversation_history = []
voice_id = "21m00Tcm4TlvDq8ikWAM" # Rachel
print("
Voice Assistant ready!")
print("Press Enter to speak, Ctrl+C to quit
")
# Greeting
greeting = "Xin chào! Tôi là trợ lý AI. Tôi có thể giúp gì cho bạn?"
print(f"Assistant: {greeting}")
stream_tts(greeting, voice_id)
while True:
try:
input("Press Enter to speak...")
# Step 1: Record audio
audio_bytes = record_audio(duration=7)
# Step 2: Transcribe
print("Transcribing...")
user_text = asyncio.run(stt_from_bytes(audio_bytes))
if not user_text.strip():
print("Không nghe thấy gì. Thử lại.")
continue
print(f"
You: {user_text}")
# Step 3: Generate response + TTS
print("Thinking...")
response_text, conversation_history = stream_claude_to_tts(
user_text,
conversation_history,
voice_id
)
print(f"Assistant: {response_text}
")
except KeyboardInterrupt:
print("
Goodbye!")
break
# Chạy voice assistant
# voice_assistant()
Voice Cloning — Giọng tùy chỉnh
ElevenLabs cho phép clone giọng nói từ audio samples:
def clone_voice(name, audio_files, description=""):
"""
Clone giọng nói từ audio samples.
Args:
name: Tên cho voice mới
audio_files: List đường dẫn đến audio files (1-25 files, 1-5 phút mỗi file)
description: Mô tả về giọng nói
Returns:
voice_id của voice mới tạo
"""
# Mở files
files = []
for path in audio_files:
files.append(open(path, "rb"))
try:
voice = eleven.clone(
name=name,
description=description,
files=files
)
print(f"Voice cloned: {voice.voice_id}")
return voice.voice_id
finally:
for f in files:
f.close()
# Ví dụ: Clone giọng nói của bạn
# my_voice_id = clone_voice(
# name="My Voice",
# audio_files=["sample1.mp3", "sample2.mp3"],
# description="Vietnamese male voice, professional"
# )
Kết luận
Voice assistant với ElevenLabs + Claude + Deepgram là stack hoàn chỉnh cho voice AI applications. ElevenLabs cung cấp giọng nói tự nhiên nhất trên thị trường, Deepgram xử lý STT chính xác, và Claude đảm bảo chất lượng AI reasoning.
Bước tiếp theo: Khám phá Deepgram + Claude để hiểu sâu hơn về STT, hoặc đọc về Wolfram Alpha + Claude để thêm tính toán chính xác vào voice assistant.
Bài viết liên quan
Bai viet co huu ich khong?
Bản quyền thuộc về tác giả. Vui lòng dẫn nguồn khi chia sẻ.


