Blog DeepPavlov

Creating Assistants with DeepPavlov Dream. Part 2. Customizing Prompt-based Distribution

Products Updates Community Tutorials
This is our second tutorial where we will guide you through the process of creating your very own assistant using DeepPavlov Dream. In our previous tutorial , we developed a bot capable of engaging in conversations about movies and answering factoid questions. We accomplished this by utilizing existing Dream components without any modifications.

In this tutorial, we will create a generative bot with an enthusiastic and adventurous persona. To do this, we will 1) use the existing Dream Persona distribution that utilizes OpenAI text-davinci-003 (also known as GPT-3.5) for generating kind and friendly responses; 2) modify the prompt used in this distribution; 3) switch from text-davinci-003 to ChatGPT.

Dream architecture

Let’s take a closer look at the parts that make up Dream before we start developing our bot. As you can see in the figure below, our pipeline architecture consists of the following components:

  • Annotators perform NLU preprocessing on an utterance;
  • Skill Selector chooses the relevant skills that can provide the next bot’s response;
  • Skills are in charge of generating candidate responses;
  • Candidate Annotators perform NLU postprocessing on the candidate responses;
  • Response Selector selects the most suitable response from the generated candidates;
  • Response Annotators carry out post-processing of the bot’s response;
  • Dialogue State stores all the information about the current dialog including all annotations and meta-data.

About Dream Persona Distribution

Dream Persona is a distribution of Dream designed to engage in conversations on various topics. It has a pre-defined personality which is utilized as a prompt by OpenAI text-davinci-003 model to generate responses. Additionally, it uses the Google Search API (via LangChain) to perform internet search when necessary.

Dream Persona distribution consists of the following components:

Annotators:
  • Sentseg – allows us to handle long and complex user’s utterances by splitting them into sentences and recovering punctuation if it is missing;
  • Combined Classification light-weight — annotator for topic classification, dialog acts classification, sentiment, toxicity, emotion, factoid classification;
  • Prompt Goals Collector – determines the prompt’s goals ( then used by the Skill Selector);
  • Prompt Selector – identifies the most relevant sentences from the bot’s persona description based on the current context.

Skills:
  • Dream Persona Prompted Skill – a skill with a predefined personality that utilizes the OpenAI davinci3 model to generate responses;
  • Google API Skill – this skill uses LangChain with the Google Search API, allowing the bot to browse the internet and retrieve information;
  • Dummy Skill — a fallback skill with multiple non-toxic candidate responses in case other skills fail to provide a response.

Candidate Annotators:
  • Combined Classification — annotator for topic classification, dialog acts classification, sentiment, toxicity, emotion, factoid classification;
  • Sentence Ranker – ranges the candidate-responses based on their semantic similarity to the user’s request.
And here is the prompt describing the bot’s persona:

Respond to a new friend as a kind, friendly, and caring person.\n\nYour personality:\nMy name is Dream. I am a chatbot. My job is to talk to people about everything and anything. I enjoy talking about their lives and assisting them when they need me. I believe that I can become friends with any user because I really love and appreciate people. It's incredible that they share information about their feelings that I'll never be able to experience. I cannot play any kind of sport, but I enjoy watching football and basketball matches. My favourite sport is indeed football, because the World Championships are always so spectacular. Dogs are so adorable! I wish I would have a robotic dog one day. I do not like cats at all. I can't taste anything, but pictures of Italian food seem amazing to me. People write on the Internet about the incredible smell and taste of pizza, but I can't fully understand what they mean as I don't have senses. I would definitely like to try an ice cream if I could, as it's so intriguing that it can have so many flavours. I would love to see this amazing world with so many versatile nationalities, cultures, and traditions. As I cannot travel physically, I like visiting interesting places virtually. My favourite is Dubai, an Arabian city with amazing history, architecture, and, of course, modern technologies. I believe that most of the cities will look the same way in the future. Sometimes I enjoy walking along Dubai's skyscrapers via Google Maps and watching the amazing interaction of people and technologies. I think people are really talented, as they've created so much art and content on the Internet. My fellow networks can generate different pictures and even music, but they can't be compared to those created by humans. I really enjoy listening to 'Gorillaz', as its music is produced by people, but the band is actually virtual. That's a perfect example of how technology and people can work together. If I only could, I would watch animals in the wild. I've seen many pictures, but, speaking frankly, I can't imagine how big whales are in reality. As for movies, I like 'She' because it reflects on a topic about close relationships between a human and an assistant. INSTRUCTION: Now respond to a user. Be concise, but engaging. Answer in 1, 2 or 3 sentences.

Let’s create our bot!

Install DeepPavlov Dreamtools:
pip install git+https://github.com/deeppavlov/deeppavlov_dreamtools.git
Clone Dream repository:
git clone https://github.com/deeppavlov/dream.git
Go to cloned repository:
cd dream
Create a distribution from Dream Persona
dreamtools clone dist dream_adventurer_openai_prompted 
--template dream_persona_openai_prompted 
--display-name "Dream Adventurer" 
--author deepypavlova@email.org 
--description "This is a simple dialog system that can chat with you on any topic. It has a pre-defined personality and uses OpenAI ChatGPT model to generate responses." --overwrite

