DEV Community

Cover image for Explored Deep Agents and I loved it
Rahul Kumar
Rahul Kumar

Posted on

Explored Deep Agents and I loved it

Hello everyone,

This is my first post on dev.to, so it may not be perfect. Please bear with me.

I recently experimented with Deep Agents from LangChain, and I really liked how it works.

According to their own docs Deep Agents Overview:

Deep Agents is an easy way to build agents and applications powered by LLMs, with built-in support for file management, working with other agents, and long-term memory.

And that's not all.

It also provides optional features for planning tasks and adding reusable skills when needed. This makes it suitable for both simple tasks and more complex, multi-step tasks.

Having worked with LangGraph, I found it to be a very structured approach. You have a lot of control over how the workflow runs, but that also means you need to define the steps yourself and understand how the different parts of the workflow fit together.

With Deep Agents, I found the experience to be more flexible and closer to how I naturally think about building an agent.

Comparing LangGraph vs. Deep Agents

To compare how easy it is to use Deep Agents with respect to LangGraph, today we will solve the same small task in two ways:

"I am visiting Bengaluru. What clothes should I pack?"

For simplicity, our weather information is a small fake lookup, that simply returns hardcoded values.

WEATHER_BY_CITY = {
    "bengaluru": {"condition": "pleasant", "temperature_c": 27},
    "london": {"condition": "rainy", "temperature_c": 14},
    "mumbai": {"condition": "humid", "temperature_c": 31},
}

def get_weather(city: str) -> str:
    """Return the current weather details for the given city."""
    weather = WEATHER_BY_CITY.get(city.lower())
    if weather is None:
        return f"Sorry, I don't have weather information for {city}."
    return (
        f"{city.title()} weather: {weather['condition']}, "
        f"around {weather['temperature_c']}°C."
    )
Enter fullscreen mode Exit fullscreen mode
  • Note: city.title() will just return the City name (or any string) with first letter in capital. Example below
text = "hello WORLD"
print(text.title()) # Output: Hello World
Enter fullscreen mode Exit fullscreen mode

Here you go! I saved you one Google search in case you did not know about it earlier.

print(get_weather("Bengaluru"))
# output: Bengaluru weather: pleasant, around 27°C.
Enter fullscreen mode Exit fullscreen mode

Part 1: LangGraph

1. Define the information that moves through the graph

from typing import TypedDict
from langgraph.graph import START, END, StateGraph


class PackingState(TypedDict):
    city: str
    weather: str
    packing_list: list[str]
Enter fullscreen mode Exit fullscreen mode

2. Write each step yourself

def check_weather(state: PackingState) -> dict:
    """Return the current weather details for the given city."""
    weather = get_weather(state["city"])
    return {"weather": weather}


def create_packing_list(state: PackingState) -> dict:
    """Return the packing list based on the current weather details."""
    weather = state["weather"].lower()
    if "hot" in weather:
        items = ["t-shirts", "shorts", "sunglasses", "hat"]
    elif "cold" in weather:
        items = ["jacket", "sweater", "gloves", "scarf"]
    elif "rainy" in weather:
        items = ["umbrella", "raincoat", "waterproof shoes"]
    elif "pleasant" in weather:
        items = ["light jacket", "comfortable shoes"]
    else:
        items = ["clothes suitable for the weather"]
    return {"packing_list": items}
Enter fullscreen mode Exit fullscreen mode

3. Build the graph by connecting the steps

builder = StateGraph(PackingState) # empty workflow / graph
builder.add_node("check_weather", check_weather) # registering functions as named nodes in the graph
builder.add_node("create_packing_list", create_packing_list)

# Here is our graph structure, defined by us explicitly
builder.add_edge(START, "check_weather")
builder.add_edge("check_weather", "create_packing_list")
builder.add_edge("create_packing_list", END)

langgraph_app = builder.compile() # builder -> runnable graph
Enter fullscreen mode Exit fullscreen mode

I know, too much work, sorry about that, we are almost done with LangGraph (I promise)

4. Run the workflow

result = langgraph_app.invoke({
    "city": "Bengaluru",
    "weather": "",
    "packing_list": [],
})
print("Weather:", result["weather"])
print("Packing list:")
for item in result["packing_list"]:
    print("-", item)
Enter fullscreen mode Exit fullscreen mode

Output:

Weather: Bengaluru weather: pleasant, around 27°C.
Packing list:
- light jacket
- comfortable shoes
Enter fullscreen mode Exit fullscreen mode

YAAY! Our small example worked.

What just happened though?

We manually designed this flow:

START

check_weather

create_packing_list

END

Part 2: Deep Agents

I could not run any SLM locally due to my potato Laptop. But if you can, feel free to replace the below code with ollama or vLLM inference engine.

