Beispiel #1
0
def init_chatbot():
    if 'bot' not in flask_app.config:
        logging.info('init_chatbot: models_folder="%s"', models_folder)

        # 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 = True  # включаем расширенную трассировку работы движка

        # Контейнер для правил
        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='flask_bot',
                             engine=machine,
                             facts=profile_facts,
                             faq=faq_storage,
                             scripting=scripting,
                             profile=profile)

        def on_order(order_anchor_str, bot, session):
            bot.say(session, 'Выполняю команду "{}"'.format(order_anchor_str))

        bot.on_process_order = on_order

        flask_app.config['bot'] = bot
        logging.info('init_chatbot complete')
Beispiel #2
0
def create_chatbot(profile_path, models_folder, w2v_folder, data_folder, debugging, bot_id='test_bot'):
    # 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 = 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=bot_id,
                         engine=machine,
                         facts=profile_facts,
                         faq=faq_storage,
                         scripting=scripting,
                         profile=profile)

    return bot
Beispiel #3
0
def create_chatbot(profile_path,
                   models_folder,
                   w2v_folder,
                   data_folder,
                   debugging,
                   bot_id='test_bot',
                   chitchat_config=None,
                   enable_verbal_forms=False):
    """Создаем и инициализируем экземпляр чатбота с заданным профилем """

    # NLP pileline: содержит инструменты для работы с текстом, включая морфологию и таблицы словоформ,
    # part-of-speech tagger, NP chunker и прочее.
    text_utils = TextUtils()
    if enable_verbal_forms:
        text_utils.load_embeddings(w2v_dir=w2v_folder, wc2v_dir=models_folder)
    else:
        text_utils.load_embeddings(w2v_dir=w2v_folder, wc2v_dir=None)
    text_utils.load_dictionaries(data_folder, models_folder)

    # Настроечные параметры аватара собраны в профиле - файле в json формате.
    profile = BotProfile()
    profile.load(profile_path, data_folder, models_folder)

    # Контейнер для правил
    scripting = BotScripting(data_folder)
    scripting.load_rules(profile.rules_path,
                         profile.smalltalk_generative_rules, profile.constants,
                         text_utils)

    # Добавляем скрипты на питоне
    scripting.add_scenario(Scenario_WhoAmI())

    # Инициализируем движок вопросно-ответной системы. Он может обслуживать несколько
    # ботов с разными провилями (базами фактов и правил), хотя тут у нас будет работать только один.
    machine = SimpleAnsweringMachine(text_utils=text_utils)
    machine.load_models(scripting.get_rule_paths(), data_folder, models_folder,
                        profile.constants, enable_verbal_forms)
    machine.trace_enabled = debugging

    # Пробуем подцепить локальный сервис читчата
    if chitchat_config is not None and chitchat_config.service_endpoint:
        probe_chitchat_url = chitchat_config.service_endpoint
        try:
            chitchat_response = requests.get(probe_chitchat_url + '/')
            if chitchat_response.ok:
                machine.chitchat_config = chitchat_config
        except Exception as ex:
            # веб-сервис чит-чата недоступен...
            pass

    # Конкретная реализация хранилища фактов - плоские файлы в 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=bot_id,
                         engine=machine,
                         facts=profile_facts,
                         faq=faq_storage,
                         scripting=scripting,
                         profile=profile)

    return bot
Beispiel #4
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)
Beispiel #5
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)