AI Agents tutorial: How to create information retrieval Chatbot
Welcome Aboard!
With AI agents gaining prominence across various applications, it's evident that they're worth exploring. Embrace this AI tutorial, where we'll craft a streamlined chatbot for data retrieval.
Plan
Our plan will be to create a chatbot using AI Agents (LangChain), with a simple UI using chainlit.
We would like our chatbot to be able to respond to a query in two stages: planning and retrieval, Agent should have access to Wikipedia and Web Search. This will be our task!
Execution
Preparation & depedencies
Let's start by creating a new project. I will start with creating new directory:
mkdir agents-chatbot
cd agents-chatbot
Let's create virtual environment and install dependencies:
python3 -m venv venv
# Linux/MacOS
source venv/bin/activate
# Windows
venv\Scripts\activate.bat
pip install langchain chainlit python-dotenv wikipedia duckduckgo-search
Now we can create our app.py
file (name is required by chainlit):
touch app.py
Last step is to import our dependencies:
import os
import chainlit as cl
from dotenv import load_dotenv
from langchain import PromptTemplate
from langchain.agents import AgentType, Tool, initialize_agent
from langchain.chains import ConversationChain
from langchain.chains.conversation.memory import ConversationBufferMemory
from langchain.chat_models import ChatOpenAI
from langchain.tools import DuckDuckGoSearchRun
from langchain.utilities import WikipediaAPIWrapper
load_dotenv()
# OpenAI API key
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
Disclaimer: I defined my environment variables in .env
, you can do the same or define secrets in code.
Coding
Now is time to initialize out LLM and Tools. I will use GPT-4 for this tutorial, but you can use a different model if you want. I will also use DuckDuckGoSearchRun
and WikipediaAPIWrapper
as my tools.
llm = ChatOpenAI(temperature=0, model="gpt-4")
search = DuckDuckGoSearchRun()
wikipedia = WikipediaAPIWrapper()
# Web Search Tool
search_tool = Tool(
name="Web Search",
func=search.run,
description="A useful tool for searching the Internet to find information on world events, issues, etc. Worth using for general topics. Use precise questions.",
)
# Wikipedia Tool
wikipedia_tool = Tool(
name="Wikipedia",
func=wikipedia.run,
description="A useful tool for searching the Internet to find information on world events, issues, etc. Worth using for general topics. Use precise questions.",
)
The next step is to prepare PromptTemplates. I will prepare two. One for the planning process and one for the process of generating the final response.
prompt = PromptTemplate(
template="""Plan: {input}
History: {chat_history}
Let's think about answer step by step.
If it's information retrieval task, solve it like a professor in particular field.""",
input_variables=["input", "chat_history"],
)
plan_prompt = PromptTemplate(
input_variables=["input", "chat_history"],
template="""Prepare plan for task execution. (e.g. retrieve current date to find weather forecast)
Tools to use: wikipedia, web search
REMEMBER: Keep in mind that you don't have information about current date, temperature, informations after September 2021. Because of that you need to use tools to find them.
Question: {input}
History: {chat_history}
Output look like this:
'''
Question: {input}
Execution plan: [execution_plan]
Rest of needed information: [rest_of_needed_information]
'''
IMPORTANT: if there is no question, or plan is not need (YOU HAVE TO DECIDE!), just populate {input} (pass it as a result). Then output should look like this:
'''
input: {input}
'''
""",
)
Now is the time to initiate the Agent and Planning Chain. Also, I will add memory so they can save information about previous messages.
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
plan_chain = ConversationChain(
llm=llm,
memory=memory,
input_key="input",
prompt=plan_prompt,
output_key="output",
)
# Initialize Agent
agent = initialize_agent(
agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION,
tools=[search_tool, wikipedia_tool],
llm=llm,
verbose=True, # verbose option is for printing logs (only for development)
max_iterations=3,
prompt=prompt,
memory=memory,
)
UI part
Now is time to create UI. I will use chainlit for this purpose. I will utilize factory
function to pass our agent to chainlit. But before triggering factory
function chainlit uses run
function to prepare pipeline of passing input to model. I will overwrite it to change flow a little bit. I want to firstly execute planning and then to generate response. Let's do it!
@cl.langchain_run
def run(agent, input_str):
# Plan execution
plan_result = plan_chain.run(input_str)
# Agent execution
res = agent(plan_result)
# Send message
cl.Message(content=res["output"]).send()
@cl.langchain_factory
def factory():
return agent
Okay, we are almost done. Last step is to run our app!
chainlit run app.py -w # -w flag is for restarting app after each change
Results!
Great, now let's test our application. I will start our application by saying hello and then ask it a question. Let's see what the result will be!
Bravo! Let's Dive Deeper
Marvelous! As you witnessed initially, the model bypassed planning until prompted – then, it organized tasks and crafted a response just as intended!
Venture forth to build your unique AI agent applications, and don't miss our AI Agents Hackathon commencing June 9th. Elevate your knowledge with our AI tutorials and shape the future using AI's prowess!
Thank you for your time! - Jakub Misiło @newnative