Close

Why is it so difficult to write an intelligent chatbot program?

A project log for Spectrum Tera

A long-term robot project

m-bindhammerM. Bindhammer 05/06/2023 at 14:580 Comments

The reason for this is that the computer can handle mathematics very well but text or text processing can hardly be described mathematically. Thus, less than 40 lines of code are sufficient to realize a calculator that performs the four basic arithmetic operations of two numbers, unthinkable for text processing.

float number1;
float number2;
char Arithmetic_Operator;

void setup() {
  Serial.begin(9600);
}

void loop() {
  while(Serial.available() > 0) {
    number1 = Serial.parseFloat();
    Arithmetic_Operator = Serial.read(); 
    number2 = Serial.parseFloat();
    Serial.print(number1);
    Serial.print(Arithmetic_Operator);
    Serial.print(number2);
    Serial.print(" = ");
    Serial.println(calculate());
  }
}

float calculate() {
  float result;
  switch(Arithmetic_Operator) {
    case '+':
    result = number1 + number2;
    break;
    case '-':
    result = number1 - number2;
    break;
    case '*':
    result = number1 * number2;
    break;
    case '/':
    result = number1 / number2;
    break;
  }
  return result;
}

The vast majority of chatbots only feign intelligence. They are based on a little probability theory but above all on brute force and the Internet as a database. A traditional approach is the keyword method. The machine searches the user input string for a keyword stored in a lookup table and outputs a corresponding ready-made response. If the machine does not find a keyword, the machine tries to get the user to enter a keyword that the machine knows. The famous program ELIZA uses exactly this technique. It was developed in 1966 by Joseph Weizenbaum and is considered the first chatbot in the history of computer science. So if we want to program a truly intelligent chatbot, we have no choice but to describe text mathematically. What a complex task this is can be seen just by looking at the English language: more than a million words in total, about 170,000 words in current use, and 20,000-30,000 words used by each individual. Of course, there are an infinite number of numbers, but each number has a strictly defined mathematical relationship to another number.

To make one thing clear: Keywords are not a bad approach at all, because our brain also works with them. I remember when I lived in China and started to learn the Chinese language, I always looked for keywords in Chinese conversations that I already understood, so I could roughly deduce what the conversation was about. It is not particularly difficult to write a small program that finds keywords in a text respectively a String.

char *keywords[] = {"CAT", "DOG", "BIRD", "HOUSE"};

void setup() {
  Serial.begin(9600);
}

void loop() {
  bool keyword_flag = false;
  Serial.println("User input:");
  while (Serial.available() == 0) {} // Wait for data available
  String userInput = Serial.readString(); // Read until timeout
  userInput.trim(); // Remove any whitespace at the end of the String
  userInput.toUpperCase(); // Get an upper-case version of the String
  Serial.println(userInput);
  for (int i = 0; i < sizeof(keywords)/sizeof(char *); i ++) {
    if (strstr(userInput.c_str(), keywords[i]) != 0) {
      Serial.print("Keyword ");
      Serial.print(keywords[i]);
      Serial.println(" found");
      keyword_flag = true;
    }
  }
  if(keyword_flag == false) Serial.println("No keyword found");
}

Let's take my example with the Chinese keywords and try to model my thoughts then.

char *keywords[] = {"CAT", "DOG", "BIRD", "HOUSE", "LOVE", "HATE"};
char *responses[] = {"A CAT", "A DOG", "A BIRD", "A HOUSE", "LOVE", "HATE"};

void setup() {
  Serial.begin(9600);
}

void loop() {
  bool keyword_flag = false;
  Serial.print("Conversation: ");
  while (Serial.available() == 0) {} // Wait for data available
  String Conversation = Serial.readString(); // Read until timeout
  Conversation.trim(); // Remove any whitespace at the end of the String
  Conversation.toUpperCase(); // Get an upper-case version of the String
  Serial.println(Conversation);
  int keyword_counter = 1;
  for (int i = 0; i < sizeof(keywords)/sizeof(char *); i ++) {
    if (strstr(Conversation.c_str(), keywords[i]) != 0) {
      if(keyword_counter == 1) Serial.print("Me: They are probably talking about ");
      keyword_counter ++;
      if(keyword_counter > 2) Serial.print(" and ");
      Serial.print(responses[i]);
      keyword_flag = true;
    }
  }
  if(keyword_flag == false) {
    Serial.println("Me: I don't understand anything");
    Serial.println();
  }
  else {
    Serial.println();
    Serial.println();
  }
}

So far so good. However, my thoughts did not end there. I tried to figure out what the real core of the conversation was. Since my vocabulary was still very small at that time, I often had no choice but to weigh probabilities against each other.

Discussions