em Tecnologia

Continuo meus estudos com Flask, para brincar um pouco com o que estou aprendendo resolvi fazer um chatbot utilizando a biblioteca PyAIML e os arquivos AIML da A.L.I.C.E. AI Foundation.

Pra quem não sabe, os arquivos AIML (Artificial Intelligence Markup Language) são marcações baseadas em XML para inteligência artificial. Usando a biblioteca PyAIML fica muito simples fazer um chatbot em Python. Mas eu queria fazê-lo via web e foi aí que o Flask entrou.

Utilizei o Flask apenas para lidar com os requests e responses via web. Ou seja, ele recebe uma pergunta vinda do navegador e devolve uma resposta do bot.

Para ver o código-fonte completo do meu chatbot, acesse meu github.

Vendo o código-fonte, percebe-se que na raiz temos apenas o diretório app e o lib, além do arquivo run.py, que roda o servidor. Dentro do diretório app temos os arquivos do Flask: __init__.py e o views.py. No diretório lib está a biblioteca PyAIML e os arquivos AIML, importados da A.L.I.C.E. AI Foundation. Nestes arquivos eu fiz pouquíssimas alterações para o funcionamento básico do Jarvis, nome que dei ao meu chatbot.

Dentro do arquivo app/__init__.py eu importo o Flask e biblioteca PyAIML, para poder utilizá-la no arquivo app/views.py. Perceba que também importo o arquivo brain.brn, que é a “compilação” dos arquivos AIML, ou seja, é o cérebro do bot. Se ele não existir, o Kernel da biblioteca PyAIML vai criá-lo. Exemplo nas linhas abaixo, retiradas do arquivo app/__init__.py.

brainfile = os.path.join('lib', 'pyaiml', 'brain.brn')
aimlfiles = os.path.join('lib', 'pyaiml', 'aiml', 'std-startup.aiml')

k = aiml.Kernel()
if os.path.isfile(brainfile):
	k.bootstrap(brainFile = brainfile)
else:
	k.bootstrap(learnFiles = aimlfiles, commands = 'load aiml b')
	k.saveBrain(brainfile)

Uma pequena observação, estou importando os arquivos com os.path.join() para que não precise me preocupar se estou em sistema operacional Windows ou em Unix-based. Isso foi necessário porque no Windows as barras que separam os arquivos são inversas às dos sistemas baseados em Unix (como Linux e MacOS).

No arquivo app/views.py encontramos as definições de rotas (@app.route()) e definimos o que cada endereço web vai fazer no sistema. No caso, temos o / ou /index, que apenas mostra o template básico, através do método render_template do Flask, e temos o /talk, que recebe a “pergunta” do browser e envia a resposta transformada em um objeto JSON com o método jsonify do Flask. Os outros métodos são apenas handlers para os erros 404 (página não encontrada) e 500 (erro interno do servidor). Veja o index e o talk no exemplo abaixo, retirado do arquivo app/views.py.

@app.route('/', methods=['GET'])
@app.route('/index', methods=['GET'])
def index():
    return render_template('index.html')

@app.route('/talk', methods=['GET'])
def talk():
    question = request.args.get('question')
    answer = k.respond(question)
    return jsonify(question=question, answer=answer)

Lembrando que quando chamamos k.respond() no método talk() estamos chamando a biblioteca PyAIML para fazer o trabalho pesado por nós. Já a importamos no arquivo app/__init__.py e a passamos para a variável app.

É importante lembrar que aquilo que fomos utilizar em um programa Python tem que ser importado. Por isso é comum vermos os comandos import no começo dos arquivos. Por exemplo, no arquivo app/views.py eu importei o render_template, o request e o jsonify do Flask e o app e k (que contem a biblioteca PyAIML) do nosso app iniciado no arquivo app/__init__.py.

from flask import render_template, request, jsonify
from app import app, k

Com a biblioteca PyAIML fazendo a interpretação dos arquivos AIML, o Flask tinha pouquíssimo trabalho pela frente. Com apenas alguns poucos métodos escritos eu consegui rodar o aplicativo web. Isto é algo que tem me agradado muito no Python e no Flask.

Utilizar o PyAIML também foi simples, mas para entender como personalizar o bot (mudar o nome, nascimento, preferências, etc) eu levei um tempinho. Precisava entender que os “predicates” do bot precisavam ser mudados no arquivo lib/pyaiml/aiml/Kernel.py da biblioteca. Para facilitar, criei um arquivo chamado lib/pyaiml/aiml/BotPredicates.py e o importei no Kernel.py, como mostro abaixo.

import BotPredicates
# Set up the bot predicates 
self._botPredicates = BotPredicates.bot

Acabou sendo mais simples do que eu imaginava criar o Jarvis. Agora vou continuar brincando um pouco com ele. Quero adicionar reconhecimento de voz para que o usuário possa conversar com o Jarvis. Também quero que o usuário se registre com login e senha, para que o Jarvis já conheça seus amigos quando eles vierem conversar. A medida que eu for desenvolvendo essas novas funcionalidades vou postando algumas notas por aqui.