Welcome to our tutorial on building a custom QnA agent with memory, using Wikipedia as the information source! In this code, we dive deep into the process of creating an intelligent agent that can remember previous interactions, providing more accurate and contextually relevant answers over time.
Import LLM
1 2 3 4 5 6 |
from langchain_openai import ChatOpenAI import os llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0, openai_api_key=os.environ.get("OPENAI_API_KEY")) |
Import Tool
1 2 3 4 5 |
from langchain.tools import WikipediaQueryRun from langchain_community.utilities import WikipediaAPIWrapper wikipedia = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper()) wikipedia.run("Highest goals in a single season of La Liga") |
Bind Tool with LLM
1 2 |
tools = [wikipedia] llm_with_tools = llm.bind_tools(tools) |
Create Prompt for LLM
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder prompt = ChatPromptTemplate.from_messages( [ ( "system", "You are very powerful assistant, but bad at calculating lengths of words.", ), MessagesPlaceholder(variable_name="chat_history"), ("user", "{input}"), MessagesPlaceholder(variable_name="agent_scratchpad"), ] ) |
Create Custom Agent with Memory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
from langchain_core.messages import AIMessage, HumanMessage chat_history = [] from langchain.agents.format_scratchpad.openai_tools import ( format_to_openai_tool_messages, ) from langchain.agents.output_parsers.openai_tools import OpenAIToolsAgentOutputParser agent = ( { "input": lambda x: x["input"], "agent_scratchpad": lambda x: format_to_openai_tool_messages( x["intermediate_steps"] ), "chat_history": lambda x: x["chat_history"], } | prompt | llm_with_tools | OpenAIToolsAgentOutputParser() ) |
1 2 3 |
from langchain.agents import AgentExecutor agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, stream_runnable = False) |
1 2 3 4 5 |
from langchain.callbacks import get_openai_callback with get_openai_callback() as cb: out = agent_executor.invoke({"input": "Highest goals in a single season of La Liga", "chat_history": chat_history}) print(out) print(cb) |
1 2 3 4 5 6 7 8 9 |
chat_history.extend( [ HumanMessage(content="Highest goals in a single season of La Liga"), AIMessage(content=out["output"]), ] ) print(chat_history) agent_executor.invoke({"input": "How many goals he has scored overall in L Liga?", "chat_history": chat_history}) |
Showcase in Gradio
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import gradio as gr agent_history = [] def call_agent(query, chat_history): print("Chat history : ", chat_history) output = agent_executor.invoke({"input": query, "chat_history": agent_history}) agent_history.extend( [ HumanMessage(content="Highest goals in a single season of La Liga"), AIMessage(content=out["output"]), ] ) chat_history += [ [ "<b>Question: </b>" + query, "<b>Answer: </b>" + output["output"] ] ] return output["output"], chat_history |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
with gr.Blocks() as demo: chatbot = gr.Chatbot(label = "QnA with Wikipedia") question = gr.Textbox(label = "Ask you query here") with gr.Row(): submit = gr.Button("Submit") clear = gr.ClearButton([chatbot, question]) def user(user_message, history): bot_message, history = call_agent(user_message, history) return "", history question.submit(user, [question, chatbot], [question, chatbot], queue=False) submit.click(user, [question, chatbot], [question, chatbot], queue=False) demo.queue() demo.launch() |
So this is how you can create your own custom agent with memory in Langchain. Hope you enjoy reading. If you have any doubt/suggestion please feel free to ask and I will do my best to help or improve myself. Good-bye until next time.