Mudanças entre as edições de "Chatbots"

De Aulas
 
(3 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
Assuntos relacionados: [[Inteligência Artificial]]
+
Afluentes: [[Inteligência Artificial]]
  
 
= Material Didático =
 
= Material Didático =
Linha 7: Linha 7:
 
* [https://{{SERVERNAME}}/aulas/ia/chatbot/aiml.zip Arquivos de exemplos básicos em AIML]
 
* [https://{{SERVERNAME}}/aulas/ia/chatbot/aiml.zip Arquivos de exemplos básicos em AIML]
 
* [https://github.com/weddige/pyaiml3 PyAIML3]
 
* [https://github.com/weddige/pyaiml3 PyAIML3]
* [https://github.com/saulopz/Acaro Ácaro]: um exemplo simples de chatbot.
+
* [https://github.com/saulopz/Acaro Ácaro]: um exemplo simples de chatbot em java (não usa AIML).
  
; Código do chatbot
+
== Código do Chatbot ==
 
+
O programa em linguagem de programação python abaixo cria um prompt de interação do interpretador AIML do PyAIML3 com o usuário.<syntaxhighlight lang="python">
<syntaxhighlight lang=python line>
 
 
import sys
 
import sys
 
import aiml
 
import aiml
 +
import unicodedata
 +
import re
  
kb = sys.argv[1]
+
# Efetua uma filtragem no texto de entrada
 +
def filter(text):
 +
    # Normaliza o texto entrado como parâmetro e remove os acentos
 +
    text = unicodedata.normalize('NFKD', text).encode('ASCII', 'ignore').decode('utf-8')
 +
    # Remove pontuação e caracteres especiais
 +
    text = re.sub(r'[^\w\s]', '', text)
 +
    return text
  
k = aiml.Kernel()
+
kb = sys.argv[1]                    # Pega a base AIML entrada por parâmetro
k.learn(kb)
+
k = aiml.Kernel()                   # Inicializa o motor de interpretação AIML
#k.respond("load aiml b")
+
k.learn(kb)                         # Insere a base AIML no motor para aprendizado
while True: print(k.respond(input("> ")))
+
while True:                        # Executa o laço indefinidamente
</syntaxhighlight>
+
    message = input("> ")           # Inicializa o prompt do chatbot
 
+
    message = filter(message)      # Limpa a mensagem entrada pelo usuário
= Instalando o Plugin do RebeccaAIML no Eclipse =
+
    response = k.respond(message)  # Envia ao motor e retorna a resposta
 
+
    print(response)                 # Imprime a resposta
# Fazer o download do [http://prdownloads.sourceforge.net/rebecca-aiml/RebeccaAIML_eclipse_plugin.zip?download Plugin do RebeccaAIML] para o eclipse;
+
</syntaxhighlight>É importante observar que deve ser feita uma filtragem na mensagem de entrada do usuário. Não deve ter caracteres especiais, acentos, etc. Para isso, criamos a função filter.
# Descompactar o arquivo zipado;
 
# Copiar os arquivos JAR para a pasta plugin do eclipse;
 
  
 
= AIML =
 
= AIML =
Linha 44: Linha 49:
 
== Documento Simples - ''Hello World'' ==
 
== Documento Simples - ''Hello World'' ==
  
<syntaxhighlight lang=xml line>
+
<syntaxhighlight lang="xml">
 
<aiml>
 
<aiml>
 
<category>
 
<category>
Linha 57: Linha 62:
 
Uma condição pode conter um curinga, ou carácter * em seu padrão
 
Uma condição pode conter um curinga, ou carácter * em seu padrão
  
<syntaxhighlight lang=xml line>
+
<syntaxhighlight lang="xml">
 
<category>
 
<category>
 
<pattern>MEU NOME E *</pattern>
 
<pattern>MEU NOME E *</pattern>
Linha 63: Linha 68:
 
</category>
 
</category>
 
</syntaxhighlight>
 
</syntaxhighlight>
 
Há também o curinga "_". Uma diferença é que este é tratado preferencialmente pelo motor, ou seja, serão tratados primeiro. Outra coisa, por enquanto, basta saber que usa-se "_" quando é importante o que o usuário diz e "*" quando não é.
 
  
 
O curinga também pode ser utilizado para pegar todas as entradas de usuário que não fecharam com nenhuma regra:
 
O curinga também pode ser utilizado para pegar todas as entradas de usuário que não fecharam com nenhuma regra:
  
<syntaxhighlight lang=xml line>
+
<syntaxhighlight lang="xml">
 
<category>
 
<category>
 
<pattern> * </pattern>
 
<pattern> * </pattern>
 
<template>Eu não entendo.</template>
 
<template>Eu não entendo.</template>
 
</category>
 
</category>
</syntaxhighlight>
+
</syntaxhighlight>A categoria acima é usada como fuga. Quando o bot não encontra uma padrão, pode responder com uma frase meio genérica ou um conjunto de frases genéricas aleatórias.
 +
 
 +
Existe também o curinga "_", mas não vamos falar sobre ele por aqui.
  
 
== Tag srai ==
 
== Tag srai ==
Linha 79: Linha 84:
 
Muitas vezes, a mesma pergunta do usuário pode ser feita de formas diferentes, mas devem ser tratadas da mesma maneira. Nesses casos, a ''tag'' '''srai''' pode ser utilizada para se referir a outra regra.
 
Muitas vezes, a mesma pergunta do usuário pode ser feita de formas diferentes, mas devem ser tratadas da mesma maneira. Nesses casos, a ''tag'' '''srai''' pode ser utilizada para se referir a outra regra.
  
<syntaxhighlight lang=xml line>
+
<syntaxhighlight lang="xml">
 
<category>
 
<category>
<pattern>COMO EU CHEGO AO SUPERMERCADO?</pattern>
+
        <pattern>COMO EU CHEGO AO SUPERMERCADO</pattern>
<template>Siga pela avenida principal e vire a primeira rua a direita.</template>
+
        <template>Siga pela avenida principal e vire a primeira rua a direita.</template>
</category>
+
    </category>
  
<category>
+
    <category>
<pattern>COMO EU CHEGO A UNIVERSIDADE?</pattern>
+
        <pattern>COMO EU CHEGO A UNIVERSIDADE</pattern>
<template>Siga pela rua principal por aproximadamente 2km.</template>
+
        <template>Siga pela rua principal por aproximadamente 2km.</template>
</category>
+
    </category>
  
<category>
+
    <category>
<pattern>QUAL O CAMINHO ATE *</pattern>
+
        <pattern>QUAL O CAMINHO ATE *</pattern>
<template><srai>COMO EU CHEGO <star/></srai></template>
+
        <template><srai>COMO EU CHEGO <star/></srai></template>
</category>
+
    </category>
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Linha 100: Linha 105:
 
Uma regra também pode ter respostas randômicas:
 
Uma regra também pode ter respostas randômicas:
  
<syntaxhighlight lang=xml line>
+
<syntaxhighlight lang="xml">
 
<category>
 
<category>
 
<pattern>COMO VAI VOCE?</pattern>
 
<pattern>COMO VAI VOCE?</pattern>
Linha 111: Linha 116:
 
</random>
 
</random>
 
</template>
 
</template>
 +
</category>
 +
</syntaxhighlight>Agora que já conhecemos o SRAI e as ações randômicas, podemos utilizar ele de outras formas. Por exemplo, na entrada OI, poderíamos falar OLA também. Além disso, pode ser OI BOT ou OLA BOT. Então são várias formas. Para não ter que escrever sempre a mesma resposta, fazemos uma referência com SRAI.
 +
 +
Para complementar, ainda podemos ter várias respostas aleatórias. Então usamos o random e li:<syntaxhighlight lang="xml">
 +
<category>
 +
    <pattern>OI</pattern>
 +
    <template>
 +
        <random>
 +
            <li>Olá, como vai você?</li>
 +
            <li>Oi.</li>
 +
            <li>Beleza.</li>
 +
            <li>Olá, tudo certo?</li>
 +
        </random>
 +
    </template>
 +
</category>
 +
 +
<category>
 +
    <pattern>OLA</pattern>
 +
    <template><srai>OI</srai></template>
 +
</category>
 +
 +
<category>
 +
    <pattern>OI *</pattern>
 +
    <template><srai>OI</srai></template>
 +
</category>
 +
 +
<category>
 +
    <pattern>OLA *</pattern>
 +
    <template><srai>OI</srai></template>
 
</category>
 
</category>
 
</syntaxhighlight>
 
</syntaxhighlight>
Linha 118: Linha 152:
 
A linguagem AIML permite a utilização de variáveis globais que podem ser utilizadas nas regras.
 
A linguagem AIML permite a utilização de variáveis globais que podem ser utilizadas nas regras.
  
<syntaxhighlight lang=xml line>
+
<syntaxhighlight lang="xml">
 
<category>
 
<category>
<pattern>MEU NOME E *</pattern>
+
    <pattern>MEU NOME E *</pattern>
<template>É um prazer te conhecer,  
+
    <template>É um prazer te conhecer,  
<set name="userName"><star/></set>.
+
        <set name="userName"><star/></set>.
</template>
+
    </template>
 
</category>
 
</category>
 
</syntaxhighlight>
 
</syntaxhighlight>
Linha 129: Linha 163:
 
A utilização da tag ''<think>'' funciona como no exemplo anterior, mas previne que as informações sejam exibidas juntamente com a resposta.
 
A utilização da tag ''<think>'' funciona como no exemplo anterior, mas previne que as informações sejam exibidas juntamente com a resposta.
  
<syntaxhighlight lang=xml line>
+
<syntaxhighlight lang="xml">
 
<category>
 
<category>
 
<pattern>MEU NOME E *</pattern>
 
<pattern>MEU NOME E *</pattern>
Linha 140: Linha 174:
 
== Usando variáveis globais em condições ==
 
== Usando variáveis globais em condições ==
  
O valor de uma variável global pode ser utilizado para testes.
+
O valor de uma variável global pode ser utilizado depois que ela foi armazenada.
  
<syntaxhighlight lang=xml line>
+
<syntaxhighlight lang="xml">
 
<category>
 
<category>
<pattern>VOCE GOSTARIA DE DANCAR COMIGO?</pattern>
+
    <pattern>QUAL E O MEU NOME</pattern>
<template>
+
    <template>
Claro, será um prazer.
+
        <condition name="userName">
<condition name="userName" value="">
+
            <li value="">Você ainda não me disse seu nome.</li>
Você poderia me dizer seu nome?
+
            <li>Seu nome é <get name="userName"/>.</li>
</condition>
+
        </condition>
</template>
+
    </template>
 
</category>
 
</category>
 
</syntaxhighlight>
 
</syntaxhighlight>
Linha 158: Linha 192:
 
A linguagem AIML permite a utilização de contextos, ou tema, por meio da tag ''<topic>''. As regras podem ser agrupadas conforme um contexto específico.
 
A linguagem AIML permite a utilização de contextos, ou tema, por meio da tag ''<topic>''. As regras podem ser agrupadas conforme um contexto específico.
  
<syntaxhighlight lang=xml line>
+
<syntaxhighlight lang="xml">
 
<category>
 
<category>
<pattern>POSSO COMPRAR UMA PASSAGEM DE AVIAO?</pattern>
+
    <pattern>POSSO COMPRAR UMA PASSAGEM DE AVIAO</pattern>
<template>Sim.</template>
+
    <template>Sim.</template>
</category>
+
</category>  
  
 
<category>
 
<category>
<pattern>POSSO COMPRAR UMA PASSAGEM PARA * ?</pattern>
+
    <pattern>POSSO COMPRAR UMA PASSAGEM PARA * </pattern>
<template>Sim, você pode.
+
    <template>Sim, você pode.
<think>
+
        <think>
<set name="userDestination"><star/></set>
+
            <set name="userDestination"><star/></set>
<set name="topic">PAGAMENTO</set>
+
            <set name="topic">PAGAMENTO</set>
</think>
+
        </think>
<srai>COMO POSSO PAGAR?</srai>
+
        <srai>COMO POSSO PAGAR?</srai>
</template>
+
    </template>
 
</category>
 
</category>
</syntaxhighlight>
+
   
 
 
<syntaxhighlight lang=xml line>
 
 
<topic name="PAGAMENTO">
 
<topic name="PAGAMENTO">
 
+
    <category>
<category>
+
        <pattern>COMO POSSO PAGAR</pattern>
<pattern>COMO POSSO PAGAR?</pattern>
+
        <template>Você pode pagar em dinheiro ou cartão de crédito.</template>
<template>Você pode pagar em dinheiro ou cartão de crédito.</template>
+
    </category>
</category>
 
 
 
 
</topic>
 
</topic>
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
<!--
 
== Tag that ==
 
== Tag that ==
  
<syntaxhighlight lang=xml line>
+
<syntaxhighlight lang="xml">
<!-- Clausula THAT -->
 
  
 
<aiml version="1.0.1">
 
<aiml version="1.0.1">
Linha 229: Linha 259:
 
</aiml>
 
</aiml>
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
-->
  
 
= Links =
 
= Links =
  
 
* [https://github.com/aichaos/rivescript-python Riverscript] Uma plataforma em python para testar um chatbot AIML.
 
* [https://github.com/aichaos/rivescript-python Riverscript] Uma plataforma em python para testar um chatbot AIML.

Edição atual tal como às 13h53min de 7 de março de 2025

Afluentes: Inteligência Artificial

Material Didático

Código do Chatbot

O programa em linguagem de programação python abaixo cria um prompt de interação do interpretador AIML do PyAIML3 com o usuário.

import sys
import aiml
import unicodedata
import re

# Efetua uma filtragem no texto de entrada
def filter(text):
    # Normaliza o texto entrado como parâmetro e remove os acentos
    text = unicodedata.normalize('NFKD', text).encode('ASCII', 'ignore').decode('utf-8')
    # Remove pontuação e caracteres especiais
    text = re.sub(r'[^\w\s]', '', text)
    return text

kb = sys.argv[1]                    # Pega a base AIML entrada por parâmetro
k = aiml.Kernel()                   # Inicializa o motor de interpretação AIML
k.learn(kb)                         # Insere a base AIML no motor para aprendizado
while True:                         # Executa o laço indefinidamente
    message = input("> ")           # Inicializa o prompt do chatbot
    message = filter(message)       # Limpa a mensagem entrada pelo usuário
    response = k.respond(message)   # Envia ao motor e retorna a resposta
    print(response)                 # Imprime a resposta

É importante observar que deve ser feita uma filtragem na mensagem de entrada do usuário. Não deve ter caracteres especiais, acentos, etc. Para isso, criamos a função filter.

AIML

O AIML (GNU GPL) é uma linguagem baseada em XML para chatbots desenvolvida em 1995 para o A.L.I.C.E. (Artificial Linguistic Internet Computer Entity) por Richard Wallace.

As regras das pequenas entidades são compostas de duas partes: condição e ação. Caso as condições forem satisfeitas, a ação é executada. No caso de mais de uma regra terem suas condições satisfeitas, temos um conflito. Neste caso, o interpretador precisa ter uma estratégia para resolver esses conflitos.

As tags mais importantes de um documento AIML são:

  • <aiml>: inicia e termina um documento AIML;
  • <category>: marca uma unidade de conhecimento;
  • <pattern>: contem um padrão simples que pode fechar com o que o usuário fala ou digita;
  • <template>: contem a resposta para uma entrada do usuário.

Documento Simples - Hello World

<aiml>
	<category>
		<pattern>OLA</pattern>
		<template>Olá, como vai você?</template>
	</category>
</aiml>

Tag star ou Curinga

Uma condição pode conter um curinga, ou carácter * em seu padrão

<category>
	<pattern>MEU NOME E *</pattern>
	<template>É um prazer conhecer você, <star/>.</template>
</category>

O curinga também pode ser utilizado para pegar todas as entradas de usuário que não fecharam com nenhuma regra:

<category>
	<pattern> * </pattern>
	<template>Eu não entendo.</template>
</category>

A categoria acima é usada como fuga. Quando o bot não encontra uma padrão, pode responder com uma frase meio genérica ou um conjunto de frases genéricas aleatórias.

Existe também o curinga "_", mas não vamos falar sobre ele por aqui.

Tag srai

Muitas vezes, a mesma pergunta do usuário pode ser feita de formas diferentes, mas devem ser tratadas da mesma maneira. Nesses casos, a tag srai pode ser utilizada para se referir a outra regra.

<category>
        <pattern>COMO EU CHEGO AO SUPERMERCADO</pattern>
        <template>Siga pela avenida principal e vire a primeira rua a direita.</template>
    </category>

    <category>
        <pattern>COMO EU CHEGO A UNIVERSIDADE</pattern>
        <template>Siga pela rua principal por aproximadamente 2km.</template>
    </category>

    <category>
        <pattern>QUAL O CAMINHO ATE *</pattern>
        <template><srai>COMO EU CHEGO <star/></srai></template>
    </category>

Ações Randômicas

Uma regra também pode ter respostas randômicas:

<category>
	<pattern>COMO VAI VOCE?</pattern>
	<template>
		<random>
			<li>Vou bem, obrigado.</li>
			<li>Tudo bem..</li>
			<li>Tudo em ordem. Agradeço muito por perguntar.</li>
			<li>Muito bem, e você?</li>
		</random>
	</template>
</category>

Agora que já conhecemos o SRAI e as ações randômicas, podemos utilizar ele de outras formas. Por exemplo, na entrada OI, poderíamos falar OLA também. Além disso, pode ser OI BOT ou OLA BOT. Então são várias formas. Para não ter que escrever sempre a mesma resposta, fazemos uma referência com SRAI. Para complementar, ainda podemos ter várias respostas aleatórias. Então usamos o random e li:

<category>
    <pattern>OI</pattern>
    <template>
        <random>
            <li>Olá, como vai você?</li>
            <li>Oi.</li>
            <li>Beleza.</li>
            <li>Olá, tudo certo?</li>
        </random>
    </template>
</category>

<category>
    <pattern>OLA</pattern>
    <template><srai>OI</srai></template>
</category>

<category>
    <pattern>OI *</pattern>
    <template><srai>OI</srai></template>
</category>

<category>
    <pattern>OLA *</pattern>
    <template><srai>OI</srai></template>
</category>

Variáveis Globais

A linguagem AIML permite a utilização de variáveis globais que podem ser utilizadas nas regras.

<category>
    <pattern>MEU NOME E *</pattern>
    <template>É um prazer te conhecer, 
        <set name="userName"><star/></set>.
    </template>
</category>

A utilização da tag <think> funciona como no exemplo anterior, mas previne que as informações sejam exibidas juntamente com a resposta.

<category>
	<pattern>MEU NOME E *</pattern>
	<template>É um prazer te conhecer.
		<think><set name="userName"><star/></set></think>
	</template>
</category>

Usando variáveis globais em condições

O valor de uma variável global pode ser utilizado depois que ela foi armazenada.

<category>
    <pattern>QUAL E O MEU NOME</pattern>
    <template>
        <condition name="userName">
            <li value="">Você ainda não me disse seu nome.</li>
            <li>Seu nome é <get name="userName"/>.</li>
        </condition>
    </template>
</category>

Utilizando Contextos

A linguagem AIML permite a utilização de contextos, ou tema, por meio da tag <topic>. As regras podem ser agrupadas conforme um contexto específico.

<category>
    <pattern>POSSO COMPRAR UMA PASSAGEM DE AVIAO</pattern>
    <template>Sim.</template>
</category> 

<category>
    <pattern>POSSO COMPRAR UMA PASSAGEM PARA * </pattern>
    <template>Sim, você pode.
        <think>
            <set name="userDestination"><star/></set>
            <set name="topic">PAGAMENTO</set>
        </think>
        <srai>COMO POSSO PAGAR?</srai>
    </template>
</category>
    
<topic name="PAGAMENTO">
    <category>
        <pattern>COMO POSSO PAGAR</pattern>
        <template>Você pode pagar em dinheiro ou cartão de crédito.</template>
    </category>
</topic>


Links

  • Riverscript Uma plataforma em python para testar um chatbot AIML.