























上周我妈抱怨手机字太小看不清,我灵机一动:要不做个语音助手?说话就能查天气、设提醒。结果这一折腾就是 3 天,踩了无数坑,最后把成本压到 50 块/月,延迟控制在 1.2 秒内。
直接说结论:用 Whisper API 做语音识别 + GPT-4o-mini 做对话 + Edge TTS 做语音合成,Python 100 行代码搞定,成本约 0.15 元/次对话。
我测了 3 套方案,这是实测数据:
| 方案 | 识别延迟 | 对话延迟 | 合成延迟 | 月成本(300次) | 踩坑指数 |
|---|---|---|---|---|---|
| Whisper + GPT-4o-mini + Edge TTS | 0.4s | 0.6s | 0.2s | ¥45 | ⭐⭐ |
| 本地 Whisper + Ollama + Piper | 1.2s | 3.5s | 0.8s | ¥0 | ⭐⭐⭐⭐⭐ |
| Azure 语音服务全家桶 | 0.3s | 0.5s | 0.15s | ¥180 | ⭐ |
本地方案我直接放弃了,Ollama 跑 Llama 3.1 8B 慢得让人抓狂,老人等 3 秒就不耐烦了。Azure 倒是快,但一个月要 180 块,我自己都舍不得。
pip install openai pyaudio edge-tts
PyAudio 在 Mac 上装起来巨坑,报一堆 portaudio 错误。最后发现要先装 portaudio:
brew install portaudio
pip install pyaudio
Windows 用户直接 pip install pyaudio 就行,Linux 要装 python3-pyaudio。
import pyaudio
import wave
def record_audio(filename="input.wav", duration=5):
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT, channels=CHANNELS,
rate=RATE, input=True,
frames_per_buffer=CHUNK)
print("开始录音...")
frames = []
for _ in range(0, int(RATE / CHUNK * duration)):
data = stream.read(CHUNK)
frames.append(data)
print("录音结束")
stream.stop_stream()
stream.close()
p.terminate()
wf = wave.open(filename, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
这里有个坑:采样率别用 44100,Whisper 对 16000 Hz 的识别准确率更高,而且文件小一半。
import openai
client = openai.OpenAI(
base_url="https://api.ofox.ai/v1",
api_key="sk-xxx" # 你的 API Key
)
def transcribe_audio(filename):
with open(filename, "rb") as audio_file:
transcript = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
language="zh" # 指定中文,识别更准
)
return transcript.text
踩坑记录 1:一开始我没加 language="zh",结果我妈说"今天天气怎么样",识别成"How's the weather today"。加上语言参数后准确率从 70% 飙到 95%。
def chat_with_ai(user_input):
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "你是一个友好的语音助手,回答要简短,控制在 50 字以内。"},
{"role": "user", "content": user_input}
],
max_tokens=100,
temperature=0.7
)
return response.choices[0].message.content
踩坑记录 2:System prompt 里的"简短"很关键。一开始没加,AI 回答"今天天气"能说 200 字,语音播报听得人想睡觉。加上字数限制后,回答变成"今天多云,15 到 22 度,适合出门",刚刚好。
import edge_tts
import asyncio
async def text_to_speech(text, output_file="output.mp3"):
communicate = edge_tts.Communicate(text, "zh-CN-XiaoxiaoNeural")
await communicate.save(output_file)
def speak(text):
asyncio.run(text_to_speech(text))
# 播放音频(需要 pygame 或 playsound)
import pygame
pygame.mixer.init()
pygame.mixer.music.load("output.mp3")
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
pygame.time.Clock().tick(10)
Edge TTS 是微软开源的,完全免费,音质吊打那些收费的 TTS API。zh-CN-XiaoxiaoNeural 是晓晓的声音,还有云希(男声)、晓伊(儿童音)可选。
def main():
print("语音助手启动,按 Ctrl+C 退出")
while True:
try:
input("按回车开始说话...")
record_audio(duration=5)
print("识别中...")
user_text = transcribe_audio("input.wav")
print(f"你说:{user_text}")
if "退出" in user_text or "再见" in user_text:
speak("再见")
break
print("思考中...")
ai_response = chat_with_ai(user_text)
print(f"AI:{ai_response}")
speak(ai_response)
except KeyboardInterrupt:
print("\n程序退出")
break
except Exception as e:
print(f"出错了:{e}")
if __name__ == "__main__":
main()
老人用起来总忘记按回车,我又加了个语音唤醒功能。用 PocketSphinx 做本地关键词检测,听到"小助手"就自动开始录音:
from pocketsphinx import LiveSpeech
def wait_for_wakeword():
speech = LiveSpeech(
lm=False,
keyphrase='小助手',
kws_threshold=1e-20
)
for phrase in speech:
if '小助手' in str(phrase):
print("检测到唤醒词!")
return True
踩坑记录 3:PocketSphinx 对中文支持很差,"小助手"经常识别成"小猪猪"。最后我改成英文"Hey Assistant",识别率才正常。中文唤醒词还是得上 Picovoice 或者 Snowboy(已停更)。
按每天 10 次对话算(早上问天气、中午设提醒、晚上聊天):
月成本:(0.0005 + 0.0002) × 10 × 30 = $0.21 ≈ ¥1.5
等等,我前面说 50 块/月是怎么算的?因为我后来加了联网搜索(天气、新闻),用了 GPT-4o 而不是 mini,成本涨到了 45 块。如果只是简单对话,1.5 块就够。
代码里我用的是 ofox.ai,一开始是因为懒得去 OpenAI 官网绑卡(我的 Visa 卡老是被拒)。
ofox.ai 是一个 AI 模型聚合平台,一个 API Key 可以调用 GPT-4o、Claude Opus 4.6、Gemini 3、DeepSeek V3 等 50+ 模型,兼容 OpenAI SDK 协议,低延迟直连无需代理,支持支付宝按量计费。
实测下来有两个意外收获:
如果你想换成 Claude 或者 DeepSeek,只需要改一行:
response = client.chat.completions.create(
model="claude-opus-4-6", # 或者 deepseek-chat
messages=[...]
)
API 格式完全一样,不用改其他代码。
做完基础版我发现总延迟 2.5 秒,老人觉得"反应慢"。优化后压到 1.2 秒:
stream=True,第一个字出来就开始合成语音,省 0.5 秒# 流式输出示例
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[...],
stream=True
)
full_response = ""
for chunk in response:
if chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
full_response += content
print(content, end="", flush=True)
我妈用了一周,反馈:
做这个项目最大的感受是:AI 应用的门槛真的降低了。3 年前做语音助手要懂 Kaldi、训练声学模型,现在 100 行 Python 就搞定。
成本也比想象中低,如果只是家用,一个月几块钱就够。当然如果要做商业化,还得考虑并发、容灾、合规这些,那是另一个故事了。
代码我放 GitHub 了(搜 voice-assistant-demo),有问题欢迎留言。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。