---
title: "Deep Agents Part 2: The Foundation – LangGraph and DeepAgentState"
description: "Diving deep into the technical components that underpin deepagents: LangGraph as the agent runtime and the custom DeepAgentState object that manages complex operations and persistent information"
author: "Colin McNamara"
tags: ["AI","LangGraph","Python","State Management","Agent Architecture"]
date: 2025-08-06
url: https://colinmcnamara.com/blog/deep-agents-part-2-foundation-langgraph
---

# Deep Agents Part 2: The Foundation – LangGraph and DeepAgentState

To truly understand how "Deep Agents" operate, it's essential to delve into the core technical components that underpin the [deepagents library](https://github.com/hwchase17/deepagents). This post focuses on LangGraph, the agent runtime, and the custom DeepAgentState object, which together manage the agent's complex operations and persistent information.

## LangGraph: The Robust Agent Runtime

The deepagents project is fundamentally built on top of **LangGraph**. LangGraph serves as the powerful agent runtime for deepagents, providing the necessary infrastructure for constructing and executing intelligent agents.

### Agents as Graphs

Within LangGraph, agents are conceptualized and built as graphs. This graph-based representation allows for complex control flow and state management, which is crucial for handling multi-step, intricate tasks. This architecture enables:

- Complex control flow patterns
- Parallel execution of independent tasks
- State management across distributed operations
- Clear visualization of agent workflows

### The "React Agent" Loop (Core Algorithm)

The core algorithm that deepagents uses under the hood is implemented by LangGraph's `create_react_agent` wrapper. This wrapper orchestrates a "react agent" loop:

1. The Large Language Model (LLM) makes a call and then decides whether to stop or take an action
2. If an action is taken, the agent executes that action and receives feedback
3. This feedback is passed back to the LLM, continuing the iterative loop

This continuous feedback loop is what enables deep, iterative problem-solving. It allows the agent to:
- Make incremental progress on complex tasks
- Adjust its approach based on intermediate results
- Maintain context across multiple iterations
- Handle unexpected situations gracefully

### Seamless Integration and Features

Because agents created with `create_deep_agent` are essentially LangGraph graphs, they inherit many benefits and can be interacted with in the same way as any other LangGraph agent. These features include:

- **Streaming**: Get results incrementally as the agent works
- **Human-in-the-loop support**: Allow human intervention when needed
- **Memory management**: Maintain conversation history and state over time
- **Integration with LangChain Studio**: Visualize and debug agent execution

## DeepAgentState: The Agent's Internal State Management

Central to the operation of a Deep Agent is its ability to track and manage information over time. LangGraph agents define a "state" for this purpose. The deepagents library implements a custom `DeepAgentState` object, which is crucial for managing the agent's internal information throughout its complex tasks.

```mermaid
graph LR
 subgraph "State Management Flow"
 INPUT["Agent Input"] --> STATE["DeepAgentState"]
 STATE --> PLAN["Planning Tool"]
 STATE --> FILES["File System Tools"]
 FILES --> PERSIST["files: Dict[str, str]"]
 PLAN --> TODO["Todo Management"]
 PERSIST --> OUTPUT["Agent Output"]
 TODO --> OUTPUT
 end
```

### Inheritance from LangGraph's AgentState

`DeepAgentState` inherits directly from LangGraph's `AgentState`. This ensures compatibility with LangGraph's core "react agent" loop and provides a robust foundation. The inheritance brings essential attributes like:

- Message tracking capabilities
- Step counting for loop control
- Base state management functionality

### Key Attributes of DeepAgentState

Beyond the attributes inherited from `AgentState`, `DeepAgentState` introduces specific attributes vital for deep agent behavior:

```mermaid
graph LR
    subgraph "DeepAgentState Structure"
        State[DeepAgentState] --> Messages[messages<br/>List of conversation history]
        State --> Steps[is_last_step<br/>remaining_steps<br/>Loop control]
        State --> ToDos[to-dos<br/>Task management list]
        State --> Files[files<br/>Virtual file system dict]
        
        Messages --> M1[Human Messages]
        Messages --> M2[AI Messages]
        Messages --> M3[Tool Messages]
        
        ToDos --> T1[pending]
        ToDos --> T2[in_progress]
        ToDos --> T3[completed]
        
        Files --> F1[filename: content]
    end
    
    style State fill:#f9f,stroke:#333,stroke-width:4px
    style Messages fill:#bbf,stroke:#333,stroke-width:2px
    style ToDos fill:#bbf,stroke:#333,stroke-width:2px
    style Files fill:#bbf,stroke:#333,stroke-width:2px
    style Steps fill:#bbf,stroke:#333,stroke-width:2px
```

