Install dependencies:
#
# Tip: Use a virtual environment to keep this project's dependencies isolated from your system Python and other projects.
#
!pip install "langchain<0.3" "langchain-core<0.3" "langchain-community<0.3" "langchain-openai<0.2"from langchain.chat_models import ChatOpenAI
from langchain.agents import Tool, initialize_agent
from langchain.memory import ConversationBufferWindowMemory
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)Below are two tools already defined for you.
def calculator(expression: str) -> str:
"""Evaluates a math expression, e.g. '12 * 4'."""
return str(eval(expression))
def word_counter(text: str) -> str:
"""Counts the number of words in a text."""
return str(len(text.split()))
tools = [
Tool(name="Calculator", func=calculator, description="Useful for solving math expressions."),
Tool(name="WordCounter", func=word_counter, description="Useful for counting words in a text."),
]Your task:
- Create an agent with
initialize_agent()usingagent="chat-conversational-react-description". - Run it with a question that requires the
Calculatortool (e.g. "What is 245 * 12?").
💡 Solution
agent = initialize_agent(
tools=tools,
llm=llm,
agent="chat-conversational-react-description",
verbose=True,
)
agent.run("What is 245 * 12?")Your task: Add a ConversationBufferWindowMemory (k=3) to your agent so it remembers previous turns. Ask two related questions, one after the other (e.g. "My name is Sam." then "What's my name?").
💡 Solution
memory = ConversationBufferWindowMemory(
memory_key="chat_history", k=3, return_messages=True
)
agent = initialize_agent(
tools=tools,
llm=llm,
agent="chat-conversational-react-description",
memory=memory,
verbose=True,
)
agent.run("My name is Sam.")
agent.run("What's my name?")Add a new tool that looks up a "weather" from a fixed dictionary:
def get_weather(city: str) -> str:
"""Returns the weather for a given city."""
fake_weather = {"Madrid": "Sunny, 30°C", "London": "Rainy, 15°C"}
return fake_weather.get(city, "No data for that city.")
tools.append(Tool(name="Weather", func=get_weather, description="Useful for checking the weather in a city."))Ask the agent a question that requires both the Weather and Calculator tools in the same query (e.g. "What's the weather in Madrid, and what is 15 * 3?").
💡 Solution
tools = [...] # make sure to pass all the tools needed (including the new one)
agent = initialize_agent(
tools=tools,
llm=llm,
agent="chat-conversational-react-description",
memory=memory,
verbose=True,
)
agent.run("What's the weather in Madrid, and what is 15 * 3?")Check the verbose output — the agent should call Weather and Calculator separately, then combine both results in its final answer.
Run any query with verbose=True and look at the printed trace (the Thought / Action / Action Input / Observation steps).
Check which tool the agent picked and why — based only on the trace, not on your own guess.
💡 Solution
There's no single "correct" answer here — check that the agent behaves as expected.
This tool fails on purpose sometimes:
import random
def flaky_tool(query: str) -> str:
"""A tool that randomly fails."""
if random.random() < 0.5:
raise ValueError("Tool temporarily unavailable")
return "Success!"
tools.append(Tool(name="FlakyTool", func=flaky_tool, description="Useful when asked to 'test the flaky tool'."))Your task: Re-create the agent with handle_parsing_errors=True and a max_iterations limit, so it doesn't crash or loop forever when the tool fails. Test by asking it to "test the flaky tool" a few times.
💡 Solution
agent = initialize_agent(
tools=tools,
llm=llm,
agent="chat-conversational-react-description",
memory=memory,
verbose=True,
handle_parsing_errors=True,
max_iterations=3,
)
agent.run("Test the flaky tool.")For a more complex bonus, you can provide a retrievar as a tool.