DeepAgents 组件详解
Q1: backend/checkpointer/store/memory 各自具体负责什么功能
四个组件的职责详解
┌─────────────────────────────────────────────────────────────────────────┐
│ Agent Application │
└─────────────────────────────────────────────────────────────────────────┘
│
┌─────────────┬───────────────┼───────────────┬─────────────┐
│ │ │ │ │
▼ ▼ ▼ ▼ │
┌─────────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ backend │ │ store │ │checkpointer│ │ memory │ │
│ (操作环境) │ │ (数据库) │ │ (存档器) │ │ (记忆加载)│ │
├─────────────┤ ├───────────┤ ├───────────┤ ├───────────┤ │
│ 文件读写 │ │ 键值存储 │ │ 状态快照 │ │ 加载记忆 │ │
│ 命令执行 │ │ 跨会话共享 │ │ 暂停/恢复 │ │ 注入提示 │ │
└──────┬──────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
│ │ │ │ │
│ │ │ │ │
▼ ▼ ▼ ▼ │
┌─────────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ 文件系统 │ │ 结构化数据 │ │ 对话状态 │ │ 记忆文件 │ │
│ 执行环境 │ │ 长期记忆 │ │ 执行进度 │ │ AGENTS.md │ │
└─────────────┘ └───────────┘ └───────────┘ └───────────┘ │
│
┌──────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 数据流向 │
│ │
│ memory ──加载──▶ system prompt ──▶ AI 决策 ──▶ backend 写入 ──▶ store │
│ │ │
│ ▼ │
│ checkpointer 保存状态 │
└─────────────────────────────────────────────────────────────────────────┘
1. backend - 操作环境
backend=(lambda rt: StoreBackend(rt, namespace=lambda ctx: NAMESPACE))
职责:管理 AI 与外部环境的交互
| 功能 |
说明 |
| 📁 文件操作 |
read_file, write_file, edit_file, ls, glob, grep |
| 🔧 命令执行 |
execute (需要实现 SandboxBackendProtocol) |
| 🗂️ 存储位置 |
决定文件存在哪里(内存、文件系统、数据库) |
常见实现:
StateBackend - 文件存在 agent 状态中(临时)
FilesystemBackend - 文件存在本地文件系统
StoreBackend - 文件存在 LangGraph Store 中(持久化)
2. checkpointer - 状态快照
checkpointer=InMemorySaver()
职责:保存对话的执行状态
| 功能 |
说明 |
| 📸 状态快照 |
定期保存图的执行状态 |
| ⏸️ 暂停/恢复 |
支持 human-in-the-loop |
| 🔄 故障恢复 |
从断点继续执行 |
| 💬 对话历史 |
保存消息记录 |
常见实现:
InMemorySaver - 内存中(临时,重启丢失)
SqliteSaver - SQLite 数据库(持久化)
PostgresSaver - PostgreSQL(生产环境)
3. store - 结构化数据存储
store=store # SqliteStore 实例
职责:提供跨会话的持久化存储
| 功能 |
说明 |
| 💾 键值存储 |
put(namespace, key, value) |
| 🔍 命名空间 |
按命名空间组织数据 |
| 🌐 跨会话共享 |
所有线程/用户共享数据 |
| 🧠 长期记忆 |
存储需要长期保留的信息 |
常见实现:
InMemoryStore - 内存中(临时)
SqliteStore - SQLite 数据库
PostgresStore - PostgreSQL(支持向量搜索)
4. memory - 记忆加载
memory=[MEMORY_FILE] # ["/memories/AGENTS.md"]
职责:启动时加载记忆文件到系统提示
| 功能 |
说明 |
| 📖 自动加载 |
会话开始时读取指定文件 |
| 💉 注入提示 |
将内容添加到 system prompt |
| 📝 指导更新 |
告诉 AI 何时/如何更新记忆 |
对比总结表
| 组件 |
类比 |
管理的数据 |
生命周期 |
典型用途 |
| backend |
操作系统 |
文件内容、执行结果 |
取决于实现 |
文件读写、命令执行 |
| checkpointer |
游戏存档 |
对话状态、消息历史 |
会话级别 |
暂停恢复、对话历史 |
| store |
数据库 |
业务数据、长期记忆 |
持久化 |
跨会话数据共享 |
| memory |
配置文件 |
记忆文件路径 |
启动时加载 |
加载项目上下文 |
工作流程示例
# 第一次对话: "记住公司的主题色是#FD5108"
#
# 1. memory 加载 /memories/AGENTS.md 到 system prompt
# 2. AI 决定使用 edit_file 工具更新记忆
# 3. backend (StoreBackend) 执行文件编辑
# 4. store (SqliteStore) 持久化保存数据
# 5. checkpointer 保存当前对话状态
# 第二次对话: "你有哪些记忆"
#
# 1. memory 再次加载 /memories/AGENTS.md(已包含主题色)
# 2. AI 从 system prompt 中读取到记忆内容
# 3. AI 回答: "公司主题色为 #FD5108"
关键区别:
checkpointer 保存的是对话进度(thread 级别)
store 保存的是业务数据(全局共享)
backend 是操作接口(怎么读写)
memory 是加载机制(读什么)
Q2: StateBackend和StoreBackend 具体有什么区别
核心区别一览
┌─────────────────────────────────────────────────────────────────────────────┐
│ 存储架构对比 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ StateBackend StoreBackend │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Agent State │ │ LangGraph │ │
│ │ (会话状态) │ │ BaseStore │ │
│ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Checkpointer │ │ SqliteStore / │ │
│ │ (内存/数据库) │ │ PostgresStore │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ 生命周期: thread 级别 生命周期: 全局持久化 │
│ 跨线程共享: ❌ 跨线程共享: ✅ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
1. StateBackend - 会话状态存储
数据存储位置
# StateBackend 将文件存储在 agent 的 state 中
files = self.runtime.state.get("files", {})
# state 结构:
{
"messages": [...],
"files": {
"/path/to/file.txt": {
"content": ["line1", "line2"],
"created_at": "2025-01-01T00:00:00",
"modified_at": "2025-01-01T00:00:00"
}
}
}
持久化机制
# StateBackend 本身不直接持久化,依赖 checkpointer
# 文件数据作为 state 的一部分被 checkpointer 保存
agent = create_deep_agent(
backend=StateBackend, # 文件存在 state.files 中
checkpointer=InMemorySaver(), # state 被保存在内存中
)
# 数据流:
# write_file() → WriteResult(files_update={...})
# → Command(update={"files": {...}})
# → state 更新
# → checkpointer 保存
生命周期
| 场景 |
数据是否保留 |
| 同一 thread 内多次调用 |
✅ 保留 |
| 不同 thread_id |
❌ 不共享 |
| 程序重启 (InMemorySaver) |
❌ 丢失 |
| 程序重启 (SqliteSaver) |
✅ 保留 |
2. StoreBackend - 全局持久化存储
数据存储位置
# StoreBackend 使用 LangGraph 的 BaseStore
store = self.runtime.store # SqliteStore / PostgresStore
# 存储结构: namespace + key + value
store.put(
namespace=("memories",), # 命名空间
key="/memories/AGENTS.md", # 文件路径
value={ # 文件数据
"content": ["line1", "line2"],
"created_at": "...",
"modified_at": "..."
}
)
持久化机制
# StoreBackend 直接使用 store 进行持久化
class StoreBackend:
def write(self, file_path: str, content: str) -> WriteResult:
store = self._get_store() # 获取 SqliteStore/PostgresStore
namespace = self._get_namespace()
# 直接写入 store,立即持久化
store.put(namespace, file_path, store_value)
return WriteResult(path=file_path, files_update=None)
# 注意: files_update=None,因为不需要更新 state
生命周期
| 场景 |
数据是否保留 |
| 同一 thread 内多次调用 |
✅ 保留 |
| 不同 thread_id |
✅ 共享 |
| 程序重启 (SqliteStore) |
✅ 保留 |
| 程序重启 (PostgresStore) |
✅ 保留 |
3. 关键代码对比
写入操作对比
# ============ StateBackend ============
def write(self, file_path: str, content: str) -> WriteResult:
files = self.runtime.state.get("files", {})
# 返回 files_update,让 LangGraph 更新 state
new_file_data = create_file_data(content)
return WriteResult(
path=file_path,
files_update={file_path: new_file_data} # ← 返回更新
)
# ============ StoreBackend ============
def write(self, file_path: str, content: str) -> WriteResult:
store = self._get_store()
namespace = self._get_namespace()
# 直接写入 store,立即持久化
store.put(namespace, file_path, store_value)
return WriteResult(
path=file_path,
files_update=None # ← 不需要更新 state
)
读取操作对比
# ============ StateBackend ============
def read(self, file_path: str, ...) -> str:
# 从 state 中读取
files = self.runtime.state.get("files", {})
file_data = files.get(file_path)
# ============ StoreBackend ============
def read(self, file_path: str, ...) -> str:
# 从 store 中读取
store = self._get_store()
namespace = self._get_namespace()
item = store.get(namespace, file_path)
4. StoreBackend 持久化实现详解
SqliteStore 的实现
from langgraph.store.sqlite import SqliteStore
# 创建 store
with SqliteStore.from_conn_string("checkpoints.db") as store:
# 写入数据
store.put(
namespace=("memories",), # 命名空间(类似文件夹)
key="/memories/AGENTS.md", # 键(类似文件名)
value={ # 值(文件内容)
"content": ["# Memory", "主题色: #FD5108"],
"created_at": "2025-01-01T00:00:00",
"modified_at": "2025-01-01T00:00:00"
}
)
# 读取数据
item = store.get(("memories",), "/memories/AGENTS.md")
# Item(namespace=['memories'], key='/memories/AGENTS.md', value={...})
# 搜索数据
items = store.search(("memories",)) # 返回该命名空间下所有项
数据库表结构(简化)
-- SQLite 内部表结构
CREATE TABLE store (
namespace TEXT, -- 命名空间
key TEXT, -- 键
value JSON, -- 值(JSON 格式)
created_at TIMESTAMP,
updated_at TIMESTAMP,
PRIMARY KEY (namespace, key)
);
-- 写入操作
INSERT OR REPLACE INTO store (namespace, key, value, created_at, updated_at)
VALUES ('["memories"]', '/memories/AGENTS.md', '{...}', ..., ...);
-- 读取操作
SELECT * FROM store
WHERE namespace = '["memories"]' AND key = '/memories/AGENTS.md';
5. 使用场景对比
| 场景 |
推荐 Backend |
原因 |
| 临时文件处理 |
StateBackend |
数据不需要跨会话保留 |
| 代码生成/编辑 |
StateBackend |
一次性任务 |
| 用户偏好设置 |
StoreBackend |
需要跨会话保留 |
| 长期记忆 |
StoreBackend |
需要跨会话共享 |
| 多用户共享数据 |
StoreBackend |
全局可访问 |
| 项目知识库 |
StoreBackend |
持久化存储 |
6. 混合使用 - CompositeBackend
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
# 混合存储:临时文件用 StateBackend,长期记忆用 StoreBackend
backend = CompositeBackend(
default=StateBackend(), # 默认使用临时存储
routes={
"/memories/": StoreBackend(namespace=lambda ctx: ("memories",)),
"/knowledge/": StoreBackend(namespace=lambda ctx: ("knowledge",)),
}
)
# 文件路径决定存储位置:
# /tmp/file.txt → StateBackend (临时)
# /memories/AGENTS.md → StoreBackend (持久化)
# /knowledge/docs.md → StoreBackend (持久化)
总结对比表
| 特性 |
StateBackend |
StoreBackend |
| 存储位置 |
state.files |
BaseStore (SQLite/PostgreSQL) |
| 持久化方式 |
依赖 checkpointer |
直接写入数据库 |
| 跨线程共享 |
❌ |
✅ |
| 生命周期 |
thread 级别 |
全局持久化 |
| 适用场景 |
临时文件、代码生成 |
长期记忆、用户偏好 |
| 性能 |
更快(内存操作) |
稍慢(数据库 I/O) |
| 可靠性 |
依赖 checkpointer |
数据库保证 |