Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Learn how to build a functional AI agent in under 30 minutes with just basic Python knowledge and no ML background. This step-by-step guide walks you through creating a weather agent using LangChain and GPT-4, with technical diagrams and advanced concepts for taking your AI development skills further.
When I first encountered the term “AI agent,” I immediately pictured complex neural networks, data science wizardry, and weeks of coding. As someone with over 11 years of software engineering experience but no machine learning background, I assumed building an AI agent would be far beyond my reach.
I couldn’t have been more wrong.
In under 30 minutes, I built a functional AI agent that could respond to natural language queries and perform real-world tasks. No data science degree required—just a bit of Python knowledge, some open-source tools, and a clear goal.
Let me walk you through how you can do the same.
Before diving in, let’s clarify what makes something an “AI agent” from a technical perspective:
Our weather agent might seem simple, but it implements all these components through the LangChain framework, which handles the complex orchestration between the language model and tools.
mermaidgraph TD
A[User Input] --> B[LLM Processing]
B --> C{Decision Making}
C -->|Use Tool| D[Tool Execution]
D --> E[Result Processing]
E --> F[Response Generation]
C -->|Direct Answer| F
F --> G[User Output]
Diagram: The decision-making flow of an AI agent
The first mistake many developers make is trying to build the next ChatGPT or an autonomous system that can handle a dozen complex tasks. Instead, begin with something targeted and useful.
For my first agent, I chose a straightforward goal: creating an AI that could fetch current weather data based on a location I provided. Simple, practical, and achievable.
Before we dive into the code, let’s get our environment ready. You’ll need:
Let’s install the required packages:
bashpip install langchain langchain_openai openai requests python-dotenv
First, let’s import all the packages we’ll need:
pythonfrom langchain_openai import ChatOpenAI
from langchain.agents import AgentType, initialize_agent
from langchain.tools import Tool
import requests
import os
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
# Verify OpenAI API key exists
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
if not OPENAI_API_KEY:
print("Warning: OPENAI_API_KEY not found in environment variables")
print("Please set your OpenAI API key as an environment variable or directly in this file")
Create a file named .env
in your project directory and add your OpenAI API key:
OPENAI_API_KEY=sk-your-api-key-here
What makes an agent truly useful is its ability to interact with external systems. Let’s create a simple function that fetches weather data using the free Open-Meteo API (no registration or API key required):
pythondef get_weather(query: str):
# Parse latitude and longitude from query
try:
lat_lon = query.strip().split(',')
latitude = float(lat_lon[0].strip())
longitude = float(lat_lon[1].strip())
except:
# Default to New York if parsing fails
latitude, longitude = 40.7128, -74.0060
url = f"https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}¤t=temperature_2m,wind_speed_10m"
response = requests.get(url)
data = response.json()
temperature = data["current"]["temperature_2m"]
wind_speed = data["current"]["wind_speed_10m"]
return f"The current temperature is {temperature}°C with a wind speed of {wind_speed} m/s."
This function accepts a string containing latitude and longitude, makes an API request to Open-Meteo, and returns the current temperature and wind speed.
We’ll use OpenAI’s gpt-4o-mini
model, which offers a great balance of capability and cost-effectiveness:
pythonllm = ChatOpenAI(model="gpt-4o-mini", openai_api_key=OPENAI_API_KEY)
Now we’ll create a tool that the AI can use:
pythontools = [
Tool(
name="Weather",
func=get_weather,
description="Get current weather. Input should be latitude and longitude as two numbers separated by a comma (e.g., '40.7128, -74.0060')."
)
]
The description is crucial—it tells the AI what the tool does and how to use it properly.
Finally, we’ll combine everything to create our agent:
pythonagent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
Setting verbose=True
lets us see the agent’s thought process, which is helpful for debugging and understanding how it works.
Let’s see our agent in action:
python# Example usage
response = agent.run("What's the weather like in Paris, France?")
print(response)
When you run this code, you’ll see something like:
> Entering new AgentExecutor chain...
I need to find the current weather in Paris, France. To do this, I will use the geographic coordinates of Paris, which are approximately 48.8566 latitude and 2.3522 longitude.
Action: Weather
Action Input: '48.8566, 2.3522'
Observation: The current temperature is 21.1°C with a wind speed of 13.9 m/s.
Thought: I now know the final answer
Final Answer: The current weather in Paris, France is 21.1°C with a wind speed of 13.9 m/s.
> Finished chain.
The current weather in Paris, France is 21.1°C with a wind speed of 13.9 m/s.
That’s it! You’ve built a working AI agent that:
To truly understand our weather agent, let’s explore what’s happening behind the scenes:
Our agent uses the ZERO_SHOT_REACT_DESCRIPTION agent type, which implements the ReAct (Reasoning + Acting) framework. This approach allows the LLM to:
This creates a loop that continues until the agent believes it has the final answer.
mermaidsequenceDiagram
participant User
participant LLM
participant Tool
User->>LLM: "What's the weather in Paris?"
LLM->>LLM: Think: Need Paris coordinates
LLM->>Tool: Action: Weather(48.8566, 2.3522)
Tool->>LLM: Observation: 21.1°C, wind 13.9 m/s
LLM->>LLM: Think: I now have the answer
LLM->>User: The weather in Paris is 21.1°C...
Diagram: Sequence of interactions in our weather agent
When you initialize an agent with AgentType.ZERO_SHOT_REACT_DESCRIPTION
, LangChain constructs a complex prompt that includes:
Here’s a simplified version of what the prompt looks like:
You have access to the following tools:
Weather: Get current weather. Input should be latitude and longitude as two numbers separated by a comma (e.g., '40.7128, -74.0060').
Use the following format:
Question: The input question
Thought: Think about what to do
Action: The action to take, should be one of [Weather]
Action Input: The input to the action
Observation: The result of the action
... (this Thought/Action/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: The final answer to the original question
This structured prompt is what enables the LLM to act as an agent and use tools effectively.
The power of this method lies in its simplicity. By focusing on a single, well-defined task, we can create something functional quickly. The LangChain framework handles the complex parts:
Once you have this foundation, you can expand your agent’s capabilities:
Agents become significantly more powerful when they can remember past interactions:
pythonfrom langchain.memory import ConversationBufferMemory
# Create a memory instance
memory = ConversationBufferMemory(memory_key="chat_history")
# Initialize agent with memory
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
memory=memory,
verbose=True
)
This allows your agent to reference previous questions and answers, maintaining context across multiple interactions.
For more complex tasks, you can create a hierarchy of tools:
pythondef get_location_coordinates(location_name: str):
"""Convert a location name to coordinates using a geocoding API"""
# Implementation using a geocoding service
return "48.8566, 2.3522" # Example for Paris
location_tool = Tool(
name="LocationFinder",
func=get_location_coordinates,
description="Converts a location name to latitude/longitude coordinates."
)
tools = [location_tool, weather_tool]
With this approach, your agent can now handle queries like “What’s the weather in Tokyo?” without requiring the user to know coordinates.
mermaidgraph TD
A[User Query] --> B[Agent]
B -->|If location name| C[Location Tool]
C --> D[Weather Tool]
B -->|If coordinates| D
D --> E[Response]
Diagram: Tool composition for a more advanced weather agent
As you grow more comfortable, you can create systems of specialized agents that work together:
pythonweather_agent = initialize_agent(
tools=[weather_tool],
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
planning_agent = initialize_agent(
tools=[Tool(name="WeatherAgent", func=weather_agent.run)],
llm=llm,
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
This creates a hierarchical system where specialized agents handle different aspects of a complex task.
Beyond these advanced techniques, consider:
When building AI agents, several technical challenges may arise. Here’s how to address them:
LLMs can sometimes “hallucinate” information, which is particularly problematic for agents that interact with real-world systems.
Solution: Implement structured validation for tool inputs:
pythondef get_weather(query: str):
# Input validation
try:
lat_lon = query.strip().split(',')
if len(lat_lon) != 2:
return "ERROR: Input must contain exactly two values separated by a comma."
latitude = float(lat_lon[0].strip())
longitude = float(lat_lon[1].strip())
if latitude < -90 or latitude > 90:
return "ERROR: Latitude must be between -90 and 90."
if longitude < -180 or longitude > 180:
return "ERROR: Longitude must be between -180 and 180."
except ValueError:
return "ERROR: Could not parse coordinates. Please provide valid numbers."
# Rest of the function...
This forces the agent to correct its approach when it provides invalid inputs.
LLMs have context window limitations, which can be an issue for complex tasks.
Solution: Implement chain-of-thought decomposition:
pythondef complex_workflow(query: str):
# Break down complex tasks into steps
step1 = agent.run(f"Step 1 for query: {query}")
step2 = agent.run(f"Step 2 using previous result: {step1}")
return step2
Making API calls to both the LLM and external services can become expensive and slow.
Solution: Implement caching:
pythonfrom langchain.cache import InMemoryCache
import langchain
# Set up cache
langchain.llm_cache = InMemoryCache()
# For tool results
weather_cache = {}
def get_weather_with_cache(query: str):
if query in weather_cache:
return weather_cache[query]
result = get_weather(query)
weather_cache[query] = result
return result
This diagram illustrates how caching affects system performance:
mermaidgraph TD
A[User Query] --> B{In Cache?}
B -->|Yes| C[Return Cached Result]
B -->|No| D[Compute Result]
D --> E[Store in Cache]
E --> F[Return Result]
C --> F
Diagram: Caching mechanism for performance optimization
When building your first agent, be mindful of these common mistakes:
To complete our technical deep dive, let’s examine the system architecture of our weather agent:
mermaidgraph TB
subgraph User Interface
A[User Query]
Z[Agent Response]
end
subgraph Agent System
B[LangChain Agent]
C[Tool Registry]
D[LLM - GPT-4o-mini]
E[Agent Executor]
end
subgraph External Services
F[OpenAI API]
G[Open-Meteo API]
end
A --> B
B --> C
B --> D
B --> E
D <--> F
E --> G
E --> Z
Diagram: Complete system architecture of our weather agent
When a user query enters the system:
This architecture provides a foundation you can extend for more complex systems while maintaining clear separation of concerns.
As you continue developing AI agents, these common patterns will prove useful:
These patterns come from traditional software engineering but apply beautifully to agent-based systems.
Building your first AI agent doesn’t have to be intimidating. With the right approach and tools, you can create something functional in minutes rather than weeks or months.
The technical concepts covered in this article—from the ReAct framework to caching strategies and design patterns—provide a foundation for creating increasingly sophisticated systems as your confidence grows.
Remember: Start small, focus on solving a real problem, and let frameworks like LangChain handle the heavy lifting. As you gain expertise, you can implement more advanced features like memory, tool composition, and multi-agent architectures.
Happy building! What will your agent do?
What simple AI agent would you build first? Share your ideas and technical questions in the comments below!