def main(): user_id = 'test' parser = argparse.ArgumentParser(description='Question answering machine') parser.add_argument('--data_folder', type=str, default='../../data') parser.add_argument('--w2v_folder', type=str, default='../../tmp') parser.add_argument('--profile', type=str, default='../../data/profile_1.json', help='path to profile file') parser.add_argument('--models_folder', type=str, default='../../tmp', help='path to folder with pretrained models') parser.add_argument('--tmp_folder', type=str, default='../../tmp', help='path to folder for logfile etc') parser.add_argument('--debugging', action='store_true') parser.add_argument('--input', type=str, help='Input file with phrases') parser.add_argument('--output', type=str, help='Output file with bot replicas') args = parser.parse_args() profile_path = os.path.expanduser(args.profile) models_folder = os.path.expanduser(args.models_folder) data_folder = os.path.expanduser(args.data_folder) w2v_folder = os.path.expanduser(args.w2v_folder) tmp_folder = os.path.expanduser(args.tmp_folder) init_trainer_logging(os.path.join(tmp_folder, 'console_chatbot.log'), args.debugging) logging.debug('Bot loading...') # Создаем необходимое окружение для бота. # NLP pileline: содержит инструменты для работы с текстом, включая морфологию и таблицы словоформ, # part-of-speech tagger, NP chunker и прочее. text_utils = TextUtils() text_utils.load_embeddings(w2v_dir=w2v_folder, wc2v_dir=models_folder) text_utils.load_dictionaries(data_folder, models_folder) # Настроечные параметры аватара собраны в профиле - файле в json формате. profile = BotProfile() profile.load(profile_path, data_folder, models_folder) # Инициализируем движок вопросно-ответной системы. Он может обслуживать несколько # ботов с разными провилями (базами фактов и правил), хотя тут у нас будет работать только один. machine = SimpleAnsweringMachine(text_utils=text_utils) machine.load_models(data_folder, models_folder, profile.constants) machine.trace_enabled = args.debugging # Контейнер для правил scripting = BotScripting(data_folder) scripting.load_rules(profile.rules_path, profile.smalltalk_generative_rules, profile.constants, text_utils) # Добавляем скрипты на питоне scripting.add_scenario(Scenario_WhoAmI()) # Конкретная реализация хранилища фактов - плоские файлы в utf-8, с минимальным форматированием profile_facts = ProfileFactsReader(text_utils=text_utils, profile_path=profile.premises_path, constants=profile.constants) # Подключем простое файловое хранилище с FAQ-правилами бота. # Движок бота сопоставляет вопрос пользователя с опорными вопросами в FAQ базе, # и если нашел хорошее соответствие (синонимичность выше порога), то # выдает ответную часть найденной записи. faq_storage = PlainFileFaqStorage(profile.faq_path, constants=profile.constants, text_utils=text_utils) # Инициализируем аватара bot = BotPersonality(bot_id='test_bot', engine=machine, facts=profile_facts, faq=faq_storage, scripting=scripting, profile=profile) bot.on_process_order = on_order # Выполняем привязку обработчиков bot.add_event_handler(u'weather_forecast', on_weather_forecast) bot.add_event_handler(u'check_emails', on_check_emails) bot.add_event_handler(u'alarm_clock', on_alarm_clock) bot.add_event_handler(u'buy_pizza', on_buy_pizza) bot.start_conversation(user_id) flush_logging() print_tech_banner() if args.input: # Пакетный режим - читаем фразы собеседника из указанного текстового файла, прогоняем # через бота, сохраняем ответные фразы бота в выходной файл. with io.open(args.input, 'r', encoding='utf-8') as rdr,\ io.open(args.output, 'w', encoding='utf-8') as wrt: # Получим стартовые реплики бота (обычно он здоровается) while True: answer = bot.pop_phrase(user_id) if len(answer) == 0: break wrt.write('B: {}\n'.format(answer)) # Теперь читаем фразы из тестового набора и даем их боту на обработку for line in rdr: inline = line.strip() if inline.startswith('#'): # Может быть спец. команда s = inline[1:].strip() if s.startswith('!'): cmd = s[1:] if cmd == 'reset_running': bot.cancel_all_running_items(user_id) else: # комментарии просто сохраняем в выходном файле для # удобства визуальной организации wrt.write('\n{}\n'.format(inline)) continue if inline: wrt.write('\nH: {}\n'.format(inline)) bot.push_phrase(user_id, line.strip()) while True: answer = bot.pop_phrase(user_id) if len(answer) == 0: break wrt.write('B: {}\n'.format(answer)) else: # Консольный интерактивный режим while True: print('\n') # В самом начале диалога, когда еще не было ни одной реплики, # бот может сгенерировать некое приветствие или вопрос для # завязывания беседы. Поэтому сразу извлечем сгенерированные фразы из # буфера и покажем их. while True: answer = bot.pop_phrase(user_id) if len(answer) == 0: break print_answer(u'B:>', answer) question = input_kbd('H:>') if len(question) > 0: if question.lower() in ('r\exit', r'\q', r'\quit', '/stop'): break bot.push_phrase(user_id, question)
def main(): user_id = 'test' parser = argparse.ArgumentParser(description='Question answering machine') parser.add_argument('--data_folder', type=str, default='../../data') parser.add_argument('--w2v_folder', type=str, default='../../tmp') parser.add_argument('--profile', type=str, default='../../data/profile_1.json', help='path to profile file') parser.add_argument('--models_folder', type=str, default='../../tmp', help='path to folder with pretrained models') parser.add_argument('--tmp_folder', type=str, default='../../tmp', help='path to folder for logfile etc') parser.add_argument('--debugging', action='store_true') args = parser.parse_args() profile_path = os.path.expanduser(args.profile) models_folder = os.path.expanduser(args.models_folder) data_folder = os.path.expanduser(args.data_folder) w2v_folder = os.path.expanduser(args.w2v_folder) tmp_folder = os.path.expanduser(args.tmp_folder) init_trainer_logging(os.path.join(tmp_folder, 'console_chatbot.log'), args.debugging) logging.debug('Bot loading...') # Создаем необходимое окружение для бота. # NLP pileline: содержит инструменты для работы с текстом, включая морфологию и таблицы словоформ, # part-of-speech tagger, NP chunker и прочее. text_utils = TextUtils() text_utils.load_embeddings(w2v_dir=w2v_folder, wc2v_dir=models_folder) text_utils.load_dictionaries(data_folder, models_folder) # Настроечные параметры аватара собраны в профиле - файле в json формате. profile = BotProfile() profile.load(profile_path, data_folder, models_folder) # Инициализируем движок вопросно-ответной системы. Он может обслуживать несколько # ботов с разными провилями (базами фактов и правил), хотя тут у нас будет работать только один. machine = SimpleAnsweringMachine(text_utils=text_utils) machine.load_models(data_folder, models_folder, profile.constants) machine.trace_enabled = args.debugging # Контейнер для правил scripting = BotScripting(data_folder) scripting.load_rules(profile.rules_path, profile.smalltalk_generative_rules, profile.constants, text_utils) # Конкретная реализация хранилища фактов - плоские файлы в utf-8, с минимальным форматированием profile_facts = ProfileFactsReader(text_utils=text_utils, profile_path=profile.premises_path, constants=profile.constants) # Подключем простое файловое хранилище с FAQ-правилами бота. # Движок бота сопоставляет вопрос пользователя с опорными вопросами в FAQ базе, # и если нашел хорошее соответствие (синонимичность выше порога), то # выдает ответную часть найденной записи. faq_storage = PlainFileFaqStorage(profile.faq_path, constants=profile.constants, text_utils=text_utils) # Инициализируем аватара bot = BotPersonality(bot_id='test_bot', engine=machine, facts=profile_facts, faq=faq_storage, scripting=scripting, profile=profile) bot.on_process_order = on_order # Выполняем привязку обработчиков bot.add_event_handler(u'weather_forecast', on_weather_forecast) bot.add_event_handler(u'check_emails', on_check_emails) bot.add_event_handler(u'alarm_clock', on_alarm_clock) bot.add_event_handler(u'buy_pizza', on_buy_pizza) bot.start_conversation(user_id) flush_logging() print_tech_banner() while True: print('\n') # В самом начале диалога, когда еще не было ни одной реплики, # бот может сгенерировать некое приветствие или вопрос для # завязывания беседы. Поэтому сразу извлечем сгенерированные фразы из # буфера и покажем их. while True: answer = bot.pop_phrase(user_id) if len(answer) == 0: break print_answer(u'B:>', answer) question = input_kbd('H:>') if len(question) > 0: if question.lower() in ('r\exit', r'\q', r'\quit', '/stop'): break bot.push_phrase(user_id, question)
bot.add_event_handler(u'buy_pizza', on_buy_pizza) if args.greeting: bot.start_conversation(user_id) flush_logging() print_tech_banner() while True: print('\n') # В самом начале диалога, когда еще не было ни одной реплики, # бот может сгенерировать некое приветствие или вопрос для # завязывания беседы. Поэтому сразу извлечем сгенерированные фразы из # буфера и покажем их. while True: answer = bot.pop_phrase(user_id) if len(answer) == 0: break print_answer(u'B:>', answer) question = input_kbd('H:>') if len(question) > 0: if question.lower() in (r'\exit', r'\q', r'\quit', '/stop'): break # 25-07-2020 пустая фраза имитирует ситуацию тупика в диалоге, бот должен попытаться # предложить продолжение... bot.push_phrase(user_id, question)