mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-28 10:49:56 +02:00
380 lines
12 KiB
Markdown
380 lines
12 KiB
Markdown
# LangGraph Architecture Specification
|
|
|
|
## Overview
|
|
|
|
LangGraph is a framework for building stateful, observable applications with large language models (LLMs). It uses a graph-based architecture with explicit state management to provide features like streaming output, cyclical workflows, human-in-the-loop capabilities, and persistence.
|
|
|
|
This document provides a comprehensive overview of LangGraph's architecture, how the components interact, and the design principles that guide its implementation.
|
|
|
|
## Architectural Layers
|
|
|
|
LangGraph follows a layered architecture that provides different levels of abstraction:
|
|
|
|
```
|
|
┌───────────────────────────────────────────────────────┐
|
|
│ Application Layer │
|
|
│ (User-defined agents and cognitive architectures) │
|
|
└────────────────────────────┬──────────────────────────┘
|
|
│
|
|
▼
|
|
┌───────────────────────────────────────────────────────┐
|
|
│ High-Level API Layer │
|
|
│ (StateGraph, Functional API, etc.) │
|
|
└────────────────────────────┬──────────────────────────┘
|
|
│
|
|
▼
|
|
┌───────────────────────────────────────────────────────┐
|
|
│ Execution Layer │
|
|
│ (Pregel) │
|
|
└────────────────────────────┬──────────────────────────┘
|
|
│
|
|
▼
|
|
┌───────────────────────────────────────────────────────┐
|
|
│ State Management Layer │
|
|
│ (Channels, Schemas, Checkpoints) │
|
|
└────────────────────────────┬──────────────────────────┘
|
|
│
|
|
▼
|
|
┌───────────────────────────────────────────────────────┐
|
|
│ Persistence Layer │
|
|
│ (Memory, Disk, Database implementations) │
|
|
└───────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Application Layer
|
|
|
|
Where users define their specific LLM applications, agents, and workflows using the LangGraph API.
|
|
|
|
### High-Level API Layer
|
|
|
|
Provides intuitive interfaces like `StateGraph` for defining computation graphs with minimal boilerplate.
|
|
|
|
### Execution Layer
|
|
|
|
Implements the Pregel computation model for executing the graph in a deterministic, observable way.
|
|
|
|
### State Management Layer
|
|
|
|
Handles state definition, validation, transformation, and propagation through the graph.
|
|
|
|
### Persistence Layer
|
|
|
|
Provides storage implementations for checkpoints and long-term memory.
|
|
|
|
## Core Components
|
|
|
|
### StateGraph
|
|
|
|
The primary user-facing API for defining computation graphs:
|
|
|
|
```python
|
|
from langgraph.graph import StateGraph
|
|
from typing import TypedDict, Annotated
|
|
|
|
# Define state schema
|
|
class State(TypedDict):
|
|
messages: list[str]
|
|
counter: int
|
|
|
|
# Create graph with schema
|
|
graph = StateGraph(State)
|
|
|
|
# Add nodes (functions)
|
|
graph.add_node("process", process_func)
|
|
graph.add_node("decide", decide_func)
|
|
|
|
# Add edges
|
|
graph.add_edge("process", "decide")
|
|
graph.add_conditional_edges(
|
|
"decide",
|
|
lambda state: "continue" if state["counter"] < 5 else "end"
|
|
)
|
|
|
|
# Compile graph into a runnable
|
|
workflow = graph.compile()
|
|
```
|
|
|
|
Key features:
|
|
|
|
- Type-safe state schema
|
|
- Conditional routing
|
|
- Cyclical execution patterns
|
|
- Checkpoint integration
|
|
- Streaming support
|
|
|
|
### Pregel Execution Engine
|
|
|
|
The computational backbone that executes the graph:
|
|
|
|
- Implements the Bulk Synchronous Parallel computation model
|
|
- Manages the lifecycle of node execution and state updates
|
|
- Ensures deterministic execution despite parallel processing
|
|
- Integrates with the checkpoint system
|
|
- Provides streaming capabilities
|
|
|
|
### Channel System
|
|
|
|
Provides communication between nodes with specialized behaviors:
|
|
|
|
- LastValue: Stores a single value, ensuring type safety
|
|
- Topic: Pub/sub pattern for multi-consumer updates
|
|
- BinaryOperatorAggregate: Combines values using operators
|
|
- Barrier channels: Synchronization mechanisms
|
|
- And more specialized channel types
|
|
|
|
### State Schema
|
|
|
|
Defines the structure and behavior of application state:
|
|
|
|
```python
|
|
class ConversationState(TypedDict):
|
|
messages: list[dict] # Regular list
|
|
context: Annotated[dict, untracked()] # Excluded from checkpoints
|
|
history: Annotated[list[str], append()] # Append-only list
|
|
```
|
|
|
|
Features:
|
|
|
|
- Type validation
|
|
- Custom reducers via annotations
|
|
- Integration with channels
|
|
- Multiple definition formats (TypedDict, Pydantic, dataclass)
|
|
|
|
### Checkpoint System
|
|
|
|
Enables persistence and human-in-the-loop capabilities:
|
|
|
|
- Thread-based execution isolation
|
|
- Checkpoint creation and restoration
|
|
- State history tracking
|
|
- Time travel debugging
|
|
- Hierarchical checkpoint namespaces
|
|
|
|
### Human-in-the-Loop
|
|
|
|
Support for interactive workflows:
|
|
|
|
- Interruption at specific points
|
|
- State inspection during interruption
|
|
- State modification
|
|
- Resumption from interrupted state
|
|
|
|
## Key Interfaces
|
|
|
|
### StateGraph API
|
|
|
|
```python
|
|
class StateGraph:
|
|
def __init__(self, state_schema: Type) -> None: ...
|
|
|
|
def add_node(self, name: str, action: Callable) -> None: ...
|
|
|
|
def add_edge(self, start: str, end: str) -> None: ...
|
|
|
|
def add_conditional_edges(
|
|
self,
|
|
start: str,
|
|
condition: Callable[[Any], str]
|
|
) -> None: ...
|
|
|
|
def compile(self, **kwargs) -> PregelRunnable: ...
|
|
```
|
|
|
|
### PregelRunnable API
|
|
|
|
```python
|
|
class PregelRunnable:
|
|
def invoke(self, input: Any, config: dict = None) -> Any: ...
|
|
|
|
def stream(
|
|
self,
|
|
input: Any,
|
|
config: dict = None,
|
|
stream_mode: StreamMode = None
|
|
) -> Iterator[Any]: ...
|
|
|
|
def get_state(self, thread_id: str = None) -> Any: ...
|
|
|
|
def update_state(self, thread_id: str, state: Any) -> None: ...
|
|
|
|
def get_state_history(self, thread_id: str) -> list[Any]: ...
|
|
```
|
|
|
|
## Design Principles
|
|
|
|
LangGraph's architecture is guided by the following principles:
|
|
|
|
### 1. Explicit State
|
|
|
|
State is always explicitly defined and validated, providing type safety and preventing many classes of bugs.
|
|
|
|
### 2. Composability
|
|
|
|
Components are designed to be combined in various ways:
|
|
|
|
- Nodes can be nested graphs
|
|
- Channels can be composed for complex behaviors
|
|
- States can be nested for hierarchical organization
|
|
|
|
### 3. Observability
|
|
|
|
Execution is transparent and observable:
|
|
|
|
- Streaming support for real-time visibility
|
|
- State history tracking
|
|
- Detailed tracing
|
|
- Checkpoint inspection
|
|
|
|
### 4. Determinism
|
|
|
|
Given the same input and thread ID, execution produces identical results:
|
|
|
|
- Consistent ordering of parallel operations
|
|
- Atomic state updates
|
|
- Reliable checkpoint restoration
|
|
|
|
### 5. Extensibility
|
|
|
|
The framework is designed for extension:
|
|
|
|
- Custom channel types
|
|
- Pluggable storage backends
|
|
- Custom state schema formats
|
|
- Integrations with other frameworks
|
|
|
|
## Implementation Invariants
|
|
|
|
These invariants are maintained and tested throughout the codebase:
|
|
|
|
### State Management Invariants
|
|
|
|
1. **Type Safety**: All state updates must conform to the schema
|
|
2. **Atomic Updates**: State updates are all-or-nothing
|
|
3. **State Isolation**: Updates are not visible until the end of a superstep
|
|
4. **Schema Compatibility**: State schemas must be compatible with serialization
|
|
|
|
### Execution Invariants
|
|
|
|
1. **Deterministic Ordering**: Node execution order is consistent
|
|
2. **Termination**: Execution always completes for valid graphs
|
|
3. **Error Handling**: Node failures are handled gracefully
|
|
4. **Checkpoint Fidelity**: Execution resumes correctly from checkpoints
|
|
|
|
### Channel Invariants
|
|
|
|
1. **Type Enforcement**: Channel values must match declared types
|
|
2. **Update Validation**: Updates are validated before application
|
|
3. **Serialization**: Channels must serialize/deserialize correctly
|
|
4. **Behavior Consistency**: Each channel type must maintain its contract
|
|
|
|
## Reimplementation Guide
|
|
|
|
If reimplementing LangGraph from scratch, follow these steps:
|
|
|
|
1. **Start with State Schemas**: Implement the state validation system
|
|
2. **Build Channel Types**: Create the basic channel implementations
|
|
3. **Implement Pregel Core**: Build the execution engine
|
|
4. **Add Checkpoint Support**: Implement persistence
|
|
5. **Create StateGraph API**: Build the high-level interface
|
|
6. **Add HITL Features**: Implement interruption/resumption
|
|
|
|
Challenging aspects:
|
|
|
|
- Maintaining determinism with parallel execution
|
|
- Ensuring type safety across the system
|
|
- Implementing efficient checkpointing
|
|
- Managing complex state transitions
|
|
|
|
## Testing Strategy
|
|
|
|
LangGraph's test suite focuses on:
|
|
|
|
1. **Unit Tests**: For individual components
|
|
2. **Integration Tests**: For component interactions
|
|
3. **Property Tests**: For invariant verification
|
|
4. **Snapshot Tests**: For regression prevention
|
|
5. **Performance Tests**: For optimization
|
|
|
|
## Optimization and Performance
|
|
|
|
LangGraph includes several optimizations:
|
|
|
|
1. **Parallel Execution**: Nodes execute in parallel when possible
|
|
2. **Lazy Checkpointing**: Only changed state is serialized
|
|
3. **Channel-specific Optimizations**: Each channel type optimizes its pattern
|
|
4. **Batched Operations**: Tasks are batched for efficiency
|
|
5. **Memory Management**: Large states use specialized handling
|
|
|
|
## Security Considerations
|
|
|
|
When implementing or extending LangGraph, consider:
|
|
|
|
1. **Input Validation**: All external inputs must be validated
|
|
2. **Serialization Safety**: Avoid security issues in serialization
|
|
3. **Access Control**: Proper thread isolation to prevent data leakage
|
|
4. **Resource Limits**: Prevent unbounded resource consumption
|
|
5. **Secrets Management**: Avoid storing secrets in checkpoints
|
|
|
|
## Advanced Patterns
|
|
|
|
### Nested Graphs
|
|
|
|
```python
|
|
# Main graph
|
|
main_graph = StateGraph(MainState)
|
|
|
|
# Subgraph
|
|
subgraph = StateGraph(SubState)
|
|
subgraph.add_node("sub_process", sub_process)
|
|
compiled_subgraph = subgraph.compile()
|
|
|
|
# Include subgraph in main graph
|
|
main_graph.add_node("subprocess", compiled_subgraph)
|
|
```
|
|
|
|
### Complex Routing
|
|
|
|
```python
|
|
# Define routing logic
|
|
def router(state: State) -> str:
|
|
if state["error"]:
|
|
return "error_handler"
|
|
elif state["counter"] > 10:
|
|
return "summarize"
|
|
else:
|
|
return "continue"
|
|
|
|
# Add conditional edges
|
|
graph.add_conditional_edges("process", router)
|
|
```
|
|
|
|
## Related Systems
|
|
|
|
LangGraph draws inspiration from and can be compared to:
|
|
|
|
1. **Airflow/Temporal**: Workflow orchestration systems
|
|
2. **Actor Frameworks**: Like Akka and Ray
|
|
3. **Stream Processing**: Systems like Apache Flink
|
|
4. **State Machines**: Like XState and statecharts
|
|
|
|
Key differentiators:
|
|
|
|
- Not for DAGs, full support for cycles
|
|
- Focus on LLM-specific workflows
|
|
- Type-safe state management
|
|
- Human-in-the-loop capabilities
|
|
- Checkpoint-based persistence
|
|
|
|
## Conclusion
|
|
|
|
LangGraph's layered architecture provides a flexible, type-safe, and observable framework for building complex LLM applications. By understanding the components and their interactions, developers can leverage the full power of the framework while maintaining robust, maintainable code.
|
|
|
|
For implementation details on specific components, refer to the other specification documents:
|
|
|
|
- [Pregel.md](Pregel.md): Execution engine details
|
|
- [Channels.md](Channels.md): Communication mechanism
|
|
- [StateSchema.md](StateSchema.md): State definition
|
|
- [StateGraph.md](StateGraph.md): High-level API
|
|
- [CheckpointSystem.md](CheckpointSystem.md): Persistence
|
|
- [HumanInTheLoop.md](HumanInTheLoop.md): Interruption/resumption
|