如何在Python的neuralintents库中使用intents.json里的responses
利用neuralintents调用intents.json中的responses字段
问题描述
使用Python的neuralintents模块开发语音助手时,发现该库仅支持将意图映射到函数,无法直接利用intents.json文件中的responses字段向用户反馈,希望找到实现该功能的方法。
解决方案
neuralintents官方没有直接提供调用responses的API,但可以通过手动读取intents.json并结合意图预测结果来实现,或者扩展GenericAssistant类封装逻辑。以下是具体实现方式:
方法一:手动读取intents.json并匹配回复
- 加载并解析intents.json文件,将其转为Python字典
- 使用
assistant.predict_intent()获取用户输入对应的意图标签 - 根据意图标签从字典中取出对应的responses列表,随机选择一条回复
- 用语音合成模块播报该回复
修改后的完整代码
from neuralintents import GenericAssistant import speech_recognition import pyttsx3 as tts import sys import json import random # 初始化语音识别与合成 recognizer = speech_recognition.Recognizer() speaker = tts.init() speaker.setProperty('rate', 150) # 可选:切换女声 voices = speaker.getProperty('voices') speaker.setProperty('voice', voices[1].id) todo_list = ['Go shopping', 'Clean Room', 'Record Videos'] # 加载intents.json def load_intents(file_path): with open(file_path, 'r', encoding='utf-8') as f: return json.load(f) intents_data = load_intents('intents.json') # 原有功能函数保留 def create_note(): global recognizer speaker.say("What do you want to write into your note") speaker.runAndWait() done = False while not done: try: with speech_recognition.Microphone() as mic: recognizer.adjust_for_ambient_noise(mic, duration=0.2) audio = recognizer.listen(mic) note = recognizer.recognize_google(audio) note = note.lower() speaker.say("Choose a filename!") speaker.runAndWait() recognizer.adjust_for_ambient_noise(mic, duration=0.2) audio = recognizer.listen(mic) filename = recognizer.recognize_google(audio) filename = filename.lower() with open(filename, 'w') as f: f.write(note) done = True speaker.say(f"I successfully created the note {filename}") speaker.runAndWait() except speech_recognition.UnknownValueError: recognizer = speech_recognition.Recognizer() speaker.say("I did not understand you! Please try again!") speaker.runAndWait() def add_todo(): global recognizer speaker.say("What todo do you want to add?") speaker.runAndWait() done = False while not done: try: with speech_recognition.Microphone() as mic: recognizer.adjust_for_ambient_noise(mic, duration=0.2) audio = recognizer.listen(mic) item = recognizer.recognize_google(audio) item = item.lower() todo_list.append(item) done = True speaker.say(f"I added {item} to the to do list!") speaker.runAndWait() except speech_recognition.UnknownValueError: recognizer = speech_recognition.Recognizer() speaker.say("I did not understand. Please try again!") speaker.runAndWait() def show_todos(): speaker.say("The items in your to do list are the following") for item in todo_list: speaker.say(item) speaker.runAndWait() def exitt(): # 从intents中获取goodbye的回复 for intent in intents_data['intents']: if intent['tag'] == 'goodbye': response = random.choice(intent['responses']) speaker.say(response) speaker.runAndWait() sys.exit(0) # 意图映射:仅保留需要执行逻辑的意图,纯回复类意图可以不用映射 mappings = { "create_note": create_note, "add_todos": add_todo, "show_todos": show_todos, "goodbye": exitt, } assistant = GenericAssistant('intents.json', intent_methods=mappings) assistant.train_model() assistant.save_model() # 处理用户请求的核心逻辑 def handle_command(command): intent_tag = assistant.predict_intent(command) # 先检查是否有映射的函数,优先执行函数 if intent_tag in mappings: mappings[intent_tag]() else: # 没有映射函数则从intents中取回复 for intent in intents_data['intents']: if intent['tag'] == intent_tag: response = random.choice(intent['responses']) speaker.say(response) speaker.runAndWait() break while True: try: with speech_recognition.Microphone() as mic: recognizer.adjust_for_ambient_noise(mic, duration=0.2) audio = recognizer.listen(mic) command = recognizer.recognize_google(audio) command = command.lower() handle_command(command) except speech_recognition.UnknownValueError: recognizer = speech_recognition.Recognizer() # 可以添加默认回复 speaker.say("Sorry, I didn't catch that. Could you repeat?") speaker.runAndWait()
方法二:扩展GenericAssistant类(更优雅)
通过继承GenericAssistant,添加获取回复的方法,封装逻辑:
from neuralintents import GenericAssistant import json import random class CustomAssistant(GenericAssistant): def __init__(self, intents_file, intent_methods=None): super().__init__(intents_file, intent_methods) # 加载intents数据 with open(intents_file, 'r', encoding='utf-8') as f: self.intents_data = json.load(f) def get_response(self, command): intent_tag = self.predict_intent(command) for intent in self.intents_data['intents']: if intent['tag'] == intent_tag: return random.choice(intent['responses']) return "Sorry, I don't understand that."
然后在主逻辑中使用这个自定义类:
# 替换原来的assistant初始化 assistant = CustomAssistant('intents.json', intent_methods=mappings) assistant.train_model() assistant.save_model() # 在循环中调用 while True: try: with speech_recognition.Microphone() as mic: recognizer.adjust_for_ambient_noise(mic, duration=0.2) audio = recognizer.listen(mic) command = recognizer.recognize_google(audio).lower() # 先检查是否有映射函数 intent_tag = assistant.predict_intent(command) if intent_tag in mappings: mappings[intent_tag]() else: response = assistant.get_response(command) speaker.say(response) speaker.runAndWait() except speech_recognition.UnknownValueError: recognizer = speech_recognition.Recognizer() speaker.say("Sorry, I didn't catch that. Could you repeat?") speaker.runAndWait()
说明
- 纯回复类的意图(如问候)不需要再写对应的函数,直接从intents.json中取回复即可
- 对于需要执行逻辑的意图(如创建笔记、添加待办),依然保留函数映射,执行完逻辑后也可以结合responses字段给用户反馈
- 随机选择回复可以让助手的交互更自然
内容的提问来源于stack exchange,提问作者Dinujaya Sandaruwan
相关产品推荐
相关产品推荐

