Skip to content

05. 后端类型详解:五种存储策略

选择最适合你场景的存储后端

引言

在上一篇文章中,我们了解了 DeepAgents 虚拟文件系统的设计理念。本文将深入探讨五种内置后端类型,帮助你根据场景选择最合适的存储策略。

后端类型速查表

后端类型持久化跨线程代码执行适用场景
StateBackend单次会话、临时任务
FilesystemBackend-本地开发、文件操作
StoreBackend长期记忆、知识库
LocalShellBackend-本地开发(需谨慎)
沙盒后端-安全代码执行

五种后端类型总览对比

1. StateBackend - 临时状态存储

概念

StateBackend 是 DeepAgents 的默认后端,将文件存储在 LangGraph 的状态中。

生活类比:就像会议白板上的笔记——会议结束后就擦掉了。

特点

优点

  • 无需额外配置,开箱即用
  • 适合临时任务和草稿
  • 同一线程内自动通过 checkpoint 持久化

限制

  • 线程结束后数据丢失
  • 不同线程之间不共享
  • 不适合长期存储

使用方式

typescript
import { createDeepAgent } from "deepagents";
import { StateBackend } from "deepagents/backends";

// 方式一:默认就是 StateBackend
const agent1 = createDeepAgent();

// 方式二:显式指定
const agent2 = createDeepAgent({
  backend: (rt) => new StateBackend(rt)
});

数据生命周期

线程 1                          线程 2
┌─────────────────────┐        ┌─────────────────────┐
│ write_file("/a.md") │        │ read_file("/a.md")  │
│       ✅ 成功        │        │       ❌ 找不到      │
└─────────────────────┘        └─────────────────────┘
         │                              │
         ▼                              ▼
    State 1                        State 2
   (独立的)                       (独立的)

StateBackend 线程隔离示意图

适用场景

  • 🎯 单次问答任务
  • 🎯 临时计算和分析
  • 🎯 原型开发和测试
  • 🎯 上下文卸载(大内容临时存储)

2. FilesystemBackend - 本地磁盘

概念

FilesystemBackend 直接读写本地磁盘文件,让代理可以操作真实的文件系统。

生活类比:代理可以直接访问你电脑上的文件夹。

⚠️ 安全警告

┌────────────────────────────────────────────────────────────┐
│  ⚠️ 重要安全提示                                           │
│                                                            │
│  FilesystemBackend 会赋予代理对本地文件的读写权限!         │
│                                                            │
│  风险:                                                    │
│  • 代理可能读取敏感文件(密钥、凭据、.env)                 │
│  • 文件修改是永久且不可逆的                                │
│  • 结合网络工具可能导致数据泄露                            │
│                                                            │
│  建议:                                                    │
│  • 仅在开发环境使用                                        │
│  • 启用 virtual_mode: true                                 │
│  • 配合人机协作审批敏感操作                                │
└────────────────────────────────────────────────────────────┘

使用方式

typescript
import { createDeepAgent } from "deepagents";
import { FilesystemBackend } from "deepagents/backends";

const agent = createDeepAgent({
  backend: new FilesystemBackend({
    rootDir: "/Users/me/projects/my-app",
    virtualMode: true  // 强烈建议开启!
  })
});

配置选项

选项类型说明
rootDirstring根目录(必须是绝对路径)
virtualModeboolean是否启用路径限制(默认 false)

virtualMode 的作用

typescript
// virtualMode: false(不安全!)
// 代理可以访问:
// - /Users/me/projects/my-app/src/
// - /Users/me/.ssh/id_rsa  ← 危险!
// - /etc/passwd            ← 危险!

// virtualMode: true(推荐)
// 代理只能访问 rootDir 内的路径
// - /Users/me/projects/my-app/src/  ✅
// - /Users/me/.ssh/id_rsa           ❌ 被阻止
// - ../../../etc/passwd             ❌ 被阻止

virtualMode 安全边界对比

适用场景

  • 🎯 本地开发 CLI 工具
  • 🎯 编码助手(操作项目文件)
  • 🎯 CI/CD 流水线(需做好安全配置)

不适用场景

  • ❌ Web 服务器或 API
  • ❌ 多租户系统
  • ❌ 处理不受信任的用户输入

3. StoreBackend - 跨线程持久化

概念

StoreBackend 使用 LangGraph 的 BaseStore 实现跨线程的持久化存储。

生活类比:像一个云端笔记本,无论什么时候打开,之前的笔记都还在。

核心优势

