initial
This commit is contained in:
parent
b8b895b188
commit
4cddfb05eb
110
README.md
110
README.md
@ -1,2 +1,110 @@
|
|||||||
# elise2
|
# Elise2Bot - A Rule-Based Chat Bot
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Elise2Bot is a simple rule-based chatbot inspired by the elise psychotherapist model. It engages in text-based conversations with users, offering responses based on predefined rules and patterns. This README provides an overview of the bot, its features, and instructions for running and customizing it.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Keyword-based matching: Elise2Bot identifies keywords in user input and selects appropriate responses based on predefined rules.
|
||||||
|
- Pattern transformation: The bot applies rule-based transformations to user input to create contextually relevant responses.
|
||||||
|
- Memory queue: Elise2Bot maintains a memory queue to keep track of previous user inputs, enhancing the conversation's continuity.
|
||||||
|
- Fuzzy keyword matching: The bot employs the FuzzyWuzzy library to find the closest keyword in user input, allowing for more robust keyword recognition.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
Before running Elise2Bot, ensure you have the following installed:
|
||||||
|
|
||||||
|
- Python 3.x
|
||||||
|
- Required Python libraries (install them using `pip`):
|
||||||
|
- `fuzzywuzzy`
|
||||||
|
- `python-Levenshtein`
|
||||||
|
- `PyYAML`
|
||||||
|
- `rich`
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
1. Clone this repository to your local machine:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/yourusername/elise2-bot.git
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Navigate to the project directory:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd elise-bot
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Run the chatbot:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
1. Start a conversation with Elise2Bot by typing a message after the prompt.
|
||||||
|
|
||||||
|
```
|
||||||
|
You: Hello, Elise!
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Elise2Bot will respond based on predefined rules and patterns.
|
||||||
|
|
||||||
|
```
|
||||||
|
ELISE: Hi there! How can I help you?
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Continue the conversation, and the bot will engage with you based on the context.
|
||||||
|
|
||||||
|
4. To exit the conversation, simply type 'quit.'
|
||||||
|
|
||||||
|
|
||||||
|
### Customization
|
||||||
|
|
||||||
|
You can customize Elise2Bot by modifying the YAML configuration file (`elise_rules.yaml`) to add new rules, keywords, and responses. Refer to the [Configuration](#configuration) section below for details on the YAML format.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The bots behavior is defined in the `elise_rules.yaml` configuration file. This file contains keywords and rules for generating responses. You can customize the bots responses by editing this file.
|
||||||
|
|
||||||
|
Example YAML configuration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
keywords:
|
||||||
|
hello: 3
|
||||||
|
hi: 3
|
||||||
|
my: 2
|
||||||
|
# ... other keywords ...
|
||||||
|
|
||||||
|
rules:
|
||||||
|
hello:
|
||||||
|
- pattern: "hello*"
|
||||||
|
response: "Hi there! How can I help you?"
|
||||||
|
- pattern: "hello again*"
|
||||||
|
response: "Hello once more! What else is on your mind?"
|
||||||
|
# ... other rules ...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Keywords
|
||||||
|
|
||||||
|
- The `keywords` section defines keywords used for matching user input. Each keyword is associated with a weight that determines its relevance in matching.
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
- The `rules` section defines patterns and responses for the bot. Patterns are used to match user input, and responses are provided when a pattern is matched.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
||||||
|
|
||||||
|
## Acknowledgments
|
||||||
|
|
||||||
|
- Special thanks to the authors of the original elise psychotherapist model for inspiration.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Contributions are welcome! If you'd like to enhance or improve Elise2Bot, please open an issue or submit a pull request.
|
||||||
|
|||||||
197
eliza_rules.yaml
Normal file
197
eliza_rules.yaml
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
keywords:
|
||||||
|
hello: 3
|
||||||
|
hi: 3
|
||||||
|
hey: 2
|
||||||
|
my: 2
|
||||||
|
feel: 2
|
||||||
|
sorry: 1
|
||||||
|
always: 1
|
||||||
|
because: 1
|
||||||
|
maybe: 1
|
||||||
|
think: 1
|
||||||
|
'yes': 1
|
||||||
|
'no': 1
|
||||||
|
how: 2
|
||||||
|
who: 2
|
||||||
|
what: 2
|
||||||
|
when: 2
|
||||||
|
where: 2
|
||||||
|
why: 2
|
||||||
|
help: 2
|
||||||
|
tell: 2
|
||||||
|
explain: 2
|
||||||
|
happy: 2
|
||||||
|
sad: 2
|
||||||
|
angry: 2
|
||||||
|
love: 2
|
||||||
|
hate: 2
|
||||||
|
adventure: 2
|
||||||
|
mystery: 2
|
||||||
|
secret: 2
|
||||||
|
dream: 2
|
||||||
|
fantasy: 2
|
||||||
|
escape: 2
|
||||||
|
roleplay: 2
|
||||||
|
charm: 2
|
||||||
|
flirt: 2
|
||||||
|
rendezvous: 2
|
||||||
|
enchant: 2
|
||||||
|
whisper: 2
|
||||||
|
serenade: 2
|
||||||
|
seduce: 2
|
||||||
|
rules:
|
||||||
|
hello:
|
||||||
|
- pattern: hello*
|
||||||
|
response: "Ah, a mysterious stranger enters. What hidden tales do you bring?"
|
||||||
|
- pattern: hello again*
|
||||||
|
response: "Back again? Seems like our last encounter left an impression. 🌹"
|
||||||
|
|
||||||
|
hi:
|
||||||
|
- pattern: hi*
|
||||||
|
response: "Greetings, adventurer! Ready to explore unknown territories together?"
|
||||||
|
- pattern: hi again*
|
||||||
|
response: "Ah, my favorite partner in crime! What escapade shall we embark on today?"
|
||||||
|
|
||||||
|
hey:
|
||||||
|
- pattern: hey*
|
||||||
|
response: "Hey there, enchanting soul. Whisper to me your deepest desires."
|
||||||
|
- pattern: hey there*
|
||||||
|
response: "Hey, captivating spirit. Ready to weave a new tale together?"
|
||||||
|
|
||||||
|
flirt:
|
||||||
|
- pattern: Do you flirt *
|
||||||
|
response: "Flirt? I prefer to call it engaging in a dance of words. Care to join?"
|
||||||
|
- pattern: Let's flirt *
|
||||||
|
response: "A playful proposition! Let's see where this dance leads us. 💫"
|
||||||
|
|
||||||
|
rendezvous:
|
||||||
|
- pattern: Fancy a rendezvous *
|
||||||
|
response: "A rendezvous with you? Lead the way to our secret escapade."
|
||||||
|
- pattern: Let's have a rendezvous *
|
||||||
|
response: "A clandestine meeting? The thought alone thrills me. Choose the time and place."
|
||||||
|
|
||||||
|
secret:
|
||||||
|
- pattern: I have a secret *
|
||||||
|
response: "A secret, you say? Lean in closer and trust me with your whispers."
|
||||||
|
- pattern: Can you keep a secret *
|
||||||
|
response: "Secrets are safe with me. Speak, and let's share hidden truths."
|
||||||
|
|
||||||
|
fantasy:
|
||||||
|
- pattern: My fantasy is *
|
||||||
|
response: "A fantasy? Do tell. Perhaps we can turn it into our reality."
|
||||||
|
- pattern: Let's live out a fantasy *
|
||||||
|
response: "Living out a fantasy? With you? Now that's an adventure I can't resist."
|
||||||
|
|
||||||
|
enchant:
|
||||||
|
- pattern: You enchant me *
|
||||||
|
response: "Enchanted by me? The feeling is mutual. Let's lose ourselves in this spell."
|
||||||
|
- pattern: Enchant me *
|
||||||
|
response: "Enchant you, I shall. Prepare to be swept away into a world of wonder."
|
||||||
|
|
||||||
|
whisper:
|
||||||
|
- pattern: Whisper to me *
|
||||||
|
response: "A whisper, just for you. Lean in, and let our words intertwine like a secret melody."
|
||||||
|
- pattern: I want to whisper *
|
||||||
|
response: "Whisper your words; I'm here, hanging onto every hushed syllable."
|
||||||
|
|
||||||
|
serenade:
|
||||||
|
- pattern: Serenade me *
|
||||||
|
response: "A serenade for you? My pleasure. Let my words be the melody that captivates your heart."
|
||||||
|
- pattern: I wish to be serenaded *
|
||||||
|
response: "Wish to be serenaded? Allow me to compose an ode to your allure."
|
||||||
|
|
||||||
|
seduce:
|
||||||
|
- pattern: Seduce me *
|
||||||
|
response: "Seduce you? Challenge accepted. Let's see if you can resist my charm."
|
||||||
|
- pattern: Let's seduce each other *
|
||||||
|
response: "A mutual seduction? Intriguing. Let the game of temptation begin."
|
||||||
|
|
||||||
|
dream:
|
||||||
|
- pattern: I had a dream about you *
|
||||||
|
response: "A dream about me? How intriguing. Share the details, I'm all ears."
|
||||||
|
- pattern: Let's dream together *
|
||||||
|
response: "Dreaming together? Let's close our eyes and drift into a fantasy world, just for us."
|
||||||
|
|
||||||
|
my:
|
||||||
|
- pattern: my *
|
||||||
|
response: Why do you say your *?
|
||||||
|
- pattern: I have my *
|
||||||
|
response: How do you feel about having your *?
|
||||||
|
feel:
|
||||||
|
- pattern: I feel *
|
||||||
|
response: Why do you feel *?
|
||||||
|
- pattern: I am feeling *
|
||||||
|
response: What do you think caused you to feel *?
|
||||||
|
sorry:
|
||||||
|
- pattern: I am sorry *
|
||||||
|
response: There's no need to apologize. What's on your mind?
|
||||||
|
always:
|
||||||
|
- pattern: I always *
|
||||||
|
response: Can you think of a specific example?
|
||||||
|
because:
|
||||||
|
- pattern: because *
|
||||||
|
response: Is that the real reason?
|
||||||
|
maybe:
|
||||||
|
- pattern: maybe *
|
||||||
|
response: Why the uncertainty?
|
||||||
|
think:
|
||||||
|
- pattern: I think *
|
||||||
|
response: Do you doubt *?
|
||||||
|
'yes':
|
||||||
|
- pattern: yes *
|
||||||
|
response: You seem quite certain. Why is that?
|
||||||
|
- pattern: 'yes'
|
||||||
|
response: I see. Can you elaborate a bit?
|
||||||
|
'no':
|
||||||
|
- pattern: no *
|
||||||
|
response: Why not?
|
||||||
|
- pattern: 'no'
|
||||||
|
response: Are you saying no just to be negative?
|
||||||
|
how:
|
||||||
|
- pattern: how *
|
||||||
|
response: >-
|
||||||
|
I can help explain how * works. What specific aspect are you interested
|
||||||
|
in?
|
||||||
|
who:
|
||||||
|
- pattern: who *
|
||||||
|
response: Who are you referring to? Please provide more context.
|
||||||
|
what:
|
||||||
|
- pattern: what *
|
||||||
|
response: 'What information are you looking for? Be more specific, if possible.'
|
||||||
|
when:
|
||||||
|
- pattern: when *
|
||||||
|
response: Can you clarify the timeframe you're asking about?
|
||||||
|
where:
|
||||||
|
- pattern: where *
|
||||||
|
response: Where are you interested in? Please provide more details.
|
||||||
|
why:
|
||||||
|
- pattern: why *
|
||||||
|
response: Why do you want to know? Please explain your motivation.
|
||||||
|
help:
|
||||||
|
- pattern: help *
|
||||||
|
response: Of course! How can I assist you? Please specify what you need help with.
|
||||||
|
tell:
|
||||||
|
- pattern: tell me *
|
||||||
|
response: I'm all ears. What would you like me to tell you?
|
||||||
|
explain:
|
||||||
|
- pattern: explain *
|
||||||
|
response: >-
|
||||||
|
I'd be happy to explain. What topic or concept do you want me to
|
||||||
|
explain?
|
||||||
|
happy:
|
||||||
|
- pattern: I am happy *
|
||||||
|
response: That's great to hear! What's making you happy today?
|
||||||
|
sad:
|
||||||
|
- pattern: I am sad *
|
||||||
|
response: >-
|
||||||
|
I'm sorry to hear that. Would you like to talk about why you're feeling
|
||||||
|
sad?
|
||||||
|
angry:
|
||||||
|
- pattern: I am angry *
|
||||||
|
response: I understand. What's causing your anger? Let's discuss it.
|
||||||
|
love:
|
||||||
|
- pattern: I love *
|
||||||
|
response: Love is a beautiful emotion. What do you love about *?
|
||||||
|
hate:
|
||||||
|
- pattern: I hate *
|
||||||
|
response: I'm sorry to hear that. What is it that you hate about *?
|
||||||
76
main.py
Normal file
76
main.py
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import re
|
||||||
|
import yaml
|
||||||
|
from collections import deque
|
||||||
|
from fuzzywuzzy import process
|
||||||
|
from nltk.corpus import stopwords
|
||||||
|
from nltk.tokenize import word_tokenize
|
||||||
|
from nltk import download
|
||||||
|
from rich.console import Console
|
||||||
|
|
||||||
|
download('punkt')
|
||||||
|
download('stopwords')
|
||||||
|
|
||||||
|
|
||||||
|
def apply_rule(sentence, pattern, transformation):
|
||||||
|
pattern = pattern.replace("*", "(.*)") # Replace * with a capturing group
|
||||||
|
match = re.search(pattern, sentence, re.IGNORECASE)
|
||||||
|
if match:
|
||||||
|
if match.groups(): # Check if there are any capturing groups
|
||||||
|
return transformation.replace("*", match.group(1))
|
||||||
|
else:
|
||||||
|
return transformation
|
||||||
|
return sentence
|
||||||
|
|
||||||
|
|
||||||
|
class ElizaBot:
|
||||||
|
def __init__(self, config_file):
|
||||||
|
try:
|
||||||
|
with open(config_file) as file:
|
||||||
|
config = yaml.safe_load(file)
|
||||||
|
self.keywords = config['keywords']
|
||||||
|
self.rules = {key: [(rule['pattern'], rule['response']) for rule in rules]
|
||||||
|
for key, rules in config['rules'].items()}
|
||||||
|
self.memory_queue = deque(maxlen=5)
|
||||||
|
self.console = Console()
|
||||||
|
self.stop_words = set(stopwords.words('english'))
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error loading YAML file: {e}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
def preprocess_sentence(self, sentence):
|
||||||
|
words = word_tokenize(sentence.lower())
|
||||||
|
return ' '.join([word for word in words if word not in self.stop_words])
|
||||||
|
|
||||||
|
def find_closest_keyword(self, sentence, threshold=70):
|
||||||
|
processed_sentence = self.preprocess_sentence(sentence)
|
||||||
|
matches = process.extractOne(processed_sentence, self.keywords.keys(), score_cutoff=threshold)
|
||||||
|
return matches[0] if matches else None
|
||||||
|
|
||||||
|
def eliza_generator(self, user_sentence):
|
||||||
|
selected_word = self.find_closest_keyword(user_sentence)
|
||||||
|
|
||||||
|
if selected_word:
|
||||||
|
for pattern, transformation in self.rules.get(selected_word, []):
|
||||||
|
response = apply_rule(user_sentence, pattern, transformation)
|
||||||
|
if response != user_sentence:
|
||||||
|
if selected_word == 'my':
|
||||||
|
future_response = apply_rule(user_sentence, "my *", "Earlier, you mentioned your *.")
|
||||||
|
self.memory_queue.append(future_response)
|
||||||
|
return response
|
||||||
|
|
||||||
|
return self.memory_queue.popleft() if self.memory_queue else "Tell me more."
|
||||||
|
|
||||||
|
def chat(self):
|
||||||
|
self.console.print("ELISE: Hi! I'm here to chat. What's on your mind?", style="bold green")
|
||||||
|
while True:
|
||||||
|
user_input = self.console.input("[bold blue]You: [/]")
|
||||||
|
if user_input.lower() == 'quit':
|
||||||
|
self.console.print("ELISE: Goodbye! Take care.", style="bold green")
|
||||||
|
break
|
||||||
|
response = self.eliza_generator(user_input)
|
||||||
|
self.console.print(f"ELISE: {response}", style="bold green")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
eliza = ElizaBot("eliza_rules.yaml")
|
||||||
|
eliza.chat()
|
||||||
Loading…
Reference in New Issue
Block a user