语音是服务机器人最自然的交互方式。完整链路:唤醒→听→理解→回答→说。
用户说话 → [VAD检测] → [唤醒词] → [ASR识别] → [NLU理解]
↓
用户听到 ← [TTS合成] ← [对话管理] ← [意图响应] ← [技能调用]基于关键词匹配的命令识别——实际系统使用深度学习模型(Whisper等):
import re, json
class SimpleASR:
def __init__(self):
self.commands = {
"navigate": ["去","导航到","带我去","走到","前往"],
"greet": ["你好","嗨","早上好","下午好","晚上好"],
"deliver": ["送","配送","递送","拿给","带给"],
"query": ["查询","问一下","帮我查","告诉我","什么"],
"stop": ["停","停止","暂停","取消","别动"],
"follow": ["跟我来","跟着我","跟随","跟上"],
"help": ["帮助","求助","救命","怎么用"],
}
self.locations = ["会议室","前台","电梯","洗手间","茶水间","出口","大厅","办公室","停车场","餐厅"]
self.items = ["咖啡","水","文件","快递","餐食","药品","钥匙"]
def recognize(self, text):
result = {"raw": text, "intent": None, "slots": {}, "confidence": 0.0}
best_intent, best_score = None, 0
for intent, kws in self.commands.items():
for kw in kws:
if kw in text:
score = len(kw)/len(text) + 0.5
if score > best_score: best_score = score; best_intent = intent
if best_intent:
result["intent"] = best_intent
result["confidence"] = min(best_score, 0.99)
for loc in self.locations:
if loc in text: result["slots"]["location"] = loc; break
for item in self.items:
if item in text: result["slots"]["item"] = item; break
nums = re.findall(r'(\d+)楼', text)
if nums: result["slots"]["floor"] = int(nums[0])
nm = re.search(r'(?:给|找|送给)([\u4e00-\u9fa5]{2,3})', text)
if nm: result["slots"]["person"] = nm.group(1)
return result
asr = SimpleASR()
tests = [
"你好,请带我去3楼会议室",
"帮我送一杯咖啡给张总",
"我想去洗手间怎么走",
"停下来,不要动了",
"查询一下前台在哪里",
"跟我来,我带你去",
"请导航到5楼办公室",
]
print("语音命令识别(ASR)模拟")
print("=" * 55)
for t in tests:
r = asr.recognize(t)
conf = f"{r['confidence']:.0%}" if r['confidence']>0 else "N/A"
slots = ", ".join(f"{k}={v}" for k,v in r["slots"].items())
print(f"\n🎤 \"{t}\"")
print(f" 意图: {r['intent'] or '❓'} (置信度:{conf})")
if slots: print(f" 槽位: {slots}")
print("\n✅ ASR验证通过")
TTS将文本转化为自然语音,SSML标记控制韵律:
import random
class SimpleTTS:
def __init__(self):
self.templates = {
"greeting": ["您好!我是{name},很高兴为您服务。","欢迎!我是{name},有什么可以帮您?"],
"navigating": ["好的,正在为您导航到{location}。","收到,我将带您前往{location}。"],
"delivering": ["{item}已送达,请确认。","您的{item}到了,请查收。"],
"arrived": ["我们已到达{location}。","{location}到了。"],
"elevator": ["正在等待电梯,预计{wait_time}秒。","电梯已到达,请小心进出。"],
"error": ["抱歉,我没有理解,能再说一遍吗?","不好意思,能换一种说法吗?"],
}
def synthesize(self, scene, **kwargs):
templates = self.templates.get(scene, self.templates["error"])
text = random.choice(templates).format(**kwargs)
pauses = {"。":500,"!":600,"?":500,",":300}
ssml = text
for p, ms in pauses.items():
ssml = ssml.replace(p, f'{p}<break time="{ms}ms"/>')
duration = len(text) * 0.12
return {"text": text, "ssml": ssml, "duration": round(duration,1)}
tts = SimpleTTS()
scenes = [
("greeting", {"name":"小云"}),
("navigating", {"location":"3楼会议室A"}),
("delivering", {"item":"咖啡"}),
("arrived", {"location":"会议室B"}),
("elevator", {"wait_time":"30"}),
("error", {}),
]
print("语音合成(TTS)模拟")
print("=" * 55)
for scene, kw in scenes:
r = tts.synthesize(scene, **kw)
print(f"\n🔊 {scene}: {r['text']} ({r['duration']}s)")
print(f" SSML: {r['ssml'][:80]}...")
print("\n✅ TTS验证通过")
VAD判断用户是否在说话,唤醒词区分是否在跟机器人说话:
import math, random
class VoiceActivityDetector:
def __init__(self, threshold=0.3, frame_size=0.02):
self.threshold = threshold; self.frame_size = frame_size
self.min_speech = int(0.3/frame_size); self.max_silence = int(0.5/frame_size)
def detect(self, energies):
segments = []; in_speech = False; start = 0; silence_count = 0; speech_count = 0
for i, e in enumerate(energies):
if e > self.threshold:
speech_count += 1; silence_count = 0
if not in_speech and speech_count >= self.min_speech:
in_speech = True; start = (i - self.min_speech) * self.frame_size
else:
if in_speech:
silence_count += 1
if silence_count >= self.max_silence:
end = (i - self.max_silence) * self.frame_size
segments.append({"start":round(start,2),"end":round(end,2),"duration":round(end-start,2)})
in_speech = False; speech_count = 0
else: speech_count = 0
if in_speech:
end = len(energies) * self.frame_size
segments.append({"start":round(start,2),"end":round(end,2),"duration":round(end-start,2)})
return segments
random.seed(42)
vad = VoiceActivityDetector()
pattern = [0.05]*30 + [0.6]*50 + [0.8]*30 + [0.05]*40 + [0.7]*60 + [0.05]*30
segments = vad.detect(pattern)
print("VAD语音活动检测模拟")
print(f"总时长: {len(pattern)*0.02:.1f}秒")
print(f"检测到语音段: {len(segments)}")
for i, s in enumerate(segments):
print(f" 段{i+1}: {s['start']}s-{s['end']}s (时长{s['duration']}s)")
print("\n✅ VAD验证通过")
| 组件 | 开源 | 云服务 | 建议 |
|---|---|---|---|
| ASR | Whisper、Vosk | 阿里/腾讯ASR | 离线Whisper,在线云 |
| TTS | VITS、Piper | 阿里/讯飞TTS | 情感表达用VITS |
| VAD | WebRTC VAD、Silero | - | Silero精度高 |
| 唤醒词 | Porcupine、Sherpa | - | Porcupine误唤醒低 |
实现中英文混合ASR:支持'帮我go to会议室'等混合语言识别。
为TTS添加情感韵律控制:根据上下文自动选择情绪。
模拟远场语音识别:加入噪声模拟,实现降噪后识别对比。