线程 1                          线程 2
┌─────────────────────────┐    ┌─────────────────────────┐
│ write_file("/pref.md")  │    │ read_file("/pref.md")   │
│        ✅ 成功           │    │        ✅ 成功           │
└───────────┬─────────────┘    └───────────┬─────────────┘
            │                              │
            ▼                              ▼
         ┌─────────────────────────────────────┐
         │           LangGraph Store           │
         │     (跨线程持久化,数据共享)          │
         └─────────────────────────────────────┘

StoreBackend 跨线程持久化架构

使用方式

typescript
import { createDeepAgent } from "deepagents";
import { StoreBackend } from "deepagents/backends";
import { InMemoryStore } from "@langchain/langgraph";

// 开发环境使用 InMemoryStore
const store = new InMemoryStore();

const agent = createDeepAgent({
  backend: (rt) => new StoreBackend(rt),
  store: store
});

Store 实现选择

Store 类型场景特点
InMemoryStore开发测试重启后数据丢失
PostgresStore生产环境真正的持久化
LangSmith 自动配置云部署无需手动配置
typescript
// 生产环境使用 PostgresStore
import { PostgresStore } from "@langchain/langgraph-checkpoint-postgres";

const store = new PostgresStore({
  connectionString: process.env.DATABASE_URL
});

const agent = createDeepAgent({
  backend: (rt) => new StoreBackend(rt),
  store: store
});

适用场景

  • 🎯 长期记忆(用户偏好、学习到的知识)
  • 🎯 跨会话的研究项目
  • 🎯 知识库积累
  • 🎯 部署到 LangSmith

4. LocalShellBackend - 本地 Shell

概念

LocalShellBackend 在 FilesystemBackend 基础上增加了 execute 工具,允许代理执行 Shell 命令。

生活类比:不仅能看你的文件,还能帮你运行命令。

⚠️⚠️⚠️ 严重安全警告

┌────────────────────────────────────────────────────────────┐
│  🚨 极度危险 - 请务必理解风险                               │
│                                                            │
│  LocalShellBackend 允许代理执行任意 Shell 命令!            │
│                                                            │
│  代理可以:                                                 │
│  • 以你的用户权限执行任何命令                               │
│  • 读取任何可访问文件                                       │
│  • 修改或删除文件                                          │
│  • 安装软件、发起网络请求                                   │
│  • 消耗无限 CPU、内存、磁盘                                 │
│                                                            │
│  仅在以下情况使用:                                         │
│  ✅ 本地开发环境                                            │
│  ✅ 你完全信任代理的行为                                    │
│  ✅ 配合人机协作审批                                        │
│                                                            │
│  绝对不要用于:                                             │
│  ❌ 生产环境                                                │
│  ❌ Web 服务器或 API                                        │
│  ❌ 处理不受信任的用户输入                                   │
└────────────────────────────────────────────────────────────┘

LocalShellBackend 安全风险与防护层级

使用方式

typescript
import { createDeepAgent } from "deepagents";
import { LocalShellBackend } from "deepagents/backends";
import { MemorySaver } from "@langchain/langgraph";

const checkpointer = new MemorySaver();

const agent = createDeepAgent({
  backend: new LocalShellBackend({
    rootDir: ".",
    env: { PATH: "/usr/bin:/bin" },
    timeout: 120,           // 命令超时(秒)
    maxOutputBytes: 100000  // 输出限制
  }),
  interruptOn: {
    execute: true  // 强烈建议:所有命令执行前需人工审批
  },
  checkpointer
});

配置选项

选项默认值说明
rootDir必填工作目录
env{}环境变量
inheritEnvfalse是否继承系统环境变量
timeout120命令超时(秒)
maxOutputBytes100000输出大小限制

execute 工具

typescript
// 代理可以这样调用
execute("npm install")
execute("npm run build")
execute("git status")

// 返回结果
{
  stdout: "...",
  stderr: "...",
  exitCode: 0
}

适用场景

  • 🎯 本地编码助手
  • 🎯 开发过程中的快速迭代
  • 🎯 仅限你完全信任代理的场景

5. 沙盒后端 - 安全代码执行

概念

沙盒后端在隔离的环境中执行代码,保护宿主系统不受影响。

生活类比:给代理一个独立的虚拟机,让它在里面自由操作。

可用的沙盒提供商

提供商特点适用场景
Modal云端容器,按需计费生产环境
Daytona开发环境管理团队协作
Deno轻量级 JS/TS 沙盒快速原型
Node VFS本地虚拟文件系统开发测试

