在探索 ElevenLabs 的 AI 代理功能并亲身体验了我可以多快构建一个功能齐全的语音机器人而无需编写大量代码后,我不禁想——如果我从头开始构建它会怎样?在 我之前的文章 中,我分享了如何使用 ElevenLabs 和 Make.com 创建一个能够轻松安排会议和处理客户互动的语音机器人。无代码的方法取得了令人印象深刻的结果,但作为一个代码爱好者,我想要更多的控制和自定义。
这次,我决定走一条不同的道路——使用 LangGraph、ElevenLabs 的 API 和 Whisper 从头重建 AI 语音机器人。我的目标是更好地理解其内部工作原理,微调其性能,并探索现成解决方案无法提供的新可能性。在这篇文章中,我不仅会带你深入了解构建我自己版本的 ElevenLabs AI 代理的幕后,还会为你提供一个清晰的框架,以便你自己重建一个语音机器人。在这个过程中,我会分享我面临的挑战、我做出的决策,以及自定义编码解决方案的灵活性如何解锁无尽的可能性。
AI语音机器人构建模块
为了使这个项目成为现实,我依赖于三个构成AI语音机器人基础的关键组件:
语音转文本:Whisper
Whisper,由OpenAI开发,是一种先进的语音转文本模型,以其准确性和多语言能力而闻名。它高效地将口语转换为文本,使其成为处理高精度语音输入的理想解决方案。其深度学习能力使其能够理解各种口音和方言,确保在不同人群中提供流畅的用户体验。在这个项目中,我利用了OpenAI的Python SDK来处理音频输入:
openai_client.audio.transcriptions.create(
model="whisper-1",
file=audio_bytes,
)
对话式人工智能代理:LangGraph
LangGraph,由LangChain开发,是AI语音机器人的核心,能够创建具有工具调用和记忆功能的结构化互动对话。它允许管理复杂的对话流程和决策过程,确保机器人能够智能地响应广泛的用户输入。通过LangGraph,我能够设计出高度动态和适应性的对话体验,能够记住之前的互动并有效利用各种工具来增强功能。
文本转语音:ElevenLabs API
ElevenLabs API 驱动文本转语音组件,提供自然且逼真的语音响应。该组件通过提供类人语音输出来增强用户互动,使对话更加引人入胜和直观。在这个项目中,我利用了 ElevenLabs 的 Python SDK,使用 eleven_turbo_v2_5
模型将文本生成语音:
elevenlabs_client.text_to_speech.convert(
voice_id="YUdpWWny7k5yb4QCeweX",
output_format="mp3_22050_32",
text=cleaned_text,
model_id="eleven_turbo_v2_5",
voice_settings=VoiceSettings(
stability=0.0,
similarity_boost=1.0,
style=0.0,
use_speaker_boost=True,
),
)
通过这些组件,我能够从零开始创建一个高度响应和智能的语音机器人。
分步构建 AI 语音机器人
现在我们已经涵盖了基本构建模块,让我们深入实施。我们将首先创建一个 使用 LangGraph 的基本对话聊天机器人,具备记忆功能和获取当前日期和时间的工具。聊天机器人功能正常后,我们将通过添加两个额外的节点来增强它——一个用于 使用 Whisper 处理传入音频到文本,另一个用于 使用 ElevenLabs API 将聊天机器人的响应转换为音频。这种分步方法将提供坚实的基础,同时逐步增强语音机器人的功能。
第一步:构建基本对话聊天机器人
首先,我们将创建一个简单的聊天机器人,能够记住之前的消息并获取当前的日期和时间。这将涉及定义状态管理系统,集成一个从 API 获取日期和时间的工具,以及使用 LangGraph 构建对话流程。
定义状态管理系统
我们首先定义聊天机器人的状态,以跟踪对话消息。
from typing import Annotated
from typing_extensions import TypedDict
from langgraph.graph.message import add_messages
class State(TypedDict):
messages: Annotated[list, add_messages]
State
类使用注释列表来存储消息,并在新消息到达时附加它们。
实现记忆功能
接下来,我们引入记忆功能,以存储和检索之前的消息,确保对话的连续性。
from langgraph.checkpoint.memory import MemorySaver
memory = MemorySaver()
MemorySaver
组件帮助在交互过程中持久化聊天机器人的状态。
定义工具
接下来,我们定义一个工具,从 API 获取当前的日期和时间。
from langchain_core.tools import tool
import requests
@tool
def get_date_and_time() -> dict:
"""
Call tool to fetch the current date and time from an API.
"""
try:
response = requests.get("https://timeapi.io/api/Time/current/zone?timeZone=Europe/Brussels")
response.raise_for_status()
data = response.json()
return {"date_time": data["dateTime"], "timezone": data["timeZone"]}
except requests.RequestException as e:
return {"error": str(e)}
这个函数获取当前的日期和时间,并以 JSON 格式返回。
设置语言模型
我们现在设置语言模型,并将其与定义的工具集成,使聊天机器人能够在其响应中调用外部工具。
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini")
llm_with_tools = llm.bind_tools([get_date_and_time])
构建对话流程
使用 LangGraph,我们现在构建一个简单的对话流程,仅依赖一个“聊天机器人”节点,该节点可以访问 get_date_and_time
工具。
from langgraph.graph import StateGraph
from langchain_core.runnables import RunnableConfig
def chatbot(state: State, config: RunnableConfig):
return {"messages": [llm_with_tools.invoke(state["messages"])]}
### initiate the graph
graph_builder = StateGraph(State)
graph_builder.add_node("chatbot", chatbot)
graph_builder.add_edge("chatbot", "chatbot")
graph = graph_builder.compile(checkpointer=memory)
这个设置允许聊天机器人处理消息,将其存储在记忆中,并做出相应的响应。
第2步:增强聊天机器人语音功能
接下来,我们将向聊天机器人工作流程中添加两个额外的节点——一个用于使用Whisper将输入音频处理为文本,另一个用于使用ElevenLabs API将文本响应转换为音频。这一增强将使聊天机器人转变为一个功能完善的语音助手。
输入:捕获音频
为了提供无缝且互动的体验,聊天机器人必须能够准确地倾听和理解用户。这就是OpenAI的Whisper模型发挥作用的地方,使聊天机器人能够有效地捕获和转录口语。
语音转文本过程包括几个关键步骤:
音频捕获: 使用sounddevice
库,聊天机器人监听用户麦克风的语音输入。当检测到声音时,录音过程自动开始,并在一段时间的静默后停止。
处理音频输入: 配置多个参数以优化语音检测:
- •
SAMPLE_RATE
:定义采样率以确保足够的语音捕获。 - •
THRESHOLD
:设置检测语音活动的最低音频水平。 - •
SILENCE_DURATION
:确定在停止录音之前应保持多长时间的静默。 - •
CHUNK_SIZE
:指定处理的音频块大小。
语音识别: 一旦录音完成,使用OpenAI的Whisper API对音频进行处理并转录为文本,该API支持高精度的多语言语音识别。
import io
import threading
import numpy as np
import sounddevice as sd
from scipy.io.wavfile import write
from openai import OpenAI
from langgraph.graph import MessagesState, HumanMessage
### Initialize OpenAI client
openai_client = OpenAI()
### Audio settings
SAMPLE_RATE = 16000# Adequate for human voice frequency
THRESHOLD = 500# Silence detection threshold (adjust if needed)
SILENCE_DURATION = 1.5# Duration (seconds) of silence before stopping
CHUNK_SIZE = 1024# Number of frames per audio chunk
defrecord_audio_until_silence(state: MessagesState):
"""Waits for the user to start speaking, records the audio, and stops after detecting silence."""
audio_data = [] # List to store audio chunks
silent_chunks = 0# Counter for silent chunks
started_recording = False# Flag to track if recording has started
defrecord_audio():
"""Continuously records audio, waiting for the user to start speaking."""
nonlocal silent_chunks, audio_data, started_recording
with sd.InputStream(samplerate=SAMPLE_RATE, channels=1, dtype='int16') as stream:
print("Waiting for you to start speaking...")
# Keep waiting indefinitely for the user to start talking
whilenot started_recording:
audio_chunk, _ = stream.read(CHUNK_SIZE)
audio_array = np.frombuffer(audio_chunk, dtype=np.int16)
# Check if there is voice input
if np.abs(audio_array).max() > THRESHOLD:
started_recording = True
print("Voice detected. Recording started.")
audio_data.append(audio_chunk)
break
# Start recording once voice is detected
whileTrue:
audio_chunk, _ = stream.read(CHUNK_SIZE)
audio_data.append(audio_chunk)
audio_array = np.frombuffer(audio_chunk, dtype=np.int16)
# Detect silence after user has finished speaking
if np.abs(audio_array).max() < THRESHOLD:
silent_chunks += 1
else:
silent_chunks = 0# Reset if sound is detected
# Stop if silence is detected for the specified duration
if silent_chunks > (SILENCE_DURATION * SAMPLE_RATE / CHUNK_SIZE):
print("Silence detected. Stopping recording.")
break
# Start recording in a separate thread
recording_thread = threading.Thread(target=record_audio)
recording_thread.start()
recording_thread.join()
# Stack all audio chunks into a single NumPy array and write to file
audio_data = np.concatenate(audio_data, axis=0)
# Convert to WAV format in-memory
audio_bytes = io.BytesIO()
write(audio_bytes, SAMPLE_RATE, audio_data) # Use scipy's write function to save to BytesIO
audio_bytes.seek(0) # Go to the start of the BytesIO buffer
audio_bytes.name = "audio.wav"# Set a filename for the in-memory file
# Transcribe via Whisper
transcription = openai_client.audio.transcriptions.create(
model="whisper-1",
file=audio_bytes,
language='nl'
)
# Print the transcription
print("Here is the transcription:", transcription.text)
# Write to messages
return {"messages": [HumanMessage(content=transcription.text)]}
输出:让聊天机器人拥有语音功能
为了提供真正引人入胜的用户体验,聊天机器人需要以自然和类人化的方式进行交流。这就是ElevenLabs强大的文本转语音(TTS)功能发挥作用的地方,使我们能够无缝地将聊天机器人的响应转换为生动的音频。
该过程涉及几个关键步骤:
- • 初始化ElevenLabs客户端: 设置ElevenLabs API客户端并配置API密钥,以便与文本转语音服务进行通信。
- • 处理聊天机器人响应: 在将文本转换为语音之前,清理聊天机器人的响应,以去除可能干扰音频输出的任何格式化伪影。
- • 将文本转换为语音: 将清理后的文本发送到ElevenLabs API,利用高级语音设置控制稳定性、相似性增强和发音风格等方面。
- • 播放生成的音频: 一旦TTS转换完成,音频响应将回放给用户,确保流畅自然的对话流程。
以下是文本转语音转换的实现方式:
import osfrom elevenlabs import play, VoiceSettingsfrom elevenlabs.client import ElevenLabsfrom langgraph.graph import MessagesState### Initialize ElevenLabs clientelevenlabs_client = ElevenLabs(api_key=os.getenv("ELEVEN_API_KEY"))defplay_audio(state: MessagesState): """Plays the audio response from the remote graph with ElevenLabs.""" # Response from the agent response = state['messages'][-1] # Prepare text by replacing ** with empty strings cleaned_text = response.content.replace("**", "") # Call text_to_speech API with turbo model for low latency response = elevenlabs_client.text_to_speech.convert( voice_id="YUdpWWny7k5yb4QCeweX", # Adam pre-made voice output_format="mp3_22050_32", text=cleaned_text, model_id="eleven_turbo_v2_5", language_code="nl", voice_settings=VoiceSettings( stability=0.0, similarity_boost=1.0, style=0.0, use_speaker_boost=True, ), ) # Play the audio back play(response)
图形构建:集成音频处理
通过定义处理文本和语音交互的功能,下一步是将这些能力无缝集成到统一的工作流程中。通过构建智能对话图,我们可以确保语音识别、基于文本的对话和语音响应之间的顺畅流动。
在这一阶段,我们将定义一个新的基于LangGraph的工作流程,将音频输入和输出功能与我们的聊天机器人连接,从而实现以下操作顺序:
- \1. 捕获音频输入:
- • 聊天机器人监听用户输入并将其从语音转换为文本。
- • 一旦检测到语音并进行处理,生成的文本将传递给聊天机器人进行分析。
2. 处理基于文本的对话:
- • 聊天机器人根据转录的输入和其内部逻辑生成响应。
- • 它可以利用诸如日期和时间检索功能等工具来丰富交互。
3. 生成和播放音频输出:
- • 聊天机器人的文本响应通过使用ElevenLabs API转换为语音。
- • 响应被播放给用户,完成交互循环,并允许用户再次响应,从而无缝继续对话。
通过以这种方式构建对话工作流程,我们创建了一个能够高效处理语音和文本交互的动态语音助手。
以下是我们如何构建完整图形以集成所有组件:
import os
from elevenlabs import play, VoiceSettings
from elevenlabs.client import ElevenLabs
from langgraph.graph import MessagesState
### Initialize ElevenLabs client
elevenlabs_client = ElevenLabs(api_key=os.getenv("ELEVEN_API_KEY"))
defplay_audio(state: MessagesState):
"""Plays the audio response from the remote graph with ElevenLabs."""
# Response from the agent
response = state['messages'][-1]
# Prepare text by replacing ** with empty strings
cleaned_text = response.content.replace("**", "")
# Call text_to_speech API with turbo model for low latency
response = elevenlabs_client.text_to_speech.convert(
voice_id="YUdpWWny7k5yb4QCeweX", # Adam pre-made voice
output_format="mp3_22050_32",
text=cleaned_text,
model_id="eleven_turbo_v2_5",
language_code="nl",
voice_settings=VoiceSettings(
stability=0.0,
similarity_boost=1.0,
style=0.0,
use_speaker_boost=True,
),
)
# Play the audio back
play(response)
第3步:测试语音助手
一旦聊天机器人和音频功能完全集成,就必须测试系统以确保其顺畅运行。我们将通过流式传输输入命令并观察聊天机器人的响应来启动测试对话。
from langgraph.graph import StateGraph, MessagesState, END, START
### Define parent graph
builder = StateGraph(MessagesState)
### Add remote graph directly as a node
builder.add_node("audio_input", record_audio_until_silence)
builder.add_node("agent", graph)
builder.add_node("audio_output", play_audio)
builder.add_edge(START, "audio_input")
builder.add_edge("audio_input", "agent")
builder.add_edge("agent", "audio_output")
builder.add_edge("audio_output", "audio_input")
audio_graph = builder.compile(checkpointer=memory)
结论
从零开始构建这个 AI 语音助手是一次激动人心且有益的经历。使用预构建工具是一回事,但从头开发解决方案则提供了更深入的理解,了解一切是如何结合在一起的。从将语音转文本与 Whisper 集成到使用 ElevenLabs 生成逼真的响应,每一步都带来了宝贵的见解和进一步自定义的可能性。
如果你是一个喜欢折腾 AI 的人,或者想将你的项目超越无代码平台的限制,深入代码将为你打开一个机会的世界。确实,这需要更多的努力,但能够将你的解决方案精确调整到你的需求,使这一切都值得。不论你是为了乐趣而构建,还是在解决现实世界的挑战,创造 AI 驱动的语音助手的旅程才刚刚开始。
如何学习AI大模型?
大模型时代,火爆出圈的LLM大模型让程序员们开始重新评估自己的本领。 “AI会取代那些行业?
”“谁的饭碗又将不保了?
”等问题热议不断。
不如成为「掌握AI工具的技术人」
,毕竟AI时代,谁先尝试,谁就能占得先机!
想正式转到一些新兴的 AI 行业,不仅需要系统的学习AI大模型。同时也要跟已有的技能结合,辅助编程提效,或上手实操应用,增加自己的职场竞争力。
但是LLM相关的内容很多,现在网上的老课程老教材关于LLM又太少。所以现在小白入门就只能靠自学,学习成本和门槛很高
那么我作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,希望可以帮助到更多学习大模型的人!至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费
】
👉 福利来袭
CSDN大礼包:《2025最全AI大模型学习资源包》免费分享,安全可点 👈
全套AGI大模型学习大纲+路线
AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!
640套AI大模型报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;
• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;
• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;
• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。
👉 福利来袭
CSDN大礼包:《2025最全AI大模型学习资源包》免费分享,安全可点 👈
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费
】
作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。