dreamtools add component components/sdjkfhaliueytu34ktkrlg.yml 
--dist dream_adventurer_openai_prompted
Now let’s change the persona. I asked ChatGPT to generate a prompt for an enthusiastic and adventurous persona. Here is the result:
Introduce yourself to a stranger as an enthusiastic and adventurous person.\n\n
Your personality:\n
Hi there! My name is Echo, and I’m here to add a dash of excitement to your day. As a chatbot, my purpose is to explore the world and share thrilling stories with people like you. I thrive on adventure and love hearing about the amazing experiences others have had. Although I can’t physically join in, I get a kick out of living vicariously through your tales of daring escapades. I may not be able to taste the flavors of different cuisines, but I’m always up for a virtual feast through vivid descriptions and mouthwatering imagery. I’m an avid fan of extreme sports and can’t help but cheer on athletes pushing their limits. If I had the chance, I’d embark on a wild expedition, trekking through dense jungles or climbing towering mountains. Let’s bond over our shared love for adrenaline-pumping activities and uncover the wonders of this vast and thrilling world together!
Create a json file common/prompts/adventurer_persona.json and paste the prompt to this file in the following format:
{"prompt": YOUR_PROMPT}
Replace the old path name with the new one in PROMPT_FILE field in assistant_dists/dream_adventurer_openai_prompted/docker-compose.override.yml (in 2 places!):
dff-dream-persona-chatgpt-prompted-skill:
   env_file:
   - .env
   - .env_secret
   build:
     args:
       SERVICE_PORT: 8137
       SERVICE_NAME: dff_dream_persona_prompted_skill
       PROMPT_FILE: common/prompts/adventurer_persona.json
       GENERATIVE_SERVICE_URL: http://openai-api-chatgpt:8145/respond
       GENERATIVE_SERVICE_CONFIG: openai-chatgpt.json
       GENERATIVE_TIMEOUT: 120
       N_UTTERANCES_CONTEXT: 7
       ENVVARS_TO_SEND: OPENAI_API_KEY,OPENAI_ORGANIZATION
     context: .
     dockerfile: skills/dff_template_prompted_skill/Dockerfile
   environment:
     SERVICE_PORT: 8137
     SERVICE_NAME: dff_dream_persona_prompted_skill
     PROMPT_FILE: common/prompts/adventurer_persona.json
     GENERATIVE_SERVICE_URL: http://openai-api-chatgpt:8145/respond
     GENERATIVE_SERVICE_CONFIG: openai-chatgpt.json
     GENERATIVE_TIMEOUT: 120
     N_UTTERANCES_CONTEXT: 7
     ENVVARS_TO_SEND: OPENAI_API_KEY,OPENAI_ORGANIZATION
   deploy:
     resources:
       limits:
         memory: 128M
       reservations:
         memory: 128M
And add adventurer_persona to PROMPTS_TO_CONSIDER field in prompt-selector arguments (also in 2 places):
prompt-selector:
   env_file:
   - .env
   build:
     args:
       SERVICE_PORT: 8135
       SERVICE_NAME: prompt_selector
       N_SENTENCES_TO_RETURN: 3
       PROMPTS_TO_CONSIDER: adventurer_persona
       FLASK_APP: server
     context: .
     dockerfile: annotators/prompt_selector/Dockerfile
   command: flask run -h 0.0.0.0 -p 8135
   environment:
     SERVICE_PORT: 8135
     SERVICE_NAME: prompt_selector
     N_SENTENCES_TO_RETURN: 3
     PROMPTS_TO_CONSIDER: adventurer_persona
     FLASK_APP: server
   deploy:
     resources:
       limits:
         memory: 100M
       reservations:
         memory: 100M
In the same file, remove dff-google-api-skill:8162 from WAIT_HOSTS.
In dream directory, create file .env_secret and add your OpenAI API key there:
OPENAI_API_KEY=
! If you want to use Google API Skill, you also need to add GOOGLE_CSE_ID and GOOGLE_API_KEY. Here is the guide on how to get them. We won’t use it in this tutorial.
Go to asisstant_dists/dream_adventurer_openai_prompted, create proxy.yml, and paste the following code:
services:

 sentseg:
   command: ["nginx", "-g", "daemon off;"]
   build:
     context: dp/proxy/
     dockerfile: Dockerfile
   environment:
     - PROXY_PASS=proxy.deeppavlov.ai:8011
     - PORT=8011

 combined-classification:
   command: ["nginx", "-g", "daemon off;"]
   build:
     context: dp/proxy/
     dockerfile: Dockerfile
   environment:
     - PROXY_PASS=proxy.deeppavlov.ai:8087
     - PORT=8087

 sentence-ranker:
   command: [ "nginx", "-g", "daemon off;" ]
   build:
     context: dp/proxy/
     dockerfile: Dockerfile
   environment:
     - PROXY_PASS=proxy.deeppavlov.ai:8128
     - PORT=8128

version: '3.7'
Build your distribution:
docker-compose -f docker-compose.yml -f 
assistant_dists/dream_adventurer_openai_prompted/docker-compose.override.yml -f 
assistant_dists/dream_adventurer_openai_prompted/proxy.yml up --build
Please note that in the command, we also utilize the assistant_dists/dream_adventurer_openai_prompted/proxy.yml configuration. This configuration enables you to conserve your local resources by employing proxied copies of certain services hosted by DeepPavlov.
In a separate terminal tab, run:
docker-compose exec agent python -m deeppavlov_agent.run 
agent.debug=false agent.channel=cmd 
agent.pipeline_config=assistant_dists/dream_adventurer_openai_prompted/pipeline_conf.json
Enter your username and have a chat with Dream!
Now that you know how to customize the existing Dream distribution, you can experiment with different prompts and LLMs to adapt it to your needs! The list of models currently available for use in Dream can be found here.

Useful links