AI 教程
使用OpenAI和Python构建你的首个语音助手:开发者教程
一份动手实践的Python教程,教你使用OpenAI的Whisper、ChatGPT和文本转语音API构建语音助手:录音、转录、生成适合口语的回复,并将其转换回音频。

语音助手听起来像是一个大型工程项目,但其核心循环只是三个串联的API调用:将语音转录为文本,将文本发送给语言模型,然后将回复转换为语音。本教程使用OpenAI的Whisper进行转录、ChatGPT生成回复以及OpenAI的文本转语音端点输出音频,构建一个可工作的命令行版本。
你需要准备
- 已安装Python 3.9或更高版本
- 已启用计费的OpenAI API密钥(本项目使用三个独立端点,每个按使用计费)
- 一个麦克风,以及从机器播放音频的方式
第一步:设置环境
创建一个项目文件夹并安装所需的软件包:
pip install openai sounddevice scipy python-dotenv
将API密钥存储在.env文件中,而不是硬编码到脚本中, , 这一点的重要性超出想象:硬编码的API密钥最终泄露在Git仓库中的频率远超开发者的预期。
OPENAI_API_KEY=your-key-here
第二步:使用Whisper录音并转录
录音步骤会捕获几秒钟的麦克风输入,并将其保存为WAV文件,然后发送到Whisper的转录端点:
import sounddevice as sd, scipy.io.wavfile as wav, os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI()
def record_audio(filename="input.wav", duration=5, fs=44100):
print("Recording...")
audio = sd.rec(int(duration * fs), samplerate=fs, channels=1)
sd.wait()
wav.write(filename, fs, audio)
def transcribe(filename="input.wav"):
with open(filename, "rb") as f:
result = client.audio.transcriptions.create(model="whisper-1", file=f)
return result.text
五秒钟足够一个简短的问题。对于更长的输入,要么增加时长,要么在生产版本中,用静音检测替换固定时长录音,这样一旦你说完就会自动停止。
第三步:将转录文本发送给ChatGPT
拿到文本后,聊天补全调用很简单。保持系统提示简洁,因为语音回复应比典型的屏幕阅读聊天输出更短、更口语化:
def get_response(user_text):
completion = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "You are a voice assistant. Keep answers under 3 sentences, conversational, no markdown."},
{"role": "user", "content": user_text}
]
)
return completion.choices[0].message.content
“no markdown”指令在此处尤为重要,因为一个项目符号列表朗读出来毫无意义, , 这是一个提示词必须考虑输出媒介而非仅内容的案例。
第四步:将回复转换为语音
OpenAI的文本转语音端点接收回复文本并直接返回音频:
def speak(text, filename="output.mp3"):
response = client.audio.speech.create(model="tts-1", voice="alloy", input=text)
response.stream_to_file(filename)
os.system(f"start {filename}" if os.name == "nt" else f"afplay {filename}")
voice参数接受几个预设选项:alloy、echo、fable、onyx、nova和shimmer,各有不同音色。针对你的使用场景多试几种;面向客户的助手和个人笔记工具不需要相同的语音。
第五步:整合起来
if __name__ == "__main__":
record_audio()
text = transcribe()
print(f"You said: {text}")
reply = get_response(text)
print(f"Assistant: {reply}")
speak(reply)
运行脚本,在提示时说出一个问题,整个循环, , 录音、转录、回复、朗读, , 在几秒钟内完成。
可能出错的地方及修复方法
最常见的问题是音频截断:如果固定的5秒窗口在你说完前就结束,转录将不完整,回复也会答非所问。增加时长是快速修复;添加一个类似webrtcvad的语音活动检测库才是正确方式。延迟是另一个值得提前规划的制约因素:三个连续的API调用通常累积2-4秒的往返时间,虽然明显,但对个人工具通常可接受;但对于追求真正实时体验的场景则不太够。