#### messages
This is a list of messages—which can be human, AI, or tool messages—that track the agent's conversation and actions over time. Messages are usually appended but can sometimes be modified. This provides a complete audit trail of:
- User requests
- Agent responses
- Tool invocations and results
- Intermediate reasoning steps

#### is_last_step and remaining_steps
These attributes are used to track the iteration of the agent loop. They allow for the agent's execution to be terminated if a user-defined threshold of steps is exceeded, preventing infinite loops and controlling computational resources.

#### to-dos
This attribute is a list of "to-do" objects. Each "to-do" object contains:
- **content**: A string describing the task
- **status**: Which can be 'pending', 'in progress', or 'completed'

This list is specifically used by the planning tool (`write_to_dos`) to track task progress and manage the agent's overarching plan. It enables the agent to:
- Break down complex tasks into manageable steps
- Track progress across multiple work sessions
- Prioritize and reorganize tasks as needed

#### files
This crucial attribute is a dictionary representing a virtual file system. It maps string keys (file names) to string content, simulating file operations.

### Why a "Virtual" File System?

The choice to use a virtual (or "mock") file system instead of interacting with a real one is a deliberate design decision. As explained in [Harrison Chase's presentation](https://www.youtube.com/watch?v=TTMYJAw5tiA), this approach offers several advantages:

- **Scalability**: It's "a lot easier to scale this" as there's no file I/O overhead
- **Concurrency**: Avoids conflicts when running multiple agents concurrently on the same machine
- **Isolation**: Agents won't edit the same underlying physical files or require separate directories
- **Portability**: The entire agent state, including files, can be easily serialized and moved

### File Reducer for Parallel Operations

A file reducer is implemented to manage updates to the files dictionary. This reducer:
- Merges dictionaries from parallel operations
- Combines new files that might be created by different parts of the graph running concurrently
- Ensures consistency when multiple sub-agents operate simultaneously

### Current Limitations

While effective for merging new files, the current implementation "does not resolve conflicts" if multiple parallel agents attempt to edit the same file. This is identified as an edge case and a potential area for future enhancement in the roadmap. For now:
- New file creation is safe in parallel
- Editing different files is safe in parallel
- Editing the same file in parallel may lead to lost updates

### Accessing Files

Files can be passed into and retrieved from the agent by using the `files` key in the LangGraph State object:

```python
# Passing files to the agent
result = agent.invoke({
    "messages": [{"role": "user", "content": "Analyze these files"}],
    "files": {"data.txt": "Sample data content"}
})

# Retrieving files from the agent
output_files = result["files"]
```

## The create_deep_agent Function

The `create_deep_agent` function, which you learned about in Part 1, is responsible for setting up an agent that utilizes these LangGraph foundations. It:
- Passes the correct model, prompt, and tools to `create_react_agent`
- Configures the custom `DeepAgentState` schema
- Sets up the graph structure for agent execution
- Integrates all the components into a cohesive system

## What's Next?

Now that we understand the foundational technical aspects of deepagents, in Part 3 we'll explore the Built-in Tools and Customization options that make Deep Agents so powerful. We'll dive into the specific functionalities the agents possess, including the planning tool, file system operations, and the powerful sub-agent delegation system.

---

*This is Part 2 of a 4-part series on Deep Agents. Tomorrow we'll explore the powerful built-in tools and customization options that enable Deep Agents to tackle complex, real-world tasks.*

**Learn more:**
- [Deep Agents GitHub Repository](https://github.com/hwchase17/deepagents)
- [Harrison Chase's Deep Agents Presentation](https://www.youtube.com/watch?v=TTMYJAw5tiA)
- [Deep Wiki - Deep Agents Documentation](https://deepwiki.com/hwchase17/deepagents)
