Search code examples
pythonpython-3.xchatbotchatterbot

How to turn off repeated response filter for my chatterbot


I am working on making a chatbot with the chatterbot library in python and it was sometimes not responding correctly, I turned on logging and found that it was because it was excluding responses that it recently used and then defaulted to the "unknown" response I have set. You can see an excerpt from the logs below: User: hi

INFO:chatterbot.chatterbot:Beginning search for close text match INFO:chatterbot.chatterbot:Processing search results INFO:chatterbot.chatterbot:Similar text found: Hi 1.0 INFO:chatterbot.chatterbot:Using "Hi" as a close match to "hi" with a confidence of 1.0 INFO:chatterbot.chatterbot:0. Excluding recent repeated response of "hi" INFO:chatterbot.chatterbot:1. Excluding recent repeated response of "Hi there, I am Minerva, how can I help you?" INFO:chatterbot.chatterbot:No responses found. Generating alternate response list.

I found out about the recent response filter in the documentation here but there is no explanation of how to turn it off or disable it, it is on by default as I have no filters specified in my chatbot code.

I was wondering if anyone knew how to remove the filter? I don't care if my chatbot repeats itself over and over.


Solution

  • It doesn't seem like there's any configuration to turn off this feature, because it's hardcoded in the BestMatch logic adapter:

    class BestMatch(LogicAdapter):
        def process(self, input_statement, additional_response_selection_parameters=None):
            ...
            recent_repeated_responses = filters.get_recent_repeated_responses(
                self.chatbot,
                input_statement.conversation
            )
            
            for index, recent_repeated_response in enumerate(recent_repeated_responses):
                self.chatbot.logger.info('{}. Excluding recent repeated response of "{}"'.format(
                    index, recent_repeated_response
                ))
            ...
    

    And the filters.get_recent_repeated_responses function doesn't provide a way to turn it off either:

    def get_recent_repeated_responses(chatbot, conversation, sample=10, threshold=3, quantity=3):
        """
        A filter that eliminates possibly repetitive responses to prevent
        a chat bot from repeating statements that it has recently said.
        """
        from collections import Counter
    
        # Get the most recent statements from the conversation
        conversation_statements = list(chatbot.storage.filter(
            conversation=conversation,
            order_by=['id']
        ))[sample * -1:]
    
        text_of_recent_responses = [
            statement.text for statement in conversation_statements
        ]
    
        counter = Counter(text_of_recent_responses)
    
        # Find the n most common responses from the conversation
        most_common = counter.most_common(quantity)
    
        return [
            counted[0] for counted in most_common
            if counted[1] >= threshold
        ]
    

    I can think of two ways to get around it:

    Create a copy of the logic adapter BestMatch without the offending lines and specifying it during setup:

    from chatterbot.logic import LogicAdapter
    class BestMatchWithRepetitions(BestMatch):
        def process(self, input_statement, additional_response_selection_parameters=None):
            ...
    
    chatbot = ChatBot(
        "My ChatterBot",
        logic_adapters=[
            # Untested, might need to specify it in another way.
            "BestMatchWithRepetitions"
        ]
    )
    

    Or, for a very hacky solution, you can monkey-patch the filters package:

    from chatterbot import filters
    filters.get_recent_repeated_responses = lambda *args, **kwargs: []