使用示例(Deno)

typescript
import { createDeepAgent } from "deepagents";
import { DenoSandbox } from "@langchain/deno";

const sandbox = await DenoSandbox.create({
  memoryMb: 1024,
  lifetime: "10m"
});

try {
  const agent = createDeepAgent({
    backend: sandbox,
    systemPrompt: "你是一个 JavaScript 编码助手,可以在沙盒中执行代码。"
  });

  const result = await agent.invoke({
    messages: [{
      role: "user",
      content: "创建一个 HTTP 服务器并测试它"
    }]
  });
} finally {
  await sandbox.close();
}

沙盒 vs LocalShellBackend

特性LocalShellBackend沙盒后端
执行环境宿主机隔离容器
安全性⚠️ 危险✅ 安全
性能稍慢
适用场景本地开发生产环境

沙盒后端 vs LocalShellBackend 对比

安全最佳实践

┌─────────────────────────────────────────────────────────────┐
│  🔒 沙盒安全原则                                            │
│                                                            │
│  1. 永远不要把密钥放入沙盒                                  │
│  2. 限制沙盒的网络访问                                      │
│  3. 设置资源限制(内存、CPU、时间)                         │
│  4. 定期清理沙盒环境                                        │
│  5. 记录和审计沙盒内的操作                                  │
└─────────────────────────────────────────────────────────────┘

后端选择决策树

开始

  ├─ 需要执行代码?
  │    │
  │    ├─ 是 ─────┬─ 生产环境?─── 是 ──→ 沙盒后端
  │    │          │
  │    │          └─ 本地开发?─── 是 ──→ LocalShellBackend
  │    │                                 (配合 interruptOn)
  │    │
  │    └─ 否 ────→ 需要跨线程持久化?
  │                  │
  │                  ├─ 是 ──→ StoreBackend
  │                  │
  │                  └─ 否 ─→ 需要操作本地文件?
  │                             │
  │                             ├─ 是 ──→ FilesystemBackend
  │                             │
  │                             └─ 否 ──→ StateBackend (默认)

  └─ 需要混合存储?─── 是 ──→ CompositeBackend (下篇详解)

后端选择决策树

实践示例:选择合适的后端

场景一:简单问答机器人

typescript
// 使用默认的 StateBackend 即可
const chatBot = createDeepAgent({
  systemPrompt: "你是一个友好的聊天助手"
});

场景二:本地编码助手

typescript
import { FilesystemBackend } from "deepagents/backends";

const codingAssistant = createDeepAgent({
  backend: new FilesystemBackend({
    rootDir: process.cwd(),
    virtualMode: true
  }),
  systemPrompt: "你是一个编码助手,可以读取和修改项目文件"
});

场景三:带记忆的个人助理

typescript
import { StoreBackend } from "deepagents/backends";
import { InMemoryStore } from "@langchain/langgraph";

const personalAssistant = createDeepAgent({
  backend: (rt) => new StoreBackend(rt),
  store: new InMemoryStore(),
  systemPrompt: `你是一个个人助理。
    记住用户的偏好,保存到 /preferences.md
    记住重要事项,保存到 /notes/`
});

场景四:安全的代码执行平台

typescript
import { DenoSandbox } from "@langchain/deno";

const sandbox = await DenoSandbox.create({ memoryMb: 512 });

const codeRunner = createDeepAgent({
  backend: sandbox,
  systemPrompt: "你可以执行用户提供的代码,在安全的沙盒环境中运行"
});

小结

本文介绍了 DeepAgents 的五种后端类型:

后端一句话总结关键场景
StateBackend临时存储,线程内有效单次任务、默认选择
FilesystemBackend本地磁盘读写编码助手、本地开发
StoreBackend跨线程持久化长期记忆、知识库
LocalShellBackend本地执行命令开发工具(需谨慎)
沙盒后端安全代码执行生产环境代码运行

选择原则

  • 🔒 安全第一:生产环境使用沙盒
  • 💾 按需持久化:长期数据用 StoreBackend
  • ⚡ 简单优先:默认 StateBackend 够用就不换

下一步

在下一篇文章中,我们将学习 CompositeBackend——如何组合多个后端,实现灵活的路由策略。

实践任务

  1. 创建一个使用 FilesystemBackend 的代理,让它能读写你项目中的文件
  2. 使用 StoreBackend 实现一个能"记住"用户偏好的助手
  3. 如果有条件,尝试配置一个沙盒后端

参考资源

读文档、看源码、写代码,理解 AI Agent 本质 🤖