Initial LangGraph architecture blueprints
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
# LangGraph State Management
|
||||
|
||||
**Version:** 1.0.0
|
||||
**Last Updated:** 2026-02-23
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
This document details how LangGraph manages state throughout the graph execution lifecycle.
|
||||
|
||||
---
|
||||
|
||||
## State Schema
|
||||
|
||||
### Typed State
|
||||
|
||||
LangGraph uses Python's `TypedDict` for type-safe state:
|
||||
|
||||
```python
|
||||
from typing import TypedDict
|
||||
|
||||
class AgentState(TypedDict):
|
||||
messages: list
|
||||
context: dict
|
||||
checkpoint_id: str | None
|
||||
```
|
||||
|
||||
### State Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ STATE FLOW IN LANGGRAPH │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
Input State
|
||||
│
|
||||
▼
|
||||
┌──────────────┐
|
||||
│ Node A │ ──▶ State Update (via reducer)
|
||||
│ (transform) │
|
||||
└──────────────┘
|
||||
│
|
||||
▼ (messages sent)
|
||||
┌──────────────┐
|
||||
│ Node B │ ──▶ State Update
|
||||
│ (transform) │
|
||||
└──────────────┘
|
||||
│
|
||||
▼
|
||||
Output State
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Reducers
|
||||
|
||||
### What Are Reducers?
|
||||
|
||||
Reducers define how state updates are merged when multiple nodes produce updates.
|
||||
|
||||
### Built-in Reducers
|
||||
|
||||
| Reducer | Behavior |
|
||||
|---------|----------|
|
||||
| `add_messages` | Append to list |
|
||||
| `operator.or` | Union of sets |
|
||||
| `last` | Last value wins |
|
||||
|
||||
### Custom Reducers
|
||||
|
||||
```python
|
||||
def merge_dicts(left: dict, right: dict) -> dict:
|
||||
"""Merge two dictionaries, with right taking precedence."""
|
||||
result = left.copy()
|
||||
result.update(right)
|
||||
return result
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Checkpointing
|
||||
|
||||
### How Checkpointing Works
|
||||
|
||||
1. **Snapshot:** At each checkpoint, serialize full state
|
||||
2. **Store:** Save to backend (SQLite, Postgres, etc.)
|
||||
3. **Resume:** On failure, load from last checkpoint
|
||||
|
||||
### Checkpoint Metadata
|
||||
|
||||
```python
|
||||
config = {
|
||||
"configurable": {
|
||||
"thread_id": "user-123",
|
||||
"checkpoint_id": "checkpoint-abc123"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Checkpoint Backends
|
||||
|
||||
| Backend | Use Case |
|
||||
|---------|----------|
|
||||
| **Memory** | Testing, short-lived |
|
||||
| **SQLite** | Single machine, local |
|
||||
| **Postgres** | Production, distributed |
|
||||
|
||||
---
|
||||
|
||||
## Thread Model
|
||||
|
||||
### What is a Thread?
|
||||
|
||||
A thread (`thread_id`) represents an isolated conversation or task:
|
||||
|
||||
```
|
||||
Thread ID: "user-123"
|
||||
├── Checkpoint 1 (checkpoint-001)
|
||||
├── Checkpoint 2 (checkpoint-002)
|
||||
├── Checkpoint 3 (checkpoint-003) ← Current
|
||||
└── State (current)
|
||||
```
|
||||
|
||||
### Thread Isolation
|
||||
|
||||
- Each `thread_id` has independent state
|
||||
- Multiple threads can run in parallel
|
||||
- Human-in-the-loop works per-thread
|
||||
|
||||
---
|
||||
|
||||
## State Updates
|
||||
|
||||
### Node Returns
|
||||
|
||||
Nodes return partial state updates:
|
||||
|
||||
```python
|
||||
def node_a(state):
|
||||
return {"messages": [AIMessage("hello")]}
|
||||
```
|
||||
|
||||
### Merge Process
|
||||
|
||||
```
|
||||
Node A returns: {"messages": [msg1], "counter": 1}
|
||||
Node B returns: {"messages": [msg2], "counter": 2}
|
||||
|
||||
After reducer:
|
||||
{"messages": [msg1, msg2], "counter": 2}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Generated for the WE*
|
||||
Reference in New Issue
Block a user