Eliza Example¶
This tutorial is to help one to understand how visualization works together with the pipeline. We will walk you through the steps to set up an Eliza chatbot that generates responses based on Eliza rules. We will utilize stave
to visualize the dialogue page that allows you to chat with the bot interactively.
Introduction¶
Eliza chatbot (https://en.wikipedia.org/wiki/ELIZA) is a famous rule-based chatbot invented in 1964. The rule-based and model-less nature makes it highly suitable for demonstration purposes. This tutorial is based on ElizaProcessor
. For more details, refer to https://github.com/asyml/forte/blob/master/forte/processors/nlp/eliza_processor.py.
Quick Start¶
Install Dependencies¶
[ ]:
!pip install torch
!pip install "forte[remote]@git+https://github.com/asyml/forte.git@master"
!pip install stave==0.0.2.dev1
Start an Eliza pipeline service¶
Run the following python script to start a pipeline service to process input queries based on Eliza rules.
[ ]:
from threading import Thread
from forte.pipeline import Pipeline
from forte.data.data_pack import DataPack
from forte.data.readers import RawDataDeserializeReader
from forte.processors.nlp import ElizaProcessor
def start_eliza_service(
input_format: str = "DataPack", service_name: str = "test_name"
) -> None:
"""
Start a remote service for ElizaProcessor
"""
pipeline = Pipeline[DataPack]()
pipeline.set_reader(RawDataDeserializeReader())
pipeline.add(ElizaProcessor())
pipeline.serve(input_format=input_format, service_name=service_name)
if __name__ == "__main__":
Thread(target=start_eliza_service).start()
Visualize the chatbot in stave
¶
We will need stave
to open a chatbot window to test the pipeline service that we just started in the previous step. stave
is a fast, lightweight, extensible web-based text annotation and visualization tool. It supports a wide range of data types and NLP tasks. For more details, refer to https://github.com/asyml/stave.
Run the following command:
[ ]:
!stave -s start -o -l -n 8889
Now we should see a browser window popped out which directs to a login page (http://localhost:8889/login) of stave
. You can log in with the default username (admin
) and password (admin
).
After successfully logging into stave
, we can navigate to the All Projects
page. Click the VIEW PROJECT
button under Eliza
project. Then click eliza.json
on the left side to enter the dialogue page where you can enter queries and get responses from the Eliza chatbot.
Code Explained¶
Overview¶
The Eliza example showcases forte
’s ability to expose a pipeline to be served as a remote service that can be called from another pipeline using RemoteProcessor. This allows users to port their local pipeline to a remote endpoint that can be accessed and shared by other users to call its functionality. We will use the Eliza example to show how we can achieve this.
Start a Pipeline Service¶
In the code snippet above we build a simple pipeline and start it as a service for Eliza chatbot:
pipeline = Pipeline[DataPack]()
pipeline.set_reader(RawDataDeserializeReader())
pipeline.add(ElizaProcessor())
pipeline.serve()
Here we set RawDataDeserializeReader as a reader of the pipeline since we expect the input request will be a sequence of serialized DataPack
strings. This reader can deserialize these strings to DataPack
s.
ElizaProcessor is responsible for generating responses based on Eliza rules from the input queries. The responses will be appended to the text payload of input DataPack
annotated as Utterance
.
Pipeline.serve(host, port) will start a pipeline service at a specific endpoint. You may configure host
and port
to specify the endpoint.
Call a Pipeline Service¶
After setting up the service, you will be able to access it from http://{host}:{port}
. You can also call it from another forte pipeline with RemoteProcessor. In the pre-loaded Eliza
project, stave
has already set up a forte pipeline to invoke the Eliza service:
# Adapted from https://github.com/asyml/stave/blob/master/simple-backend/stave_backend/handlers/nlp.py#L49
pipeline = Pipeline[DataPack](do_init_type_check)
pipeline.set_reader(RawDataDeserializeReader())
pipeline.add(RemoteProcessor(), config)
pipeline.initialize()
RawDataDeserializeReader is set as the reader of this pipeline because stave
stores DataPack
s as serialized strings in the database. Input queries entered by users are integrated into an existing chatbot DataPack
and saved to the database, which will be fed into the pipeline above.
RemoteProcessor provides a wrapping of interactions with the remote forte service endpoint. Each input DataPack from the upstream component will be serialized and packed into a POST request to be sent to a remote service, which should return a response that can be parsed into a DataPack to update the input. In the Eliza example, it will 1. prepare a POST request from the deserialized DataPack
(which
contains the user inputs) 2. send it to the remote service we just set up 3. parse the response (which contains the generated text from ElizaProcessor
) into a new DataPack
that can be passed to the downstream components.
Create Your Own Chatbot Service¶
You might notice that the pipeline of Eliza
project in stave
actually doesn’t constrain the remote service to be an Eliza
chatbot. It should be able to support any type of chatbot service as long as the service can process input DataPack
s in a way that stave
can understand.
To render a chatbot page, stave
will retrieve the Utterance annotations stored in DataPack
and lay out the dialogues based on Utterance.speaker. If speaker
of an Utterance
is "ai"
(e.g., the initial prompt message and chatbot responses), then its message will be placed on the left side of the page. For messages users
enter, stave
will append them to DataPack
as new Utterance
annotations with their speaker
field set to "user"
and place them on the right side of the chatbot window.
The chatbot service must conform to the protocol described above to display its response in stave
correctly. This service will receive a serialized DataPack
. Hence it always needs to set RawDataDeserializeReader
as the reader. The downstream processor should retrieve the Utterance
annotations from it. The processor can choose to analyze the whole chat history or generate a response simply based on the latest query from the user. It must append its responses to DataPack
and
annotate them as Utterance
s whose speaker
should be set to "ai"
.