Esempio n. 1
0
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)
Esempio n. 2
0
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)
Esempio n. 3
0
    logging.debug('Bot loading...')
    bot = create_chatbot(profile_path, models_folder, w2v_folder, data_folder, args.debugging, chitchat_config=rugpt_chitchat_config)

    # Выполняем привязку обработчиков
    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)

    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)