def say(self, session, answer): self.logger.info(u'say "%s"', answer) answer_interpretation = InterpretedPhrase(answer) answer_interpretation.is_bot_phrase = True answer_interpretation.set_modality(*self.modality_model.get_modality( answer, self.text_utils, self.word_embeddings)) session.add_to_buffer(answer) session.add_phrase_to_history(answer_interpretation)
def do_action(self, bot, session, interlocutor, interpreted_phrase): uttered = False wordbag = [] for question in self.wordbag_questions: if bot.get_engine().does_bot_know_answer(question, bot, session, interlocutor): interpreted_phrase2 = InterpretedPhrase(question) answers = bot.get_engine().build_answers(session, bot, interlocutor, interpreted_phrase2) for answer in answers: tokens = bot.get_engine().get_text_utils().tokenize(answer) wordbag.extend((word, 1.0) for word in tokens) wordbag.extend((word, 1.0) for word in self.wordbag_words) if len(wordbag) > 0: replicas = [] for template_str in self.templates: replicas1 = bot.get_engine().replica_grammar.generate_by_terms(template_str, wordbag, bot.get_engine().get_text_utils().known_words, use_assocs=False) replicas.extend(replicas1) if len(replicas) > 0: # Выбираем одну рандомную реплику среди сгенерированных. # TODO: взвешивать через модель уместности по контексту bot.say(session, bot.get_engine().select_relevant_replica(replicas, session, interlocutor)) uttered = True return uttered
def do_action(self, bot, session, interlocutor, interpreted_phrase, condition_matching_results, text_utils): if self.np_sources: if condition_matching_results is None: condition_matching_results = RuleConditionMatching.create(True) for np, question in self.np_sources.items(): if bot.get_engine().does_bot_know_answer( question, bot, session, interlocutor): interpreted_phrase2 = InterpretedPhrase(question) answers = bot.get_engine().build_answers( session, bot, interlocutor, interpreted_phrase2) if answers: answer = answers[0] tokens = text_utils.tokenize(answer) tagsets = list(text_utils.postagger.tag(tokens)) lemmas = text_utils.lemmatizer.lemmatize(tagsets) phrase_tokens = [] for word_index, (token, tagset, lemma) in enumerate( zip(tokens, tagsets, lemmas)): t = PhraseToken() t.word = token t.norm_word = token.lower() t.lemma = lemma[2] t.tagset = tagset[1] t.word_index = word_index phrase_tokens.append(t) condition_matching_results.add_group( np, tokens, phrase_tokens) else: return None # Сначала попробуем убрать из списка те реплики, которые мы уже произносили. new_utterances = [] for utterance0 in self.phrases: utterance = self.prepare4saying(utterance0, condition_matching_results, text_utils) if '$' in utterance: # Не удалось подставить значение в один из $-слотов, значит # надо исключить фразу. continue if session.count_bot_phrase(utterance) == 0: if self.known_answer_policy == 'skip' and utterance[-1] == '?': # Проверим, что бот еще не знает ответ на этот вопрос: if bot.does_bot_know_answer(utterance, session, interlocutor): continue new_utterances.append(utterance) uttered = False if len(new_utterances) > 0: # Выбираем одну из оставшихся фраз. if len(new_utterances) == 1: bot.say(session, new_utterances[0]) else: bot.say(session, random.choice(new_utterances)) uttered = True else: # Все фразы бот уже произнес # Если задан список фраз на случай исчерпания (типа "не знаю больше ничего про кошек"), # то выдадим одну из них. new_utterances = [] for utterance0 in self.exhausted_phrases: utterance = self.prepare4saying(utterance0, condition_matching_results, text_utils) if '$' in utterance: # Не удалось подставить значение в один из $-слотов, значит # надо исключить фразу. continue if session.count_bot_phrase(utterance) == 0: if self.known_answer_policy == 'skip' and utterance[ -1] == '?': # Проверим, что бот еще не знает ответ на этот вопрос: if bot.does_bot_know_answer(utterance, session, interlocutor): continue new_utterances.append(utterance) if new_utterances: bot.say(session, random.choice(new_utterances)) uttered = True else: if self.known_answer_policy == 'skip': pass else: # Начиная с этого момента данное правило будет повторно выдавать # одну из фраз. #for src_phrase in sorted(self.phrases, key=lambda z: random.random()): # random_phrase = self.prepare4saying(src_phrase, condition_matching_results, text_utils) # if '$' not in random_phrase: # bot.say(session, random_phrase) # uttered = True # break uttered = False return uttered
def interpret_phrase(self, bot, session, raw_phrase, internal_issuer): interpreted = InterpretedPhrase(raw_phrase) phrase = raw_phrase phrase_modality, phrase_person = self.modality_model.get_modality( phrase, self.text_utils, self.word_embeddings) phrase_is_question = phrase_modality == ModalityDetector.question # история фраз доступна в session как conversation_history was_interpreted = False last_phrase = session.conversation_history[-1] if len( session.conversation_history) > 0 else None if not internal_issuer: # Интерпретация вопроса собеседника (человека): # (H) Ты яблоки любишь? # (B) Да # (H) А виноград? <<----- == Ты виноград любишь? if len(session.conversation_history) > 1 and phrase_is_question: last2_phrase = session.conversation_history[ -2] # это вопрос человека "Ты яблоки любишь?" if not last2_phrase.is_bot_phrase\ and last2_phrase.is_question\ and self.interpreter is not None: if self.req_interpretation.require_interpretation( raw_phrase, self.text_utils, self.word_embeddings): context_phrases = list() # Контекст состоит из двух предыдущих фраз context_phrases.append(last2_phrase.raw_phrase) context_phrases.append(last_phrase.raw_phrase) context_phrases.append(raw_phrase) phrase = self.interpreter.interpret( context_phrases, self.text_utils, self.word_embeddings) if self.intent_detector is not None: interpreted.intent = self.intent_detector.detect_intent( raw_phrase, self.text_utils, self.word_embeddings) self.logger.debug(u'intent="%s"', interpreted.intent) was_interpreted = True # and last_phrase.is_question\ if not was_interpreted\ and len(session.conversation_history) > 0\ and last_phrase.is_bot_phrase\ and not phrase_is_question\ and self.interpreter is not None: if self.req_interpretation.require_interpretation( raw_phrase, self.text_utils, self.word_embeddings): # В отдельной ветке обрабатываем ситуацию, когда бот # задал вопрос или квази-вопрос типа "А давай xxx", на который собеседник дал краткий ответ. # с помощью специальной модели мы попробуем восстановить полный # текст ответа собеседника. context_phrases = list() context_phrases.append(last_phrase.interpretation) context_phrases.append(raw_phrase) phrase = self.interpreter.interpret( context_phrases, self.text_utils, self.word_embeddings) if self.intent_detector is not None: interpreted.intent = self.intent_detector.detect_intent( raw_phrase, self.text_utils, self.word_embeddings) self.logger.debug(u'intent="%s"', interpreted.intent) was_interpreted = True if not interpreted.intent: if self.intent_detector is not None: interpreted.intent = self.intent_detector.detect_intent( raw_phrase, self.text_utils, self.word_embeddings) self.logger.debug(u'intent="%s"', interpreted.intent) if was_interpreted: phrase = self.interpreter.normalize_person(phrase, self.text_utils, self.word_embeddings) if not internal_issuer: # Попробуем найти шаблон трансляции, достаточно похожий на эту фразу. # Может получиться так, что введенная императивная фраза станет обычным вопросом: # "назови свое имя!" ==> "Как тебя зовут?" translated_str = self.translate_interlocutor_replica( bot, session, phrase) if translated_str is not None: phrase = translated_str raw_phrase = translated_str phrase_modality, phrase_person = self.modality_model.get_modality( phrase, self.text_utils, self.word_embeddings) was_interpreted = True if not was_interpreted: phrase = self.interpreter.normalize_person(raw_phrase, self.text_utils, self.word_embeddings) # TODO: Если результат интерпретации содержит мусор, то не нужно его обрабатывать. # Поэтому тут надо проверить phrase с помощью верификатора синтаксиса. # ... interpreted.interpretation = phrase interpreted.set_modality(phrase_modality, phrase_person) return interpreted