{"product_id":"voice-assistant-với-elevenlabs-claude-trợ-ly-giọng-noi","title":"Voice Assistant với ElevenLabs + Claude — Trợ lý giọng nói","description":"\n\u003cp\u003eVoice assistant hoàn chỉnh cần ba thành phần: \u003cstrong\u003eSTT\u003c\/strong\u003e (Speech-to-Text — nghe người dùng), \u003cstrong\u003eLLM\u003c\/strong\u003e (xử lý và trả lời), và \u003cstrong\u003eTTS\u003c\/strong\u003e (Text-to-Speech — nói lại). Bài này xây dựng pipeline kết hợp \u003cstrong\u003eDeepgram STT\u003c\/strong\u003e + \u003cstrong\u003eClaude\u003c\/strong\u003e + \u003cstrong\u003eElevenLabs TTS\u003c\/strong\u003e — tạo voice assistant chất lượng cao với giọng nói tự nhiên.\u003c\/p\u003e\n\n\u003cp\u003eElevenLabs 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.\u003c\/p\u003e\n\n\u003ch2\u003eKiến trúc Voice Assistant\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003eMicrophone  --[Deepgram STT]--\u0026gt;  Text\n    Text    --[Claude LLM]  --\u0026gt;  Response text\n    Text    --[ElevenLabs]  --\u0026gt;  Audio\n  Audio     --\u0026gt;  Speaker\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eCài đặt\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003epip install anthropic deepgram-sdk elevenlabs pyaudio sounddevice numpy\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport os\nimport asyncio\nimport anthropic\nfrom elevenlabs.client import ElevenLabs\nfrom elevenlabs import VoiceSettings\nfrom deepgram import DeepgramClient, PrerecordedOptions\n\nclaude = anthropic.Anthropic(api_key=os.environ.get(\"ANTHROPIC_API_KEY\"))\neleven = ElevenLabs(api_key=os.environ.get(\"ELEVENLABS_API_KEY\"))\ndeepgram = DeepgramClient(api_key=os.environ.get(\"DEEPGRAM_API_KEY\"))\n\nprint(\"Voice assistant components initialized\")\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eElevenLabs TTS — Text thành giọng nói\u003c\/h2\u003e\n\n\u003cp\u003eElevenLabs cung cấp nhiều giọng nói pre-built và API để generate audio:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003edef list_available_voices():\n    \"\"\"Liệt kê tất cả voices có sẵn.\"\"\"\n    voices_response = eleven.voices.get_all()\n    voices = []\n    for voice in voices_response.voices:\n        voices.append({\n            \"id\": voice.voice_id,\n            \"name\": voice.name,\n            \"category\": voice.category,\n            \"labels\": voice.labels\n        })\n    return voices\n\ndef text_to_speech(\n    text,\n    voice_id=\"21m00Tcm4TlvDq8ikWAM\",  # Rachel - tự nhiên, rõ ràng\n    model_id=\"eleven_multilingual_v2\",   # Hỗ trợ tiếng Việt\n    output_path=None\n):\n    \"\"\"\n    Chuyển text thành audio với ElevenLabs.\n\n    Args:\n        text: Nội dung cần đọc\n        voice_id: ID của voice (lấy từ list_available_voices)\n        model_id: Model TTS (multilingual_v2 cho tiếng Việt)\n        output_path: Lưu file nếu cần, None để stream\n\n    Returns:\n        Audio bytes hoặc path đến file\n    \"\"\"\n    audio = eleven.generate(\n        text=text,\n        voice=voice_id,\n        model=model_id,\n        voice_settings=VoiceSettings(\n            stability=0.5,          # 0-1, cao = ổn định hơn\n            similarity_boost=0.8,   # 0-1, cao = giống voice hơn\n            style=0.0,              # Style exaggeration\n            use_speaker_boost=True  # Tăng chất lượng\n        )\n    )\n\n    audio_bytes = b\"\".join(audio)\n\n    if output_path:\n        with open(output_path, \"wb\") as f:\n            f.write(audio_bytes)\n        return output_path\n\n    return audio_bytes\n\n# Test TTS\naudio_data = text_to_speech(\n    \"Xin chào! Tôi là trợ lý AI của bạn. Tôi có thể giúp gì cho bạn?\",\n    output_path=\"greeting.mp3\"\n)\nprint(f\"Generated audio: {len(audio_data)} bytes\")\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eStreaming TTS cho low latency\u003c\/h2\u003e\n\n\u003cp\u003eĐể giảm latency, stream audio ngay khi Claude bắt đầu generate text:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport sounddevice as sd\nimport numpy as np\nimport io\nfrom pydub import AudioSegment\n\ndef stream_tts(text, voice_id=\"21m00Tcm4TlvDq8ikWAM\"):\n    \"\"\"Stream TTS và play ngay khi có audio.\"\"\"\n    audio_stream = eleven.generate(\n        text=text,\n        voice=voice_id,\n        model=\"eleven_multilingual_v2\",\n        stream=True\n    )\n\n    # Collect chunks và play\n    audio_chunks = []\n    for chunk in audio_stream:\n        if chunk:\n            audio_chunks.append(chunk)\n\n    # Convert và play\n    audio_bytes = b\"\".join(audio_chunks)\n    audio = AudioSegment.from_mp3(io.BytesIO(audio_bytes))\n\n    # Convert to numpy array cho sounddevice\n    samples = np.array(audio.get_array_of_samples(), dtype=np.float32)\n    samples = samples \/ (2**15)  # Normalize to [-1, 1]\n\n    sd.play(samples, audio.frame_rate)\n    sd.wait()  # Chờ finish\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eStreaming Claude + TTS Pipeline\u003c\/h2\u003e\n\n\u003cp\u003eKỹ thuật nâng cao: stream response từ Claude và feed từng câu vào TTS để minimize perceived latency:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport re\n\ndef stream_claude_to_tts(user_message, conversation_history=None, voice_id=\"21m00Tcm4TlvDq8ikWAM\"):\n    \"\"\"\n    Stream response từ Claude, feed câu hoàn chỉnh vào TTS ngay lập tức.\n    Giảm latency từ 3-5s xuống còn ~1s perceived.\n    \"\"\"\n    messages = conversation_history or []\n    messages.append({\"role\": \"user\", \"content\": user_message})\n\n    full_response = \"\"\n    sentence_buffer = \"\"\n    tts_tasks = []\n\n    # Stream Claude response\n    with claude.messages.stream(\n        model=\"claude-haiku-4-5\",  # Haiku nhanh nhất\n        max_tokens=1024,\n        system=\"\"\"Bạn là voice assistant thông minh. Trả lời ngắn gọn, tự nhiên,\n        phù hợp khi đọc to. Không dùng bullet points, markdown, hay code blocks.\n        Tối đa 2-3 câu mỗi lần trả lời.\"\"\",\n        messages=messages\n    ) as stream:\n        for text in stream.text_stream:\n            full_response += text\n            sentence_buffer += text\n\n            # Detect câu hoàn chỉnh (kết thúc bằng . ! ? hoặc ...)\n            sentences = re.split(r'(?\u0026lt;=[.!?])s+', sentence_buffer)\n\n            if len(sentences) \u0026gt; 1:\n                # Có ít nhất 1 câu hoàn chỉnh\n                complete_sentence = sentences[0].strip()\n                sentence_buffer = \" \".join(sentences[1:])\n\n                if complete_sentence:\n                    print(f\"[TTS] {complete_sentence}\")\n                    # Generate TTS cho câu này (trong production: async)\n                    audio = text_to_speech(complete_sentence, voice_id)\n                    tts_tasks.append(audio)\n\n        # Xử lý phần còn lại\n        if sentence_buffer.strip():\n            audio = text_to_speech(sentence_buffer.strip(), voice_id)\n            tts_tasks.append(audio)\n\n    # Play tất cả audio chunks theo thứ tự\n    for audio_chunk in tts_tasks:\n        play_audio(audio_chunk)\n\n    return full_response, messages\n\ndef play_audio(audio_bytes):\n    \"\"\"Play audio bytes.\"\"\"\n    import io\n    from pydub import AudioSegment, playback\n\n    audio = AudioSegment.from_mp3(io.BytesIO(audio_bytes))\n    playback.play(audio)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eComplete Voice Assistant Loop\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport sounddevice as sd\nimport numpy as np\n\ndef record_audio(duration=5, sample_rate=16000):\n    \"\"\"Record audio từ microphone.\"\"\"\n    print(f\"Recording {duration}s... (Speak now)\")\n    audio = sd.rec(\n        int(duration * sample_rate),\n        samplerate=sample_rate,\n        channels=1,\n        dtype=np.int16\n    )\n    sd.wait()\n    return audio.tobytes()\n\nasync def stt_from_bytes(audio_bytes, language=\"vi\"):\n    \"\"\"STT từ raw audio bytes.\"\"\"\n    payload = {\"buffer\": audio_bytes}\n    options = PrerecordedOptions(\n        model=\"nova-2\",\n        language=language,\n        punctuate=True,\n        smart_format=True\n    )\n    response = await deepgram.listen.asyncprerecorded.v(\"1\").transcribe_file(\n        payload, options\n    )\n    return response.results.channels[0].alternatives[0].transcript\n\ndef voice_assistant():\n    \"\"\"Main voice assistant loop.\"\"\"\n    conversation_history = []\n    voice_id = \"21m00Tcm4TlvDq8ikWAM\"  # Rachel\n\n    print(\"\nVoice Assistant ready!\")\n    print(\"Press Enter to speak, Ctrl+C to quit\n\")\n\n    # Greeting\n    greeting = \"Xin chào! Tôi là trợ lý AI. Tôi có thể giúp gì cho bạn?\"\n    print(f\"Assistant: {greeting}\")\n    stream_tts(greeting, voice_id)\n\n    while True:\n        try:\n            input(\"Press Enter to speak...\")\n\n            # Step 1: Record audio\n            audio_bytes = record_audio(duration=7)\n\n            # Step 2: Transcribe\n            print(\"Transcribing...\")\n            user_text = asyncio.run(stt_from_bytes(audio_bytes))\n\n            if not user_text.strip():\n                print(\"Không nghe thấy gì. Thử lại.\")\n                continue\n\n            print(f\"\nYou: {user_text}\")\n\n            # Step 3: Generate response + TTS\n            print(\"Thinking...\")\n            response_text, conversation_history = stream_claude_to_tts(\n                user_text,\n                conversation_history,\n                voice_id\n            )\n\n            print(f\"Assistant: {response_text}\n\")\n\n        except KeyboardInterrupt:\n            print(\"\nGoodbye!\")\n            break\n\n# Chạy voice assistant\n# voice_assistant()\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eVoice Cloning — Giọng tùy chỉnh\u003c\/h2\u003e\n\n\u003cp\u003eElevenLabs cho phép clone giọng nói từ audio samples:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003edef clone_voice(name, audio_files, description=\"\"):\n    \"\"\"\n    Clone giọng nói từ audio samples.\n\n    Args:\n        name: Tên cho voice mới\n        audio_files: List đường dẫn đến audio files (1-25 files, 1-5 phút mỗi file)\n        description: Mô tả về giọng nói\n\n    Returns:\n        voice_id của voice mới tạo\n    \"\"\"\n    # Mở files\n    files = []\n    for path in audio_files:\n        files.append(open(path, \"rb\"))\n\n    try:\n        voice = eleven.clone(\n            name=name,\n            description=description,\n            files=files\n        )\n        print(f\"Voice cloned: {voice.voice_id}\")\n        return voice.voice_id\n    finally:\n        for f in files:\n            f.close()\n\n# Ví dụ: Clone giọng nói của bạn\n# my_voice_id = clone_voice(\n#     name=\"My Voice\",\n#     audio_files=[\"sample1.mp3\", \"sample2.mp3\"],\n#     description=\"Vietnamese male voice, professional\"\n# )\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eKết luận\u003c\/h2\u003e\n\n\u003cp\u003eVoice 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.\u003c\/p\u003e\n\n\u003cp\u003eBước tiếp theo: Khám phá \u003ca href=\"\/en\/collections\/ung-dung\"\u003eDeepgram + Claude\u003c\/a\u003e để hiểu sâu hơn về STT, hoặc đọc về \u003ca href=\"\/en\/collections\/ung-dung\"\u003eWolfram Alpha + Claude\u003c\/a\u003e để thêm tính toán chính xác vào voice assistant.\u003c\/p\u003e\n\n\u003chr\u003e\n\u003ch3\u003eBài viết liên quan\u003c\/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/evaluator-optimizer-t%E1%BB%B1-c%E1%BA%A3i-thi%E1%BB%87n-output-v%E1%BB%9Bi-feedback-loop\"\u003eEvaluator-Optimizer — Tự cải thiện output với feedback loop\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/multi-modal-rag-v%E1%BB%9Bi-llamaindex-claude-vision\"\u003eMulti-Modal RAG với LlamaIndex + Claude Vision\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/claude-skills-t%E1%BA%A1o-excel-powerpoint-pdf-t%E1%BB%B1-d%E1%BB%99ng\"\u003eClaude Skills — Tạo Excel, PowerPoint, PDF tự động\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/claude-phan-tich-d%E1%BB%AF-li%E1%BB%87u-h%C6%B0%E1%BB%9Bng-d%E1%BA%ABn-k%E1%BA%BFt-n%E1%BB%91i-cong-c%E1%BB%A5\"\u003eClaude Phân tích Dữ liệu: Hướng dẫn Kết nối Công cụ\u003c\/a\u003e\u003c\/li\u003e\n\u003cli\u003e\u003ca href=\"\/en\/products\/claude-code-toan-t%E1%BA%ADp-l%E1%BA%ADp-trinh-v%E1%BB%9Bi-ai-agent-trong-terminal\"\u003eClaude Code toàn tập — Lập trình với AI agent trong terminal\u003c\/a\u003e\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721906667732,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/voice-assistant-v_i-elevenlabs-claude-tr_-ly-gi_ng-noi.jpg?v=1774521810","url":"https:\/\/claude.vn\/en\/products\/voice-assistant-v%e1%bb%9bi-elevenlabs-claude-tr%e1%bb%a3-ly-gi%e1%bb%8dng-noi","provider":"CLAUDE.VN","version":"1.0","type":"link"}