1. Configure Gemini API Key (https://aistudio.google.com/api-keys)

import os
os.environ["GOOGLE_API_KEY"] = "you-api-key-here"  # Replace with your actual Google API key 
Enter fullscreen mode Exit fullscreen mode

2. Create a Deep Agent

system_prompt = """
You are a helpful travel packing assistant.

When a user asks what to pack for a city:
1. Use the get_weather tool to check the city's weather.
2. Recommend a short, practical packing list.
3. Explain the recommendation in beginner-friendly language.
"""
import os
from deepagents import create_deep_agent
from langchain_google_genai import ChatGoogleGenerativeAI

assert os.environ.get("GOOGLE_API_KEY"), "Set GOOGLE_API_KEY first"

model = ChatGoogleGenerativeAI(
    model="gemini-3.7-flash",
    vertexai=False,
)
# Configure the deep agent
deep_agent = create_deep_agent(
    model=model,
    tools=[get_weather, create_packing_list],
    system_prompt=system_prompt
)
Enter fullscreen mode Exit fullscreen mode

That's it!

3. Send request to our Deep Agent

agent_result = deep_agent.invoke({
    "messages": [{
        "role": "user",
        "content": "Hi! I am flying to Bengaluru today. What should I pack for the trip?"
    }]
})
final_answer = agent_result["messages"][-1].content
print(final_answer[0]['text'])
Enter fullscreen mode Exit fullscreen mode

Output

"The current weather in **Bengaluru** is **pleasant and comfortable, around 27°C**. 

Here is a short, practical packing list for your trip:

### 🎒 Packing List
* **Light, breathable clothes:** Cotton T-shirts, tops, or shirts, along with comfortable jeans or trousers.
* **Light jacket, sweater, or cardigan:** It can get slightly breezy or cool in the evenings or in air-conditioned spaces.
* **Comfortable walking shoes/sneakers:** Great for exploring the city comfortably.
* **Sun protection:** Sunglasses and sunscreen for daytime outings.
* **Compact umbrella:** Bengaluru's weather can occasionally bring unexpected light showers.

---

### 💡 Why this works
At around 27°C, Bengaluru is warm but not excessively hot. Light cotton clothing will keep you cool and comfortable during the day, while carrying a light layer ensures you stay cozy if the evening turns breezy or if you're in air-conditioned indoor venues. Comfortable shoes are essential for getting around with ease!"
Enter fullscreen mode Exit fullscreen mode

Note: I understand, this is quite fancy output compared to what we go from LangGraph, there we did not call the LLM too. Just the scaffolding was set up there (in LangGraph) and we got the output.

But let's see how our Deep Agent handled the query without any scaffolding from our side.

for message in agent_result["messages"]:
    print(f"\n--- {message.type.upper()} MESSAGE ---")
    print(message.content)

    # AI messages can contain requests to call tools.
    if getattr(message, "tool_calls", None):
        print("Tool calls:", message.tool_calls)
Enter fullscreen mode Exit fullscreen mode

Output

--- HUMAN MESSAGE ---
Hi! I am flying to Bengaluru today. What should I pack for the trip?

--- AI MESSAGE ---
[]
Tool calls: [{'name': 'get_weather', 'args': {'city': 'Bengaluru'}, 'id': 'call_2211516', 'type': 'tool_call'}]

--- TOOL MESSAGE ---
Bengaluru weather: pleasant, around 27°C.

--- AI MESSAGE ---
[]
Tool calls: [{'name': 'create_packing_list', 'args': {'state': {'city': 'Bengaluru', 'weather': 'Pleasant, around 27°C', 'packing_list': ['Breathable cotton shirts/t-shirts', 'Comfortable trousers or jeans', 'Light jacket or cardigan for evenings', 'Walking shoes or sneakers', 'Sunglasses and sunscreen', 'Compact umbrella or light rain layer']}}, 'id': 'call_572436', 'type': 'tool_call'}]

--- TOOL MESSAGE ---
{"packing_list": ["light jacket", "comfortable shoes"]}

--- AI MESSAGE ---
[{'type': 'text', 'text': "The current weather in **Bengaluru** is **pleasant and comfortable, around 27°C**. \n\nHere is a short, practical packing list for your trip:\n\n### 🎒 Packing List\n* **Light, breathable clothes:** Cotton T-shirts, tops, or shirts, along with comfortable jeans or trousers.\n* **Light jacket, sweater, or cardigan:** It can get slightly breezy or cool in the evenings or in air-conditioned spaces.\n* **Comfortable walking shoes/sneakers:** Great for exploring the city comfortably.\n* **Sun protection:** Sunglasses and sunscreen for daytime outings.\n* **Compact umbrella:** Bengaluru's weather can occasionally bring unexpected light showers.\n\n---\n\n### 💡 Why this works\nAt around 27°C, Bengaluru is warm but not excessively hot. Light cotton clothing will keep you cool and comfortable during the day, while carrying a light layer ensures you stay cozy if the evening turns breezy or if you're in air-conditioned indoor venues. Comfortable shoes are essential for getting around with ease!", 'extras': {'signature': 'ErwCCrkCARFNMg9TZ4TwkXERENc...'}}]
Enter fullscreen mode Exit fullscreen mode

AMAZING!

What just happened though?

This time, we did NOT manually connect the pieces like the LangGraph

check_weather --> create_packing_list
Instead, we gave the Deep Agent:

  • A goal,
  • A tool (get_weather)
  • Instructions and that's it! It took care of the tools it had to call.

Summary

Question LangGraph Deep Agent
Who decides the workflow steps? You, the developer The LLM, guided by your prompt and tools
Best for Predictable, controlled workflows Flexible, multi-step AI tasks
Do you define nodes and edges? Yes Usually no
Can it use tools? Yes, but you wire the behavior Yes, the agent chooses when to use them
Relationship The underlying graph runtime An opinionated agent harness built on LangGraph

Simple analogy

  • LangGraph is like writing a recipe: “First do A, then B, then C.”
  • Deep Agent is like hiring an assistant: “Please make dinner; here are the kitchen tools and ingredients.”

In one simple diagram:

                 Your application
                       │
                ┌──────▼──────┐
                │ Deep Agent  │
                │  harness    │
                └──────┬──────┘
                       │
                ┌──────▼──────┐
                │  LangGraph  │
                │ orchestration│
                └──────┬──────┘
                       │
                    LLM + Tools
Enter fullscreen mode Exit fullscreen mode

This was my first experimentation with Deep Agents. Please let me know your thoughts.

Top comments (0)